From ef271da33f1423b3f14aab6448c3001132cd128e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 18 Dec 2018 13:48:37 +0100 Subject: bc: shrink zdc_lex_string() This actually fixes a rather obscure bug. This was failing to find end of the string: $ echo -n '[foo]' | dc dc: string end could not be found function old new delta zbc_lex_next 2230 2141 -89 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-89) Total: -89 bytes text data bss dec hex filename 981461 485 7296 989242 f183a busybox_old 981372 485 7296 989153 f17e1 busybox_unstripped Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'miscutils/bc.c') diff --git a/miscutils/bc.c b/miscutils/bc.c index 37c9012f9..5d969c9d0 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -3272,25 +3272,31 @@ static BC_STATUS zdc_lex_register(BcLex *l) static BC_STATUS zdc_lex_string(BcLex *l) { - size_t depth = 1, nls = 0, i = l->i; - char c; + size_t depth, nls, i; l->t.t = BC_LEX_STR; bc_vec_pop_all(&l->t.v); - for (c = l->buf[i]; c != 0 && depth; c = l->buf[++i]) { - - depth += (c == '[' && (i == l->i || l->buf[i - 1] != '\\')); - depth -= (c == ']' && (i == l->i || l->buf[i - 1] != '\\')); + nls = 0; + depth = 1; + i = l->i; + for (;;) { + char c = l->buf[i]; + if (c == '\0') { + l->i = i; + RETURN_STATUS(bc_error("string end could not be found")); + } nls += (c == '\n'); - - if (depth) bc_vec_push(&l->t.v, &c); - } - - if (c == '\0') { - l->i = i; - RETURN_STATUS(bc_error("string end could not be found")); + if (i == l->i || l->buf[i - 1] != '\\') { + if (c == '[') depth++; + if (c == ']') + if (--depth == 0) + break; + } + bc_vec_push(&l->t.v, &l->buf[i]); + i++; } + i++; bc_vec_pushZeroByte(&l->t.v); // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. -- cgit v1.2.3