Menu

#8 segfault while removing attribute with ezxml_set_attr

open
nobody
None
7
2007-02-07
2007-02-06
Peter_Hajdu
No

While doing simple attribute deleting with the ezxml_set_attr function, the program throws segfault.

I've attached the sample code.

gcc version: 4.1.2

Discussion

  • Peter_Hajdu

    Peter_Hajdu - 2007-02-06
     
  • Peter_Hajdu

    Peter_Hajdu - 2007-02-06
    • priority: 5 --> 7
     
  • Peter_Hajdu

    Peter_Hajdu - 2007-02-06

    Logged In: YES
    user_id=1565254
    Originator: YES

    The error occurs at line 951 in ezxml.c according to valgrind. It sais: Invalid read of size 1

    memmove(xml->attr[c + 1] + (l / 2), xml->attr[c + 1] + (l / 2) + 1,
    (c / 2) - (l / 2)); // fix list of which name/vals are malloced

    It's a bit complicated to me, so I couldn't fix it.

     
  • Peter_Hajdu

    Peter_Hajdu - 2007-02-07

    Logged In: YES
    user_id=1565254
    Originator: YES

    I have solved the problem, and have sent the patch. Please have a look at it.

     
  • Peter_Hajdu

    Peter_Hajdu - 2007-02-07
    • status: open --> pending
     
  • Peter_Hajdu

    Peter_Hajdu - 2007-02-07
    • status: pending --> open
     
  • Nobody/Anonymous

    Logged In: NO

    I ran into the same bug with Visual C++ 2005.
    My fix was to change..

    if (value) xml->attr[l + 1] = (char *)value; // set attribute value
    else { // remove attribute
    if (xml->attr[c + 1][l / 2] & EZXML_NAMEM) free(xml->attr[l]);
    memmove(xml->attr + l, xml->attr + l + 2, (c - l + 2) * sizeof(char*));
    xml->attr = realloc(xml->attr, (c + 2) * sizeof(char *));
    memmove(xml->attr[c + 1] + (l / 2), xml->attr[c + 1] + (l / 2) + 1,
    (c / 2) - (l / 2)); // fix list of which name/vals are malloced
    }

    to

    if (value) xml->attr[l + 1] = (char *)value; // set attribute value
    else { // remove attribute
    if (xml->attr[c + 1][l / 2] & EZXML_NAMEM) free(xml->attr[l]);
    memmove(xml->attr + l, xml->attr + l + 2, (c - l + 2) * sizeof(char*));
    c -= 2; /* We have one less element */
    xml->attr = realloc(xml->attr, (c + 2) * sizeof(char *));
    memmove(xml->attr[c + 1] + (l / 2), xml->attr[c + 1] + (l / 2) + 1,
    (c / 2) - (l / 2)); // fix list of which name/vals are malloced
    }

    After we move the data with memmove to compress the attribute list, the old set of flags is in undefined memory. Also c is too big anyways when we hit the realloc.

     

Log in to post a comment.