Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0e60607

Browse files
committed
ecpg: fix some memory leakage of data-type-related structures.
ECPGfree_type() and related functions were quite incompleteabout removing subsidiary data structures. Possibly this isbecause ecpg wasn't careful to make sure said data structuresalways had their own storage. Previous patches in this seriescleaned up a lot of that, and I had to add a couple moremm_strdup's here.Also, ecpg.trailer tended to overwrite struct_member_list[struct_level]without bothering to free up its previous contents, thus potentiallyleaking a lot of struct-member-related storage. AddECPGfree_struct_member() calls at appropriate points.Discussion:https://postgr.es/m/2011420.1713493114@sss.pgh.pa.us
1 parent5c32c21 commit0e60607

File tree

5 files changed

+42
-13
lines changed

5 files changed

+42
-13
lines changed

‎src/interfaces/ecpg/preproc/ecpg.header

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,19 @@ static char *actual_startline[STRUCT_DEPTH];
4444
static intvarchar_counter = 1;
4545
static intbytea_counter = 1;
4646

47-
/* temporarily store struct members while creating the data structure */
47+
/*
48+
* We temporarily store struct members here while parsing struct declarations.
49+
* The struct_member_list (at a given nesting depth) is constructed while
50+
* scanning the fields within "struct { .... }", but we can't remove it upon
51+
* seeing the right brace. It's kept around and copied into the variables
52+
* or typedefs that follow, in order to handle cases like
53+
* "struct foo { ... } foovar1, foovar2;". We recycle the storage only
54+
* upon closing the current nesting level or starting the next struct
55+
* declaration within the same nesting level.
56+
* For cases like "struct foo foovar1, foovar2;", we copy the saved struct
57+
* field list for the typedef or struct tag into the struct_member_list
58+
* global variable, and then copy it again to the newly-declared variables.
59+
*/
4860
struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = {NULL};
4961

5062
/* also store struct type so we can do a sizeof() later */
@@ -507,11 +519,12 @@ add_typedef(const char *name, const char *dimension, const char *length,
507519
this->name = mm_strdup(name);
508520
this->brace_level = braces_open;
509521
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
522+
this->type->type_storage = NULL;
510523
this->type->type_enum = type_enum;
511524
this->type->type_str = mm_strdup(name);
512525
this->type->type_dimension = mm_strdup(dimension); /* dimension of array */
513526
this->type->type_index = mm_strdup(length);/* length of string */
514-
this->type->type_sizeof = ECPGstruct_sizeof;
527+
this->type->type_sizeof = ECPGstruct_sizeof ? mm_strdup(ECPGstruct_sizeof) : NULL;
515528
this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
516529
ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
517530

‎src/interfaces/ecpg/preproc/ecpg.trailer

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,7 @@ var_type: simple_type
755755
else
756756
$$.type_sizeof = cat_str(3, "sizeof(", this->name, ")");
757757

758+
ECPGfree_struct_member(struct_member_list[struct_level]);
758759
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
759760
}
760761
}
@@ -882,6 +883,7 @@ var_type: simple_type
882883
else
883884
$$.type_sizeof = cat_str(3, "sizeof(", this->name, ")");
884885

886+
ECPGfree_struct_member(struct_member_list[struct_level]);
885887
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
886888
}
887889
}
@@ -904,6 +906,7 @@ var_type: simple_type
904906
$$.type_dimension = this->type->type_dimension;
905907
$$.type_index = this->type->type_index;
906908
$$.type_sizeof = this->type->type_sizeof;
909+
ECPGfree_struct_member(struct_member_list[struct_level]);
907910
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
908911
}
909912
else
@@ -913,6 +916,7 @@ var_type: simple_type
913916
$$.type_dimension = "-1";
914917
$$.type_index = "-1";
915918
$$.type_sizeof = "";
919+
ECPGfree_struct_member(struct_member_list[struct_level]);
916920
struct_member_list[struct_level] = NULL;
917921
}
918922
}
@@ -928,6 +932,7 @@ enum_definition: '{' c_list '}'
928932

