Applied patch from Donn that converts strcpy() calls in ext2spice

to "safer" strncpy() calls to prevent string buffer overflow.
Also:  Reimplemented the loop in the GDS write routine that counts
ports and then outputs them in order.  It was possible to hang
magic for a long time by giving a port a very, very large index
number.  The new implementation uses qsort() to sort the ports
by index, which is obviously much more efficient for the worst
case (and efficient enough for all normal cases).
This commit is contained in:
Tim Edwards 2023-03-21 22:04:30 -04:00
parent d8f926865d
commit 58c6a32a6c
5 changed files with 137 additions and 60 deletions

View File

@ -1 +1 @@
8.3.383 8.3.384

View File

@ -50,6 +50,7 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c
#include "utils/styles.h" #include "utils/styles.h"
#include "textio/textio.h" #include "textio/textio.h"
#include "calma/calmaInt.h" #include "calma/calmaInt.h"
#include "extract/extractInt.h" /* for LabelList */
#include "utils/main.h" /* for Path and CellLibPath */ #include "utils/main.h" /* for Path and CellLibPath */
#include "utils/stack.h" #include "utils/stack.h"
@ -117,7 +118,7 @@ typedef struct {
#define GDS_UNPROCESSED CLIENTDEFAULT #define GDS_UNPROCESSED CLIENTDEFAULT
#define GDS_PROCESSED 1 #define GDS_PROCESSED 1
#define PUSHTILE(tp) \ #define PUSHTILEC(tp) \
if ((tp)->ti_client == (ClientData) GDS_UNPROCESSED) { \ if ((tp)->ti_client == (ClientData) GDS_UNPROCESSED) { \
(tp)->ti_client = (ClientData) GDS_PENDING; \ (tp)->ti_client = (ClientData) GDS_PENDING; \
STACKPUSH((ClientData) (tp), SegStack); \ STACKPUSH((ClientData) (tp), SegStack); \
@ -1244,6 +1245,30 @@ calmaProcessDef(def, outf, do_library)
return 0; return 0;
} }
/*
* ----------------------------------------------------------------------------
*
* compport ---
*
* Compare two port labels by port index. Sorting function used with
* qsort().
*
* ----------------------------------------------------------------------------
*/
int
compport(const void *one, const void *two)
{
PortLabel *pl1 = (PortLabel *)one;
PortLabel *pl2 = (PortLabel *)two;
if (pl1->pl_port < pl2->pl_port)
return -1;
if (pl1->pl_port > pl2->pl_port)
return 1;
else
return 0;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
@ -1383,7 +1408,8 @@ calmaOutFunc(def, f, cliprect)
if (CalmaDoLabels) if (CalmaDoLabels)
{ {
int i, ltype, maxport = -1; int i, ltype, numports = 0;
LabelList *ll = NULL, *newll;
for (lab = def->cd_labels; lab; lab = lab->lab_next) for (lab = def->cd_labels; lab; lab = lab->lab_next)
{ {
@ -1395,23 +1421,42 @@ calmaOutFunc(def, f, cliprect)
} }
else else
{ {
if ((int)lab->lab_port > maxport) newll = (LabelList *)mallocMagic(sizeof(LabelList));
maxport = (int)lab->lab_port; newll->ll_label = lab;
newll->ll_attr = (unsigned int)lab->lab_port;
newll->ll_next = ll;
ll = newll;
numports++;
} }
} }
if (maxport >= 0) if (newll != NULL)
for (i = 0; i <= maxport; i++) {
for (lab = def->cd_labels; lab; lab = lab->lab_next) /* Turn linked list into an array, then run qsort on it */
{ /* to sort by port number. */
ltype = CIFCurStyle->cs_portText[lab->lab_type];
type = CIFCurStyle->cs_portLayer[lab->lab_type]; PortLabel *pllist = (PortLabel *)mallocMagic(numports * sizeof(PortLabel));
if ((type >= 0) && ((lab->lab_flags & PORT_DIR_MASK) != 0) && i = 0;
(lab->lab_port == i)) while (ll != NULL)
{ {
calmaWriteLabelFunc(lab, ltype, type, f); pllist[i].pl_label = ll->ll_label;
/* break; */ /* Do not limit to unique labels! */ pllist[i].pl_port = (unsigned int)ll->ll_attr;
} freeMagic(ll);
} ll = ll->ll_next;
i++;
}
qsort(pllist, numports, sizeof(PortLabel), compport);
for (i = 0; i < numports; i++)
{
lab = pllist[i].pl_label;
ltype = CIFCurStyle->cs_portText[lab->lab_type];
type = CIFCurStyle->cs_portLayer[lab->lab_type];
if (type >= 0)
calmaWriteLabelFunc(lab, ltype, type, f);
}
freeMagic(pllist);
}
} }
/* End of structure */ /* End of structure */
@ -2461,7 +2506,7 @@ calmaMergePaintFunc(tile, cos)
if (SegStack == (Stack *)NULL) if (SegStack == (Stack *)NULL)
SegStack = StackNew(64); SegStack = StackNew(64);
PUSHTILE(tile); PUSHTILEC(tile);
while (!StackEmpty(SegStack)) while (!StackEmpty(SegStack))
{ {
t = (Tile *) STACKPOP(SegStack); t = (Tile *) STACKPOP(SegStack);
@ -2629,7 +2674,7 @@ calmaMergePaintFunc(tile, cos)
intedges += calmaAddSegment(&lb, is_ext, intedges += calmaAddSegment(&lb, is_ext,
MIN(RIGHT(t), RIGHT(tp)), TOP(t), MIN(RIGHT(t), RIGHT(tp)), TOP(t),
MAX(LEFT(t), LEFT(tp)), TOP(t)); MAX(LEFT(t), LEFT(tp)), TOP(t));
if (!is_ext) PUSHTILE(tp); if (!is_ext) PUSHTILEC(tp);
} }
if (split_type == 0x3) if (split_type == 0x3)
@ -2649,7 +2694,7 @@ left_search:
intedges += calmaAddSegment(&lb, is_ext, intedges += calmaAddSegment(&lb, is_ext,
LEFT(t), MIN(TOP(t), TOP(tp)), LEFT(t), MIN(TOP(t), TOP(tp)),
LEFT(t), MAX(BOTTOM(t), BOTTOM(tp))); LEFT(t), MAX(BOTTOM(t), BOTTOM(tp)));
if (!is_ext) PUSHTILE(tp); if (!is_ext) PUSHTILEC(tp);
} }
if (split_type == 0x0) if (split_type == 0x0)
@ -2669,7 +2714,7 @@ bottom_search:
intedges += calmaAddSegment(&lb, is_ext, intedges += calmaAddSegment(&lb, is_ext,
MAX(LEFT(t), LEFT(tp)), BOTTOM(t), MAX(LEFT(t), LEFT(tp)), BOTTOM(t),
MIN(RIGHT(t), RIGHT(tp)), BOTTOM(t)); MIN(RIGHT(t), RIGHT(tp)), BOTTOM(t));
if (!is_ext) PUSHTILE(tp); if (!is_ext) PUSHTILEC(tp);
} }
if (split_type == 0x1) if (split_type == 0x1)
@ -2688,7 +2733,7 @@ right_search:
intedges += calmaAddSegment(&lb, is_ext, intedges += calmaAddSegment(&lb, is_ext,
RIGHT(t), MAX(BOTTOM(t), BOTTOM(tp)), RIGHT(t), MAX(BOTTOM(t), BOTTOM(tp)),
RIGHT(t), MIN(TOP(t), TOP(tp))); RIGHT(t), MIN(TOP(t), TOP(tp)));
if (!is_ext) PUSHTILE(tp); if (!is_ext) PUSHTILEC(tp);
} }
/* If tile is isolated, process it now and we're done */ /* If tile is isolated, process it now and we're done */

