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