diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-18 13:48:37 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-18 13:48:37 +0100 |
| commit | ef271da33f1423b3f14aab6448c3001132cd128e (patch) | |
| tree | 14e25586c34da380e0cf41559c6b0fb2ac1d2280 /miscutils | |
| parent | d4258dd321dfdfd9586fb588f17f2a61fa7829d2 (diff) | |
| download | busybox-w32-ef271da33f1423b3f14aab6448c3001132cd128e.tar.gz busybox-w32-ef271da33f1423b3f14aab6448c3001132cd128e.tar.bz2 busybox-w32-ef271da33f1423b3f14aab6448c3001132cd128e.zip | |
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 <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/bc.c | 32 |
1 files changed, 19 insertions, 13 deletions
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) | |||
| 3272 | 3272 | ||
| 3273 | static BC_STATUS zdc_lex_string(BcLex *l) | 3273 | static BC_STATUS zdc_lex_string(BcLex *l) |
| 3274 | { | 3274 | { |
| 3275 | size_t depth = 1, nls = 0, i = l->i; | 3275 | size_t depth, nls, i; |
| 3276 | char c; | ||
| 3277 | 3276 | ||
| 3278 | l->t.t = BC_LEX_STR; | 3277 | l->t.t = BC_LEX_STR; |
| 3279 | bc_vec_pop_all(&l->t.v); | 3278 | bc_vec_pop_all(&l->t.v); |
| 3280 | 3279 | ||
| 3281 | for (c = l->buf[i]; c != 0 && depth; c = l->buf[++i]) { | 3280 | nls = 0; |
| 3282 | 3281 | depth = 1; | |
| 3283 | depth += (c == '[' && (i == l->i || l->buf[i - 1] != '\\')); | 3282 | i = l->i; |
| 3284 | depth -= (c == ']' && (i == l->i || l->buf[i - 1] != '\\')); | 3283 | for (;;) { |
| 3284 | char c = l->buf[i]; | ||
| 3285 | if (c == '\0') { | ||
| 3286 | l->i = i; | ||
| 3287 | RETURN_STATUS(bc_error("string end could not be found")); | ||
| 3288 | } | ||
| 3285 | nls += (c == '\n'); | 3289 | nls += (c == '\n'); |
| 3286 | 3290 | if (i == l->i || l->buf[i - 1] != '\\') { | |
| 3287 | if (depth) bc_vec_push(&l->t.v, &c); | 3291 | if (c == '[') depth++; |
| 3288 | } | 3292 | if (c == ']') |
| 3289 | 3293 | if (--depth == 0) | |
| 3290 | if (c == '\0') { | 3294 | break; |
| 3291 | l->i = i; | 3295 | } |
| 3292 | RETURN_STATUS(bc_error("string end could not be found")); | 3296 | bc_vec_push(&l->t.v, &l->buf[i]); |
| 3297 | i++; | ||
| 3293 | } | 3298 | } |
| 3299 | i++; | ||
| 3294 | 3300 | ||
| 3295 | bc_vec_pushZeroByte(&l->t.v); | 3301 | bc_vec_pushZeroByte(&l->t.v); |
| 3296 | // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. | 3302 | // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. |