View File

@ -60,6 +60,7 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c
#include "utils/styles.h" #include "utils/styles.h"
#include "textio/textio.h" #include "textio/textio.h"
#include "calma/calmaInt.h" #include "calma/calmaInt.h"
#include "extract/extractInt.h" /* for LabelList */
#include "utils/main.h" /* for Path and CellLibPath */ #include "utils/main.h" /* for Path and CellLibPath */
#include "utils/stack.h" #include "utils/stack.h"
@ -122,7 +123,7 @@ typedef struct {
#define GDS_UNPROCESSED CLIENTDEFAULT #define GDS_UNPROCESSED CLIENTDEFAULT
#define GDS_PROCESSED 1 #define GDS_PROCESSED 1
#define PUSHTILE(tp) \ #define PUSHTILEZ(tp) \
if ((tp)->ti_client == (ClientData) GDS_UNPROCESSED) { \ if ((tp)->ti_client == (ClientData) GDS_UNPROCESSED) { \
(tp)->ti_client = (ClientData) GDS_PENDING; \ (tp)->ti_client = (ClientData) GDS_PENDING; \
STACKPUSH((ClientData) (tp), SegStack); \ STACKPUSH((ClientData) (tp), SegStack); \
@ -1186,6 +1187,7 @@ calmaOutFuncZ(def, f, cliprect)
calmaOutputStructZ cos; calmaOutputStructZ cos;
bool propfound; bool propfound;
char *propvalue; char *propvalue;
extern int compport(); /* Forward declaration */
cos.f = f; cos.f = f;
cos.area = (cliprect == &TiPlaneRect) ? NULL : cliprect; cos.area = (cliprect == &TiPlaneRect) ? NULL : cliprect;
@ -1290,7 +1292,8 @@ calmaOutFuncZ(def, f, cliprect)
if (CalmaDoLabels) if (CalmaDoLabels)
{ {
int i, ltype, maxport = -1; int i, ltype, numports = 0;
LabelList *ll = NULL, *newll;
for (lab = def->cd_labels; lab; lab = lab->lab_next) for (lab = def->cd_labels; lab; lab = lab->lab_next)
{ {
@ -1302,23 +1305,42 @@ calmaOutFuncZ(def, f, cliprect)
} }
else else
{ {
if ((int)lab->lab_port > maxport) newll = (LabelList *)mallocMagic(sizeof(LabelList));
maxport = (int)lab->lab_port; newll->ll_label = lab;
newll->ll_attr = (unsigned int)lab->lab_port;
newll->ll_next = ll;
ll = newll;
numports++;
} }
} }
if (maxport >= 0) if (newll != NULL)
for (i = 0; i <= maxport; i++) {
for (lab = def->cd_labels; lab; lab = lab->lab_next) /* Turn linked list into an array, then run qsort on it */
{ /* to sort by port number. */
ltype = CIFCurStyle->cs_portText[lab->lab_type];
type = CIFCurStyle->cs_portLayer[lab->lab_type]; PortLabel *pllist = (PortLabel *)mallocMagic(numports * sizeof(PortLabel));
if ((type >= 0) && ((lab->lab_flags & PORT_DIR_MASK) != 0) && i = 0;
(lab->lab_port == i)) while (ll != NULL)
{ {
calmaWriteLabelFuncZ(lab, ltype, type, f); pllist[i].pl_label = ll->ll_label;
/* break; */ /* Do not limit to unique labels! */ pllist[i].pl_port = (unsigned int)ll->ll_attr;
} freeMagic(ll);
} ll = ll->ll_next;
i++;
}
qsort(pllist, numports, sizeof(PortLabel), compport);
for (i = 0; i < numports; i++)
{
lab = pllist[i].pl_label;
ltype = CIFCurStyle->cs_portText[lab->lab_type];
type = CIFCurStyle->cs_portLayer[lab->lab_type];
if (type >= 0)
calmaWriteLabelFuncZ(lab, ltype, type, f);
}
freeMagic(pllist);
}
} }
/* End of structure */ /* End of structure */
@ -1737,7 +1759,7 @@ calmaWriteContactsZ(f)
/* Get clip bounds, so that residue surround is */ /* Get clip bounds, so that residue surround is */
/* minimum. Note that these values are in CIF/GDS */ /* minimum. Note that these values are in CIF/GDS */
/* units, and the clipping rectangle passed to */ /* units, and the clipping rectangle passed to */
/* calmaOutFunc is also in CIF/GDS units. */ /* calmaOutFuncZ is also in CIF/GDS units. */
halfsize = CIFGetContactSize(type, NULL, NULL, NULL) >> 1; halfsize = CIFGetContactSize(type, NULL, NULL, NULL) >> 1;
@ -1882,7 +1904,7 @@ calmaMergePaintFuncZ(tile, cos)
if (SegStack == (Stack *)NULL) if (SegStack == (Stack *)NULL)
SegStack = StackNew(64); SegStack = StackNew(64);
PUSHTILE(tile); PUSHTILEZ(tile);
while (!StackEmpty(SegStack)) while (!StackEmpty(SegStack))
{ {
t = (Tile *) STACKPOP(SegStack); t = (Tile *) STACKPOP(SegStack);
@ -2050,7 +2072,7 @@ calmaMergePaintFuncZ(tile, cos)
intedges += calmaAddSegment(&lb, is_ext, intedges += calmaAddSegment(&lb, is_ext,
MIN(RIGHT(t), RIGHT(tp)), TOP(t), MIN(RIGHT(t), RIGHT(tp)), TOP(t),
MAX(LEFT(t), LEFT(tp)), TOP(t)); MAX(LEFT(t), LEFT(tp)), TOP(t));
if (!is_ext) PUSHTILE(tp); if (!is_ext) PUSHTILEZ(tp);
} }
if (split_type == 0x3) if (split_type == 0x3)
@ -2070,7 +2092,7 @@ left_search:
intedges += calmaAddSegment(&lb, is_ext, intedges += calmaAddSegment(&lb, is_ext,
LEFT(t), MIN(TOP(t), TOP(tp)), LEFT(t), MIN(TOP(t), TOP(tp)),
LEFT(t), MAX(BOTTOM(t), BOTTOM(tp))); LEFT(t), MAX(BOTTOM(t), BOTTOM(tp)));
if (!is_ext) PUSHTILE(tp); if (!is_ext) PUSHTILEZ(tp);
} }
if (split_type == 0x0) if (split_type == 0x0)
@ -2090,7 +2112,7 @@ bottom_search:
intedges += calmaAddSegment(&lb, is_ext, intedges += calmaAddSegment(&lb, is_ext,
MAX(LEFT(t), LEFT(tp)), BOTTOM(t), MAX(LEFT(t), LEFT(tp)), BOTTOM(t),
MIN(RIGHT(t), RIGHT(tp)), BOTTOM(t)); MIN(RIGHT(t), RIGHT(tp)), BOTTOM(t));
if (!is_ext) PUSHTILE(tp); if (!is_ext) PUSHTILEZ(tp);
} }
if (split_type == 0x1) if (split_type == 0x1)
@ -2109,7 +2131,7 @@ right_search:
intedges += calmaAddSegment(&lb, is_ext, intedges += calmaAddSegment(&lb, is_ext,
RIGHT(t), MAX(BOTTOM(t), BOTTOM(tp)), RIGHT(t), MAX(BOTTOM(t), BOTTOM(tp)),
RIGHT(t), MIN(TOP(t), TOP(tp))); RIGHT(t), MIN(TOP(t), TOP(tp)));
if (!is_ext) PUSHTILE(tp); if (!is_ext) PUSHTILEZ(tp);
} }
/* If tile is isolated, process it now and we're done */ /* If tile is isolated, process it now and we're done */

