From 66389492338d874f20307d37f49079c7adece1d0 Mon Sep 17 00:00:00 2001 From: Mohamed Gaber Date: Tue, 30 Jun 2026 01:32:20 +0300 Subject: [PATCH] codebase-wide: use flexible arrays where appropriate In platforms with bounds-checking enabled, placeholder values for array sizes in structs that may be exceeded always result in a sigtrap. This patch updates the following classes to use flexible arrays at the end of structs: - database - Label - PropertyRecord (union of three flexible arrays and a pointer*) - cellUE - extflat - HierName - EFAttr - Dev - utils - HashEntry (union of two flexible arrays and a pointer*) - internalUndoEvent: Was a plain int, replaced with a flexible char array Additionally, the database struct editUE, which would have just a single flexible-array member, was removed and simply replaced with a character pointer. Where possible, allocation size macros have been introduced. --- * It is noted flexible-length arrays as part of unions are not part of the C language spec and are a GNU99 extension, however, it is supported by both GCC and Clang. --- calma/CalmaRdcl.c | 8 +++---- cif/CIFrdcl.c | 2 +- cif/CIFrdpt.c | 3 +-- commands/CmdLQ.c | 20 ++++++++---------- database/DBio.c | 32 ++++++++++------------------ database/DBlabel.c | 6 ++---- database/DBundo.c | 48 +++++++++++++----------------------------- database/database.h.in | 36 +++++++++++++++++++++---------- dbwind/DBWundo.c | 8 ++----- extflat/EFtypes.h | 12 +++++------ extract/ExtHard.c | 4 ++-- extract/ExtLength.c | 9 ++------ extract/ExtSubtree.c | 3 +-- extract/ExtYank.c | 4 ++-- lef/defRead.c | 3 +-- lef/lefRead.c | 35 +++++++++++++++++------------- sim/SimDBstuff.c | 5 ++--- utils/hash.c | 26 +++++++++++++++++------ utils/hash.h | 15 ++++--------- utils/undo.c | 5 ++--- 20 files changed, 132 insertions(+), 152 deletions(-) diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 5db40879..7484dd88 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -513,7 +513,7 @@ calmaParseStructure( /* the same way that cell references are handled in .mag files. */ DBPathSubstitute(filename, cstring, cifReadCellDef); - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord)); + proprec = (PropertyRecord *)mallocMagic(dlongPropertyRecordSize(1)); proprec->prop_type = PROPERTY_TYPE_DOUBLE; proprec->prop_len = 1; proprec->prop_value.prop_double[0] = filepos; @@ -521,14 +521,14 @@ calmaParseStructure( filepos = FTELL(calmaInputFile); - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord)); + proprec = (PropertyRecord *)mallocMagic(dlongPropertyRecordSize(1)); proprec->prop_type = PROPERTY_TYPE_DOUBLE; proprec->prop_len = 1; proprec->prop_value.prop_double[0] = filepos; DBPropPut(cifReadCellDef, "GDS_END", (ClientData)proprec); - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) - 7 + - strlen(cstring)); + proprec = (PropertyRecord *)mallocMagic( + strPropertyRecordSize(strlen(cstring))); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = 1; strcpy(proprec->prop_value.prop_string, cstring); diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index 0f1cd370..4274beef 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -1066,7 +1066,7 @@ cifMakeBoundaryFunc( } } - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + 2 * sizeof(int)); + proprec = (PropertyRecord *)mallocMagic(intPropertyRecordSize(4)); proprec->prop_type = PROPERTY_TYPE_DIMENSION; proprec->prop_len = 4; proprec->prop_value.prop_integer[0] = area.r_xbot; diff --git a/cif/CIFrdpt.c b/cif/CIFrdpt.c index 6ed09889..cd627266 100644 --- a/cif/CIFrdpt.c +++ b/cif/CIFrdpt.c @@ -274,8 +274,7 @@ CIFPropRecordPath( pathp = pathp->cifp_next; } /* Allocate enough space to hold 2 * N points. */ - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - ((components - 1) * 2) * sizeof(int)); + proprec = (PropertyRecord *)mallocMagic(intPropertyRecordSize(components * 2)); proprec->prop_type = PROPERTY_TYPE_DIMENSION; proprec->prop_len = components * 2; diff --git a/commands/CmdLQ.c b/commands/CmdLQ.c index 6b3245b3..df8991ae 100644 --- a/commands/CmdLQ.c +++ b/commands/CmdLQ.c @@ -2567,8 +2567,7 @@ CmdDoProperty( if (proptype == PROPERTY_TYPE_STRING) { proplen = strlen(cmd->tx_argv[argstart + 1]); - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) - - 7 + proplen); + proprec = (PropertyRecord *)mallocMagic(strPropertyRecordSize(proplen)); proprec->prop_type = proptype; proprec->prop_len = proplen; strcpy(proprec->prop_value.prop_string, cmd->tx_argv[argstart + 1]); @@ -2586,17 +2585,17 @@ CmdDoProperty( { proplen = locargc - 2; if (proptype == PROPERTY_TYPE_DOUBLE) - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - (proplen - 1)*sizeof(dlong)); + proprec = (PropertyRecord *)mallocMagic( + dlongPropertyRecordSize(proplen)); else if (proptype == PROPERTY_TYPE_PLANE) { proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord)); - plane = DBNewPlane((ClientData)TT_SPACE); - proprec->prop_value.prop_plane = plane; + plane = DBNewPlane((ClientData)TT_SPACE); + proprec->prop_value.prop_plane = plane; } else - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - (proplen - 2)*sizeof(int)); + proprec = (PropertyRecord *)mallocMagic( + intPropertyRecordSize(proplen)); proprec->prop_type = proptype; proprec->prop_len = proplen; @@ -2680,9 +2679,8 @@ CmdDoProperty( plane = DBNewPlane((ClientData)TT_SPACE); proprec->prop_value.prop_plane = plane; } else { - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) + - (proplen - 2) * sizeof(int)); + proprec = (PropertyRecord *)mallocMagic( + intPropertyRecordSize(proplen)); } proprec->prop_type = proptype; proprec->prop_len = proplen; diff --git a/database/DBio.c b/database/DBio.c index 770c9198..dd7e571b 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -2538,8 +2538,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) propertyname); /* Unable to parse correctly. Save as a string value */ proplen = strlen(pvalueptr); - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) - 7 + proplen); + proprec = (PropertyRecord *)mallocMagic(strPropertyRecordSize(proplen)); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = proplen; strcpy(proprec->prop_value.prop_string, pvalueptr); @@ -2565,8 +2564,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) if (propertyname[0] == 'F') cellDef->cd_flags |= CDFIXEDBBOX; - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) + 2 * sizeof(int)); + proprec = (PropertyRecord *)mallocMagic(intPropertyRecordSize(4)); proprec->prop_type = PROPERTY_TYPE_DIMENSION; proprec->prop_len = 4; proprec->prop_value.prop_integer[0] = locbbox.r_xbot; @@ -2651,8 +2649,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) propertyname); /* Unable to parse correctly. Save as a string value */ proplen = strlen(pvalueptr); - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) - 7 + proplen); + proprec = (PropertyRecord *)mallocMagic(strPropertyRecordSize(proplen)); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = proplen; strcpy(proprec->prop_value.prop_string, pvalueptr); @@ -2661,7 +2658,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) } else { - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord)); + proprec = (PropertyRecord *)mallocMagic(dlongPropertyRecordSize(1)); proprec->prop_type = PROPERTY_TYPE_DOUBLE; proprec->prop_len = 1; proprec->prop_value.prop_double[0] = dval; @@ -2671,8 +2668,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) else { proplen = strlen(pvalueptr); - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) - 7 + proplen); + proprec = (PropertyRecord *)mallocMagic(strPropertyRecordSize(proplen)); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = proplen; strcpy(proprec->prop_value.prop_string, pvalueptr); @@ -2703,8 +2699,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) { /* Unable to parse correctly. Save as a string value */ proplen = strlen(pvalueptr); - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) - 7 + proplen); + proprec = (PropertyRecord *)mallocMagic(strPropertyRecordSize(proplen)); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = proplen; strcpy(proprec->prop_value.prop_string, pvalueptr); @@ -2717,8 +2712,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) } pptr = pvalueptr; - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) + ((numvals - 2) * sizeof(int))); + proprec = (PropertyRecord *)mallocMagic(intPropertyRecordSize(numvals)); proprec->prop_type = PROPERTY_TYPE_INTEGER; proprec->prop_len = numvals; @@ -2762,8 +2756,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) { /* Unable to parse correctly. Save as a string value */ proplen = strlen(pvalueptr); - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) - 7 + proplen); + proprec = (PropertyRecord *)mallocMagic(strPropertyRecordSize(proplen)); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = proplen; strcpy(proprec->prop_value.prop_string, pvalueptr); @@ -2776,8 +2769,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) } pptr = pvalueptr; - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) + ((numvals - 1) * sizeof(dlong))); + proprec = (PropertyRecord *)mallocMagic(dlongPropertyRecordSize(numvals)); proprec->prop_type = PROPERTY_TYPE_DOUBLE; proprec->prop_len = numvals; @@ -2821,8 +2813,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) { /* Unable to parse correctly. Save as a string value */ proplen = strlen(pvalueptr); - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) - 7 + proplen); + proprec = (PropertyRecord *)mallocMagic(strPropertyRecordSize(proplen)); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = proplen; strcpy(proprec->prop_value.prop_string, pvalueptr); @@ -2835,8 +2826,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) } pptr = pvalueptr; - proprec = (PropertyRecord *)mallocMagic( - sizeof(PropertyRecord) + ((numvals - 2) * sizeof(int))); + proprec = (PropertyRecord *)mallocMagic(intPropertyRecordSize(numvals)); proprec->prop_type = PROPERTY_TYPE_DIMENSION; proprec->prop_len = numvals; diff --git a/database/DBlabel.c b/database/DBlabel.c index f8e0f58a..a732eda6 100644 --- a/database/DBlabel.c +++ b/database/DBlabel.c @@ -149,10 +149,8 @@ DBPutFontLabel(cellDef, rect, font, size, rot, offset, align, text, type, flags, unsigned int port; /* Port index (if label is a port, per the flags) */ { Label *lab; - int len, x1, x2, y1, y2, tmp, labx, laby; - - len = strlen(text) + sizeof (Label) - sizeof lab->lab_text + 1; - lab = (Label *) mallocMagic ((unsigned) len); + int x1, x2, y1, y2, tmp, labx, laby; + lab = (Label *) mallocMagic ((unsigned)labelSize(strlen(text))); strcpy(lab->lab_text, text); /* Pick a nice alignment if the caller didn't give one. If the diff --git a/database/DBundo.c b/database/DBundo.c index 73b98414..b14a77e4 100644 --- a/database/DBundo.c +++ b/database/DBundo.c @@ -436,14 +436,6 @@ typedef Label labelUE; #define lue_text lab_text #define lue_port lab_port - /* - * labelSize(n) is the size of a labelUE large enough to hold - * a string of n characters. Space for the trailing NULL byte - * is allocated automatically. - */ - -#define labelSize(n) (sizeof (labelUE) - 3 + (n)) - /* * ---------------------------------------------------------------------------- * @@ -614,14 +606,14 @@ dbUndoLabelBack(up) Rect cue_bbox; Rect cue_extended; unsigned char cue_flags; - char cue_id[4]; + char cue_id[]; /* Flexible array, must be last element */ } cellUE; - /* - * Compute the size of a cellUE, with sufficient space - * at the end to store the use id. - */ -#define cellSize(n) (sizeof (cellUE) - 3 + (n)) +/* +* Compute the size of a cellUE, with sufficient space +* at the end to store the use id (not including the NULL byte) +*/ +#define cellSize(n) (sizeof (cellUE) + n + 1) /* * ---------------------------------------------------------------------------- @@ -894,16 +886,6 @@ findUse(up, matchName) * ============================================================================ */ - typedef struct - { - char eue_name[4]; /* Name of cell def edited. This is - * a place holder only, the actual - * structure is allocated to hold all - * the bytes in the def name, plus - * the null byte. - */ - } editUE; - /* * ---------------------------------------------------------------------------- * @@ -926,7 +908,7 @@ void dbUndoEdit(new) CellDef *new; { - editUE *up; + char *up; CellDef *old = dbUndoLastCell; ASSERT(new != old, "dbUndoEdit"); @@ -938,18 +920,18 @@ dbUndoEdit(new) */ if (old) { - up = (editUE *) UndoNewEvent(dbUndoIDCloseCell, + up = (char *) UndoNewEvent(dbUndoIDCloseCell, (unsigned) strlen(old->cd_name) + 1); - if (up == (editUE *) NULL) + if (up == (char *) NULL) return; - strcpy(up->eue_name, old->cd_name); + strcpy(up, old->cd_name); } - up = (editUE *) UndoNewEvent(dbUndoIDOpenCell, + up = (char *) UndoNewEvent(dbUndoIDOpenCell, (unsigned) strlen(new->cd_name) + 1); - if (up == (editUE *) NULL) + if (up == (char *) NULL) return; - strcpy(up->eue_name, new->cd_name); + strcpy(up, new->cd_name); dbUndoLastCell = new; } @@ -971,11 +953,11 @@ dbUndoEdit(new) void dbUndoOpenCell(eup) - editUE *eup; + char *eup; { CellDef *newDef; - newDef = DBCellLookDef(eup->eue_name); + newDef = DBCellLookDef(eup); ASSERT(newDef != (CellDef *) NULL, "dbUndoOpenCell"); dbUndoLastCell = newDef; } diff --git a/database/database.h.in b/database/database.h.in index 3f184c10..bfa910b6 100644 --- a/database/database.h.in +++ b/database/database.h.in @@ -257,15 +257,18 @@ typedef struct label */ unsigned int lab_port; /* Port number, if label is a port */ struct label *lab_next; /* Next label in list */ - char lab_text[4]; /* Actual text of label. This field - * is just a place-holder: the actual - * field will be large enough to - * contain the label name. This - * MUST be the last field in the - * structure. - */ + char lab_text[]; /* Actual text of label. This + * MUST be the last field in the + * structure. + */ } Label; +/* + * Size of a Label big enough to hold a string containing + * n bytes (not including the NULL byte). + */ +#define labelSize(n) (sizeof(Label) + n + 1) + /* * Label flags bit fields */ @@ -731,13 +734,24 @@ typedef struct int prop_type; /* See codes below; e.g., PROPERTY_TYPE_STRING */ int prop_len; /* String length or number of values */ union { - char prop_string[8]; /* For PROPERTY_TYPE_STRING */ - int prop_integer[2]; /* For PROPERTY_TYPE_INTEGER or _DIMENSION */ - dlong prop_double[1]; /* For PROPERTY_TYPE_DOUBLE */ - Plane *prop_plane; /* For PROPERTY_TYPE_PLANE */ + Plane *prop_plane; /* For PROPERTY_TYPE_PLANE */ + int prop_integer[]; /* For PROPERTY_TYPE_INTEGER or _DIMENSION */ + dlong prop_double[]; /* For PROPERTY_TYPE_DOUBLE */ + char prop_string[]; /* For PROPERTY_TYPE_STRING, must be last in + * struct and union */ } prop_value; } PropertyRecord; +#define intPropertyRecordSize(n) ( \ + sizeof(PropertyRecord) + n * sizeof(int) \ + - sizeof(((PropertyRecord *) 0)->prop_value)) +#define dlongPropertyRecordSize(n) ( \ + sizeof(PropertyRecord) + n * sizeof(dlong) \ + - sizeof(((PropertyRecord *) 0)->prop_value)) +#define strPropertyRecordSize(n) ( \ + sizeof(PropertyRecord) + n + 1 - \ + sizeof(((PropertyRecord *) 0)->prop_value)) + /* -------------- Undo information passed to DBPaintPlane ------------- */ typedef struct diff --git a/dbwind/DBWundo.c b/dbwind/DBWundo.c index 37b78db3..050f176a 100644 --- a/dbwind/DBWundo.c +++ b/dbwind/DBWundo.c @@ -63,14 +63,10 @@ typedef struct CellDef *e_parentDef; /* Parent def of the editcell, or NULL if the * edit cell was a root itself. */ - char e_useId[4]; /* Use identifier. This is a place holder - * only; the actual structure is allocated to - * hold all the bytes in the use id, plus the - * null byte. - */ + char e_useId[]; /* Use identifier. Dynamically allocated. */ } editUE; -#define editSize(n) (sizeof (editUE) - 3 + (n)) +#define editSize(n) (sizeof (editUE) + n + 1) /* Structure used for undo-ing changes in the box. It just holds the * box's old and new locations. diff --git a/extflat/EFtypes.h b/extflat/EFtypes.h index 71335c8c..8ad40ef9 100644 --- a/extflat/EFtypes.h +++ b/extflat/EFtypes.h @@ -74,14 +74,14 @@ typedef struct hiername { struct hiername *hn_parent; /* Back-pointer toward root */ int hn_hash; /* For speed in hashing */ - char hn_name[4]; /* String is allocated here */ + char hn_name[]; /* String is allocated here */ } HierName; /* * Size of a HierName big enough to hold a string containing * n bytes (not including the NULL byte). */ -#define HIERNAMESIZE(n) ((n) + sizeof (HierName) - 3) +#define HIERNAMESIZE(n) (sizeof (HierName) + n + 1) /* Indicates where the HierName was allocated: passed to EFHNFree() */ #define HN_ALLOC 0 /* Normal name (FromStr) */ @@ -96,14 +96,14 @@ typedef struct efattr struct efattr *efa_next; /* Next in list */ Rect efa_loc; /* Location of attr label */ int efa_type; /* Tile type attr attached to */ - char efa_text[4]; /* String is allocated here */ + char efa_text[]; /* String is allocated here */ } EFAttr; /* * Size of an EFAttr big enough to hold a string containing * n bytes (not including the NULL byte). */ -#define ATTRSIZE(n) ((n) + sizeof (EFAttr) - 3) +#define ATTRSIZE(n) (sizeof (EFAttr) + n + 1) /* ------------------- Hierarchical and flat nodes -------------------- */ @@ -289,14 +289,14 @@ typedef struct dev int dev_length; int dev_width; DevParam *dev_params; /* List of subcircuit parameters to output */ - DevTerm dev_terms[1]; /* Terminals. The actual number will depend + DevTerm dev_terms[]; /* Terminals. The actual number will depend * on dev_nterm above, so the size of this * structure will vary. */ } Dev; /* Size of a Dev structure for 'n' terminals (including the "gate") */ -#define DevSize(n) (sizeof (Dev) + ((n)-1)*sizeof (DevTerm)) +#define DevSize(n) (sizeof (Dev) + n * sizeof (DevTerm)) /* -------------------------------------------------------------------- */ diff --git a/extract/ExtHard.c b/extract/ExtHard.c index e4c182f1..d3877c85 100644 --- a/extract/ExtHard.c +++ b/extract/ExtHard.c @@ -327,7 +327,7 @@ extHardSetLabel(scx, reg, arg) len = strlen(oldlab->lab_text) + prefixlen; /* Allocate a Label big enough to hold the complete path */ - newlab = (Label *) mallocMagic((unsigned) (sizeof (Label) + len - 3)); + newlab = (Label *) mallocMagic((unsigned)labelSize(len)); r=oldlab->lab_rect; if (!GEO_SURROUND(&scx->scx_area,&r)) { @@ -431,7 +431,7 @@ extHardGenerateLabel(scx, reg, arg) prefixlen = tpath->tp_next - tpath->tp_first; len = strlen(gen) + prefixlen; - newlab = (Label *) mallocMagic((unsigned) (sizeof (Label) + len - 3)); + newlab = (Label *) mallocMagic((unsigned)labelSize(len)); r.r_ll = reg->treg_tile->ti_ll; r.r_ur.p_x = r.r_ll.p_x+1; r.r_ur.p_y = r.r_ll.p_y+1; diff --git a/extract/ExtLength.c b/extract/ExtLength.c index f245107b..abaa1d83 100644 --- a/extract/ExtLength.c +++ b/extract/ExtLength.c @@ -497,7 +497,6 @@ extLengthLabelsFunc(scx, label, tpath) { Label *newLab; HashEntry *he; - int len; /* Concatenate the prefix and label to get the full hierarchical name */ (void) strcpy(tpath->tp_next, label->lab_text); @@ -511,9 +510,7 @@ extLengthLabelsFunc(scx, label, tpath) HashSetValue(he, (ClientData) 1); /* Allocate and fill in a new hierarchical label */ - len = strlen(tpath->tp_first) + sizeof (Label) - - sizeof newLab->lab_text + 1; - newLab = (Label *) mallocMagic((unsigned) len); + newLab = (Label *) mallocMagic((unsigned)labelSize(strlen(tpath->tp_first))); newLab->lab_type = label->lab_type; newLab->lab_just = GeoTransPos(&scx->scx_trans, label->lab_just); GeoTransRect(&scx->scx_trans, &label->lab_rect, &newLab->lab_rect); @@ -587,10 +584,8 @@ extPathLabelFunc(rect, text, childLab, pLabList) */ { Label *lab; - int len; - len = strlen(text) + sizeof (Label) - sizeof lab->lab_text + 1; - lab = (Label *) mallocMagic((unsigned) len); + lab = (Label *) mallocMagic((unsigned)labelSize(strlen(text))); lab->lab_type = childLab->lab_type; lab->lab_rect = *rect; lab->lab_just = GEO_CENTER; /* Irrelevant */ diff --git a/extract/ExtSubtree.c b/extract/ExtSubtree.c index 19e1109c..06d23dab 100644 --- a/extract/ExtSubtree.c +++ b/extract/ExtSubtree.c @@ -918,8 +918,7 @@ extSubtreeFunc(scx, ha) extFoundProc, (ClientData)NULL) == 0) continue; - n = sizeof (Label) + strlen(lab->lab_text) - - sizeof lab->lab_text + 1; + n = labelSize(strlen(lab->lab_text)); newlab = (Label *)mallocMagic(n); newlab->lab_type = lab->lab_type; diff --git a/extract/ExtYank.c b/extract/ExtYank.c index 18ee7909..2267bcea 100644 --- a/extract/ExtYank.c +++ b/extract/ExtYank.c @@ -79,7 +79,7 @@ extHierCopyLabels(sourceDef, targetDef) firstLab = lastLab = (Label *) NULL; for (lab = sourceDef->cd_labels; lab; lab = lab->lab_next) { - n = sizeof (Label) + strlen(lab->lab_text) - sizeof lab->lab_text + 1; + n = labelSize(strlen(lab->lab_text)); newlab = (Label *) mallocMagic((unsigned) n); bcopy((char *) lab, (char *) newlab, (int) n); @@ -228,7 +228,7 @@ extHierLabelFunc(scx, label, tpath, targetDef) len += srcp - tpath->tp_first + 1; /* Allocate new label at correct location */ - newlab = (Label *) mallocMagic((unsigned) (sizeof (Label) + len - 4)); + newlab = (Label *) mallocMagic((unsigned)labelSize(len - 1)); GeoTransRect(&scx->scx_trans, &label->lab_rect, &newlab->lab_rect); newlab->lab_just = GeoTransPos(&scx->scx_trans, label->lab_just); newlab->lab_type = label->lab_type; diff --git a/lef/defRead.c b/lef/defRead.c index e9fcba79..cac86fde 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -2633,8 +2633,7 @@ DefRead( break; case DEF_DIEAREA: dierect = LefReadRect(f, 0, oscale); - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - 2 * sizeof(int)); + proprec = (PropertyRecord *)mallocMagic(intPropertyRecordSize(4)); proprec->prop_type = PROPERTY_TYPE_DIMENSION; proprec->prop_len = 4; proprec->prop_value.prop_integer[0] = dierect->r_xbot; diff --git a/lef/lefRead.c b/lef/lefRead.c index a083ed15..ba928725 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -2191,8 +2191,8 @@ LefReadMacro( sprintf(tsave + strlen(tsave), " %s", token); token = LefNextToken(f, TRUE); } - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - strlen(tsave + 1) - 7); + proprec = (PropertyRecord *)mallocMagic( + strPropertyRecordSize(strlen(tsave + 1))); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = strlen(tsave + 1); strcpy(proprec->prop_value.prop_string, tsave + 1); @@ -2240,8 +2240,8 @@ origin_error: sprintf(tsave + strlen(tsave), " %s", token); token = LefNextToken(f, TRUE); } - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - strlen(tsave + 1) - 7); + proprec = (PropertyRecord *)mallocMagic( + strPropertyRecordSize(strlen(tsave + 1))); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = strlen(tsave + 1); strcpy(proprec->prop_value.prop_string, tsave + 1); @@ -2257,8 +2257,8 @@ origin_error: token = LefNextToken(f, TRUE); if (*token != '\n') { - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - strlen(token) - 7); + proprec = (PropertyRecord *)mallocMagic( + strPropertyRecordSize(strlen(token))); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = strlen(token); strcpy(proprec->prop_value.prop_string, token); @@ -2281,8 +2281,16 @@ origin_error: sprintf(tsave, "%.127s", token); token = LefNextToken(f, TRUE); - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - propsize + strlen(tsave) + strlen(token) - 3); + proprec = (PropertyRecord *)mallocMagic( + // stores three separate strings contiguously… + sizeof(PropertyRecord) + + propsize + 1 + + strlen(tsave) + 1 + + strlen(token) + 1 + + 1 // the prop_len was + 4 before I edited this and I'm not + // really tempted to set it to + 3 and find out why. I'm + // just going to allocate the extra byte. + ); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = propsize + strlen(tsave) + strlen(token) + 4; @@ -2368,8 +2376,7 @@ foreign_error: if (has_size) { lefMacro->cd_flags |= CDFIXEDBBOX; - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - (2 * sizeof(int))); + proprec = (PropertyRecord *)mallocMagic(intPropertyRecordSize(4)); proprec->prop_type = PROPERTY_TYPE_DIMENSION; proprec->prop_len = 4; proprec->prop_value.prop_integer[0] = lefBBox.r_xbot; @@ -2387,8 +2394,7 @@ foreign_error: if (has_size) { lefMacro->cd_flags |= CDFIXEDBBOX; - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - (2 * sizeof(int))); + proprec = (PropertyRecord *)mallocMagic(intPropertyRecordSize(4)); proprec->prop_type = PROPERTY_TYPE_DIMENSION; proprec->prop_len = 4; proprec->prop_value.prop_integer[0] = lefBBox.r_xbot; @@ -2406,8 +2412,7 @@ foreign_error: /* Set the placement bounding box property to the current bounding box */ lefMacro->cd_flags |= CDFIXEDBBOX; lefMacro->cd_flags |= CDFIXEDBBOX; - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + - (2 * sizeof(int))); + proprec = (PropertyRecord *)mallocMagic(intPropertyRecordSize(4)); proprec->prop_type = PROPERTY_TYPE_DIMENSION; proprec->prop_len = 4; proprec->prop_value.prop_integer[0] = lefMacro->cd_bbox.r_xbot; @@ -2431,7 +2436,7 @@ foreign_error: if (!is_imported) { - proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord)); + proprec = (PropertyRecord *)mallocMagic(strPropertyRecordSize(4)); proprec->prop_type = PROPERTY_TYPE_STRING; proprec->prop_len = 4; strcpy(proprec->prop_value.prop_string, "TRUE"); diff --git a/sim/SimDBstuff.c b/sim/SimDBstuff.c index 8ae21aa4..c968c0b5 100644 --- a/sim/SimDBstuff.c +++ b/sim/SimDBstuff.c @@ -866,10 +866,9 @@ SimPutLabel( TileType type) /* Type of tile to be labeled */ { Label *lab; - int len, x1, x2, y1, y2, tmp, labx, laby; + int x1, x2, y1, y2, tmp, labx, laby; - len = strlen(text) + sizeof (Label) - sizeof lab->lab_text + 1; - lab = (Label *) mallocMagic((unsigned) len); + lab = (Label *) mallocMagic((unsigned)labelSize(strlen(text))); strcpy(lab->lab_text, text); /* Pick a nice alignment if the caller didn't give one. If the diff --git a/utils/hash.c b/utils/hash.c index 342f2f57..2e973b24 100644 --- a/utils/hash.c +++ b/utils/hash.c @@ -418,7 +418,13 @@ next: switch (table->ht_ptrKeys) { case HT_STRINGKEYS: - h = (HashEntry *) mallocMagic((unsigned) (sizeof(HashEntry)+strlen(key)-3)); + // n char entries + h = (HashEntry *) mallocMagic((unsigned)( + sizeof(HashEntry) + + strlen(key) // key + + 1 // NUL char + - sizeof(h->h_key) // redundant pointer alloc + )); (void) strcpy(h->h_key.h_name, key); break; case HT_CLIENTKEYS: @@ -434,17 +440,25 @@ next: h->h_key.h_ptr = key; break; case HT_STRUCTKEYS: - h = (HashEntry *) mallocMagic( - (unsigned) (sizeof (HashEntry) + sizeof (unsigned))); + // exactly two unsigned entries + h = (HashEntry *) mallocMagic((unsigned)( + sizeof (HashEntry) + + 2 * sizeof (unsigned) + - sizeof(h->h_key) // redundant pointer alloc + )); up = h->h_key.h_words; kp = (unsigned *) key; *up++ = *kp++; *up = *kp; break; default: - n = table->ht_ptrKeys; - h = (HashEntry *) mallocMagic( - (unsigned) (sizeof(HashEntry) + (n-1) * sizeof (unsigned))); + // n unsigned entries + n = table->ht_ptrKeys; + h = (HashEntry *) mallocMagic((unsigned)( + sizeof(HashEntry) + + n * sizeof (unsigned) + + -sizeof(h->h_key) // redundant pointer alloc + )); up = h->h_key.h_words; kp = (unsigned *) key; do { *up++ = *kp++; } while (--n); diff --git a/utils/hash.h b/utils/hash.h index a55692bd..1fb25ee4 100644 --- a/utils/hash.h +++ b/utils/hash.h @@ -33,18 +33,11 @@ typedef struct h1 { char *h_pointer; /* Pointer to anything. */ struct h1 *h_next; /* Next element, zero for end. */ - union - { + union { const char *h_ptr; /* One-word key value to identify entry. */ - unsigned h_words[1]; /* N-word key value. Note: the actual - * size may be longer if necessary to hold - * the entire key. - */ - char h_name[4]; /* Text name of this entry. Note: the - * actual size may be longer if necessary - * to hold the whole string. This MUST be - * the last entry in the structure!!! - */ + /* Following members must be the last part of the struct and union:*/ + unsigned h_words[]; /* N-word key value. */ + char h_name[]; /* Text name of this entry. */ } h_key; } HashEntry; diff --git a/utils/undo.c b/utils/undo.c index b4124c5e..f9b33ce8 100644 --- a/utils/undo.c +++ b/utils/undo.c @@ -79,7 +79,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ UndoType iue_type; /* Event type */ struct ue *iue_back; /* Previous event on list */ struct ue *iue_forw; /* Next event on list */ - int iue_client; /* Client data area. This is merely a + char iue_client[]; /* Client data area. This is merely a * dummy placeholder; the actual size * of one of these structures is * determined at the time of @@ -95,8 +95,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ * n bytes. */ -#define undoSize(n) (sizeof (struct ue) + (n) \ - - sizeof (((struct ue *) 0)->iue_client)) +#define undoSize(n) (sizeof (struct ue) + n) /* * Mapping between internal and external undo event pointers.