cmark

My personal build of CMark ✏️

Commit
c0b9c3125abab6081e0b54140900718c9b7a18d3
Parent
54b377278187f02621a60b3585de4ec02399234a
Author
Steffen Kieß <kiess@ki4.de>
Date

Fix handling of empty strings when creating XML/HTML output.

Diffstat

2 files changed, 14 insertions, 12 deletions

Status File Name N° Changes Insertions Deletions
Modified src/html.c 8 4 4
Modified src/xml.c 18 10 8
diff --git a/src/html.c b/src/html.c
@@ -276,8 +276,8 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
   case CMARK_NODE_LINK:
     if (entering) {
       cmark_strbuf_puts(html, "<a href=\"");
-      if ((options & CMARK_OPT_UNSAFE) ||
-            !(_scan_dangerous_url(node->as.link.url))) {
+      if (node->as.link.url && ((options & CMARK_OPT_UNSAFE) ||
+                                !(_scan_dangerous_url(node->as.link.url)))) {
         houdini_escape_href(html, node->as.link.url,
                             strlen((char *)node->as.link.url));
       }
@@ -295,8 +295,8 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
   case CMARK_NODE_IMAGE:
     if (entering) {
       cmark_strbuf_puts(html, "<img src=\"");
-      if ((options & CMARK_OPT_UNSAFE) ||
-            !(_scan_dangerous_url(node->as.link.url))) {
+      if (node->as.link.url && ((options & CMARK_OPT_UNSAFE) ||
+                                !(_scan_dangerous_url(node->as.link.url)))) {
         houdini_escape_href(html, node->as.link.url,
                             strlen((char *)node->as.link.url));
       }
diff --git a/src/xml.c b/src/xml.c
@@ -18,6 +18,11 @@ static void escape_xml(cmark_strbuf *dest, const unsigned char *source,
   houdini_escape_html0(dest, source, length, 0);
 }
 
+static void escape_xml_str(cmark_strbuf *dest, const unsigned char *source) {
+  if (source)
+    escape_xml(dest, source, strlen((char *)source));
+}
+
 struct render_state {
   cmark_strbuf *xml;
   int indent;
@@ -97,7 +102,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
     case CMARK_NODE_CODE_BLOCK:
       if (node->as.code.info) {
         cmark_strbuf_puts(xml, " info=\"");
-        escape_xml(xml, node->as.code.info, strlen((char *)node->as.code.info));
+        escape_xml_str(xml, node->as.code.info);
         cmark_strbuf_putc(xml, '"');
       }
       cmark_strbuf_puts(xml, " xml:space=\"preserve\">");
@@ -109,23 +114,20 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
     case CMARK_NODE_CUSTOM_BLOCK:
     case CMARK_NODE_CUSTOM_INLINE:
       cmark_strbuf_puts(xml, " on_enter=\"");
-      escape_xml(xml, node->as.custom.on_enter,
-                 strlen((char *)node->as.custom.on_enter));
+      escape_xml_str(xml, node->as.custom.on_enter);
       cmark_strbuf_putc(xml, '"');
       cmark_strbuf_puts(xml, " on_exit=\"");
-      escape_xml(xml, node->as.custom.on_exit,
-                 strlen((char *)node->as.custom.on_exit));
+      escape_xml_str(xml, node->as.custom.on_exit);
       cmark_strbuf_putc(xml, '"');
       break;
     case CMARK_NODE_LINK:
     case CMARK_NODE_IMAGE:
       cmark_strbuf_puts(xml, " destination=\"");
-      escape_xml(xml, node->as.link.url, strlen((char *)node->as.link.url));
+      escape_xml_str(xml, node->as.link.url);
       cmark_strbuf_putc(xml, '"');
       if (node->as.link.title) {
         cmark_strbuf_puts(xml, " title=\"");
-        escape_xml(xml, node->as.link.title,
-                   strlen((char *)node->as.link.title));
+        escape_xml_str(xml, node->as.link.title);
         cmark_strbuf_putc(xml, '"');
       }
       break;