929933
struct_union_type_with_symbol: s_struct_union_symbol
930934
{
935+
ECPGfree_struct_member(struct_member_list[struct_level]);
931936
struct_member_list[struct_level++] = NULL;
932937
if (struct_level >= STRUCT_DEPTH)
933938
mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");
@@ -969,12 +974,13 @@ struct_union_type_with_symbol: s_struct_union_symbol
969974
this->name = mm_strdup(su_type.type_str);
970975
this->brace_level = braces_open;
971976
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
977+
this->type->type_storage = NULL;
972978
this->type->type_enum = su_type.type_enum;
973979
this->type->type_str = mm_strdup(su_type.type_str);
974980
this->type->type_dimension = mm_strdup("-1");/* dimension of array */
975981
this->type->type_index = mm_strdup("-1");/* length of string */
976-
this->type->type_sizeof = ECPGstruct_sizeof;
977-
this->struct_member_list = struct_member_list[struct_level];
982+
this->type->type_sizeof = ECPGstruct_sizeof ? mm_strdup(ECPGstruct_sizeof) : NULL;
983+
this->struct_member_list =ECPGstruct_member_dup(struct_member_list[struct_level]);
978984

979985
types = this;
980986
@$ = cat_str(4, su_type.type_str, "{", @4, "}");
@@ -984,6 +990,7 @@ struct_union_type_with_symbol: s_struct_union_symbol
984990
struct_union_type: struct_union_type_with_symbol
985991
| s_struct_union
986992
{
993+
ECPGfree_struct_member(struct_member_list[struct_level]);
987994
struct_member_list[struct_level++] = NULL;
988995
if (struct_level >= STRUCT_DEPTH)
989996
mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");

‎src/interfaces/ecpg/preproc/type.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,14 @@ ECPGmake_array_type(struct ECPGtype *type, const char *size)
9494
}
9595

9696
structECPGtype*
97-
ECPGmake_struct_type(structECPGstruct_member*rm,enumECPGttypetype,char*type_name,char*struct_sizeof)
97+
ECPGmake_struct_type(structECPGstruct_member*rm,enumECPGttypetype,
98+
constchar*type_name,constchar*struct_sizeof)
9899
{
99100
structECPGtype*ne=ECPGmake_simple_type(type,"1",0);
100101

101102
ne->type_name=mm_strdup(type_name);
102103
ne->u.members=ECPGstruct_member_dup(rm);
103-
ne->struct_sizeof=struct_sizeof;
104+
ne->struct_sizeof=mm_strdup(struct_sizeof);
104105

105106
returnne;
106107
}
@@ -622,7 +623,7 @@ ECPGfree_struct_member(struct ECPGstruct_member *rm)
622623

623624
rm=rm->next;
624625
free(p->name);
625-
free(p->type);
626+
ECPGfree_type(p->type);
626627
free(p);
627628
}
628629
}
@@ -643,14 +644,13 @@ ECPGfree_type(struct ECPGtype *type)
643644
caseECPGt_struct:
644645
caseECPGt_union:
645646
/* Array of structs. */
646-
ECPGfree_struct_member(type->u.element->u.members);
647-
free(type->u.element);
647+
ECPGfree_type(type->u.element);
648648
break;
649649
default:
650650
if (!IS_SIMPLE_TYPE(type->u.element->type))
651651
base_yyerror("internal error: unknown datatype, please report this to <"PACKAGE_BUGREPORT">");
652652

653-
free(type->u.element);
653+
ECPGfree_type(type->u.element);
654654
}
655655
break;
656656
caseECPGt_struct:
@@ -662,6 +662,9 @@ ECPGfree_type(struct ECPGtype *type)
662662
break;
663663
}
664664
}
665+
free(type->type_name);
666+
free(type->size);
667+
free(type->struct_sizeof);
665668
free(type);
666669
}
667670

‎src/interfaces/ecpg/preproc/type.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ voidECPGmake_struct_member(const char *name, struct ECPGtype *type,
3838
structECPGtype*ECPGmake_simple_type(enumECPGttypetype,constchar*size,intcounter);
3939
structECPGtype*ECPGmake_array_type(structECPGtype*type,constchar*size);
4040
structECPGtype*ECPGmake_struct_type(structECPGstruct_member*rm,
41-
enumECPGttypetype,char*type_name,
42-
char*struct_sizeof);
41+
enumECPGttypetype,
42+
constchar*type_name,
43+
constchar*struct_sizeof);
4344
structECPGstruct_member*ECPGstruct_member_dup(structECPGstruct_member*rm);
4445

4546
/* Frees a type. */

‎src/interfaces/ecpg/preproc/variable.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,12 @@ remove_typedefs(int brace_level)
277277
prev->next=p->next;
278278

279279
if (p->type->type_enum==ECPGt_struct||p->type->type_enum==ECPGt_union)
280-
free(p->struct_member_list);
280+
ECPGfree_struct_member(p->struct_member_list);
281+
free(p->type->type_storage);
282+
free(p->type->type_str);
283+
free(p->type->type_dimension);
284+
free(p->type->type_index);
285+
free(p->type->type_sizeof);
281286
free(p->type);
282287
free(p->name);
283288
free(p);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp