From 307e22af30f483bb52ec68118454002fb5864fe5 Mon Sep 17 00:00:00 2001 From: "R. Timothy Edwards" Date: Wed, 26 Aug 2026 16:26:30 -0400 Subject: [PATCH] Got Claude Opus to investigate and correct an error when reading plane property data---A bug was causing this to fail for lines of coordinates exceeding the original allocated string size. This only happens in unusual use-cases but the error needed to be fixed nonetheless. Considered adding a line extension method but decided against it. --- VERSION | 2 +- database/DBio.c | 31 +++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/VERSION b/VERSION index d961c8e6..4cad9d0e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.681 +8.3.682 diff --git a/database/DBio.c b/database/DBio.c index dd7e571b..21b92e44 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -2457,30 +2457,44 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) /* Read the string value from the file, accounting for overflow */ pvalueptr = &propertyvalue[0]; - /* Handle string overflows in property values */ + /* Handle string overflows in property values. If "line" was */ + /* filled completely by dbFgets() without finding a newline, */ + /* then the property value scanned above was cut off where */ + /* "line" was cut off, and more of it remains to be read. */ + /* Keep appending 2048-byte chunks, always writing the next */ + /* chunk at the current end of the string (per strlen()), until */ + /* a chunk is read that is not itself cut off at the boundary. */ + /* (Code issue corrected by Claude Opus, 8/26/2026) */ + if (line[len - 1] == '\0') { - int pvlen = strlen(pvalueptr); - *(pvalueptr + pvlen - 1) = '\0'; + int curlen = strlen(pvalueptr); - while (*(pvalueptr + pvlen - 1) == '\0') + while (TRUE) { char *newpvalue; + int newsize = curlen + 2048; - pvlen += 2048; - newpvalue = (char *)mallocMagic(pvlen); + newpvalue = (char *)mallocMagic(newsize); strcpy(newpvalue, pvalueptr); if (pvalueptr != &propertyvalue[0]) freeMagic(pvalueptr); pvalueptr = newpvalue; - *(pvalueptr + pvlen - 1) = 'X'; - if (dbFgets(newpvalue + pvlen - 2048, 2048, f) == NULL) + + /* Sentinel: detect whether dbFgets() fills this */ + /* entire new chunk, meaning there is still more to */ + /* read. */ + + *(pvalueptr + newsize - 1) = 'X'; + if (dbFgets(pvalueptr + curlen, 2048, f) == NULL) { /* Oops, hit end-of-file in the middle of a property */ freeMagic(pvalueptr); cellDef->cd_flags |= noeditflag; return (TRUE); } + if (*(pvalueptr + newsize - 1) != '\0') break; + curlen = strlen(pvalueptr); } /* "pvalueptr" now points to a string containing the complete @@ -2592,6 +2606,7 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) { Rect r; while (isspace(*pptr) && (*pptr != '\0')) pptr++; + if (*pptr == '\0') break; if (!isspace(*pptr)) { if (sscanf(pptr, "%d", &ival) != 1)