diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-10 19:20:32 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-10 19:20:32 +0100 |
commit | 3cb60c39737208ca073842f4f0386d5e5c278705 (patch) | |
tree | 7e96890a5016885d75dea187edd1c63cbbf05f6a /editors | |
parent | eae697fb93362dd51365fdd5283128cb339b91c2 (diff) | |
download | busybox-w32-3cb60c39737208ca073842f4f0386d5e5c278705.tar.gz busybox-w32-3cb60c39737208ca073842f4f0386d5e5c278705.tar.bz2 busybox-w32-3cb60c39737208ca073842f4f0386d5e5c278705.zip |
awk: fix the case where nested "for" loops with the same variable misbehave
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'editors')
-rw-r--r-- | editors/awk.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/editors/awk.c b/editors/awk.c index b9bc01f16..5cc4adce7 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -912,8 +912,10 @@ static void nvfree(var *v) | |||
912 | free(p->x.array->items); | 912 | free(p->x.array->items); |
913 | free(p->x.array); | 913 | free(p->x.array); |
914 | } | 914 | } |
915 | if (p->type & VF_WALK) | 915 | if (p->type & VF_WALK) { |
916 | //bb_error_msg("free(walker@%p:%p) #1", &p->x.walker, p->x.walker); | ||
916 | free(p->x.walker); | 917 | free(p->x.walker); |
918 | } | ||
917 | 919 | ||
918 | clrvar(p); | 920 | clrvar(p); |
919 | } | 921 | } |
@@ -1724,18 +1726,20 @@ static void hashwalk_init(var *v, xhash *array) | |||
1724 | char **w; | 1726 | char **w; |
1725 | hash_item *hi; | 1727 | hash_item *hi; |
1726 | unsigned i; | 1728 | unsigned i; |
1727 | 1729 | char **prev_walker = (v->type & VF_WALK) ? v->x.walker : NULL; | |
1728 | if (v->type & VF_WALK) | ||
1729 | free(v->x.walker); | ||
1730 | 1730 | ||
1731 | v->type |= VF_WALK; | 1731 | v->type |= VF_WALK; |
1732 | w = v->x.walker = xzalloc(2 + 2*sizeof(char *) + array->glen); | 1732 | |
1733 | w[0] = w[1] = (char *)(w + 2); | 1733 | /* walker structure is: "[ptr2end][ptr2start][prev]<word1>NUL<word2>NUL" */ |
1734 | w = v->x.walker = xzalloc(2 + 3*sizeof(char *) + array->glen); | ||
1735 | //bb_error_msg("walker@%p=%p", &v->x.walker, v->x.walker); | ||
1736 | w[0] = w[1] = (char *)(w + 3); | ||
1737 | w[2] = (char *)prev_walker; | ||
1734 | for (i = 0; i < array->csize; i++) { | 1738 | for (i = 0; i < array->csize; i++) { |
1735 | hi = array->items[i]; | 1739 | hi = array->items[i]; |
1736 | while (hi) { | 1740 | while (hi) { |
1737 | strcpy(*w, hi->name); | 1741 | strcpy(w[0], hi->name); |
1738 | nextword(w); | 1742 | nextword(&w[0]); |
1739 | hi = hi->next; | 1743 | hi = hi->next; |
1740 | } | 1744 | } |
1741 | } | 1745 | } |
@@ -1746,10 +1750,16 @@ static int hashwalk_next(var *v) | |||
1746 | char **w; | 1750 | char **w; |
1747 | 1751 | ||
1748 | w = v->x.walker; | 1752 | w = v->x.walker; |
1749 | if (w[1] == w[0]) | 1753 | if (w[1] == w[0]) { |
1754 | char **prev_walker = (char**)w[2]; | ||
1755 | |||
1756 | //bb_error_msg("free(walker@%p:%p) #3, restoring to %p", &v->x.walker, v->x.walker, prev_walker); | ||
1757 | free(v->x.walker); | ||
1758 | v->x.walker = prev_walker; | ||
1750 | return FALSE; | 1759 | return FALSE; |
1760 | } | ||
1751 | 1761 | ||
1752 | setvar_s(v, nextword(w+1)); | 1762 | setvar_s(v, nextword(&w[1])); |
1753 | return TRUE; | 1763 | return TRUE; |
1754 | } | 1764 | } |
1755 | 1765 | ||