Char buffer error in a Structure

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • ...vagrahb

    Char buffer error in a Structure

    Hi,
    I have the following structure

    struct Format
    {
    char x[12];
    unsigned char a;
    unsigned char b;
    unsigned char c;
    char y[30];
    } __attribute__(( __aligned__));

    I have a csv file which I am reading the data from which has fields
    which match the structure and I tokenize the data read from the file
    using strtok. the problem is when I do a strcpy to the the string x
    and print the value from the structure for x,
    I get the whole string and an extra char at the end of the string. it
    is a special char and I am not able to get rid of that special char.
    It only happens when I have a token that is exactly 12 chars wide. if
    the token being copied into x is smaller than 12 it is fine. But if I
    try to copy a token which is 12 bytes long I get an extra char at the
    end in x.


    I tried all sorts of stuff even memcpy etc and still I end up with
    that extra char in x. If I just print the token there is no extra char
    but when I copy it into that member of structure and print it I get a
    extra token.

    sample out put :
    Original token
    Awsche-tonol
    1
    9
    47
    Fiery Legion

    Error output from displaying members of the Struct:
    Awsche-tonol,1,9,47,F iery Legion


    Any help regarding this please.

    Regards.



  • Gordon Burditt

    #2
    Re: Char buffer error in a Structure

    I have the following structure
    >
    struct Format
    {
    char x[12];
    unsigned char a;
    unsigned char b;
    unsigned char c;
    char y[30];
    } __attribute__(( __aligned__));
    >
    >I have a csv file which I am reading the data from which has fields
    >which match the structure and I tokenize the data read from the file
    >using strtok. the problem is when I do a strcpy to the the string x
    >and print the value from the structure for x,
    Show me the code. Particularly, show me where you modify format.a
    and how that relates to the point where you put something in x.
    >I get the whole string and an extra char at the end of the string. it
    >is a special char and I am not able to get rid of that special char.
    >It only happens when I have a token that is exactly 12 chars wide. if
    If you put 12 characters (not including the \0 terminator) into x,
    then it is NOT A String and you should not use the %s format to
    attempt to print NOT A Strings. If you used strcpy() (as opposed
    to, say, strncpy()) to do it, you also committed a buffer overflow
    and invoked the wrath of undefined behaviour by doing so.

    After you did that copy, did you perhaps assign something to format.a,
    clobbering the string terminator character ?
    >the token being copied into x is smaller than 12 it is fine. But if I
    >try to copy a token which is 12 bytes long I get an extra char at the
    >end in x.
    >

    Comment

    • ...vagrahb

      #3
      Re: Char buffer error in a Structure

      On Apr 19, 12:53 pm, gordonb.2y...@b urditt.org (Gordon Burditt) wrote:
      I have the following structure
      >
      struct Format
      {
      char x[12];
      unsigned char a;
      unsigned char b;
      unsigned char c;
      char y[30];
      } __attribute__(( __aligned__));
      >
      I have a csv file which I am reading the data from which has fields
      which match the structure and I tokenize the data read from the file
      using strtok. the problem is when I do a strcpy to the the string x
      and print the value from the structure for x,
      >
      Show me the code. Particularly, show me where you modify format.a
      and how that relates to the point where you put something in x.
      >
      I get the whole string and an extra char at the end of the string. it
      is a special char and I am not able to get rid of that special char.
      It only happens when I have a token that is exactly 12 chars wide. if
      >
      If you put 12 characters (not including the \0 terminator) into x,
      then it is NOT A String and you should not use the %s format to
      attempt to print NOT A Strings. If you used strcpy() (as opposed
      to, say, strncpy()) to do it, you also committed a buffer overflow
      and invoked the wrath of undefined behaviour by doing so.
      >
      After you did that copy, did you perhaps assign something to format.a,
      clobbering the string terminator character ?
      >
      the token being copied into x is smaller than 12 it is fine. But if I
      try to copy a token which is 12 bytes long I get an extra char at the
      end in x.
      the thing is I have to get the structure size to be 45 bytes and so I
      cannot fit in \0 into the string coz then I will have to make the size
      of the x as 13 as opposed to 12.

      Code to tokenize
      split = strtok(buffer," ,");
      no_tok =0;
      j=0;
      while(split != NULL)
      {

      strcpy(temp[j],split);
      strcat(temp[j],"\0");
      //printf("%s",tem p[j]);
      j++;
      split = strtok(NULL,"," );
      ++no_tok;
      }

      Code to store into the Structure
      if(no_tok != 0)
      {
      rec++;
      strcpy(F.x,temp[0]);
      F.a = atoi(temp[1]);
      F.b = atoi(temp[2]);
      F.c = atoi(temp[3]);

      if(no_tok == 5)
      strcpy(F.y,temp[4]);
      else
      if(no_tok == 4)
      {
      strcpy(F.Guild, "\0");
      }
      }

      and another problem is even if I am using #pragma(1) I am not able to
      get the size of the struct to 45 and always ends up as 48.

      Comment

      • Eric Sosman

        #4
        Re: Char buffer error in a Structure

        ....vagrahb wrote:
        Hi,
        I have the following structure
        >
        struct Format
        {
        char x[12];
        unsigned char a;
        unsigned char b;
        unsigned char c;
        char y[30];
        } __attribute__(( __aligned__));
        FYI, the __attribute__(( __aligned__)) stuff is not C, but
        C-with-lipstick.
        [...] if
        the token being copied into x is smaller than 12 it is fine. But if I
        try to copy a token which is 12 bytes long I get an extra char at the
        end in x.
        You have forgotten the '\0' character that marks the end of
        a string in C. The x[] array has room for twelve characters, so
        it can hold *eleven* characters of string "payload" in addition
        to the '\0' that marks the end. When you try to stuff thirteen
        characters -- twelve payload plus the '\0' marker -- into an
        array that only has room for twelve of them, your program starts
        behaving like Jack Nicholson in "The Shining."

        --
        Eric Sosman
        esosman@ieee-dot-org.invalid

        Comment

        • Gordon Burditt

          #5
          Re: Char buffer error in a Structure

          struct Format
          {
          char x[12];
          unsigned char a;
          unsigned char b;
          unsigned char c;
          char y[30];
          } __attribute__(( __aligned__));
          Most of the stuff on the above line isn't actual C, and doesn't it
          *DEMAND* padding?
          >If you put 12 characters (not including the \0 terminator) into x,
          >then it is NOT A String and you should not use the %s format to
          >attempt to print NOT A Strings. If you used strcpy() (as opposed
          >to, say, strncpy()) to do it, you also committed a buffer overflow
          >and invoked the wrath of undefined behaviour by doing so.
          >the thing is I have to get the structure size to be 45 bytes and so I
          >cannot fit in \0 into the string coz then I will have to make the size
          >of the x as 13 as opposed to 12.
          If you leave it as size 12 then when you copy a 12-character something
          into it, you'd darn well better NOT use strcpy(), and you'd darn
          well better NOT use %s to print it. It is acceptable (but very bad
          style because things that look like strings but aren't are confusing
          to handle) to use fixed-size arrays like this (UNIX v6 used directories
          with a 14-character array for the name and a short for an inode
          number), but DON'T PRETEND IT'S A STRING. You get the extra character
          because you don't stop outputting at 12 characters. If you printed
          it properly, you'd never go over 12 characters.

          >Code to store into the Structure
          >if(no_tok != 0)
          >{
          rec++;
          strcpy(F.x,temp[0]);
          ***ERROR*** If temp[0] contains a 12-character string, you are committing
          a buffer overflow here. Try:
          strncpy(F.x, temp[0], sizeof(F.x));
          AND REALIZE THAT F.x DOES NOT CONTAIN A STRING, SO YOU CAN'T PRINT IT LIKE ONE.
          F.a = atoi(temp[1]);
          F.b = atoi(temp[2]);
          F.c = atoi(temp[3]);
          >
          if(no_tok == 5)
          strcpy(F.y,temp[4]);
          Likely you have the same problem here if you need to cram 30 characters
          into y.
          else
          > if(no_tok == 4)
          > {
          > strcpy(F.Guild, "\0");
          > }
          >}
          >
          >and another problem is even if I am using #pragma(1) I am not able to
          >get the size of the struct to 45 and always ends up as 48.
          C lets the compiler make the structure any size it wants to make
          it. And doesn't that extra non-C crap on the structure declaration
          REQUIRE alignment?


          Comment

          Working...