Came across a weird error today in which some tool inserted bogus

data into an array reference in GDS;  This may be ignored by most
tools (which are not trying to keep track of grid scaling) which
read the bogus value which then gets discarded because it is
unused (X pitch is irrelevant when there is only one column, and
Y pitch is irrelevant when there is only one row).  But since
magic will try to interpret all input relative to the grid, a
bogus value can cause serious problems, and magic needs to actively
ignore the appropriate input in the case of rows = 1 or columns = 1.
This commit is contained in:
R. Timothy Edwards 2026-02-24 20:56:27 -05:00
parent cedd64adcb
commit f3404f67b7
3 changed files with 57 additions and 2 deletions

View File

@ -994,12 +994,39 @@ calmaElementSref(
* and place the cell in the magic database. However, if this is
* a cell to be flattened a la "gds flatten", then we keep the GDS
* coordinates, and don't scale to the magic database.
*
* NOTE: Scaling everything in the middle or reading array data
* and then retroactively adjusting the array data read earlier
* is problematic, and probably incorrect.
*/
for (n = 0; n < nref; n++)
{
savescale = cifCurReadStyle->crs_scaleFactor;
calmaReadPoint(&refarray[n], 1);
/* If there is only one column, then X data in the 2nd or 3rd
* entry is irrelevant. If there is only one row, then Y data
* in the 2nd or 3rd entry is irrelevant. Prevent issues caused
* by incorrect/uninitialized data in these positions by ignoring
* them as needed.
*/
if ((n > 0) && (rows == 1))
{
calmaReadX(&refarray[n], 1);
calmaSkipBytes(4);
refarray[n].p_y = 0;
}
else if ((n > 0) && (cols == 1))
{
calmaSkipBytes(4);
calmaReadY(&refarray[n], 1);
refarray[n].p_x = 0;
}
else
{
calmaReadPoint(&refarray[n], 1);
}
refunscaled[n] = refarray[n]; // Save for CDFLATGDS cells
refarray[n].p_x = CIFScaleCoord(refarray[n].p_x, COORD_EXACT);
if (savescale != cifCurReadStyle->crs_scaleFactor)

View File

@ -114,6 +114,8 @@ calmaInputRescale(
/*
* ----------------------------------------------------------------------------
*
* calmaReadX ---
* calmaReadY ---
* calmaReadPoint ---
*
* Read a point from the input.
@ -132,11 +134,17 @@ calmaInputRescale(
* encountered, then everything in the GDS planes is rescaled
* to match.
*
* Notes:
* This routine has been split into individual X and Y reads so that
* array data can be read while ignoring offset information when there
* is only one row or column; otherwise, bad or uninitialized data
* in the record can cause unnecessary and incorrect scaling.
*
* ----------------------------------------------------------------------------
*/
void
calmaReadPoint(
calmaReadX(
Point *p,
int iscale)
{
@ -163,6 +171,15 @@ calmaReadPoint(
}
}
p->p_x /= calmaReadScale2;
}
void
calmaReadY(
Point *p,
int iscale)
{
int rescale;
READI4((p)->p_y);
p->p_y *= (calmaReadScale1 * iscale);
@ -188,6 +205,15 @@ calmaReadPoint(
p->p_y /= calmaReadScale2;
}
void
calmaReadPoint(
Point *p,
int iscale)
{
calmaReadX(p, iscale);
calmaReadY(p, iscale);
}
/*
* ----------------------------------------------------------------------------

View File

@ -82,6 +82,8 @@ extern int calmaProcessDefZ(CellDef *def, gzFile outf, bool do_library);
#endif
extern bool calmaReadI2Record(int type, int *pvalue);
extern bool calmaReadI4Record(int type, int *pvalue);
extern void calmaReadX(Point *p, int iscale);
extern void calmaReadY(Point *p, int iscale);
extern void calmaReadPoint(Point *p, int iscale);
extern bool calmaReadR8(double *pd);
extern bool calmaReadStampRecord(int type, int *stampptr);