Fossil SCM
Avoid unnecessary quoting of ASCII characters 34 and 39 in the markdown formatter.
Commit
7950dc2297431d373d157a9bcadba1ddecde033f8083ac5970a17b239eca2eac
Parent
eae0a9821dc8f0c…
1 file changed
+39
-9
+39
-9
| --- src/markdown_html.c | ||
| +++ src/markdown_html.c | ||
| @@ -48,21 +48,25 @@ | ||
| 48 | 48 | /* BLOB_APPEND_BLOB -- append blob contents to another */ |
| 49 | 49 | #define BLOB_APPEND_BLOB(dest, src) \ |
| 50 | 50 | blob_append((dest), blob_buffer(src), blob_size(src)) |
| 51 | 51 | |
| 52 | 52 | |
| 53 | -/* HTML escape */ | |
| 54 | - | |
| 55 | -static void html_escape(struct Blob *ob, const char *data, size_t size){ | |
| 53 | +/* HTML escapes | |
| 54 | +** | |
| 55 | +** html_escape() converts < to <, > to >, and & to &. | |
| 56 | +** html_quote() goes further and converts " into " and ' in '. | |
| 57 | +*/ | |
| 58 | +static void html_quote(struct Blob *ob, const char *data, size_t size){ | |
| 56 | 59 | size_t beg = 0, i = 0; |
| 57 | 60 | while( i<size ){ |
| 58 | 61 | beg = i; |
| 59 | 62 | while( i<size |
| 60 | 63 | && data[i]!='<' |
| 61 | 64 | && data[i]!='>' |
| 62 | 65 | && data[i]!='"' |
| 63 | 66 | && data[i]!='&' |
| 67 | + && data[i]!='\'' | |
| 64 | 68 | ){ |
| 65 | 69 | i++; |
| 66 | 70 | } |
| 67 | 71 | blob_append(ob, data+beg, i-beg); |
| 68 | 72 | while( i<size ){ |
| @@ -80,10 +84,36 @@ | ||
| 80 | 84 | break; |
| 81 | 85 | } |
| 82 | 86 | i++; |
| 83 | 87 | } |
| 84 | 88 | } |
| 89 | +} | |
| 90 | +static void html_escape(struct Blob *ob, const char *data, size_t size){ | |
| 91 | + size_t beg = 0, i = 0; | |
| 92 | + while( i<size ){ | |
| 93 | + beg = i; | |
| 94 | + while( i<size | |
| 95 | + && data[i]!='<' | |
| 96 | + && data[i]!='>' | |
| 97 | + && data[i]!='&' | |
| 98 | + ){ | |
| 99 | + i++; | |
| 100 | + } | |
| 101 | + blob_append(ob, data+beg, i-beg); | |
| 102 | + while( i<size ){ | |
| 103 | + if( data[i]=='<' ){ | |
| 104 | + BLOB_APPEND_LITERAL(ob, "<"); | |
| 105 | + }else if( data[i]=='>' ){ | |
| 106 | + BLOB_APPEND_LITERAL(ob, ">"); | |
| 107 | + }else if( data[i]=='&' ){ | |
| 108 | + BLOB_APPEND_LITERAL(ob, "&"); | |
| 109 | + }else{ | |
| 110 | + break; | |
| 111 | + } | |
| 112 | + i++; | |
| 113 | + } | |
| 114 | + } | |
| 85 | 115 | } |
| 86 | 116 | |
| 87 | 117 | |
| 88 | 118 | /* HTML block tags */ |
| 89 | 119 | |
| @@ -283,11 +313,11 @@ | ||
| 283 | 313 | void *opaque |
| 284 | 314 | ){ |
| 285 | 315 | if( !link || blob_size(link)<=0 ) return 0; |
| 286 | 316 | BLOB_APPEND_LITERAL(ob, "<a href=\""); |
| 287 | 317 | if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITERAL(ob, "mailto:"); |
| 288 | - html_escape(ob, blob_buffer(link), blob_size(link)); | |
| 318 | + html_quote(ob, blob_buffer(link), blob_size(link)); | |
| 289 | 319 | BLOB_APPEND_LITERAL(ob, "\">"); |
| 290 | 320 | if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){ |
| 291 | 321 | /* remove "mailto:" from displayed text */ |
| 292 | 322 | html_escape(ob, blob_buffer(link)+7, blob_size(link)-7); |
| 293 | 323 | }else{ |
| @@ -336,16 +366,16 @@ | ||
| 336 | 366 | struct Blob *title, |
| 337 | 367 | struct Blob *alt, |
| 338 | 368 | void *opaque |
| 339 | 369 | ){ |
| 340 | 370 | BLOB_APPEND_LITERAL(ob, "<img src=\""); |
| 341 | - html_escape(ob, blob_buffer(link), blob_size(link)); | |
| 371 | + html_quote(ob, blob_buffer(link), blob_size(link)); | |
| 342 | 372 | BLOB_APPEND_LITERAL(ob, "\" alt=\""); |
| 343 | - html_escape(ob, blob_buffer(alt), blob_size(alt)); | |
| 373 | + html_quote(ob, blob_buffer(alt), blob_size(alt)); | |
| 344 | 374 | if( title && blob_size(title)>0 ){ |
| 345 | 375 | BLOB_APPEND_LITERAL(ob, "\" title=\""); |
| 346 | - html_escape(ob, blob_buffer(title), blob_size(title)); | |
| 376 | + html_quote(ob, blob_buffer(title), blob_size(title)); | |
| 347 | 377 | } |
| 348 | 378 | BLOB_APPEND_LITERAL(ob, "\" />"); |
| 349 | 379 | return 1; |
| 350 | 380 | } |
| 351 | 381 | |
| @@ -366,14 +396,14 @@ | ||
| 366 | 396 | if( zLink && zLink[0]=='/' && g.zTop ){ |
| 367 | 397 | /* For any hyperlink that begins with "/", make it refer to the root |
| 368 | 398 | ** of the Fossil repository */ |
| 369 | 399 | blob_append(ob, g.zTop, -1); |
| 370 | 400 | } |
| 371 | - html_escape(ob, blob_buffer(link), blob_size(link)); | |
| 401 | + html_quote(ob, blob_buffer(link), blob_size(link)); | |
| 372 | 402 | if( title && blob_size(title)>0 ){ |
| 373 | 403 | BLOB_APPEND_LITERAL(ob, "\" title=\""); |
| 374 | - html_escape(ob, blob_buffer(title), blob_size(title)); | |
| 404 | + html_quote(ob, blob_buffer(title), blob_size(title)); | |
| 375 | 405 | } |
| 376 | 406 | BLOB_APPEND_LITERAL(ob, "\">"); |
| 377 | 407 | BLOB_APPEND_BLOB(ob, content); |
| 378 | 408 | BLOB_APPEND_LITERAL(ob, "</a>"); |
| 379 | 409 | return 1; |
| 380 | 410 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -48,21 +48,25 @@ | |
| 48 | /* BLOB_APPEND_BLOB -- append blob contents to another */ |
| 49 | #define BLOB_APPEND_BLOB(dest, src) \ |
| 50 | blob_append((dest), blob_buffer(src), blob_size(src)) |
| 51 | |
| 52 | |
| 53 | /* HTML escape */ |
| 54 | |
| 55 | static void html_escape(struct Blob *ob, const char *data, size_t size){ |
| 56 | size_t beg = 0, i = 0; |
| 57 | while( i<size ){ |
| 58 | beg = i; |
| 59 | while( i<size |
| 60 | && data[i]!='<' |
| 61 | && data[i]!='>' |
| 62 | && data[i]!='"' |
| 63 | && data[i]!='&' |
| 64 | ){ |
| 65 | i++; |
| 66 | } |
| 67 | blob_append(ob, data+beg, i-beg); |
| 68 | while( i<size ){ |
| @@ -80,10 +84,36 @@ | |
| 80 | break; |
| 81 | } |
| 82 | i++; |
| 83 | } |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | |
| 88 | /* HTML block tags */ |
| 89 | |
| @@ -283,11 +313,11 @@ | |
| 283 | void *opaque |
| 284 | ){ |
| 285 | if( !link || blob_size(link)<=0 ) return 0; |
| 286 | BLOB_APPEND_LITERAL(ob, "<a href=\""); |
| 287 | if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITERAL(ob, "mailto:"); |
| 288 | html_escape(ob, blob_buffer(link), blob_size(link)); |
| 289 | BLOB_APPEND_LITERAL(ob, "\">"); |
| 290 | if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){ |
| 291 | /* remove "mailto:" from displayed text */ |
| 292 | html_escape(ob, blob_buffer(link)+7, blob_size(link)-7); |
| 293 | }else{ |
| @@ -336,16 +366,16 @@ | |
| 336 | struct Blob *title, |
| 337 | struct Blob *alt, |
| 338 | void *opaque |
| 339 | ){ |
| 340 | BLOB_APPEND_LITERAL(ob, "<img src=\""); |
| 341 | html_escape(ob, blob_buffer(link), blob_size(link)); |
| 342 | BLOB_APPEND_LITERAL(ob, "\" alt=\""); |
| 343 | html_escape(ob, blob_buffer(alt), blob_size(alt)); |
| 344 | if( title && blob_size(title)>0 ){ |
| 345 | BLOB_APPEND_LITERAL(ob, "\" title=\""); |
| 346 | html_escape(ob, blob_buffer(title), blob_size(title)); |
| 347 | } |
| 348 | BLOB_APPEND_LITERAL(ob, "\" />"); |
| 349 | return 1; |
| 350 | } |
| 351 | |
| @@ -366,14 +396,14 @@ | |
| 366 | if( zLink && zLink[0]=='/' && g.zTop ){ |
| 367 | /* For any hyperlink that begins with "/", make it refer to the root |
| 368 | ** of the Fossil repository */ |
| 369 | blob_append(ob, g.zTop, -1); |
| 370 | } |
| 371 | html_escape(ob, blob_buffer(link), blob_size(link)); |
| 372 | if( title && blob_size(title)>0 ){ |
| 373 | BLOB_APPEND_LITERAL(ob, "\" title=\""); |
| 374 | html_escape(ob, blob_buffer(title), blob_size(title)); |
| 375 | } |
| 376 | BLOB_APPEND_LITERAL(ob, "\">"); |
| 377 | BLOB_APPEND_BLOB(ob, content); |
| 378 | BLOB_APPEND_LITERAL(ob, "</a>"); |
| 379 | return 1; |
| 380 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -48,21 +48,25 @@ | |
| 48 | /* BLOB_APPEND_BLOB -- append blob contents to another */ |
| 49 | #define BLOB_APPEND_BLOB(dest, src) \ |
| 50 | blob_append((dest), blob_buffer(src), blob_size(src)) |
| 51 | |
| 52 | |
| 53 | /* HTML escapes |
| 54 | ** |
| 55 | ** html_escape() converts < to <, > to >, and & to &. |
| 56 | ** html_quote() goes further and converts " into " and ' in '. |
| 57 | */ |
| 58 | static void html_quote(struct Blob *ob, const char *data, size_t size){ |
| 59 | size_t beg = 0, i = 0; |
| 60 | while( i<size ){ |
| 61 | beg = i; |
| 62 | while( i<size |
| 63 | && data[i]!='<' |
| 64 | && data[i]!='>' |
| 65 | && data[i]!='"' |
| 66 | && data[i]!='&' |
| 67 | && data[i]!='\'' |
| 68 | ){ |
| 69 | i++; |
| 70 | } |
| 71 | blob_append(ob, data+beg, i-beg); |
| 72 | while( i<size ){ |
| @@ -80,10 +84,36 @@ | |
| 84 | break; |
| 85 | } |
| 86 | i++; |
| 87 | } |
| 88 | } |
| 89 | } |
| 90 | static void html_escape(struct Blob *ob, const char *data, size_t size){ |
| 91 | size_t beg = 0, i = 0; |
| 92 | while( i<size ){ |
| 93 | beg = i; |
| 94 | while( i<size |
| 95 | && data[i]!='<' |
| 96 | && data[i]!='>' |
| 97 | && data[i]!='&' |
| 98 | ){ |
| 99 | i++; |
| 100 | } |
| 101 | blob_append(ob, data+beg, i-beg); |
| 102 | while( i<size ){ |
| 103 | if( data[i]=='<' ){ |
| 104 | BLOB_APPEND_LITERAL(ob, "<"); |
| 105 | }else if( data[i]=='>' ){ |
| 106 | BLOB_APPEND_LITERAL(ob, ">"); |
| 107 | }else if( data[i]=='&' ){ |
| 108 | BLOB_APPEND_LITERAL(ob, "&"); |
| 109 | }else{ |
| 110 | break; |
| 111 | } |
| 112 | i++; |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | |
| 118 | /* HTML block tags */ |
| 119 | |
| @@ -283,11 +313,11 @@ | |
| 313 | void *opaque |
| 314 | ){ |
| 315 | if( !link || blob_size(link)<=0 ) return 0; |
| 316 | BLOB_APPEND_LITERAL(ob, "<a href=\""); |
| 317 | if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITERAL(ob, "mailto:"); |
| 318 | html_quote(ob, blob_buffer(link), blob_size(link)); |
| 319 | BLOB_APPEND_LITERAL(ob, "\">"); |
| 320 | if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){ |
| 321 | /* remove "mailto:" from displayed text */ |
| 322 | html_escape(ob, blob_buffer(link)+7, blob_size(link)-7); |
| 323 | }else{ |
| @@ -336,16 +366,16 @@ | |
| 366 | struct Blob *title, |
| 367 | struct Blob *alt, |
| 368 | void *opaque |
| 369 | ){ |
| 370 | BLOB_APPEND_LITERAL(ob, "<img src=\""); |
| 371 | html_quote(ob, blob_buffer(link), blob_size(link)); |
| 372 | BLOB_APPEND_LITERAL(ob, "\" alt=\""); |
| 373 | html_quote(ob, blob_buffer(alt), blob_size(alt)); |
| 374 | if( title && blob_size(title)>0 ){ |
| 375 | BLOB_APPEND_LITERAL(ob, "\" title=\""); |
| 376 | html_quote(ob, blob_buffer(title), blob_size(title)); |
| 377 | } |
| 378 | BLOB_APPEND_LITERAL(ob, "\" />"); |
| 379 | return 1; |
| 380 | } |
| 381 | |
| @@ -366,14 +396,14 @@ | |
| 396 | if( zLink && zLink[0]=='/' && g.zTop ){ |
| 397 | /* For any hyperlink that begins with "/", make it refer to the root |
| 398 | ** of the Fossil repository */ |
| 399 | blob_append(ob, g.zTop, -1); |
| 400 | } |
| 401 | html_quote(ob, blob_buffer(link), blob_size(link)); |
| 402 | if( title && blob_size(title)>0 ){ |
| 403 | BLOB_APPEND_LITERAL(ob, "\" title=\""); |
| 404 | html_quote(ob, blob_buffer(title), blob_size(title)); |
| 405 | } |
| 406 | BLOB_APPEND_LITERAL(ob, "\">"); |
| 407 | BLOB_APPEND_BLOB(ob, content); |
| 408 | BLOB_APPEND_LITERAL(ob, "</a>"); |
| 409 | return 1; |
| 410 |