From 16a04fe061bf6c9b3fe5fdc6250255a9b55cd337 Mon Sep 17 00:00:00 2001 From: Matthew Fernandez Date: Wed, 7 Sep 2022 20:04:06 -0700 Subject: [PATCH] Revert "cgraph: rewrite scanner to use an agxbuf" This reverts commit 2d7852a049b729fb0db71c5a8ef2366215ae2035. This commit introduced a bug where the string buffer was assumed to be uninitialized when beginning parsing a string, but it may not be if a previously unterminated string was processed. Github: fixes #2272 Reported-by: Rob Hart --- CHANGELOG.md | 2 ++ lib/cgraph/scan.l | 51 +++++++++++++++++++++++++--------------- tests/test_regression.py | 1 - 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 218a2f913..dd6b38bc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Id attribute is not used in linearGradient. #2258 - Graphviz 5.0.1 undocumented change of automatically generated output filename with -O flag (missing dot separator). This was a regression in 5.0.1. #2270 +- Assert fail in `aaglex` for multiple calls to `agmemread`. This was a + regression in 5.0.1. #2272 ### Removed diff --git a/lib/cgraph/scan.l b/lib/cgraph/scan.l index 078f16711..597c79c19 100644 --- a/lib/cgraph/scan.l +++ b/lib/cgraph/scan.l @@ -23,12 +23,10 @@ %option noinput %{ -#include #include #include #include #include -#include #include #include #include @@ -71,25 +69,40 @@ int gv_isatty_suppression; #endif /* buffer for arbitrary length strings (longer than BUFSIZ) */ -static agxbuf Sbuf; - +static char *Sbuf,*Sptr,*Send; static void beginstr(void) { - // nothing required, but we should not have pending string data - assert(agxblen(&Sbuf) == 0 && - "pending string data that was not consumed (missing " - "endstr()/endhtmlstr()?)"); + if (Sbuf == NULL) { + Sbuf = malloc(BUFSIZ); + Send = Sbuf + BUFSIZ; + } + Sptr = Sbuf; + *Sptr = 0; } static void addstr(char *src) { - agxbput(&Sbuf, src); + char c; + if (Sptr > Sbuf) Sptr--; + do { + do {c = *Sptr++ = *src++;} while (c && Sptr < Send); + if (c) { + long sz = Send - Sbuf; + long off = Sptr - Sbuf; + sz *= 2; + Sbuf = realloc(Sbuf,sz); + Send = Sbuf + sz; + Sptr = Sbuf + off; + } + } while (c); } static void endstr(void) { - aaglval.str = agstrdup(Ag_G_global, agxbuse(&Sbuf)); + aaglval.str = agstrdup(Ag_G_global,Sbuf); + *Sbuf = 0; } static void endstr_html(void) { - aaglval.str = agstrdup_html(Ag_G_global, agxbuse(&Sbuf)); + aaglval.str = agstrdup_html(Ag_G_global,Sbuf); + *Sbuf = 0; } static void @@ -235,20 +248,20 @@ void aagerror(const char *str) else switch (YYSTATE) { case qstring : agxbprint(&xb, " scanning a quoted string (missing endquote? longer than %d?)", YY_BUF_SIZE); - if (agxblen(&Sbuf) > 0) { - size_t len = agxblen(&Sbuf); + if (*Sbuf) { + size_t len = strlen(Sbuf); if (len > 80) - len = 80; - agxbprint(&xb, "\nString starting:\"%.*s", (int)len, Sbuf.buf); + Sbuf[80] = '\0'; + agxbprint (&xb, "\nString starting:\"%s", Sbuf); } break; case hstring : agxbprint(&xb, " scanning a HTML string (missing '>'? bad nesting? longer than %d?)", YY_BUF_SIZE); - if (agxblen(&Sbuf)) { - size_t len = agxblen(&Sbuf); + if (*Sbuf) { + size_t len = strlen(Sbuf); if (len > 80) - len = 80; - agxbprint(&xb, "\nString starting:<%.*s", (int)len, Sbuf.buf); + Sbuf[80] = '\0'; + agxbprint (&xb, "\nString starting:<%s", Sbuf); } break; case comment : diff --git a/tests/test_regression.py b/tests/test_regression.py index c7dac5474..0ab5141e6 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -1970,7 +1970,6 @@ def test_2270(tmp_path: Path): output = tmp_path / "hello.gv.core.dot.plain" assert output.exists(), "-O resulted in an unexpected output filename" -@pytest.mark.xfail() def test_2272(): """ using `agmemread` with an unterminated string should not fail assertions -- 2.40.0