Fossil SCM
Refactor the safe-html interface names. Improved comments. No functional changes.
Commit
54c1fd6fbb5f8dd266344659829e222f7f83f94eadef6cc040400802b3a65832
Parent
cd0b228de7b3814…
2 files changed
+2
-2
+32
-13
+2
-2
| --- src/markdown_html.c | ||
| +++ src/markdown_html.c | ||
| @@ -45,11 +45,11 @@ | ||
| 45 | 45 | * the error is not overly explicit. |
| 46 | 46 | */ |
| 47 | 47 | |
| 48 | 48 | /* BLOB_APPEND_BLOB -- append blob contents to another */ |
| 49 | 49 | #define BLOB_APPEND_BLOB(dest, src) \ |
| 50 | - blob_append_safe_html((dest), blob_buffer(src), blob_size(src)) | |
| 50 | + safe_html_append((dest), blob_buffer(src), blob_size(src)) | |
| 51 | 51 | |
| 52 | 52 | |
| 53 | 53 | /* HTML escapes |
| 54 | 54 | ** |
| 55 | 55 | ** html_escape() converts < to <, > to >, and & to &. |
| @@ -147,11 +147,11 @@ | ||
| 147 | 147 | int nTag = html_tag_length(data); |
| 148 | 148 | blob_append(title, data+nTag, size - nTag - 5); |
| 149 | 149 | return; |
| 150 | 150 | } |
| 151 | 151 | INTER_BLOCK(ob); |
| 152 | - blob_append_safe_html(ob, data, size); | |
| 152 | + safe_html_append(ob, data, size); | |
| 153 | 153 | BLOB_APPEND_LITERAL(ob, "\n"); |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | 156 | static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){ |
| 157 | 157 | INTER_BLOCK(ob); |
| 158 | 158 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -45,11 +45,11 @@ | |
| 45 | * the error is not overly explicit. |
| 46 | */ |
| 47 | |
| 48 | /* BLOB_APPEND_BLOB -- append blob contents to another */ |
| 49 | #define BLOB_APPEND_BLOB(dest, src) \ |
| 50 | blob_append_safe_html((dest), blob_buffer(src), blob_size(src)) |
| 51 | |
| 52 | |
| 53 | /* HTML escapes |
| 54 | ** |
| 55 | ** html_escape() converts < to <, > to >, and & to &. |
| @@ -147,11 +147,11 @@ | |
| 147 | int nTag = html_tag_length(data); |
| 148 | blob_append(title, data+nTag, size - nTag - 5); |
| 149 | return; |
| 150 | } |
| 151 | INTER_BLOCK(ob); |
| 152 | blob_append_safe_html(ob, data, size); |
| 153 | BLOB_APPEND_LITERAL(ob, "\n"); |
| 154 | } |
| 155 | |
| 156 | static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){ |
| 157 | INTER_BLOCK(ob); |
| 158 |
| --- src/markdown_html.c | |
| +++ src/markdown_html.c | |
| @@ -45,11 +45,11 @@ | |
| 45 | * the error is not overly explicit. |
| 46 | */ |
| 47 | |
| 48 | /* BLOB_APPEND_BLOB -- append blob contents to another */ |
| 49 | #define BLOB_APPEND_BLOB(dest, src) \ |
| 50 | safe_html_append((dest), blob_buffer(src), blob_size(src)) |
| 51 | |
| 52 | |
| 53 | /* HTML escapes |
| 54 | ** |
| 55 | ** html_escape() converts < to <, > to >, and & to &. |
| @@ -147,11 +147,11 @@ | |
| 147 | int nTag = html_tag_length(data); |
| 148 | blob_append(title, data+nTag, size - nTag - 5); |
| 149 | return; |
| 150 | } |
| 151 | INTER_BLOCK(ob); |
| 152 | safe_html_append(ob, data, size); |
| 153 | BLOB_APPEND_LITERAL(ob, "\n"); |
| 154 | } |
| 155 | |
| 156 | static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){ |
| 157 | INTER_BLOCK(ob); |
| 158 |
+32
-13
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -2400,36 +2400,51 @@ | ||
| 2400 | 2400 | fossil_puts(blob_str(&out), 0); |
| 2401 | 2401 | blob_reset(&out); |
| 2402 | 2402 | } |
| 2403 | 2403 | } |
| 2404 | 2404 | |
| 2405 | +/**************************************************************************** | |
| 2406 | +** safe-html: | |
| 2407 | +** | |
| 2408 | +** An interface for preventing HTML constructs (ex: <style>, <form>, etc) | |
| 2409 | +** from being inserted into Wiki and Forum posts using Markdown. See the | |
| 2410 | +** comment on safe_html_append() for additional information on what is meant | |
| 2411 | +** by "safe". | |
| 2412 | +** | |
| 2413 | +** The safe-html restrictions only apply to Markdown, as Fossil-Wiki only | |
| 2414 | +** allows safe-html by design - unsafe-HTML is never and has never been | |
| 2415 | +** allowed in Fossil-Wiki. | |
| 2416 | +** | |
| 2417 | +** This code is in the wikiformat.c file so that it can have access to the | |
| 2418 | +** white-list of acceptable HTML in the aMarkup[] array. | |
| 2419 | +*/ | |
| 2420 | + | |
| 2405 | 2421 | /* |
| 2406 | 2422 | ** An instance of this object keeps track of the nesting of HTML |
| 2407 | -** elements for blob_append_safe_html(). | |
| 2423 | +** elements for safe_html_append(). | |
| 2408 | 2424 | */ |
| 2409 | -#if LOCAL_INTERFACE | |
| 2425 | +typedef struct HtmlTagStack HtmlTagStack; | |
| 2410 | 2426 | struct HtmlTagStack { |
| 2411 | 2427 | int n; /* Current tag stack depth */ |
| 2412 | 2428 | int nAlloc; /* Space allocated for aStack[] */ |
| 2413 | 2429 | int *aStack; /* The stack of tags */ |
| 2414 | 2430 | int aSpace[10]; /* Initial static space, to avoid malloc() */ |
| 2415 | 2431 | }; |
| 2416 | -#endif /* LOCAL_INTERFACE */ | |
| 2417 | 2432 | |
| 2418 | 2433 | /* |
| 2419 | 2434 | ** Initialize bulk memory to a valid empty tagstack. |
| 2420 | 2435 | */ |
| 2421 | -void html_tagstack_init(HtmlTagStack *p){ | |
| 2436 | +static void html_tagstack_init(HtmlTagStack *p){ | |
| 2422 | 2437 | p->n = 0; |
| 2423 | 2438 | p->nAlloc = 0; |
| 2424 | 2439 | p->aStack = p->aSpace; |
| 2425 | 2440 | } |
| 2426 | 2441 | |
| 2427 | 2442 | /* |
| 2428 | 2443 | ** Push a new element onto the tag statk |
| 2429 | 2444 | */ |
| 2430 | -void html_tagstack_push(HtmlTagStack *p, int e){ | |
| 2445 | +static void html_tagstack_push(HtmlTagStack *p, int e){ | |
| 2431 | 2446 | if( p->n>=ArraySize(p->aSpace) && p->n>=p->nAlloc ){ |
| 2432 | 2447 | if( p->nAlloc==0 ){ |
| 2433 | 2448 | int *aNew; |
| 2434 | 2449 | p->nAlloc = 50; |
| 2435 | 2450 | aNew = fossil_malloc( sizeof(p->aStack[0])*p->nAlloc ); |
| @@ -2444,11 +2459,11 @@ | ||
| 2444 | 2459 | } |
| 2445 | 2460 | |
| 2446 | 2461 | /* |
| 2447 | 2462 | ** Clear a tag stack, reclaiming any memory allocations. |
| 2448 | 2463 | */ |
| 2449 | -void html_tagstack_clear(HtmlTagStack *p){ | |
| 2464 | +static void html_tagstack_clear(HtmlTagStack *p){ | |
| 2450 | 2465 | if( p->nAlloc ){ |
| 2451 | 2466 | fossil_free(p->aStack); |
| 2452 | 2467 | p->nAlloc = 0; |
| 2453 | 2468 | p->aStack = p->aSpace; |
| 2454 | 2469 | } |
| @@ -2463,11 +2478,11 @@ | ||
| 2463 | 2478 | ** end-tags as you go. |
| 2464 | 2479 | ** |
| 2465 | 2480 | ** If there is no open-tag for eEnd on the stack, then this |
| 2466 | 2481 | ** routine is a no-op. |
| 2467 | 2482 | */ |
| 2468 | -void html_tagstack_pop(HtmlTagStack *p, Blob *pBlob, int eEnd){ | |
| 2483 | +static void html_tagstack_pop(HtmlTagStack *p, Blob *pBlob, int eEnd){ | |
| 2469 | 2484 | int i, e; |
| 2470 | 2485 | if( eEnd!=0 ){ |
| 2471 | 2486 | for(i=p->n-1; i>=0 && p->aStack[i]!=eEnd; i--){} |
| 2472 | 2487 | if( i<0 ){ |
| 2473 | 2488 | blob_appendf(pBlob, "<span class='error'></%s></span>", |
| @@ -2491,22 +2506,26 @@ | ||
| 2491 | 2506 | ** |
| 2492 | 2507 | ** 1. Omit any elements that are not on the AllowedMarkup list. |
| 2493 | 2508 | ** |
| 2494 | 2509 | ** 2. Omit any attributes that are not on the AllowedMarkup list. |
| 2495 | 2510 | ** |
| 2496 | -** 3. Omit any surplus close-tags. | |
| 2511 | +** 3. Omit any surplus close-tags. (This prevents a surplus </div> | |
| 2512 | +** or </body> or similar element from interferring with formatting | |
| 2513 | +** of the outer context in which the HTML is being inserted.) | |
| 2497 | 2514 | ** |
| 2498 | -** 4. Insert additional close-tags as necessary so that all | |
| 2499 | -** tag in the input that needs a close-tag has one. | |
| 2515 | +** 4. Insert additional close-tags as necessary so that any | |
| 2516 | +** tag in the input that needs a close-tag has one. (This prevents | |
| 2517 | +** the inserted HTML from messing up the formatting of subsequent | |
| 2518 | +** sections of the document into which it is being inserted.) | |
| 2500 | 2519 | ** |
| 2501 | 2520 | ** The input must be writable. Temporary changes may be made to the |
| 2502 | 2521 | ** input, but the input is restored to its original state prior to |
| 2503 | 2522 | ** returning. If zHtml[nHtml] is not a zero character, then a zero |
| 2504 | 2523 | ** might be written in that position temporarily, but that slot will |
| 2505 | 2524 | ** also be restored before this routine returns. |
| 2506 | 2525 | */ |
| 2507 | -void blob_append_safe_html(Blob *pBlob, char *zHtml, int nHtml){ | |
| 2526 | +void safe_html_append(Blob *pBlob, char *zHtml, int nHtml){ | |
| 2508 | 2527 | char cLast; |
| 2509 | 2528 | int i, j, n; |
| 2510 | 2529 | HtmlTagStack s; |
| 2511 | 2530 | ParsedMarkup markup; |
| 2512 | 2531 | |
| @@ -2560,11 +2579,11 @@ | ||
| 2560 | 2579 | ** COMMAND: test-safe-html |
| 2561 | 2580 | ** |
| 2562 | 2581 | ** Usage: %fossil test-safe-html FILE ... |
| 2563 | 2582 | ** |
| 2564 | 2583 | ** Read files named on the command-line. Send the text of each file |
| 2565 | -** through blob_append_safe_html() and then write the result on | |
| 2584 | +** through safe_html_append() and then write the result on | |
| 2566 | 2585 | ** standard output. |
| 2567 | 2586 | */ |
| 2568 | 2587 | void test_safe_html_cmd(void){ |
| 2569 | 2588 | int i; |
| 2570 | 2589 | Blob x; |
| @@ -2573,14 +2592,14 @@ | ||
| 2573 | 2592 | char *z; |
| 2574 | 2593 | int n; |
| 2575 | 2594 | blob_read_from_file(&x, g.argv[i], ExtFILE); |
| 2576 | 2595 | blob_init(&y, 0, 0); |
| 2577 | 2596 | blob_terminate(&x); |
| 2578 | - blob_append_safe_html(&y, blob_buffer(&x), blob_size(&x)); | |
| 2597 | + safe_html_append(&y, blob_buffer(&x), blob_size(&x)); | |
| 2579 | 2598 | blob_reset(&x); |
| 2580 | 2599 | z = blob_str(&y); |
| 2581 | 2600 | n = blob_size(&y); |
| 2582 | 2601 | while( n>0 && (z[n-1]=='\n' || z[n-1]=='\r') ) n--; |
| 2583 | 2602 | fossil_print("%.*s\n", n, z); |
| 2584 | 2603 | blob_reset(&y); |
| 2585 | 2604 | } |
| 2586 | 2605 | } |
| 2587 | 2606 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -2400,36 +2400,51 @@ | |
| 2400 | fossil_puts(blob_str(&out), 0); |
| 2401 | blob_reset(&out); |
| 2402 | } |
| 2403 | } |
| 2404 | |
| 2405 | /* |
| 2406 | ** An instance of this object keeps track of the nesting of HTML |
| 2407 | ** elements for blob_append_safe_html(). |
| 2408 | */ |
| 2409 | #if LOCAL_INTERFACE |
| 2410 | struct HtmlTagStack { |
| 2411 | int n; /* Current tag stack depth */ |
| 2412 | int nAlloc; /* Space allocated for aStack[] */ |
| 2413 | int *aStack; /* The stack of tags */ |
| 2414 | int aSpace[10]; /* Initial static space, to avoid malloc() */ |
| 2415 | }; |
| 2416 | #endif /* LOCAL_INTERFACE */ |
| 2417 | |
| 2418 | /* |
| 2419 | ** Initialize bulk memory to a valid empty tagstack. |
| 2420 | */ |
| 2421 | void html_tagstack_init(HtmlTagStack *p){ |
| 2422 | p->n = 0; |
| 2423 | p->nAlloc = 0; |
| 2424 | p->aStack = p->aSpace; |
| 2425 | } |
| 2426 | |
| 2427 | /* |
| 2428 | ** Push a new element onto the tag statk |
| 2429 | */ |
| 2430 | void html_tagstack_push(HtmlTagStack *p, int e){ |
| 2431 | if( p->n>=ArraySize(p->aSpace) && p->n>=p->nAlloc ){ |
| 2432 | if( p->nAlloc==0 ){ |
| 2433 | int *aNew; |
| 2434 | p->nAlloc = 50; |
| 2435 | aNew = fossil_malloc( sizeof(p->aStack[0])*p->nAlloc ); |
| @@ -2444,11 +2459,11 @@ | |
| 2444 | } |
| 2445 | |
| 2446 | /* |
| 2447 | ** Clear a tag stack, reclaiming any memory allocations. |
| 2448 | */ |
| 2449 | void html_tagstack_clear(HtmlTagStack *p){ |
| 2450 | if( p->nAlloc ){ |
| 2451 | fossil_free(p->aStack); |
| 2452 | p->nAlloc = 0; |
| 2453 | p->aStack = p->aSpace; |
| 2454 | } |
| @@ -2463,11 +2478,11 @@ | |
| 2463 | ** end-tags as you go. |
| 2464 | ** |
| 2465 | ** If there is no open-tag for eEnd on the stack, then this |
| 2466 | ** routine is a no-op. |
| 2467 | */ |
| 2468 | void html_tagstack_pop(HtmlTagStack *p, Blob *pBlob, int eEnd){ |
| 2469 | int i, e; |
| 2470 | if( eEnd!=0 ){ |
| 2471 | for(i=p->n-1; i>=0 && p->aStack[i]!=eEnd; i--){} |
| 2472 | if( i<0 ){ |
| 2473 | blob_appendf(pBlob, "<span class='error'></%s></span>", |
| @@ -2491,22 +2506,26 @@ | |
| 2491 | ** |
| 2492 | ** 1. Omit any elements that are not on the AllowedMarkup list. |
| 2493 | ** |
| 2494 | ** 2. Omit any attributes that are not on the AllowedMarkup list. |
| 2495 | ** |
| 2496 | ** 3. Omit any surplus close-tags. |
| 2497 | ** |
| 2498 | ** 4. Insert additional close-tags as necessary so that all |
| 2499 | ** tag in the input that needs a close-tag has one. |
| 2500 | ** |
| 2501 | ** The input must be writable. Temporary changes may be made to the |
| 2502 | ** input, but the input is restored to its original state prior to |
| 2503 | ** returning. If zHtml[nHtml] is not a zero character, then a zero |
| 2504 | ** might be written in that position temporarily, but that slot will |
| 2505 | ** also be restored before this routine returns. |
| 2506 | */ |
| 2507 | void blob_append_safe_html(Blob *pBlob, char *zHtml, int nHtml){ |
| 2508 | char cLast; |
| 2509 | int i, j, n; |
| 2510 | HtmlTagStack s; |
| 2511 | ParsedMarkup markup; |
| 2512 | |
| @@ -2560,11 +2579,11 @@ | |
| 2560 | ** COMMAND: test-safe-html |
| 2561 | ** |
| 2562 | ** Usage: %fossil test-safe-html FILE ... |
| 2563 | ** |
| 2564 | ** Read files named on the command-line. Send the text of each file |
| 2565 | ** through blob_append_safe_html() and then write the result on |
| 2566 | ** standard output. |
| 2567 | */ |
| 2568 | void test_safe_html_cmd(void){ |
| 2569 | int i; |
| 2570 | Blob x; |
| @@ -2573,14 +2592,14 @@ | |
| 2573 | char *z; |
| 2574 | int n; |
| 2575 | blob_read_from_file(&x, g.argv[i], ExtFILE); |
| 2576 | blob_init(&y, 0, 0); |
| 2577 | blob_terminate(&x); |
| 2578 | blob_append_safe_html(&y, blob_buffer(&x), blob_size(&x)); |
| 2579 | blob_reset(&x); |
| 2580 | z = blob_str(&y); |
| 2581 | n = blob_size(&y); |
| 2582 | while( n>0 && (z[n-1]=='\n' || z[n-1]=='\r') ) n--; |
| 2583 | fossil_print("%.*s\n", n, z); |
| 2584 | blob_reset(&y); |
| 2585 | } |
| 2586 | } |
| 2587 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -2400,36 +2400,51 @@ | |
| 2400 | fossil_puts(blob_str(&out), 0); |
| 2401 | blob_reset(&out); |
| 2402 | } |
| 2403 | } |
| 2404 | |
| 2405 | /**************************************************************************** |
| 2406 | ** safe-html: |
| 2407 | ** |
| 2408 | ** An interface for preventing HTML constructs (ex: <style>, <form>, etc) |
| 2409 | ** from being inserted into Wiki and Forum posts using Markdown. See the |
| 2410 | ** comment on safe_html_append() for additional information on what is meant |
| 2411 | ** by "safe". |
| 2412 | ** |
| 2413 | ** The safe-html restrictions only apply to Markdown, as Fossil-Wiki only |
| 2414 | ** allows safe-html by design - unsafe-HTML is never and has never been |
| 2415 | ** allowed in Fossil-Wiki. |
| 2416 | ** |
| 2417 | ** This code is in the wikiformat.c file so that it can have access to the |
| 2418 | ** white-list of acceptable HTML in the aMarkup[] array. |
| 2419 | */ |
| 2420 | |
| 2421 | /* |
| 2422 | ** An instance of this object keeps track of the nesting of HTML |
| 2423 | ** elements for safe_html_append(). |
| 2424 | */ |
| 2425 | typedef struct HtmlTagStack HtmlTagStack; |
| 2426 | struct HtmlTagStack { |
| 2427 | int n; /* Current tag stack depth */ |
| 2428 | int nAlloc; /* Space allocated for aStack[] */ |
| 2429 | int *aStack; /* The stack of tags */ |
| 2430 | int aSpace[10]; /* Initial static space, to avoid malloc() */ |
| 2431 | }; |
| 2432 | |
| 2433 | /* |
| 2434 | ** Initialize bulk memory to a valid empty tagstack. |
| 2435 | */ |
| 2436 | static void html_tagstack_init(HtmlTagStack *p){ |
| 2437 | p->n = 0; |
| 2438 | p->nAlloc = 0; |
| 2439 | p->aStack = p->aSpace; |
| 2440 | } |
| 2441 | |
| 2442 | /* |
| 2443 | ** Push a new element onto the tag statk |
| 2444 | */ |
| 2445 | static void html_tagstack_push(HtmlTagStack *p, int e){ |
| 2446 | if( p->n>=ArraySize(p->aSpace) && p->n>=p->nAlloc ){ |
| 2447 | if( p->nAlloc==0 ){ |
| 2448 | int *aNew; |
| 2449 | p->nAlloc = 50; |
| 2450 | aNew = fossil_malloc( sizeof(p->aStack[0])*p->nAlloc ); |
| @@ -2444,11 +2459,11 @@ | |
| 2459 | } |
| 2460 | |
| 2461 | /* |
| 2462 | ** Clear a tag stack, reclaiming any memory allocations. |
| 2463 | */ |
| 2464 | static void html_tagstack_clear(HtmlTagStack *p){ |
| 2465 | if( p->nAlloc ){ |
| 2466 | fossil_free(p->aStack); |
| 2467 | p->nAlloc = 0; |
| 2468 | p->aStack = p->aSpace; |
| 2469 | } |
| @@ -2463,11 +2478,11 @@ | |
| 2478 | ** end-tags as you go. |
| 2479 | ** |
| 2480 | ** If there is no open-tag for eEnd on the stack, then this |
| 2481 | ** routine is a no-op. |
| 2482 | */ |
| 2483 | static void html_tagstack_pop(HtmlTagStack *p, Blob *pBlob, int eEnd){ |
| 2484 | int i, e; |
| 2485 | if( eEnd!=0 ){ |
| 2486 | for(i=p->n-1; i>=0 && p->aStack[i]!=eEnd; i--){} |
| 2487 | if( i<0 ){ |
| 2488 | blob_appendf(pBlob, "<span class='error'></%s></span>", |
| @@ -2491,22 +2506,26 @@ | |
| 2506 | ** |
| 2507 | ** 1. Omit any elements that are not on the AllowedMarkup list. |
| 2508 | ** |
| 2509 | ** 2. Omit any attributes that are not on the AllowedMarkup list. |
| 2510 | ** |
| 2511 | ** 3. Omit any surplus close-tags. (This prevents a surplus </div> |
| 2512 | ** or </body> or similar element from interferring with formatting |
| 2513 | ** of the outer context in which the HTML is being inserted.) |
| 2514 | ** |
| 2515 | ** 4. Insert additional close-tags as necessary so that any |
| 2516 | ** tag in the input that needs a close-tag has one. (This prevents |
| 2517 | ** the inserted HTML from messing up the formatting of subsequent |
| 2518 | ** sections of the document into which it is being inserted.) |
| 2519 | ** |
| 2520 | ** The input must be writable. Temporary changes may be made to the |
| 2521 | ** input, but the input is restored to its original state prior to |
| 2522 | ** returning. If zHtml[nHtml] is not a zero character, then a zero |
| 2523 | ** might be written in that position temporarily, but that slot will |
| 2524 | ** also be restored before this routine returns. |
| 2525 | */ |
| 2526 | void safe_html_append(Blob *pBlob, char *zHtml, int nHtml){ |
| 2527 | char cLast; |
| 2528 | int i, j, n; |
| 2529 | HtmlTagStack s; |
| 2530 | ParsedMarkup markup; |
| 2531 | |
| @@ -2560,11 +2579,11 @@ | |
| 2579 | ** COMMAND: test-safe-html |
| 2580 | ** |
| 2581 | ** Usage: %fossil test-safe-html FILE ... |
| 2582 | ** |
| 2583 | ** Read files named on the command-line. Send the text of each file |
| 2584 | ** through safe_html_append() and then write the result on |
| 2585 | ** standard output. |
| 2586 | */ |
| 2587 | void test_safe_html_cmd(void){ |
| 2588 | int i; |
| 2589 | Blob x; |
| @@ -2573,14 +2592,14 @@ | |
| 2592 | char *z; |
| 2593 | int n; |
| 2594 | blob_read_from_file(&x, g.argv[i], ExtFILE); |
| 2595 | blob_init(&y, 0, 0); |
| 2596 | blob_terminate(&x); |
| 2597 | safe_html_append(&y, blob_buffer(&x), blob_size(&x)); |
| 2598 | blob_reset(&x); |
| 2599 | z = blob_str(&y); |
| 2600 | n = blob_size(&y); |
| 2601 | while( n>0 && (z[n-1]=='\n' || z[n-1]=='\r') ) n--; |
| 2602 | fossil_print("%.*s\n", n, z); |
| 2603 | blob_reset(&y); |
| 2604 | } |
| 2605 | } |
| 2606 |