awk: be more paranoid when freeing loop variable; make code less obfuscated
function old new delta nvfree 149 170 +21 next_token 928 932 +4 getvar_i 95 94 -1 skip_spaces 51 45 -6 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/2 up/down: 25/-7) Total: 18 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
90f19fa468
commit
da62b09ab1
@ -14,6 +14,16 @@
|
|||||||
/* This is a NOEXEC applet. Be very careful! */
|
/* This is a NOEXEC applet. Be very careful! */
|
||||||
|
|
||||||
|
|
||||||
|
/* If you comment out one of these below, it will be #defined later
|
||||||
|
* to perform debug printfs to stderr: */
|
||||||
|
#define debug_printf_walker(...) do {} while (0)
|
||||||
|
|
||||||
|
#ifndef debug_printf_walker
|
||||||
|
# define debug_printf_walker(...) (fprintf(stderr, __VA_ARGS__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define MAXVARFMT 240
|
#define MAXVARFMT 240
|
||||||
#define MINNVBLOCK 64
|
#define MINNVBLOCK 64
|
||||||
|
|
||||||
@ -32,6 +42,13 @@
|
|||||||
/* these flags are static, don't change them when value is changed */
|
/* these flags are static, don't change them when value is changed */
|
||||||
#define VF_DONTTOUCH (VF_ARRAY | VF_SPECIAL | VF_WALK | VF_CHILD | VF_DIRTY)
|
#define VF_DONTTOUCH (VF_ARRAY | VF_SPECIAL | VF_WALK | VF_CHILD | VF_DIRTY)
|
||||||
|
|
||||||
|
typedef struct walker_list {
|
||||||
|
char *end;
|
||||||
|
char *cur;
|
||||||
|
struct walker_list *prev;
|
||||||
|
char wbuf[1];
|
||||||
|
} walker_list;
|
||||||
|
|
||||||
/* Variable */
|
/* Variable */
|
||||||
typedef struct var_s {
|
typedef struct var_s {
|
||||||
unsigned type; /* flags */
|
unsigned type; /* flags */
|
||||||
@ -41,7 +58,7 @@ typedef struct var_s {
|
|||||||
int aidx; /* func arg idx (for compilation stage) */
|
int aidx; /* func arg idx (for compilation stage) */
|
||||||
struct xhash_s *array; /* array ptr */
|
struct xhash_s *array; /* array ptr */
|
||||||
struct var_s *parent; /* for func args, ptr to actual parameter */
|
struct var_s *parent; /* for func args, ptr to actual parameter */
|
||||||
char **walker; /* list of array elements (for..in) */
|
walker_list *walker; /* list of array elements (for..in) */
|
||||||
} x;
|
} x;
|
||||||
} var;
|
} var;
|
||||||
|
|
||||||
@ -913,10 +930,17 @@ static void nvfree(var *v)
|
|||||||
free(p->x.array);
|
free(p->x.array);
|
||||||
}
|
}
|
||||||
if (p->type & VF_WALK) {
|
if (p->type & VF_WALK) {
|
||||||
//bb_error_msg("free(walker@%p:%p) #1", &p->x.walker, p->x.walker);
|
walker_list *n;
|
||||||
free(p->x.walker);
|
walker_list *w = p->x.walker;
|
||||||
|
debug_printf_walker("nvfree: freeing walker @%p\n", &p->x.walker);
|
||||||
|
p->x.walker = NULL;
|
||||||
|
while (w) {
|
||||||
|
n = w->prev;
|
||||||
|
debug_printf_walker(" free(%p)\n", w);
|
||||||
|
free(w);
|
||||||
|
w = n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clrvar(p);
|
clrvar(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1724,23 +1748,28 @@ static node *nextarg(node **pn)
|
|||||||
|
|
||||||
static void hashwalk_init(var *v, xhash *array)
|
static void hashwalk_init(var *v, xhash *array)
|
||||||
{
|
{
|
||||||
char **w;
|
|
||||||
hash_item *hi;
|
hash_item *hi;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
char **prev_walker = (v->type & VF_WALK) ? v->x.walker : NULL;
|
walker_list *w;
|
||||||
|
walker_list *prev_walker;
|
||||||
|
|
||||||
v->type |= VF_WALK;
|
if (v->type & VF_WALK) {
|
||||||
|
prev_walker = v->x.walker;
|
||||||
|
} else {
|
||||||
|
v->type |= VF_WALK;
|
||||||
|
prev_walker = NULL;
|
||||||
|
}
|
||||||
|
debug_printf_walker("hashwalk_init: prev_walker:%p\n", prev_walker);
|
||||||
|
|
||||||
/* walker structure is: "[ptr2end][ptr2start][prev]<word1>NUL<word2>NUL" */
|
w = v->x.walker = xzalloc(sizeof(*w) + array->glen + 1); /* why + 1? */
|
||||||
w = v->x.walker = xzalloc(2 + 3*sizeof(char *) + array->glen);
|
debug_printf_walker(" walker@%p=%p\n", &v->x.walker, w);
|
||||||
//bb_error_msg("walker@%p=%p", &v->x.walker, v->x.walker);
|
w->cur = w->end = w->wbuf;
|
||||||
w[0] = w[1] = (char *)(w + 3);
|
w->prev = prev_walker;
|
||||||
w[2] = (char *)prev_walker;
|
|
||||||
for (i = 0; i < array->csize; i++) {
|
for (i = 0; i < array->csize; i++) {
|
||||||
hi = array->items[i];
|
hi = array->items[i];
|
||||||
while (hi) {
|
while (hi) {
|
||||||
strcpy(w[0], hi->name);
|
strcpy(w->end, hi->name);
|
||||||
nextword(&w[0]);
|
nextword(&w->end);
|
||||||
hi = hi->next;
|
hi = hi->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1748,19 +1777,18 @@ static void hashwalk_init(var *v, xhash *array)
|
|||||||
|
|
||||||
static int hashwalk_next(var *v)
|
static int hashwalk_next(var *v)
|
||||||
{
|
{
|
||||||
char **w;
|
walker_list *w = v->x.walker;
|
||||||
|
|
||||||
w = v->x.walker;
|
if (w->cur >= w->end) {
|
||||||
if (w[1] == w[0]) {
|
walker_list *prev_walker = w->prev;
|
||||||
char **prev_walker = (char**)w[2];
|
|
||||||
|
|
||||||
//bb_error_msg("free(walker@%p:%p) #3, restoring to %p", &v->x.walker, v->x.walker, prev_walker);
|
debug_printf_walker("end of iteration, free(walker@%p:%p), prev_walker:%p\n", &v->x.walker, w, prev_walker);
|
||||||
free(v->x.walker);
|
free(w);
|
||||||
v->x.walker = prev_walker;
|
v->x.walker = prev_walker;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
setvar_s(v, nextword(&w[1]));
|
setvar_s(v, nextword(&w->cur));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user