NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/52499: stresep uses memmove with of-by-one length



>Number:         52499
>Category:       lib
>Synopsis:       stresep uses memmove with of-by-one length
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Aug 23 07:15:00 +0000 2017
>Originator:     Justin
>Release:        1.3
>Organization:
XLAB d.o.o.
>Environment:
N/A
>Description:
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/string/stresep.c.diff?r1=1.2&r2=1.3&only_with_tag=MAIN&f=h

old:
strcpy(s - 1, s);
new:
memmove(s - 1, s, strlen(s));

But 'new' should also copy terminating NULL (as strcpy does), otherwise s gets longer by 1 char for each escaped delim. memmove should be corrected to:
memmove(s - 1, s, strlen(s) + 1);


>How-To-Repeat:
#include <stdio.h>
#define NN 10
int main() {
    //char* str = strdup("aa bb \"cc\\ dd\"-");
    char* str = strdup("aa bb cc\\ \\ \\ \\ dd-");
    char **ap, *argv[NN];
    const char *delim = " \t\n";;
    char esc = '\\';

    printf("/*-------------------------------------*/\n");

    // parse string
    for (ap = argv; ap < &argv[NN-1] && (*ap = stresep(&str, delim, esc)) != NULL;) {
        if (**ap != '\0')
            ap++;
    }

    // print result
    char **ch;
    int ii;
    for (ii = 0, ch = argv; *ch != nullptr; ii++, ch++) {
        printf("argv[%d] = %p %s\n", ii, *ch, *ch);
    }
    printf("/*-------------------------------------*/\n");
}


I expected:
argv[2] = 0x15aac26 cc    dd-
But I got:
argv[2] = 0x15aac26 cc    dd-----

>Fix:
memmove(s - 1, s, strlen(s) + 1);



Home | Main Index | Thread Index | Old Index