View File

@ -216,6 +216,14 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
UNREADRH(nb, rt); \ UNREADRH(nb, rt); \
} }
/* Structure used for sorting ports by number */
typedef struct portlabel
{
Label *pl_label;
unsigned int pl_port;
} PortLabel;
/* Other commonly used globals */ /* Other commonly used globals */
extern HashTable calmaLayerHash; extern HashTable calmaLayerHash;
extern int calmaElementIgnore[]; extern int calmaElementIgnore[];
@ -230,6 +238,8 @@ extern bool calmaIsContactCell;
extern char *calmaRecordName(); extern char *calmaRecordName();
extern void calmaSkipSet(); extern void calmaSkipSet();
extern int compport();
/* ------------------- Imports from CIF reading ----------------------- */ /* ------------------- Imports from CIF reading ----------------------- */
extern CellDef *cifReadCellDef; extern CellDef *cifReadCellDef;

View File

@ -3189,8 +3189,8 @@ int spcnAP(dterm, node, resClass, scale, asterm, psterm, m, outf, w)
return 1; return 1;
} }
if (asterm) sprintf(afmt, " %s=", asterm); if (asterm) snprintf(afmt, sizeof afmt, " %s=", asterm);
if (psterm) sprintf(pfmt, " %s=", psterm); if (psterm) snprintf(pfmt, sizeof pfmt, " %s=", psterm);
if (!esDistrJunct || w == -1) goto newFmt; if (!esDistrJunct || w == -1) goto newFmt;
@ -3206,13 +3206,13 @@ int spcnAP(dterm, node, resClass, scale, asterm, psterm, m, outf, w)
{ {
if (asterm) if (asterm)
{ {
fprintf(outf, afmt); fputs(afmt, outf);
esSIvalue(outf, 1.0E-12 * node->efnode_pa[resClass].pa_area esSIvalue(outf, 1.0E-12 * node->efnode_pa[resClass].pa_area
* scale * scale * dsc); * scale * scale * dsc);
} }
if (psterm) if (psterm)
{ {
fprintf(outf, pfmt); fputs(pfmt, outf);
esSIvalue(outf, 1.0E-6 * node->efnode_pa[resClass].pa_perim * scale * dsc); esSIvalue(outf, 1.0E-6 * node->efnode_pa[resClass].pa_perim * scale * dsc);
} }
} }
@ -3220,13 +3220,13 @@ int spcnAP(dterm, node, resClass, scale, asterm, psterm, m, outf, w)
{ {
if (asterm) if (asterm)
{ {
fprintf(outf, afmt); fputs(afmt, outf);
esSIvalue(outf, 1.0E-12 * ((float)node->efnode_pa[resClass].pa_area esSIvalue(outf, 1.0E-12 * ((float)node->efnode_pa[resClass].pa_area
* scale * scale) * esScale * esScale * dsc); * scale * scale) * esScale * esScale * dsc);
} }
if (psterm) if (psterm)
{ {
fprintf(outf, pfmt); fputs(pfmt, outf);
esSIvalue(outf, 1.0E-6 * ((float)node->efnode_pa[resClass].pa_perim esSIvalue(outf, 1.0E-6 * ((float)node->efnode_pa[resClass].pa_perim
* scale) * esScale * dsc); * scale) * esScale * dsc);
} }
@ -3274,12 +3274,12 @@ newFmt:
{ {
if (asterm) if (asterm)
{ {
fprintf(outf, afmt); fputs(afmt, outf);
esSIvalue(outf, 1.0E-12 * area * scale * scale / m); esSIvalue(outf, 1.0E-12 * area * scale * scale / m);
} }
if (psterm) if (psterm)
{ {
fprintf(outf, pfmt); fputs(pfmt, outf);
esSIvalue(outf, 1.0E-6 * perim * scale / m); esSIvalue(outf, 1.0E-6 * perim * scale / m);
} }
} }
@ -3287,12 +3287,12 @@ newFmt:
{ {
if (asterm) if (asterm)
{ {
fprintf(outf, afmt); fputs(afmt, outf);
esSIvalue(outf, 1.0E-12 * ((float)area * scale * scale) * esScale * esScale); esSIvalue(outf, 1.0E-12 * ((float)area * scale * scale) * esScale * esScale);
} }
if (psterm) if (psterm)
{ {
fprintf(outf, pfmt); fputs(pfmt, outf);
esSIvalue(outf, 1.0E-6 * ((float)perim * scale) * esScale); esSIvalue(outf, 1.0E-6 * ((float)perim * scale) * esScale);
} }
} }
@ -3357,16 +3357,16 @@ int spcnAPHier(dterm, hierName, resClass, scale, asterm, psterm, m, outf)
if (esScale < 0) if (esScale < 0)
{ {
fprintf(outf, afmt); fputs(afmt, outf);
esSIvalue(outf, 1.0E-12 * area * scale * scale / m); esSIvalue(outf, 1.0E-12 * area * scale * scale / m);
fprintf(outf, pfmt); fputs(pfmt, outf);
esSIvalue(outf, 1.0E-6 * perim * scale / m); esSIvalue(outf, 1.0E-6 * perim * scale / m);
} }
else else
{ {
fprintf(outf, afmt); fputs(afmt, outf);
esSIvalue(outf, 1.0E-12 * ((float)area * scale) * esScale * esScale); esSIvalue(outf, 1.0E-12 * ((float)area * scale) * esScale * esScale);
fprintf(outf, pfmt); fputs(pfmt, outf);
esSIvalue(outf, 1.0E-6 * ((float)perim * scale) * esScale); esSIvalue(outf, 1.0E-6 * ((float)perim * scale) * esScale);
} }
return 0; return 0;