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 "textio/textio.h"
#include "calma/calmaInt.h"
#include "extract/extractInt.h" /* for LabelList */
#include "utils/main.h" /* for Path and CellLibPath */
#include "utils/stack.h"
@ -117,7 +118,7 @@ typedef struct {
#define GDS_UNPROCESSED CLIENTDEFAULT
#define GDS_PROCESSED 1
#define PUSHTILE(tp) \
#define PUSHTILEC(tp) \
if ((tp)->ti_client == (ClientData) GDS_UNPROCESSED) { \
(tp)->ti_client = (ClientData) GDS_PENDING; \
STACKPUSH((ClientData) (tp), SegStack); \
@ -1244,6 +1245,30 @@ calmaProcessDef(def, outf, do_library)
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)
{
int i, ltype, maxport = -1;
int i, ltype, numports = 0;
LabelList *ll = NULL, *newll;
for (lab = def->cd_labels; lab; lab = lab->lab_next)
{
@ -1395,23 +1421,42 @@ calmaOutFunc(def, f, cliprect)
}
else
{
if ((int)lab->lab_port > maxport)
maxport = (int)lab->lab_port;
newll = (LabelList *)mallocMagic(sizeof(LabelList));
newll->ll_label = lab;
newll->ll_attr = (unsigned int)lab->lab_port;
newll->ll_next = ll;
ll = newll;
numports++;
}
}
if (maxport >= 0)
for (i = 0; i <= maxport; i++)
for (lab = def->cd_labels; lab; lab = lab->lab_next)
{
ltype = CIFCurStyle->cs_portText[lab->lab_type];
type = CIFCurStyle->cs_portLayer[lab->lab_type];
if ((type >= 0) && ((lab->lab_flags & PORT_DIR_MASK) != 0) &&
(lab->lab_port == i))
{
calmaWriteLabelFunc(lab, ltype, type, f);
/* break; */ /* Do not limit to unique labels! */
}
}
if (newll != NULL)
{
/* Turn linked list into an array, then run qsort on it */
/* to sort by port number. */
PortLabel *pllist = (PortLabel *)mallocMagic(numports * sizeof(PortLabel));
i = 0;
while (ll != NULL)
{
pllist[i].pl_label = ll->ll_label;
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 */
@ -2461,7 +2506,7 @@ calmaMergePaintFunc(tile, cos)
if (SegStack == (Stack *)NULL)
SegStack = StackNew(64);
PUSHTILE(tile);
PUSHTILEC(tile);
while (!StackEmpty(SegStack))
{
t = (Tile *) STACKPOP(SegStack);
@ -2629,7 +2674,7 @@ calmaMergePaintFunc(tile, cos)
intedges += calmaAddSegment(&lb, is_ext,
MIN(RIGHT(t), RIGHT(tp)), TOP(t),
MAX(LEFT(t), LEFT(tp)), TOP(t));
if (!is_ext) PUSHTILE(tp);
if (!is_ext) PUSHTILEC(tp);
}
if (split_type == 0x3)
@ -2649,7 +2694,7 @@ left_search:
intedges += calmaAddSegment(&lb, is_ext,
LEFT(t), MIN(TOP(t), TOP(tp)),
LEFT(t), MAX(BOTTOM(t), BOTTOM(tp)));
if (!is_ext) PUSHTILE(tp);
if (!is_ext) PUSHTILEC(tp);
}
if (split_type == 0x0)
@ -2669,7 +2714,7 @@ bottom_search:
intedges += calmaAddSegment(&lb, is_ext,
MAX(LEFT(t), LEFT(tp)), BOTTOM(t),
MIN(RIGHT(t), RIGHT(tp)), BOTTOM(t));
if (!is_ext) PUSHTILE(tp);
if (!is_ext) PUSHTILEC(tp);
}
if (split_type == 0x1)
@ -2688,7 +2733,7 @@ right_search:
intedges += calmaAddSegment(&lb, is_ext,
RIGHT(t), MAX(BOTTOM(t), BOTTOM(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 */

View File

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

View File

@ -216,6 +216,14 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
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 */
extern HashTable calmaLayerHash;
extern int calmaElementIgnore[];
@ -230,6 +238,8 @@ extern bool calmaIsContactCell;
extern char *calmaRecordName();
extern void calmaSkipSet();
extern int compport();
/* ------------------- Imports from CIF reading ----------------------- */
extern CellDef *cifReadCellDef;

View File

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