]> granicus.if.org Git - graphviz/commitdiff
Revert "cgraph: rewrite scanner to use an agxbuf"
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Thu, 8 Sep 2022 03:04:06 +0000 (20:04 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Thu, 8 Sep 2022 03:06:25 +0000 (20:06 -0700)
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 <robhart@google.com>
CHANGELOG.md
lib/cgraph/scan.l
tests/test_regression.py

index 218a2f9138a2a30e3d952129a1ffd547cffe8953..dd6b38bc792f6f92aed4bf548d9b86bbb5c2fad2 100644 (file)
@@ -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
 
index 078f1671154a4214b6147135b703e19fd9cff40b..597c79c1969f69bfd8d09499f586b2b37b66f9eb 100644 (file)
 %option noinput
 
 %{
-#include <assert.h>
 #include <grammar.h>
 #include <cghdr.h>
 #include <agxbuf.h>
 #include <cgraph/agxbuf.h>
-#include <cgraph/alloc.h>
 #include <ctype.h>
 #include <stdbool.h>
 #include <stddef.h>
@@ -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 :
index c7dac5474f2e29a5450fafd6e65555b442768e73..0ab5141e67a1326e03cabedeed67915455663b1e 100644 (file)
@@ -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