From 76fbcfdd66556dfe8e813cda50ac28071d0da573 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 14 Mar 1998 09:27:24 +0000 Subject: [PATCH] Update. 1998-03-14 00:52 Tim Waugh * posix/wordexp.c (parse_param): Perform field-splitting after expanding positional parameter. * posix/wordexp-tst.sh: Test that field-splitting is performed after expanding positional parameter. * posix/wordexp.c (parse_param): Fixed memory leak in field-splitting after parameter expansion. 1998-03-14 Ulrich Drepper * locale/programs/linereader.c (lr_token): Return EOF token at EOF. (get_toplvl_escape): Correctly terminate loop at EOF. Patch by Cristian Gafton . --- ChangeLog | 18 +++++++++++++ locale/programs/linereader.c | 10 ++++++-- localedata/ChangeLog | 5 ++++ localedata/locales/ru_RU | 20 +++++++-------- posix/wordexp-tst.sh | 6 +++-- posix/wordexp.c | 49 +++++++++++++++++++++++------------- string/bits/string2.h | 2 +- 7 files changed, 77 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8f4a14ba85..a9445895e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +1998-03-14 00:52 Tim Waugh + + * posix/wordexp.c (parse_param): Perform field-splitting after + expanding positional parameter. + + * posix/wordexp-tst.sh: Test that field-splitting is performed + after expanding positional parameter. + + * posix/wordexp.c (parse_param): Fixed memory leak in + field-splitting after parameter expansion. + +1998-03-14 Ulrich Drepper + + * locale/programs/linereader.c (lr_token): Return EOF token at + EOF. + (get_toplvl_escape): Correctly terminate loop at EOF. + Patch by Cristian Gafton . + 1998-03-13 16:55 Ulrich Drepper * string/tester.c (test_strpbrk): Add more strpbrk tests. diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c index 83679b7655..8da5c5330f 100644 --- a/locale/programs/linereader.c +++ b/locale/programs/linereader.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -159,6 +159,12 @@ lr_token (struct linereader *lr, const struct charset_t *charset) { ch = lr_getc (lr); + if (ch == EOF) + { + lr->token.tok = tok_eof; + return &lr->token; + }; + if (ch == '\n') { lr->token.tok = tok_eol; @@ -283,7 +289,7 @@ get_toplvl_escape (struct linereader *lr) esc_error: lr->token.val.str.start = &lr->buf[start_idx]; - while (ch != EOF || !isspace (ch)) + while (ch != EOF && !isspace (ch)) ch = lr_getc (lr); lr->token.val.str.len = lr->idx - start_idx; diff --git a/localedata/ChangeLog b/localedata/ChangeLog index 05b3b0b163..34e95cdfe4 100644 --- a/localedata/ChangeLog +++ b/localedata/ChangeLog @@ -1,3 +1,8 @@ +1998-03-14 Ulrich Drepper + + * locales/ru_RU: Correct last patch. + Patch by Cristian Gafton . + 1998-03-11 Ulrich Drepper * locales/de_DE: Use common german data and time format not ISO diff --git a/localedata/locales/ru_RU b/localedata/locales/ru_RU index d898f63eec..56755ca316 100644 --- a/localedata/locales/ru_RU +++ b/localedata/locales/ru_RU @@ -2134,18 +2134,18 @@ abday "";/ "";/ "";/ "" -mon "<%'>";/ - "<%'>";/ +mon "";/ + "";/ "";/ - "<%'>";/ + "";/ "";/ - "<%'>";/ - "<%'>";/ - "";/ - "<%'>";/ - "<%'>";/ - "<%'>";/ - "<%'>" + "";/ + "";/ + "";/ + "";/ + "";/ + "";/ + "" abmon "";/ "";/ "";/ diff --git a/posix/wordexp-tst.sh b/posix/wordexp-tst.sh index e341e6435d..a5445f1ee6 100755 --- a/posix/wordexp-tst.sh +++ b/posix/wordexp-tst.sh @@ -61,11 +61,13 @@ we_wordv[0] = "5" EOF ${elf_objpfx}${rtld_installed_name} --library-path ${common_objpfx} \ -${common_objpfx}posix/wordexp-test '$2 ${3}' 2nd 3rd > ${testout}6 -cat <<"EOF" | cmp - ${testout}6 || failed=1 +${common_objpfx}posix/wordexp-test '$2 ${3} $4' 2nd 3rd "4 th" > ${testout}7 +cat <<"EOF" | cmp - ${testout}7 || failed=1 wordexp returned 0 we_wordv[0] = "2nd" we_wordv[1] = "3rd" +we_wordv[2] = "4" +we_wordv[3] = "th" EOF exit $failed diff --git a/posix/wordexp.c b/posix/wordexp.c index 0c89e02234..5e0e985006 100644 --- a/posix/wordexp.c +++ b/posix/wordexp.c @@ -1018,6 +1018,7 @@ parse_param (char **word, size_t *word_length, size_t *max_length, int colon_seen = 0; int depth = 0; int seen_hash = 0; + int free_value = 0; int error; for (; words[*offset]; ++(*offset)) @@ -1285,7 +1286,6 @@ envsubst: if (isdigit(*env)) { int n = *env - '0'; - char *param; free (env); if (n >= __libc_argc) @@ -1293,12 +1293,8 @@ envsubst: return 0; /* Replace with the appropriate positional parameter */ - param = __strdup (__libc_argv[n]); - if (!param) - return WRDE_NOSPACE; - - *word = w_addstr (*word, word_length, max_length, param); - return *word ? 0 : WRDE_NOSPACE; + value = __libc_argv[n]; + goto maybe_fieldsplit; } /* Is it `$$' ? */ else if (*env == '$') @@ -1347,6 +1343,7 @@ envsubst: } } + free_value = 1; if (value) goto maybe_fieldsplit; @@ -1666,31 +1663,42 @@ envsubst: return *word ? 0 : WRDE_NOSPACE; } - maybe_fieldsplit: if (quoted || !pwordexp) { /* Quoted - no field split */ *word = w_addstr (*word, word_length, max_length, value); + if (free_value) + free (value); + return *word ? 0 : WRDE_NOSPACE; } else { /* Need to field-split */ - char *field_begin = value; + char *value_copy = __strdup (value); /* Don't modify value */ + char *field_begin = value_copy; int seen_nonws_ifs = 0; + if (free_value) + free (value); + + if (value_copy == NULL) + return WRDE_NOSPACE; + do { char *field_end = field_begin; char *next_field; - char ch; /* If this isn't the first field, start a new word */ - if (field_begin != value) + if (field_begin != value_copy) { if (w_addword (pwordexp, *word) == WRDE_NOSPACE) - return WRDE_NOSPACE; + { + free (value_copy); + return WRDE_NOSPACE; + } *word = NULL; *word_length = *max_length = 0; @@ -1710,8 +1718,7 @@ envsubst: field_end++; /* Set up pointer to the character after end of field */ - ch = *field_end; - next_field = ch ? field_end : NULL; + next_field = *field_end ? field_end : NULL; /* Skip whitespace IFS after the field */ while (next_field && *next_field && strchr (ifs_white, *next_field)) @@ -1729,13 +1736,19 @@ envsubst: *field_end = 0; /* Tag a copy onto the current word */ - *word = w_addstr (*word, word_length, max_length, - __strdup (field_begin)); + *word = w_addstr (*word, word_length, max_length, field_begin); + if (*word == NULL) - return WRDE_NOSPACE; + { + free (value_copy); + return WRDE_NOSPACE; + } field_begin = next_field; - } while (seen_nonws_ifs || (field_begin && *field_begin)); + } + while (seen_nonws_ifs || (field_begin != NULL && *field_begin)); + + free (value_copy); } return 0; diff --git a/string/bits/string2.h b/string/bits/string2.h index 45c6112b55..3104f949ba 100644 --- a/string/bits/string2.h +++ b/string/bits/string2.h @@ -840,7 +840,7 @@ __strsep_g (char **__s, __const char *__reject) register char *__retval = *__s; if (__retval == NULL || *__retval == '\0') return NULL; - if ((*__s = strpbrk (__retval, __reject)) != '\0') + if ((*__s = strpbrk (__retval, __reject)) != NULL) *(*__s)++ = '\0'; return __retval; }