summaryrefslogtreecommitdiff
path: root/src/commonmark.c
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2019-04-06 10:20:02 -0700
committerJohn MacFarlane <jgm@berkeley.edu>2019-04-06 10:20:02 -0700
commit6122d5cc3c5e5e8f94f203daddfd38a36be7aed4 (patch)
tree25a00f6583e3623d345f4ce8bf76d9382ff6fd3e /src/commonmark.c
parentbecfb75e9f2f85cfff18aec49fd96e252f737eb2 (diff)
commonmark renderer: improve escaping.
URL-escape special characters when escape mode is URL, and not otherwise. Entity-escape control characters (< 0x20) in non-literal escape modes.
Diffstat (limited to 'src/commonmark.c')
-rw-r--r--src/commonmark.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/commonmark.c b/src/commonmark.c
index 0db0f34..404c290 100644
--- a/src/commonmark.c
+++ b/src/commonmark.c
@@ -32,7 +32,8 @@ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
needs_escaping =
c < 0x80 && escape != LITERAL &&
((escape == NORMAL &&
- (c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
+ (c < 0x20 ||
+ c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
c == '>' || c == '\\' || c == '`' || c == '!' ||
(c == '&' && cmark_isalpha(nextc)) || (c == '!' && nextc == '[') ||
(renderer->begin_content && (c == '-' || c == '+' || c == '=') &&
@@ -48,14 +49,18 @@ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
(c == '`' || c == '<' || c == '>' || c == '"' || c == '\\')));
if (needs_escaping) {
- if (cmark_isspace(c)) {
+ if (escape == URL && cmark_isspace(c)) {
// use percent encoding for spaces
- snprintf(encoded, ENCODED_SIZE, "%%%2x", c);
+ snprintf(encoded, ENCODED_SIZE, "%%%2X", c);
cmark_strbuf_puts(renderer->buffer, encoded);
renderer->column += 3;
- } else {
+ } else if (cmark_ispunct(c)) {
cmark_render_ascii(renderer, "\\");
cmark_render_code_point(renderer, c);
+ } else { // render as entity
+ snprintf(encoded, ENCODED_SIZE, "&#%d;", c);
+ cmark_strbuf_puts(renderer->buffer, encoded);
+ renderer->column += strlen(encoded);
}
} else {
cmark_render_code_point(renderer, c);