]> granicus.if.org Git - graphviz/commitdiff
fix: exit when erroring during HTML lexing
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 28 Jan 2023 19:10:08 +0000 (11:10 -0800)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sun, 29 Jan 2023 15:30:10 +0000 (07:30 -0800)
Labels can be either plain text or HTML-like labels (`<`, `>` delimited). When
parsing an HTML-like label, the lexer would return the same result for a warning
or an error. This meant the caller would attempt to fallback to a plain text
label in either case. But when the HTML lexer has errored, the input has been
determined unparseable. Falling back to parsing a plain text label is unlikely
to work, and even if it does it produces something that is certainly not what
the user intended. In most scenarios, this fallback behavior would go onto to
crash messily, now that labels were populated with garbage data.

This change simply teaches the calling code to notice the error and exit instead
of falling back. Exiting from within library code like this is not particularly
clean or desirable, but there is no easy elegant error path from this code.

Gitlab: fixes #1311
Reported-by: Google Autofuzz project
CHANGELOG.md
lib/common/htmllex.c
lib/common/htmlparse.y
lib/common/htmltable.c

index a5db79d68fcac2d6ca4ed70343f32c14e09c0295..179b183bfa18835c9c6094c86e46c3e57a1a1aa2 100644 (file)
@@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
   SVG. #799
 - Legacy man page references to `dotty` have been removed. `dotty` was removed
   in Graphviz 4.0.0.
+- Graphviz will now exit when encountering a syntactically invalid HTML label
+  instead of attempting to recover and continue. #1311
 
 ### Fixed
 
index 5d5aacacc879aa6408dfcd5ba8d5a61d4314e278..15cdcffc6aa63f9d3abf624048b2e195d0270765 100644 (file)
@@ -791,7 +791,7 @@ int initHTMLlexer(char *src, agxbuf * xb, htmlenv_t *env)
 int clearHTMLlexer()
 {
 #ifdef HAVE_EXPAT
-    int rv = state.warn | state.error;
+    int rv = state.error ? 3 : state.warn;
     XML_ParserFree(state.parser);
     agxbfree (&state.lb);
     return rv;
index 51394d20bf35737a89daa80afd3b17fcb6664610..ca349369b5e4e99519c47819c7136a84aadbe12b 100644 (file)
@@ -586,7 +586,8 @@ VR  : T_vr T_end_vr
 
 /* parseHTML:
  * Return parsed label or NULL if failure.
- * Set warn to 0 on success; 1 for warning message; 2 if no expat.
+ * Set warn to 0 on success; 1 for warning message; 2 if no expat; 3 for error
+ * message.
  */
 htmllabel_t*
 parseHTML (char* txt, int* warn, htmlenv_t *env)
index 76e975098ff5eb2817971bb940b0141b4ce788c1..46ed79475ea25f82d76213b85661815f90398b8d 100644 (file)
@@ -36,6 +36,7 @@
 #include <common/intset.h>
 #include <cdt/cdt.h>
 #include <cgraph/alloc.h>
+#include <cgraph/exit.h>
 #include <cgraph/itos.h>
 #include <cgraph/strcasecmp.h>
 #include <stddef.h>
@@ -2010,6 +2011,10 @@ int make_html_label(void *obj, textlabel_t * lp)
     env.finfo.flags = 0;
     lbl = parseHTML(lp->text, &rv, &env);
     if (!lbl) {
+       if (rv == 3) {
+           // fatal error
+           graphviz_exit(EXIT_FAILURE);
+       }
        /* Parse of label failed; revert to simple text label */
        agxbuf xb;
        char buf[SMALLBUF];