diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2019-01-18 14:39:08 +0200 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2019-01-18 14:39:08 +0200 |
commit | c25c7d9359451ec91c4290a84b17185fa32f167f (patch) | |
tree | eab754306affe4bbc2d427cbd4bc8f837499a75e | |
parent | 6f16c4f468e6f3a6769509e1e70ff2dc4873e8d2 (diff) | |
download | egawk-c25c7d9359451ec91c4290a84b17185fa32f167f.tar.gz egawk-c25c7d9359451ec91c4290a84b17185fa32f167f.tar.bz2 egawk-c25c7d9359451ec91c4290a84b17185fa32f167f.zip |
Start fixing memory leaks in namespace management.
-rwxr-xr-x | ChangeLog | 16 | ||||
-rw-r--r-- | awkgram.c | 98 | ||||
-rw-r--r-- | awkgram.y | 36 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | profile.c | 2 |
5 files changed, 113 insertions, 41 deletions
@@ -1,3 +1,19 @@ +2019-01-18 Arnold D. Robbins <arnold@skeeve.com> + + Start fixing memory leaks related to namespaces. + + * awkgram.y (Grammar): At simple_variable -> NAME, qualify names + before lookup/install. + (next_sourcefile): Check if need to free current_namespace before + assigning to it. + (yylex): Fix length of string to be dup'ed before returning + NAME or FUNC_CALL. + (set_namespace): Always free ns->lextok, adjust memory allocations + appropriately. + * main.c (main): Check if need to free current_namespace before + assigning to it. + * profile.c (pp_namespace): Ditto. (This may not be necessary.) + 2019-01-14 Andrew J. Schorr <aschorr@telemetry-investments.com> * builtin.c (do_typeof): Fix memory leak when populating the @@ -700,8 +700,8 @@ static const yytype_uint16 yyrline[] = 1826, 1828, 1830, 1832, 1834, 1839, 1843, 1875, 1883, 1889, 1895, 1908, 1909, 1910, 1915, 1920, 1924, 1928, 1943, 1964, 1969, 2006, 2048, 2049, 2055, 2056, 2061, 2063, 2070, 2087, - 2104, 2106, 2113, 2118, 2126, 2136, 2148, 2157, 2161, 2166, - 2170, 2174, 2178, 2183, 2184, 2188, 2192, 2196 + 2104, 2106, 2113, 2118, 2148, 2158, 2170, 2179, 2183, 2188, + 2192, 2196, 2200, 2205, 2206, 2210, 2214, 2218 }; #endif @@ -4341,28 +4341,50 @@ regular_print: case 193: #line 2119 "awkgram.y" /* yacc.c:1645 */ { + // FIXME: Code here and at function call + // should be moved into a function char *var_name = (yyvsp[0])->lextok; + bool is_all_upper = true; + char *cp; + for (cp = var_name; *cp != '\0'; cp++) { + if (! isupper(*cp)) { + is_all_upper = false; + break; + } + } + + if (current_namespace != awk_namespace && strchr(var_name, ':') == NULL && ! is_all_upper) { + size_t len = strlen(current_namespace) + 2 + strlen(var_name) + 1; + char *buf; + + emalloc(buf, char *, len, "simple_variable"); + sprintf(buf, "%s::%s", current_namespace, var_name); + + efree((void *) (yyvsp[0])->lextok); + (yyvsp[0])->lextok = buf; + } + (yyvsp[0])->opcode = Op_push; - (yyvsp[0])->memory = variable((yyvsp[0])->source_line, var_name, Node_var_new); + (yyvsp[0])->memory = variable((yyvsp[0])->source_line, (yyvsp[0])->lextok, Node_var_new); (yyval) = list_create((yyvsp[0])); } -#line 4351 "awkgram.c" /* yacc.c:1645 */ +#line 4373 "awkgram.c" /* yacc.c:1645 */ break; case 194: -#line 2127 "awkgram.y" /* yacc.c:1645 */ +#line 2149 "awkgram.y" /* yacc.c:1645 */ { char *arr = (yyvsp[-1])->lextok; (yyvsp[-1])->memory = variable((yyvsp[-1])->source_line, arr, Node_var_new); (yyvsp[-1])->opcode = Op_push_array; (yyval) = list_prepend((yyvsp[0]), (yyvsp[-1])); } -#line 4362 "awkgram.c" /* yacc.c:1645 */ +#line 4384 "awkgram.c" /* yacc.c:1645 */ break; case 195: -#line 2137 "awkgram.y" /* yacc.c:1645 */ +#line 2159 "awkgram.y" /* yacc.c:1645 */ { INSTRUCTION *ip = (yyvsp[0])->nexti; if (ip->opcode == Op_push @@ -4374,85 +4396,85 @@ regular_print: } else (yyval) = (yyvsp[0]); } -#line 4378 "awkgram.c" /* yacc.c:1645 */ +#line 4400 "awkgram.c" /* yacc.c:1645 */ break; case 196: -#line 2149 "awkgram.y" /* yacc.c:1645 */ +#line 2171 "awkgram.y" /* yacc.c:1645 */ { (yyval) = list_append((yyvsp[-1]), (yyvsp[-2])); if ((yyvsp[0]) != NULL) mk_assignment((yyvsp[-1]), NULL, (yyvsp[0])); } -#line 4388 "awkgram.c" /* yacc.c:1645 */ +#line 4410 "awkgram.c" /* yacc.c:1645 */ break; case 197: -#line 2158 "awkgram.y" /* yacc.c:1645 */ +#line 2180 "awkgram.y" /* yacc.c:1645 */ { (yyvsp[0])->opcode = Op_postincrement; } -#line 4396 "awkgram.c" /* yacc.c:1645 */ +#line 4418 "awkgram.c" /* yacc.c:1645 */ break; case 198: -#line 2162 "awkgram.y" /* yacc.c:1645 */ +#line 2184 "awkgram.y" /* yacc.c:1645 */ { (yyvsp[0])->opcode = Op_postdecrement; } -#line 4404 "awkgram.c" /* yacc.c:1645 */ +#line 4426 "awkgram.c" /* yacc.c:1645 */ break; case 199: -#line 2166 "awkgram.y" /* yacc.c:1645 */ +#line 2188 "awkgram.y" /* yacc.c:1645 */ { (yyval) = NULL; } -#line 4410 "awkgram.c" /* yacc.c:1645 */ +#line 4432 "awkgram.c" /* yacc.c:1645 */ break; case 200: -#line 2170 "awkgram.y" /* yacc.c:1645 */ +#line 2192 "awkgram.y" /* yacc.c:1645 */ { (yyval) = (yyvsp[0]); } -#line 4416 "awkgram.c" /* yacc.c:1645 */ +#line 4438 "awkgram.c" /* yacc.c:1645 */ break; case 201: -#line 2174 "awkgram.y" /* yacc.c:1645 */ +#line 2196 "awkgram.y" /* yacc.c:1645 */ { (yyval) = (yyvsp[0]); yyerrok; } -#line 4422 "awkgram.c" /* yacc.c:1645 */ +#line 4444 "awkgram.c" /* yacc.c:1645 */ break; case 202: -#line 2178 "awkgram.y" /* yacc.c:1645 */ +#line 2200 "awkgram.y" /* yacc.c:1645 */ { yyerrok; } -#line 4428 "awkgram.c" /* yacc.c:1645 */ +#line 4450 "awkgram.c" /* yacc.c:1645 */ break; case 203: -#line 2183 "awkgram.y" /* yacc.c:1645 */ +#line 2205 "awkgram.y" /* yacc.c:1645 */ { (yyval) = NULL; } -#line 4434 "awkgram.c" /* yacc.c:1645 */ +#line 4456 "awkgram.c" /* yacc.c:1645 */ break; case 205: -#line 2188 "awkgram.y" /* yacc.c:1645 */ +#line 2210 "awkgram.y" /* yacc.c:1645 */ { yyerrok; } -#line 4440 "awkgram.c" /* yacc.c:1645 */ +#line 4462 "awkgram.c" /* yacc.c:1645 */ break; case 206: -#line 2192 "awkgram.y" /* yacc.c:1645 */ +#line 2214 "awkgram.y" /* yacc.c:1645 */ { (yyval) = (yyvsp[0]); yyerrok; } -#line 4446 "awkgram.c" /* yacc.c:1645 */ +#line 4468 "awkgram.c" /* yacc.c:1645 */ break; case 207: -#line 2196 "awkgram.y" /* yacc.c:1645 */ +#line 2218 "awkgram.y" /* yacc.c:1645 */ { (yyval) = (yyvsp[0]); yyerrok; } -#line 4452 "awkgram.c" /* yacc.c:1645 */ +#line 4474 "awkgram.c" /* yacc.c:1645 */ break; -#line 4456 "awkgram.c" /* yacc.c:1645 */ +#line 4478 "awkgram.c" /* yacc.c:1645 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -4679,7 +4701,7 @@ yyreturn: #endif return yyresult; } -#line 2198 "awkgram.y" /* yacc.c:1903 */ +#line 2220 "awkgram.y" /* yacc.c:1903 */ struct token { @@ -5534,6 +5556,8 @@ next_sourcefile() sourceline = 0; source = NULL; lasttok = 0; + if (current_namespace != awk_namespace) + efree((char *) current_namespace); current_namespace = awk_namespace; } } @@ -6943,7 +6967,7 @@ make_instruction: return lasttok = class; } out: - tokkey = estrdup(tokstart, tok - tokstart); + tokkey = estrdup(tokstart, tok - tokstart - 1); if (*lexptr == '(') { yylval = bcalloc(Op_token, 2, sourceline); yylval->lextok = tokkey; @@ -9284,15 +9308,17 @@ set_namespace(INSTRUCTION *ns, INSTRUCTION *comment) } if (strcmp(ns->lextok, current_namespace) == 0) - efree(ns->lextok); + ; // nothing to do else if (strcmp(ns->lextok, awk_namespace) == 0) { - efree(ns->lextok); + if (current_namespace != awk_namespace) + efree((char *) current_namespace); current_namespace = awk_namespace; } else { if (current_namespace != awk_namespace) efree((char *) current_namespace); - current_namespace = ns->lextok; + current_namespace = estrdup(ns->lextok, strlen(ns->lextok)); } + efree(ns->lextok); // save info and push on front of list of namespaces seen INSTRUCTION *new_ns = instruction(Op_K_namespace); @@ -2117,10 +2117,32 @@ subscript_list simple_variable : NAME { + // FIXME: Code here and at function call + // should be moved into a function char *var_name = $1->lextok; + bool is_all_upper = true; + char *cp; + for (cp = var_name; *cp != '\0'; cp++) { + if (! isupper(*cp)) { + is_all_upper = false; + break; + } + } + + if (current_namespace != awk_namespace && strchr(var_name, ':') == NULL && ! is_all_upper) { + size_t len = strlen(current_namespace) + 2 + strlen(var_name) + 1; + char *buf; + + emalloc(buf, char *, len, "simple_variable"); + sprintf(buf, "%s::%s", current_namespace, var_name); + + efree((void *) $1->lextok); + $1->lextok = buf; + } + $1->opcode = Op_push; - $1->memory = variable($1->source_line, var_name, Node_var_new); + $1->memory = variable($1->source_line, $1->lextok, Node_var_new); $$ = list_create($1); } | NAME subscript_list @@ -3049,6 +3071,8 @@ next_sourcefile() sourceline = 0; source = NULL; lasttok = 0; + if (current_namespace != awk_namespace) + efree((char *) current_namespace); current_namespace = awk_namespace; } } @@ -4458,7 +4482,7 @@ make_instruction: return lasttok = class; } out: - tokkey = estrdup(tokstart, tok - tokstart); + tokkey = estrdup(tokstart, tok - tokstart - 1); if (*lexptr == '(') { yylval = bcalloc(Op_token, 2, sourceline); yylval->lextok = tokkey; @@ -6799,15 +6823,17 @@ set_namespace(INSTRUCTION *ns, INSTRUCTION *comment) } if (strcmp(ns->lextok, current_namespace) == 0) - efree(ns->lextok); + ; // nothing to do else if (strcmp(ns->lextok, awk_namespace) == 0) { - efree(ns->lextok); + if (current_namespace != awk_namespace) + efree((char *) current_namespace); current_namespace = awk_namespace; } else { if (current_namespace != awk_namespace) efree((char *) current_namespace); - current_namespace = ns->lextok; + current_namespace = estrdup(ns->lextok, strlen(ns->lextok)); } + efree(ns->lextok); // save info and push on front of list of namespaces seen INSTRUCTION *new_ns = instruction(Op_K_namespace); @@ -520,6 +520,8 @@ main(int argc, char **argv) interpret(code_block); if (do_pretty_print) { + if (current_namespace != awk_namespace) + efree((char *) current_namespace); current_namespace = awk_namespace; dump_prog(code_block); dump_funcs(); @@ -2033,6 +2033,8 @@ pp_namespace(const char *name, INSTRUCTION *comment) if (strcmp(current_namespace, name) == 0) return; + if (current_namespace != awk_namespace) + efree((void *) current_namespace); current_namespace = name; if (do_profile) |