Fossil SCM

Simplifications to TH1 for improved defense against accident and mischief: Omit the enable_htmlify command. Htmlify is always turned on. Omit the --th option from the "fossil pikchr" command.

drh 2025-04-25 16:08 trunk merge
Commit 9164a5d1aab52d524bd1080241e33d0d1a8b4d384a0117410ba4588a45623682
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -696,11 +696,11 @@
696696
){
697697
blob_appendf(&bSrc, "fontscale = %.13g\n", rPikVar);
698698
}
699699
blob_append(&bSrc, zSrc, nSrc)
700700
/*have to dup input to ensure a NUL-terminated source string */;
701
- pikchr_process(blob_str(&bSrc), pikFlags, 0, ob);
701
+ pikchr_process(blob_str(&bSrc), pikFlags, ob);
702702
blob_reset(&bSrc);
703703
}
704704
705705
/* Invoked for `...` blocks where there are nSep grave accents in a
706706
** row that serve as the delimiter. According to CommonMark:
707707
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -696,11 +696,11 @@
696 ){
697 blob_appendf(&bSrc, "fontscale = %.13g\n", rPikVar);
698 }
699 blob_append(&bSrc, zSrc, nSrc)
700 /*have to dup input to ensure a NUL-terminated source string */;
701 pikchr_process(blob_str(&bSrc), pikFlags, 0, ob);
702 blob_reset(&bSrc);
703 }
704
705 /* Invoked for `...` blocks where there are nSep grave accents in a
706 ** row that serve as the delimiter. According to CommonMark:
707
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -696,11 +696,11 @@
696 ){
697 blob_appendf(&bSrc, "fontscale = %.13g\n", rPikVar);
698 }
699 blob_append(&bSrc, zSrc, nSrc)
700 /*have to dup input to ensure a NUL-terminated source string */;
701 pikchr_process(blob_str(&bSrc), pikFlags, ob);
702 blob_reset(&bSrc);
703 }
704
705 /* Invoked for `...` blocks where there are nSep grave accents in a
706 ** row that serve as the delimiter. According to CommonMark:
707
+89 -182
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -27,12 +27,10 @@
2727
/* The first two must match the values from pikchr.c */
2828
#define PIKCHR_PROCESS_PLAINTEXT_ERRORS 0x0001
2929
#define PIKCHR_PROCESS_DARK_MODE 0x0002
3030
/* end of flags supported directly by pikchr() */
3131
#define PIKCHR_PROCESS_PASSTHROUGH 0x0003 /* Pass through these flags */
32
-#define PIKCHR_PROCESS_TH1 0x0004
33
-#define PIKCHR_PROCESS_TH1_NOSVG 0x0008
3432
#define PIKCHR_PROCESS_NONCE 0x0010
3533
#define PIKCHR_PROCESS_ERR_PRE 0x0020
3634
#define PIKCHR_PROCESS_SRC 0x0040
3735
#define PIKCHR_PROCESS_DIV 0x0080
3836
#define PIKCHR_PROCESS_DIV_INDENT 0x0100
@@ -43,36 +41,20 @@
4341
#define PIKCHR_PROCESS_DIV_SOURCE 0x2000
4442
#define PIKCHR_PROCESS_DIV_SOURCE_INLINE 0x4000
4543
#endif
4644
4745
/*
48
-** Processes a pikchr script, optionally with embedded TH1, and
49
-** produces HTML code for it. zIn is the NUL-terminated input
46
+** Processes a pikchr script. zIn is the NUL-terminated input
5047
** script. pikFlags may be a bitmask of any of the PIKCHR_PROCESS_xxx
51
-** flags documented below. thFlags may be a bitmask of any of the
52
-** TH_INIT_xxx and/or TH_R2B_xxx flags. Output is sent to pOut,
53
-** appending to it without modifying any prior contents.
48
+** flags documented below. Output is sent to pOut,
5449
**
55
-** Returns 0 on success, 1 if TH1 processing failed, or 2 if pikchr
56
-** processing failed. In either case, the error message (if any) from
57
-** TH1 or pikchr will be appended to pOut.
50
+** Returns 0 on success, or non-zero if pikchr processing failed.
51
+** In either case, the error message (if any) from pikchr will be
52
+** appended to pOut.
5853
**
5954
** pikFlags flag descriptions:
6055
**
61
-** - PIKCHR_PROCESS_TH1 means to run zIn through TH1, using the TH1
62
-** init flags specified in the 3rd argument. If thFlags is non-0 then
63
-** this flag is assumed even if it is not specified.
64
-**
65
-** - PIKCHR_PROCESS_TH1_NOSVG means that processing stops after the
66
-** TH1 eval step, thus the output will be (presumably) a
67
-** TH1-generated/processed pikchr script (or whatever else the TH1
68
-** outputs). If this flag is set, PIKCHR_PROCESS_TH1 is assumed even
69
-** if it is not specified.
70
-**
71
-** All of the remaining flags listed below are ignored if
72
-** PIKCHR_PROCESS_TH1_NOSVG is specified!
73
-**
7456
** - PIKCHR_PROCESS_DIV: if set, the SVG result is wrapped in a DIV
7557
** element which specifies a max-width style value based on the SVG's
7658
** calculated size. This flag has multiple mutually exclusive forms:
7759
**
7860
** - PIKCHR_PROCESS_DIV uses default element alignment.
@@ -116,14 +98,14 @@
11698
**
11799
** - PIKCHR_PROCESS_ERR_PRE: if set and pikchr() fails, the resulting
118100
** error report is wrapped in a PRE element, else it is retained
119101
** as-is (intended only for console output).
120102
*/
121
-int pikchr_process(const char * zIn, int pikFlags, int thFlags,
122
- Blob * pOut){
123
- Blob bIn = empty_blob;
103
+int pikchr_process(const char *zIn, int pikFlags, Blob * pOut){
124104
int isErr = 0;
105
+ int w = 0, h = 0;
106
+ char *zOut;
125107
const char *zNonce = (PIKCHR_PROCESS_NONCE & pikFlags)
126108
? safe_html_nonce(1) : 0;
127109
128110
if(!(PIKCHR_PROCESS_DIV & pikFlags)
129111
/* If any DIV_xxx flags are set, set DIV */
@@ -135,115 +117,87 @@
135117
| PIKCHR_PROCESS_DIV_SOURCE_INLINE
136118
| PIKCHR_PROCESS_DIV_TOGGLE
137119
) & pikFlags){
138120
pikFlags |= PIKCHR_PROCESS_DIV;
139121
}
140
- if(!(PIKCHR_PROCESS_TH1 & pikFlags)
141
- /* If any TH1_xxx flags are set, set TH1 */
142
- && (PIKCHR_PROCESS_TH1_NOSVG & pikFlags || thFlags!=0)){
143
- pikFlags |= PIKCHR_PROCESS_TH1;
144
- }
145
- if(zNonce){
146
- blob_appendf(pOut, "%s\n", zNonce);
147
- }
148
- if(PIKCHR_PROCESS_TH1 & pikFlags){
149
- Blob out = empty_blob;
150
- isErr = Th_RenderToBlob(zIn, &out, thFlags)
151
- ? 1 : 0;
152
- if(isErr){
153
- blob_append(pOut, blob_str(&out), blob_size(&out));
154
- blob_reset(&out);
155
- }else{
156
- bIn = out;
157
- }
158
- }else{
159
- blob_init(&bIn, zIn, -1);
160
- }
161
- if(!isErr){
162
- if(PIKCHR_PROCESS_TH1_NOSVG & pikFlags){
163
- blob_append(pOut, blob_str(&bIn), blob_size(&bIn));
164
- }else{
165
- int w = 0, h = 0;
166
- const char * zContent = blob_str(&bIn);
167
- char *zOut;
168
- zOut = pikchr(zContent, "pikchr",
169
- 0x01 | (pikFlags&PIKCHR_PROCESS_PASSTHROUGH),
170
- &w, &h);
171
- if( w>0 && h>0 ){
172
- const char * zClassToggle = "";
173
- const char * zClassSource = "";
174
- const char * zWrapperClass = "";
175
- if(PIKCHR_PROCESS_DIV & pikFlags){
176
- if(PIKCHR_PROCESS_DIV_CENTER & pikFlags){
177
- zWrapperClass = " center";
178
- }else if(PIKCHR_PROCESS_DIV_INDENT & pikFlags){
179
- zWrapperClass = " indent";
180
- }else if(PIKCHR_PROCESS_DIV_FLOAT_LEFT & pikFlags){
181
- zWrapperClass = " float-left";
182
- }else if(PIKCHR_PROCESS_DIV_FLOAT_RIGHT & pikFlags){
183
- zWrapperClass = " float-right";
184
- }
185
- if(PIKCHR_PROCESS_DIV_TOGGLE & pikFlags){
186
- zClassToggle = " toggle";
187
- }
188
- if(PIKCHR_PROCESS_DIV_SOURCE_INLINE & pikFlags){
189
- if(PIKCHR_PROCESS_DIV_SOURCE & pikFlags){
190
- zClassSource = " source source-inline";
191
- }else{
192
- zClassSource = " source-inline";
193
- }
194
- pikFlags |= PIKCHR_PROCESS_SRC;
195
- }else if(PIKCHR_PROCESS_DIV_SOURCE & pikFlags){
196
- zClassSource = " source";
197
- pikFlags |= PIKCHR_PROCESS_SRC;
198
- }
199
- blob_appendf(pOut,"<div class='pikchr-wrapper"
200
- "%s%s%s'>"
201
- "<div class=\"pikchr-svg\" "
202
- "style=\"max-width:%dpx\">\n",
203
- zWrapperClass/*safe-for-%s*/,
204
- zClassToggle/*safe-for-%s*/,
205
- zClassSource/*safe-for-%s*/, w);
206
- }
207
- blob_append(pOut, zOut, -1);
208
- if(PIKCHR_PROCESS_DIV & pikFlags){
209
- blob_append(pOut, "</div>\n", 7);
210
- }
211
- if(PIKCHR_PROCESS_SRC & pikFlags){
212
- static int counter = 0;
213
- ++counter;
214
- blob_appendf(pOut, "<div class='pikchr-src'>"
215
- "<pre id='pikchr-src-%d'>%h</pre>"
216
- "<span class='hidden'>"
217
- "<a href='%R/pikchrshow?fromSession' "
218
- "class='pikchr-src-pikchrshow' target='_new-%d' "
219
- "data-pikchrid='pikchr-src-%d' "
220
- "title='Open this pikchr in /pikchrshow'"
221
- ">&rarr; /pikchrshow</a></span>"
222
- "</div>\n",
223
- counter, blob_str(&bIn), counter, counter);
224
- }
225
- if(PIKCHR_PROCESS_DIV & pikFlags){
226
- blob_append(pOut, "</div>\n", 7);
227
- }
228
- }else{
229
- isErr = 2;
230
- if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
231
- blob_append(pOut, "<pre class='error'>\n", 20);
232
- }
233
- blob_appendf(pOut, "%h", zOut);
234
- if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
235
- blob_append(pOut, "\n</pre>\n", 8);
236
- }
237
- }
238
- fossil_free(zOut);
239
- }
240
- }
241
- if(zNonce){
242
- blob_appendf(pOut, "%s\n", zNonce);
243
- }
244
- blob_reset(&bIn);
122
+ if(zNonce){
123
+ blob_appendf(pOut, "%s\n", zNonce);
124
+ }
125
+ zOut = pikchr(zIn, "pikchr",
126
+ 0x01 | (pikFlags&PIKCHR_PROCESS_PASSTHROUGH),
127
+ &w, &h);
128
+ if( w>0 && h>0 ){
129
+ const char * zClassToggle = "";
130
+ const char * zClassSource = "";
131
+ const char * zWrapperClass = "";
132
+ if(PIKCHR_PROCESS_DIV & pikFlags){
133
+ if(PIKCHR_PROCESS_DIV_CENTER & pikFlags){
134
+ zWrapperClass = " center";
135
+ }else if(PIKCHR_PROCESS_DIV_INDENT & pikFlags){
136
+ zWrapperClass = " indent";
137
+ }else if(PIKCHR_PROCESS_DIV_FLOAT_LEFT & pikFlags){
138
+ zWrapperClass = " float-left";
139
+ }else if(PIKCHR_PROCESS_DIV_FLOAT_RIGHT & pikFlags){
140
+ zWrapperClass = " float-right";
141
+ }
142
+ if(PIKCHR_PROCESS_DIV_TOGGLE & pikFlags){
143
+ zClassToggle = " toggle";
144
+ }
145
+ if(PIKCHR_PROCESS_DIV_SOURCE_INLINE & pikFlags){
146
+ if(PIKCHR_PROCESS_DIV_SOURCE & pikFlags){
147
+ zClassSource = " source source-inline";
148
+ }else{
149
+ zClassSource = " source-inline";
150
+ }
151
+ pikFlags |= PIKCHR_PROCESS_SRC;
152
+ }else if(PIKCHR_PROCESS_DIV_SOURCE & pikFlags){
153
+ zClassSource = " source";
154
+ pikFlags |= PIKCHR_PROCESS_SRC;
155
+ }
156
+ blob_appendf(pOut,"<div class='pikchr-wrapper"
157
+ "%s%s%s'>"
158
+ "<div class=\"pikchr-svg\" "
159
+ "style=\"max-width:%dpx\">\n",
160
+ zWrapperClass/*safe-for-%s*/,
161
+ zClassToggle/*safe-for-%s*/,
162
+ zClassSource/*safe-for-%s*/, w);
163
+ }
164
+ blob_append(pOut, zOut, -1);
165
+ if(PIKCHR_PROCESS_DIV & pikFlags){
166
+ blob_append(pOut, "</div>\n", 7);
167
+ }
168
+ if(PIKCHR_PROCESS_SRC & pikFlags){
169
+ static int counter = 0;
170
+ ++counter;
171
+ blob_appendf(pOut, "<div class='pikchr-src'>"
172
+ "<pre id='pikchr-src-%d'>%h</pre>"
173
+ "<span class='hidden'>"
174
+ "<a href='%R/pikchrshow?fromSession' "
175
+ "class='pikchr-src-pikchrshow' target='_new-%d' "
176
+ "data-pikchrid='pikchr-src-%d' "
177
+ "title='Open this pikchr in /pikchrshow'"
178
+ ">&rarr; /pikchrshow</a></span>"
179
+ "</div>\n",
180
+ counter, zIn, counter, counter);
181
+ }
182
+ if(PIKCHR_PROCESS_DIV & pikFlags){
183
+ blob_append(pOut, "</div>\n", 7);
184
+ }
185
+ }else{
186
+ isErr = 2;
187
+ if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
188
+ blob_append(pOut, "<pre class='error'>\n", 20);
189
+ }
190
+ blob_appendf(pOut, "%h", zOut);
191
+ if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
192
+ blob_append(pOut, "\n</pre>\n", 8);
193
+ }
194
+ }
195
+ fossil_free(zOut);
196
+ if(zNonce){
197
+ blob_appendf(pOut, "%s\n", zNonce);
198
+ }
245199
return isErr;
246200
}
247201
248202
/*
249203
** Legacy impl of /pikchrshow. pikchrshow_page() will delegate to
@@ -279,11 +233,11 @@
279233
TODO: respond with JSON instead.*/
280234
cgi_set_content_type("text/html");
281235
if(zContent && *zContent){
282236
Blob out = empty_blob;
283237
const int isErr =
284
- pikchr_process(zContent, pikFlags, 0, &out);
238
+ pikchr_process(zContent, pikFlags, &out);
285239
if(isErr){
286240
cgi_printf_header("x-pikchrshow-is-error: %d\r\n", isErr);
287241
}
288242
CX("%b", &out);
289243
blob_reset(&out);
@@ -384,11 +338,11 @@
384338
/* Reminder: Firefox does not properly flexbox a LEGEND
385339
element, always flowing it in column mode. */);
386340
CX("<div id='pikchrshow-output'>");
387341
if(*zContent){
388342
Blob out = empty_blob;
389
- pikchr_process(zContent, pikFlags, 0, &out);
343
+ pikchr_process(zContent, pikFlags, &out);
390344
CX("%b", &out);
391345
blob_reset(&out);
392346
} CX("</div>"/*#pikchrshow-output*/);
393347
} CX("</fieldset>"/*#pikchrshow-output-wrapper*/);
394348
} CX("</div>"/*sbs-wrapper*/);
@@ -561,60 +515,23 @@
561515
**
562516
** -src Store the input pikchr's source code in the output as
563517
** a separate element adjacent to the SVG one. Implied
564518
** by -div-source.
565519
**
566
-**
567
-** -th Process the input using TH1 before passing it to pikchr
568
-**
569
-** -th-novar Disable $var and $<var> TH1 processing. Use this if the
570
-** pikchr script uses '$' for its own purposes and that
571
-** causes issues. This only affects parsing of '$' outside
572
-** of TH1 script blocks. Code in such blocks is unaffected.
573
-**
574
-** -th-nosvg When using -th, output the post-TH1'd script
575
-** instead of the pikchr-rendered output
576
-**
577
-** -th-trace Trace TH1 execution (for debugging purposes)
578
-**
579520
** -dark Change pikchr colors to assume a dark-mode theme.
580521
**
581522
**
582523
** The -div-indent/center/left/right flags may not be combined.
583
-**
584
-** TH1-related Notes and Caveats:
585
-**
586
-** If the -th flag is used, this command must open a fossil database
587
-** for certain functionality to work (via a check-out or the -R REPO
588
-** flag). If opening a db fails, execution will continue but any TH1
589
-** commands which require a db will trigger a fatal error.
590
-**
591
-** In Fossil skins, TH1 variables in the form $varName are expanded
592
-** as-is and those in the form $<varName> are htmlized in the
593
-** resulting output. This processor disables the htmlizing step, so $x
594
-** and $<x> are equivalent unless the TH1-processed pikchr script
595
-** invokes the TH1 command [enable_htmlify 1] to enable it. Normally
596
-** that option will interfere with pikchr output, however, e.g. by
597
-** HTML-encoding double-quotes.
598
-**
599
-** Many of the fossil-installed TH1 functions simply do not make any
600
-** sense for pikchr scripts.
601524
*/
602525
void pikchr_cmd(void){
603526
Blob bIn = empty_blob;
604527
Blob bOut = empty_blob;
605528
const char * zInfile = "-";
606529
const char * zOutfile = "-";
607
- const int fTh1 = find_option("th",0,0)!=0;
608
- const int fNosvg = find_option("th-nosvg",0,0)!=0;
609530
int isErr = 0;
610531
int pikFlags = find_option("src",0,0)!=0
611532
? PIKCHR_PROCESS_SRC : 0;
612
- u32 fThFlags = TH_INIT_NO_ENCODE
613
- | (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
614
-
615
- Th_InitTraceLog()/*processes -th-trace flag*/;
616533
617534
if(find_option("div",0,0)!=0){
618535
pikFlags |= PIKCHR_PROCESS_DIV;
619536
}else if(find_option("div-indent",0,0)!=0){
620537
pikFlags |= PIKCHR_PROCESS_DIV_INDENT;
@@ -644,24 +561,14 @@
644561
}
645562
if(g.argc>3){
646563
zOutfile = g.argv[3];
647564
}
648565
blob_read_from_file(&bIn, zInfile, ExtFILE);
649
- if(fTh1){
650
- db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
651
- /* ^^^ needed for certain TH1 functions to work */;
652
- pikFlags |= PIKCHR_PROCESS_TH1;
653
- if(fNosvg) pikFlags |= PIKCHR_PROCESS_TH1_NOSVG;
654
- }
655
- isErr = pikchr_process(blob_str(&bIn), pikFlags,
656
- fTh1 ? fThFlags : 0, &bOut);
566
+ isErr = pikchr_process(blob_str(&bIn), pikFlags, &bOut);
657567
if(isErr){
658
- fossil_fatal("%s ERROR:%c%b", 1==isErr ? "TH1" : "pikchr",
659
- 1==isErr ? ' ' : '\n',
660
- &bOut);
568
+ fossil_fatal("pikchr ERROR: %b", &bOut);
661569
}else{
662570
blob_write_to_file(&bOut, zOutfile);
663571
}
664
- Th_PrintTraceLog();
665572
blob_reset(&bIn);
666573
blob_reset(&bOut);
667574
}
668575
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -27,12 +27,10 @@
27 /* The first two must match the values from pikchr.c */
28 #define PIKCHR_PROCESS_PLAINTEXT_ERRORS 0x0001
29 #define PIKCHR_PROCESS_DARK_MODE 0x0002
30 /* end of flags supported directly by pikchr() */
31 #define PIKCHR_PROCESS_PASSTHROUGH 0x0003 /* Pass through these flags */
32 #define PIKCHR_PROCESS_TH1 0x0004
33 #define PIKCHR_PROCESS_TH1_NOSVG 0x0008
34 #define PIKCHR_PROCESS_NONCE 0x0010
35 #define PIKCHR_PROCESS_ERR_PRE 0x0020
36 #define PIKCHR_PROCESS_SRC 0x0040
37 #define PIKCHR_PROCESS_DIV 0x0080
38 #define PIKCHR_PROCESS_DIV_INDENT 0x0100
@@ -43,36 +41,20 @@
43 #define PIKCHR_PROCESS_DIV_SOURCE 0x2000
44 #define PIKCHR_PROCESS_DIV_SOURCE_INLINE 0x4000
45 #endif
46
47 /*
48 ** Processes a pikchr script, optionally with embedded TH1, and
49 ** produces HTML code for it. zIn is the NUL-terminated input
50 ** script. pikFlags may be a bitmask of any of the PIKCHR_PROCESS_xxx
51 ** flags documented below. thFlags may be a bitmask of any of the
52 ** TH_INIT_xxx and/or TH_R2B_xxx flags. Output is sent to pOut,
53 ** appending to it without modifying any prior contents.
54 **
55 ** Returns 0 on success, 1 if TH1 processing failed, or 2 if pikchr
56 ** processing failed. In either case, the error message (if any) from
57 ** TH1 or pikchr will be appended to pOut.
58 **
59 ** pikFlags flag descriptions:
60 **
61 ** - PIKCHR_PROCESS_TH1 means to run zIn through TH1, using the TH1
62 ** init flags specified in the 3rd argument. If thFlags is non-0 then
63 ** this flag is assumed even if it is not specified.
64 **
65 ** - PIKCHR_PROCESS_TH1_NOSVG means that processing stops after the
66 ** TH1 eval step, thus the output will be (presumably) a
67 ** TH1-generated/processed pikchr script (or whatever else the TH1
68 ** outputs). If this flag is set, PIKCHR_PROCESS_TH1 is assumed even
69 ** if it is not specified.
70 **
71 ** All of the remaining flags listed below are ignored if
72 ** PIKCHR_PROCESS_TH1_NOSVG is specified!
73 **
74 ** - PIKCHR_PROCESS_DIV: if set, the SVG result is wrapped in a DIV
75 ** element which specifies a max-width style value based on the SVG's
76 ** calculated size. This flag has multiple mutually exclusive forms:
77 **
78 ** - PIKCHR_PROCESS_DIV uses default element alignment.
@@ -116,14 +98,14 @@
116 **
117 ** - PIKCHR_PROCESS_ERR_PRE: if set and pikchr() fails, the resulting
118 ** error report is wrapped in a PRE element, else it is retained
119 ** as-is (intended only for console output).
120 */
121 int pikchr_process(const char * zIn, int pikFlags, int thFlags,
122 Blob * pOut){
123 Blob bIn = empty_blob;
124 int isErr = 0;
 
 
125 const char *zNonce = (PIKCHR_PROCESS_NONCE & pikFlags)
126 ? safe_html_nonce(1) : 0;
127
128 if(!(PIKCHR_PROCESS_DIV & pikFlags)
129 /* If any DIV_xxx flags are set, set DIV */
@@ -135,115 +117,87 @@
135 | PIKCHR_PROCESS_DIV_SOURCE_INLINE
136 | PIKCHR_PROCESS_DIV_TOGGLE
137 ) & pikFlags){
138 pikFlags |= PIKCHR_PROCESS_DIV;
139 }
140 if(!(PIKCHR_PROCESS_TH1 & pikFlags)
141 /* If any TH1_xxx flags are set, set TH1 */
142 && (PIKCHR_PROCESS_TH1_NOSVG & pikFlags || thFlags!=0)){
143 pikFlags |= PIKCHR_PROCESS_TH1;
144 }
145 if(zNonce){
146 blob_appendf(pOut, "%s\n", zNonce);
147 }
148 if(PIKCHR_PROCESS_TH1 & pikFlags){
149 Blob out = empty_blob;
150 isErr = Th_RenderToBlob(zIn, &out, thFlags)
151 ? 1 : 0;
152 if(isErr){
153 blob_append(pOut, blob_str(&out), blob_size(&out));
154 blob_reset(&out);
155 }else{
156 bIn = out;
157 }
158 }else{
159 blob_init(&bIn, zIn, -1);
160 }
161 if(!isErr){
162 if(PIKCHR_PROCESS_TH1_NOSVG & pikFlags){
163 blob_append(pOut, blob_str(&bIn), blob_size(&bIn));
164 }else{
165 int w = 0, h = 0;
166 const char * zContent = blob_str(&bIn);
167 char *zOut;
168 zOut = pikchr(zContent, "pikchr",
169 0x01 | (pikFlags&PIKCHR_PROCESS_PASSTHROUGH),
170 &w, &h);
171 if( w>0 && h>0 ){
172 const char * zClassToggle = "";
173 const char * zClassSource = "";
174 const char * zWrapperClass = "";
175 if(PIKCHR_PROCESS_DIV & pikFlags){
176 if(PIKCHR_PROCESS_DIV_CENTER & pikFlags){
177 zWrapperClass = " center";
178 }else if(PIKCHR_PROCESS_DIV_INDENT & pikFlags){
179 zWrapperClass = " indent";
180 }else if(PIKCHR_PROCESS_DIV_FLOAT_LEFT & pikFlags){
181 zWrapperClass = " float-left";
182 }else if(PIKCHR_PROCESS_DIV_FLOAT_RIGHT & pikFlags){
183 zWrapperClass = " float-right";
184 }
185 if(PIKCHR_PROCESS_DIV_TOGGLE & pikFlags){
186 zClassToggle = " toggle";
187 }
188 if(PIKCHR_PROCESS_DIV_SOURCE_INLINE & pikFlags){
189 if(PIKCHR_PROCESS_DIV_SOURCE & pikFlags){
190 zClassSource = " source source-inline";
191 }else{
192 zClassSource = " source-inline";
193 }
194 pikFlags |= PIKCHR_PROCESS_SRC;
195 }else if(PIKCHR_PROCESS_DIV_SOURCE & pikFlags){
196 zClassSource = " source";
197 pikFlags |= PIKCHR_PROCESS_SRC;
198 }
199 blob_appendf(pOut,"<div class='pikchr-wrapper"
200 "%s%s%s'>"
201 "<div class=\"pikchr-svg\" "
202 "style=\"max-width:%dpx\">\n",
203 zWrapperClass/*safe-for-%s*/,
204 zClassToggle/*safe-for-%s*/,
205 zClassSource/*safe-for-%s*/, w);
206 }
207 blob_append(pOut, zOut, -1);
208 if(PIKCHR_PROCESS_DIV & pikFlags){
209 blob_append(pOut, "</div>\n", 7);
210 }
211 if(PIKCHR_PROCESS_SRC & pikFlags){
212 static int counter = 0;
213 ++counter;
214 blob_appendf(pOut, "<div class='pikchr-src'>"
215 "<pre id='pikchr-src-%d'>%h</pre>"
216 "<span class='hidden'>"
217 "<a href='%R/pikchrshow?fromSession' "
218 "class='pikchr-src-pikchrshow' target='_new-%d' "
219 "data-pikchrid='pikchr-src-%d' "
220 "title='Open this pikchr in /pikchrshow'"
221 ">&rarr; /pikchrshow</a></span>"
222 "</div>\n",
223 counter, blob_str(&bIn), counter, counter);
224 }
225 if(PIKCHR_PROCESS_DIV & pikFlags){
226 blob_append(pOut, "</div>\n", 7);
227 }
228 }else{
229 isErr = 2;
230 if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
231 blob_append(pOut, "<pre class='error'>\n", 20);
232 }
233 blob_appendf(pOut, "%h", zOut);
234 if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
235 blob_append(pOut, "\n</pre>\n", 8);
236 }
237 }
238 fossil_free(zOut);
239 }
240 }
241 if(zNonce){
242 blob_appendf(pOut, "%s\n", zNonce);
243 }
244 blob_reset(&bIn);
245 return isErr;
246 }
247
248 /*
249 ** Legacy impl of /pikchrshow. pikchrshow_page() will delegate to
@@ -279,11 +233,11 @@
279 TODO: respond with JSON instead.*/
280 cgi_set_content_type("text/html");
281 if(zContent && *zContent){
282 Blob out = empty_blob;
283 const int isErr =
284 pikchr_process(zContent, pikFlags, 0, &out);
285 if(isErr){
286 cgi_printf_header("x-pikchrshow-is-error: %d\r\n", isErr);
287 }
288 CX("%b", &out);
289 blob_reset(&out);
@@ -384,11 +338,11 @@
384 /* Reminder: Firefox does not properly flexbox a LEGEND
385 element, always flowing it in column mode. */);
386 CX("<div id='pikchrshow-output'>");
387 if(*zContent){
388 Blob out = empty_blob;
389 pikchr_process(zContent, pikFlags, 0, &out);
390 CX("%b", &out);
391 blob_reset(&out);
392 } CX("</div>"/*#pikchrshow-output*/);
393 } CX("</fieldset>"/*#pikchrshow-output-wrapper*/);
394 } CX("</div>"/*sbs-wrapper*/);
@@ -561,60 +515,23 @@
561 **
562 ** -src Store the input pikchr's source code in the output as
563 ** a separate element adjacent to the SVG one. Implied
564 ** by -div-source.
565 **
566 **
567 ** -th Process the input using TH1 before passing it to pikchr
568 **
569 ** -th-novar Disable $var and $<var> TH1 processing. Use this if the
570 ** pikchr script uses '$' for its own purposes and that
571 ** causes issues. This only affects parsing of '$' outside
572 ** of TH1 script blocks. Code in such blocks is unaffected.
573 **
574 ** -th-nosvg When using -th, output the post-TH1'd script
575 ** instead of the pikchr-rendered output
576 **
577 ** -th-trace Trace TH1 execution (for debugging purposes)
578 **
579 ** -dark Change pikchr colors to assume a dark-mode theme.
580 **
581 **
582 ** The -div-indent/center/left/right flags may not be combined.
583 **
584 ** TH1-related Notes and Caveats:
585 **
586 ** If the -th flag is used, this command must open a fossil database
587 ** for certain functionality to work (via a check-out or the -R REPO
588 ** flag). If opening a db fails, execution will continue but any TH1
589 ** commands which require a db will trigger a fatal error.
590 **
591 ** In Fossil skins, TH1 variables in the form $varName are expanded
592 ** as-is and those in the form $<varName> are htmlized in the
593 ** resulting output. This processor disables the htmlizing step, so $x
594 ** and $<x> are equivalent unless the TH1-processed pikchr script
595 ** invokes the TH1 command [enable_htmlify 1] to enable it. Normally
596 ** that option will interfere with pikchr output, however, e.g. by
597 ** HTML-encoding double-quotes.
598 **
599 ** Many of the fossil-installed TH1 functions simply do not make any
600 ** sense for pikchr scripts.
601 */
602 void pikchr_cmd(void){
603 Blob bIn = empty_blob;
604 Blob bOut = empty_blob;
605 const char * zInfile = "-";
606 const char * zOutfile = "-";
607 const int fTh1 = find_option("th",0,0)!=0;
608 const int fNosvg = find_option("th-nosvg",0,0)!=0;
609 int isErr = 0;
610 int pikFlags = find_option("src",0,0)!=0
611 ? PIKCHR_PROCESS_SRC : 0;
612 u32 fThFlags = TH_INIT_NO_ENCODE
613 | (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
614
615 Th_InitTraceLog()/*processes -th-trace flag*/;
616
617 if(find_option("div",0,0)!=0){
618 pikFlags |= PIKCHR_PROCESS_DIV;
619 }else if(find_option("div-indent",0,0)!=0){
620 pikFlags |= PIKCHR_PROCESS_DIV_INDENT;
@@ -644,24 +561,14 @@
644 }
645 if(g.argc>3){
646 zOutfile = g.argv[3];
647 }
648 blob_read_from_file(&bIn, zInfile, ExtFILE);
649 if(fTh1){
650 db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
651 /* ^^^ needed for certain TH1 functions to work */;
652 pikFlags |= PIKCHR_PROCESS_TH1;
653 if(fNosvg) pikFlags |= PIKCHR_PROCESS_TH1_NOSVG;
654 }
655 isErr = pikchr_process(blob_str(&bIn), pikFlags,
656 fTh1 ? fThFlags : 0, &bOut);
657 if(isErr){
658 fossil_fatal("%s ERROR:%c%b", 1==isErr ? "TH1" : "pikchr",
659 1==isErr ? ' ' : '\n',
660 &bOut);
661 }else{
662 blob_write_to_file(&bOut, zOutfile);
663 }
664 Th_PrintTraceLog();
665 blob_reset(&bIn);
666 blob_reset(&bOut);
667 }
668
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -27,12 +27,10 @@
27 /* The first two must match the values from pikchr.c */
28 #define PIKCHR_PROCESS_PLAINTEXT_ERRORS 0x0001
29 #define PIKCHR_PROCESS_DARK_MODE 0x0002
30 /* end of flags supported directly by pikchr() */
31 #define PIKCHR_PROCESS_PASSTHROUGH 0x0003 /* Pass through these flags */
 
 
32 #define PIKCHR_PROCESS_NONCE 0x0010
33 #define PIKCHR_PROCESS_ERR_PRE 0x0020
34 #define PIKCHR_PROCESS_SRC 0x0040
35 #define PIKCHR_PROCESS_DIV 0x0080
36 #define PIKCHR_PROCESS_DIV_INDENT 0x0100
@@ -43,36 +41,20 @@
41 #define PIKCHR_PROCESS_DIV_SOURCE 0x2000
42 #define PIKCHR_PROCESS_DIV_SOURCE_INLINE 0x4000
43 #endif
44
45 /*
46 ** Processes a pikchr script. zIn is the NUL-terminated input
 
47 ** script. pikFlags may be a bitmask of any of the PIKCHR_PROCESS_xxx
48 ** flags documented below. Output is sent to pOut,
 
 
49 **
50 ** Returns 0 on success, or non-zero if pikchr processing failed.
51 ** In either case, the error message (if any) from pikchr will be
52 ** appended to pOut.
53 **
54 ** pikFlags flag descriptions:
55 **
 
 
 
 
 
 
 
 
 
 
 
 
 
56 ** - PIKCHR_PROCESS_DIV: if set, the SVG result is wrapped in a DIV
57 ** element which specifies a max-width style value based on the SVG's
58 ** calculated size. This flag has multiple mutually exclusive forms:
59 **
60 ** - PIKCHR_PROCESS_DIV uses default element alignment.
@@ -116,14 +98,14 @@
98 **
99 ** - PIKCHR_PROCESS_ERR_PRE: if set and pikchr() fails, the resulting
100 ** error report is wrapped in a PRE element, else it is retained
101 ** as-is (intended only for console output).
102 */
103 int pikchr_process(const char *zIn, int pikFlags, Blob * pOut){
 
 
104 int isErr = 0;
105 int w = 0, h = 0;
106 char *zOut;
107 const char *zNonce = (PIKCHR_PROCESS_NONCE & pikFlags)
108 ? safe_html_nonce(1) : 0;
109
110 if(!(PIKCHR_PROCESS_DIV & pikFlags)
111 /* If any DIV_xxx flags are set, set DIV */
@@ -135,115 +117,87 @@
117 | PIKCHR_PROCESS_DIV_SOURCE_INLINE
118 | PIKCHR_PROCESS_DIV_TOGGLE
119 ) & pikFlags){
120 pikFlags |= PIKCHR_PROCESS_DIV;
121 }
122 if(zNonce){
123 blob_appendf(pOut, "%s\n", zNonce);
124 }
125 zOut = pikchr(zIn, "pikchr",
126 0x01 | (pikFlags&PIKCHR_PROCESS_PASSTHROUGH),
127 &w, &h);
128 if( w>0 && h>0 ){
129 const char * zClassToggle = "";
130 const char * zClassSource = "";
131 const char * zWrapperClass = "";
132 if(PIKCHR_PROCESS_DIV & pikFlags){
133 if(PIKCHR_PROCESS_DIV_CENTER & pikFlags){
134 zWrapperClass = " center";
135 }else if(PIKCHR_PROCESS_DIV_INDENT & pikFlags){
136 zWrapperClass = " indent";
137 }else if(PIKCHR_PROCESS_DIV_FLOAT_LEFT & pikFlags){
138 zWrapperClass = " float-left";
139 }else if(PIKCHR_PROCESS_DIV_FLOAT_RIGHT & pikFlags){
140 zWrapperClass = " float-right";
141 }
142 if(PIKCHR_PROCESS_DIV_TOGGLE & pikFlags){
143 zClassToggle = " toggle";
144 }
145 if(PIKCHR_PROCESS_DIV_SOURCE_INLINE & pikFlags){
146 if(PIKCHR_PROCESS_DIV_SOURCE & pikFlags){
147 zClassSource = " source source-inline";
148 }else{
149 zClassSource = " source-inline";
150 }
151 pikFlags |= PIKCHR_PROCESS_SRC;
152 }else if(PIKCHR_PROCESS_DIV_SOURCE & pikFlags){
153 zClassSource = " source";
154 pikFlags |= PIKCHR_PROCESS_SRC;
155 }
156 blob_appendf(pOut,"<div class='pikchr-wrapper"
157 "%s%s%s'>"
158 "<div class=\"pikchr-svg\" "
159 "style=\"max-width:%dpx\">\n",
160 zWrapperClass/*safe-for-%s*/,
161 zClassToggle/*safe-for-%s*/,
162 zClassSource/*safe-for-%s*/, w);
163 }
164 blob_append(pOut, zOut, -1);
165 if(PIKCHR_PROCESS_DIV & pikFlags){
166 blob_append(pOut, "</div>\n", 7);
167 }
168 if(PIKCHR_PROCESS_SRC & pikFlags){
169 static int counter = 0;
170 ++counter;
171 blob_appendf(pOut, "<div class='pikchr-src'>"
172 "<pre id='pikchr-src-%d'>%h</pre>"
173 "<span class='hidden'>"
174 "<a href='%R/pikchrshow?fromSession' "
175 "class='pikchr-src-pikchrshow' target='_new-%d' "
176 "data-pikchrid='pikchr-src-%d' "
177 "title='Open this pikchr in /pikchrshow'"
178 ">&rarr; /pikchrshow</a></span>"
179 "</div>\n",
180 counter, zIn, counter, counter);
181 }
182 if(PIKCHR_PROCESS_DIV & pikFlags){
183 blob_append(pOut, "</div>\n", 7);
184 }
185 }else{
186 isErr = 2;
187 if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
188 blob_append(pOut, "<pre class='error'>\n", 20);
189 }
190 blob_appendf(pOut, "%h", zOut);
191 if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
192 blob_append(pOut, "\n</pre>\n", 8);
193 }
194 }
195 fossil_free(zOut);
196 if(zNonce){
197 blob_appendf(pOut, "%s\n", zNonce);
198 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199 return isErr;
200 }
201
202 /*
203 ** Legacy impl of /pikchrshow. pikchrshow_page() will delegate to
@@ -279,11 +233,11 @@
233 TODO: respond with JSON instead.*/
234 cgi_set_content_type("text/html");
235 if(zContent && *zContent){
236 Blob out = empty_blob;
237 const int isErr =
238 pikchr_process(zContent, pikFlags, &out);
239 if(isErr){
240 cgi_printf_header("x-pikchrshow-is-error: %d\r\n", isErr);
241 }
242 CX("%b", &out);
243 blob_reset(&out);
@@ -384,11 +338,11 @@
338 /* Reminder: Firefox does not properly flexbox a LEGEND
339 element, always flowing it in column mode. */);
340 CX("<div id='pikchrshow-output'>");
341 if(*zContent){
342 Blob out = empty_blob;
343 pikchr_process(zContent, pikFlags, &out);
344 CX("%b", &out);
345 blob_reset(&out);
346 } CX("</div>"/*#pikchrshow-output*/);
347 } CX("</fieldset>"/*#pikchrshow-output-wrapper*/);
348 } CX("</div>"/*sbs-wrapper*/);
@@ -561,60 +515,23 @@
515 **
516 ** -src Store the input pikchr's source code in the output as
517 ** a separate element adjacent to the SVG one. Implied
518 ** by -div-source.
519 **
 
 
 
 
 
 
 
 
 
 
 
 
 
520 ** -dark Change pikchr colors to assume a dark-mode theme.
521 **
522 **
523 ** The -div-indent/center/left/right flags may not be combined.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
524 */
525 void pikchr_cmd(void){
526 Blob bIn = empty_blob;
527 Blob bOut = empty_blob;
528 const char * zInfile = "-";
529 const char * zOutfile = "-";
 
 
530 int isErr = 0;
531 int pikFlags = find_option("src",0,0)!=0
532 ? PIKCHR_PROCESS_SRC : 0;
 
 
 
 
533
534 if(find_option("div",0,0)!=0){
535 pikFlags |= PIKCHR_PROCESS_DIV;
536 }else if(find_option("div-indent",0,0)!=0){
537 pikFlags |= PIKCHR_PROCESS_DIV_INDENT;
@@ -644,24 +561,14 @@
561 }
562 if(g.argc>3){
563 zOutfile = g.argv[3];
564 }
565 blob_read_from_file(&bIn, zInfile, ExtFILE);
566 isErr = pikchr_process(blob_str(&bIn), pikFlags, &bOut);
 
 
 
 
 
 
 
567 if(isErr){
568 fossil_fatal("pikchr ERROR: %b", &bOut);
 
 
569 }else{
570 blob_write_to_file(&bOut, zOutfile);
571 }
 
572 blob_reset(&bIn);
573 blob_reset(&bOut);
574 }
575
+3 -51
--- src/th_main.c
+++ src/th_main.c
@@ -31,13 +31,11 @@
3131
#define TH_INIT_NEED_CONFIG ((u32)0x00000001) /* Open configuration first? */
3232
#define TH_INIT_FORCE_TCL ((u32)0x00000002) /* Force Tcl to be enabled? */
3333
#define TH_INIT_FORCE_RESET ((u32)0x00000004) /* Force TH1 commands re-added? */
3434
#define TH_INIT_FORCE_SETUP ((u32)0x00000008) /* Force eval of setup script? */
3535
#define TH_INIT_NO_REPO ((u32)0x00000010) /* Skip opening repository. */
36
-#define TH_INIT_NO_ENCODE ((u32)0x00000020) /* Do not html-encode sendText()*/
37
- /* output. */
38
-#define TH_INIT_MASK ((u32)0x0000003F) /* All possible init flags. */
36
+#define TH_INIT_MASK ((u32)0x0000001F) /* All possible init flags. */
3937
4038
/*
4139
** Useful and/or "well-known" combinations of flag values.
4240
*/
4341
#define TH_INIT_DEFAULT (TH_INIT_NONE) /* Default flags. */
@@ -297,50 +295,10 @@
297295
TH1_LEN(argl[1]),argv[1],enableOutput);
298296
}
299297
return rc;
300298
}
301299
302
-/*
303
-** TH1 command: enable_htmlify ?BOOLEAN?
304
-**
305
-** Enable or disable the HTML escaping done by all output which
306
-** originates from TH1 (via sendText()).
307
-**
308
-** If passed no arguments it instead returns 0 or 1 to indicate the
309
-** current state.
310
-*/
311
-static int enableHtmlifyCmd(
312
- Th_Interp *interp,
313
- void *p,
314
- int argc,
315
- const char **argv,
316
- int *argl
317
-){
318
- int rc = 0, buul;
319
- if( argc>3 ){
320
- return Th_WrongNumArgs(interp,
321
- "enable_htmlify [TRACE_LABEL] ?BOOLEAN?");
322
- }
323
- buul = (TH_INIT_NO_ENCODE & g.th1Flags) ? 0 : 1;
324
- Th_SetResultInt(g.interp, buul);
325
- if(argc>1){
326
- if( g.thTrace ){
327
- Th_Trace("enable_htmlify {%.*s} -> %d<br>\n",
328
- TH1_LEN(argl[1]),argv[1],buul);
329
- }
330
- rc = Th_ToInt(interp, argv[argc-1], argl[argc-1], &buul);
331
- if(!rc){
332
- if(buul){
333
- g.th1Flags &= ~TH_INIT_NO_ENCODE;
334
- }else{
335
- g.th1Flags |= TH_INIT_NO_ENCODE;
336
- }
337
- }
338
- }
339
- return rc;
340
-}
341
-
342300
/*
343301
** Returns a name for a TH1 return code.
344302
*/
345303
const char *Th_ReturnCodeName(int rc, int nullIfOk){
346304
static char zRc[32];
@@ -376,23 +334,19 @@
376334
377335
/*
378336
** Send text to the appropriate output: If pOut is not NULL, it is
379337
** appended there, else to the console or to the CGI reply buffer.
380338
** Escape all characters with special meaning to HTML if the encode
381
-** parameter is true, with the exception that that flag is ignored if
382
-** g.th1Flags has the TH_INIT_NO_ENCODE flag.
339
+** parameter is true.
383340
**
384341
** If pOut is NULL and the global pThOut is not then that blob
385342
** is used for output.
386343
*/
387344
static void sendText(Blob *pOut, const char *z, int n, int encode){
388345
if(0==pOut && pThOut!=0){
389346
pOut = pThOut;
390347
}
391
- if(TH_INIT_NO_ENCODE & g.th1Flags){
392
- encode = 0;
393
- }
394348
if( enableOutput && n ){
395349
if( n<0 ){
396350
n = strlen(z);
397351
}else{
398352
n = TH1_LEN(n);
@@ -2429,11 +2383,10 @@
24292383
{"copybtn", copybtnCmd, 0},
24302384
{"date", dateCmd, 0},
24312385
{"decorate", wikiCmd, (void*)&aFlags[2]},
24322386
{"defHeader", defHeaderCmd, 0},
24332387
{"dir", dirCmd, 0},
2434
- {"enable_htmlify",enableHtmlifyCmd, 0},
24352388
{"enable_output", enableOutputCmd, 0},
24362389
{"encode64", encode64Cmd, 0},
24372390
{"getParameter", getParameterCmd, 0},
24382391
{"glob_match", globMatchCmd, 0},
24392392
{"globalState", globalStateCmd, 0},
@@ -3047,12 +3000,11 @@
30473000
** e.g. via the "render" script function binding, need to use the
30483001
** pThOut blob in order to avoid out-of-order output if
30493002
** Th_SetOutputBlob() has been called. If it has not been called,
30503003
** pThOut will be 0, which will redirect the output to CGI/stdout,
30513004
** as appropriate. We need to pass on g.th1Flags for the case of
3052
- ** recursive calls, so that, e.g., TH_INIT_NO_ENCODE does not get
3053
- ** inadvertently toggled off by a recursive call.
3005
+ ** recursive calls.
30543006
*/;
30553007
}
30563008
30573009
/*
30583010
** SETTING: vuln-report width=8 default=log
30593011
--- src/th_main.c
+++ src/th_main.c
@@ -31,13 +31,11 @@
31 #define TH_INIT_NEED_CONFIG ((u32)0x00000001) /* Open configuration first? */
32 #define TH_INIT_FORCE_TCL ((u32)0x00000002) /* Force Tcl to be enabled? */
33 #define TH_INIT_FORCE_RESET ((u32)0x00000004) /* Force TH1 commands re-added? */
34 #define TH_INIT_FORCE_SETUP ((u32)0x00000008) /* Force eval of setup script? */
35 #define TH_INIT_NO_REPO ((u32)0x00000010) /* Skip opening repository. */
36 #define TH_INIT_NO_ENCODE ((u32)0x00000020) /* Do not html-encode sendText()*/
37 /* output. */
38 #define TH_INIT_MASK ((u32)0x0000003F) /* All possible init flags. */
39
40 /*
41 ** Useful and/or "well-known" combinations of flag values.
42 */
43 #define TH_INIT_DEFAULT (TH_INIT_NONE) /* Default flags. */
@@ -297,50 +295,10 @@
297 TH1_LEN(argl[1]),argv[1],enableOutput);
298 }
299 return rc;
300 }
301
302 /*
303 ** TH1 command: enable_htmlify ?BOOLEAN?
304 **
305 ** Enable or disable the HTML escaping done by all output which
306 ** originates from TH1 (via sendText()).
307 **
308 ** If passed no arguments it instead returns 0 or 1 to indicate the
309 ** current state.
310 */
311 static int enableHtmlifyCmd(
312 Th_Interp *interp,
313 void *p,
314 int argc,
315 const char **argv,
316 int *argl
317 ){
318 int rc = 0, buul;
319 if( argc>3 ){
320 return Th_WrongNumArgs(interp,
321 "enable_htmlify [TRACE_LABEL] ?BOOLEAN?");
322 }
323 buul = (TH_INIT_NO_ENCODE & g.th1Flags) ? 0 : 1;
324 Th_SetResultInt(g.interp, buul);
325 if(argc>1){
326 if( g.thTrace ){
327 Th_Trace("enable_htmlify {%.*s} -> %d<br>\n",
328 TH1_LEN(argl[1]),argv[1],buul);
329 }
330 rc = Th_ToInt(interp, argv[argc-1], argl[argc-1], &buul);
331 if(!rc){
332 if(buul){
333 g.th1Flags &= ~TH_INIT_NO_ENCODE;
334 }else{
335 g.th1Flags |= TH_INIT_NO_ENCODE;
336 }
337 }
338 }
339 return rc;
340 }
341
342 /*
343 ** Returns a name for a TH1 return code.
344 */
345 const char *Th_ReturnCodeName(int rc, int nullIfOk){
346 static char zRc[32];
@@ -376,23 +334,19 @@
376
377 /*
378 ** Send text to the appropriate output: If pOut is not NULL, it is
379 ** appended there, else to the console or to the CGI reply buffer.
380 ** Escape all characters with special meaning to HTML if the encode
381 ** parameter is true, with the exception that that flag is ignored if
382 ** g.th1Flags has the TH_INIT_NO_ENCODE flag.
383 **
384 ** If pOut is NULL and the global pThOut is not then that blob
385 ** is used for output.
386 */
387 static void sendText(Blob *pOut, const char *z, int n, int encode){
388 if(0==pOut && pThOut!=0){
389 pOut = pThOut;
390 }
391 if(TH_INIT_NO_ENCODE & g.th1Flags){
392 encode = 0;
393 }
394 if( enableOutput && n ){
395 if( n<0 ){
396 n = strlen(z);
397 }else{
398 n = TH1_LEN(n);
@@ -2429,11 +2383,10 @@
2429 {"copybtn", copybtnCmd, 0},
2430 {"date", dateCmd, 0},
2431 {"decorate", wikiCmd, (void*)&aFlags[2]},
2432 {"defHeader", defHeaderCmd, 0},
2433 {"dir", dirCmd, 0},
2434 {"enable_htmlify",enableHtmlifyCmd, 0},
2435 {"enable_output", enableOutputCmd, 0},
2436 {"encode64", encode64Cmd, 0},
2437 {"getParameter", getParameterCmd, 0},
2438 {"glob_match", globMatchCmd, 0},
2439 {"globalState", globalStateCmd, 0},
@@ -3047,12 +3000,11 @@
3047 ** e.g. via the "render" script function binding, need to use the
3048 ** pThOut blob in order to avoid out-of-order output if
3049 ** Th_SetOutputBlob() has been called. If it has not been called,
3050 ** pThOut will be 0, which will redirect the output to CGI/stdout,
3051 ** as appropriate. We need to pass on g.th1Flags for the case of
3052 ** recursive calls, so that, e.g., TH_INIT_NO_ENCODE does not get
3053 ** inadvertently toggled off by a recursive call.
3054 */;
3055 }
3056
3057 /*
3058 ** SETTING: vuln-report width=8 default=log
3059
--- src/th_main.c
+++ src/th_main.c
@@ -31,13 +31,11 @@
31 #define TH_INIT_NEED_CONFIG ((u32)0x00000001) /* Open configuration first? */
32 #define TH_INIT_FORCE_TCL ((u32)0x00000002) /* Force Tcl to be enabled? */
33 #define TH_INIT_FORCE_RESET ((u32)0x00000004) /* Force TH1 commands re-added? */
34 #define TH_INIT_FORCE_SETUP ((u32)0x00000008) /* Force eval of setup script? */
35 #define TH_INIT_NO_REPO ((u32)0x00000010) /* Skip opening repository. */
36 #define TH_INIT_MASK ((u32)0x0000001F) /* All possible init flags. */
 
 
37
38 /*
39 ** Useful and/or "well-known" combinations of flag values.
40 */
41 #define TH_INIT_DEFAULT (TH_INIT_NONE) /* Default flags. */
@@ -297,50 +295,10 @@
295 TH1_LEN(argl[1]),argv[1],enableOutput);
296 }
297 return rc;
298 }
299
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300 /*
301 ** Returns a name for a TH1 return code.
302 */
303 const char *Th_ReturnCodeName(int rc, int nullIfOk){
304 static char zRc[32];
@@ -376,23 +334,19 @@
334
335 /*
336 ** Send text to the appropriate output: If pOut is not NULL, it is
337 ** appended there, else to the console or to the CGI reply buffer.
338 ** Escape all characters with special meaning to HTML if the encode
339 ** parameter is true.
 
340 **
341 ** If pOut is NULL and the global pThOut is not then that blob
342 ** is used for output.
343 */
344 static void sendText(Blob *pOut, const char *z, int n, int encode){
345 if(0==pOut && pThOut!=0){
346 pOut = pThOut;
347 }
 
 
 
348 if( enableOutput && n ){
349 if( n<0 ){
350 n = strlen(z);
351 }else{
352 n = TH1_LEN(n);
@@ -2429,11 +2383,10 @@
2383 {"copybtn", copybtnCmd, 0},
2384 {"date", dateCmd, 0},
2385 {"decorate", wikiCmd, (void*)&aFlags[2]},
2386 {"defHeader", defHeaderCmd, 0},
2387 {"dir", dirCmd, 0},
 
2388 {"enable_output", enableOutputCmd, 0},
2389 {"encode64", encode64Cmd, 0},
2390 {"getParameter", getParameterCmd, 0},
2391 {"glob_match", globMatchCmd, 0},
2392 {"globalState", globalStateCmd, 0},
@@ -3047,12 +3000,11 @@
3000 ** e.g. via the "render" script function binding, need to use the
3001 ** pThOut blob in order to avoid out-of-order output if
3002 ** Th_SetOutputBlob() has been called. If it has not been called,
3003 ** pThOut will be 0, which will redirect the output to CGI/stdout,
3004 ** as appropriate. We need to pass on g.th1Flags for the case of
3005 ** recursive calls.
 
3006 */;
3007 }
3008
3009 /*
3010 ** SETTING: vuln-report width=8 default=log
3011
+1 -1
--- test/th1.test
+++ test/th1.test
@@ -1061,11 +1061,11 @@
10611061
#fossil test-th-eval "info commands"
10621062
#set sorted_result [lsort $RESULT]
10631063
#protOut "Sorted: $sorted_result"
10641064
#set base_commands {anoncap anycap array artifact break breakpoint \
10651065
# builtin_request_js capexpr captureTh1 catch cgiHeaderLine checkout \
1066
-# combobox continue copybtn date decorate defHeader dir enable_htmlify \
1066
+# combobox continue copybtn date decorate defHeader dir \
10671067
# enable_output encode64 error expr for foreach getParameter glob_match \
10681068
# globalState hascap hasfeature html htmlize http httpize if info \
10691069
# insertCsrf lappend lindex linecount list llength lsearch markdown nonce \
10701070
# proc puts query randhex redirect regexp reinitialize rename render \
10711071
# repository return searchable set setParameter setting stime string \
10721072
--- test/th1.test
+++ test/th1.test
@@ -1061,11 +1061,11 @@
1061 #fossil test-th-eval "info commands"
1062 #set sorted_result [lsort $RESULT]
1063 #protOut "Sorted: $sorted_result"
1064 #set base_commands {anoncap anycap array artifact break breakpoint \
1065 # builtin_request_js capexpr captureTh1 catch cgiHeaderLine checkout \
1066 # combobox continue copybtn date decorate defHeader dir enable_htmlify \
1067 # enable_output encode64 error expr for foreach getParameter glob_match \
1068 # globalState hascap hasfeature html htmlize http httpize if info \
1069 # insertCsrf lappend lindex linecount list llength lsearch markdown nonce \
1070 # proc puts query randhex redirect regexp reinitialize rename render \
1071 # repository return searchable set setParameter setting stime string \
1072
--- test/th1.test
+++ test/th1.test
@@ -1061,11 +1061,11 @@
1061 #fossil test-th-eval "info commands"
1062 #set sorted_result [lsort $RESULT]
1063 #protOut "Sorted: $sorted_result"
1064 #set base_commands {anoncap anycap array artifact break breakpoint \
1065 # builtin_request_js capexpr captureTh1 catch cgiHeaderLine checkout \
1066 # combobox continue copybtn date decorate defHeader dir \
1067 # enable_output encode64 error expr for foreach getParameter glob_match \
1068 # globalState hascap hasfeature html htmlize http httpize if info \
1069 # insertCsrf lappend lindex linecount list llength lsearch markdown nonce \
1070 # proc puts query randhex redirect regexp reinitialize rename render \
1071 # repository return searchable set setParameter setting stime string \
1072
+15 -8
--- www/changes.wiki
+++ www/changes.wiki
@@ -140,18 +140,25 @@
140140
when a user's permissions change.
141141
<li>Show project description on repository list.
142142
<li>Make [/help?cmd=/chat|/chat] better-behaved during server outages, reducing
143143
the frequency of reconnection attempts over time and providing feedback
144144
to the user when the connection is down.
145
- <li>The [/doc/trunk/www/th1.md|TH1 script language] now makes a distinction
146
- between [/doc/trunk/www/th1.md#taint|tainted and untainted string values].
147
- This is a security enhancement that makes it more difficult to write
148
- custom TH1 scripts that contain XSS or SQL-injection bugs. As part of
149
- this enhancement, the [/help?cmd=vuln-report|vuln-report] setting was
150
- added to control what Fossil does when it encounters a potential TH1
151
- security problem.
152
- <li>Diverse minor fixes and additions.
145
+ <li>The [/doc/trunk/www/th1.md|TH1 script language] is enhanced for improved
146
+ security:
147
+ <ol type="a">
148
+ <li> TH1 now makes a distinction between
149
+ [/doc/trunk/www/th1.md#taint|tainted and untainted string values].
150
+ This makes it more difficult to write custom TH1 scripts that
151
+ contain XSS or SQL-injection bugs. The
152
+ [/help?cmd=vuln-report|vuln-report] setting was added to control
153
+ what Fossil does when it encounters a potential TH1
154
+ security problem.
155
+ <li> The "--th" option was removed from the [/help?cmd=pikchr|fossil pikchr]
156
+ command.
157
+ <li> The "enable_htmlify" TH1 command was removed.
158
+ </ol>
159
+ <li>Many other minor fixes and additions.
153160
</ol>
154161
155162
<h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
156163
157164
* The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
158165
--- www/changes.wiki
+++ www/changes.wiki
@@ -140,18 +140,25 @@
140 when a user's permissions change.
141 <li>Show project description on repository list.
142 <li>Make [/help?cmd=/chat|/chat] better-behaved during server outages, reducing
143 the frequency of reconnection attempts over time and providing feedback
144 to the user when the connection is down.
145 <li>The [/doc/trunk/www/th1.md|TH1 script language] now makes a distinction
146 between [/doc/trunk/www/th1.md#taint|tainted and untainted string values].
147 This is a security enhancement that makes it more difficult to write
148 custom TH1 scripts that contain XSS or SQL-injection bugs. As part of
149 this enhancement, the [/help?cmd=vuln-report|vuln-report] setting was
150 added to control what Fossil does when it encounters a potential TH1
151 security problem.
152 <li>Diverse minor fixes and additions.
 
 
 
 
 
 
 
153 </ol>
154
155 <h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
156
157 * The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
158
--- www/changes.wiki
+++ www/changes.wiki
@@ -140,18 +140,25 @@
140 when a user's permissions change.
141 <li>Show project description on repository list.
142 <li>Make [/help?cmd=/chat|/chat] better-behaved during server outages, reducing
143 the frequency of reconnection attempts over time and providing feedback
144 to the user when the connection is down.
145 <li>The [/doc/trunk/www/th1.md|TH1 script language] is enhanced for improved
146 security:
147 <ol type="a">
148 <li> TH1 now makes a distinction between
149 [/doc/trunk/www/th1.md#taint|tainted and untainted string values].
150 This makes it more difficult to write custom TH1 scripts that
151 contain XSS or SQL-injection bugs. The
152 [/help?cmd=vuln-report|vuln-report] setting was added to control
153 what Fossil does when it encounters a potential TH1
154 security problem.
155 <li> The "--th" option was removed from the [/help?cmd=pikchr|fossil pikchr]
156 command.
157 <li> The "enable_htmlify" TH1 command was removed.
158 </ol>
159 <li>Many other minor fixes and additions.
160 </ol>
161
162 <h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
163
164 * The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
165
+15 -8
--- www/changes.wiki
+++ www/changes.wiki
@@ -140,18 +140,25 @@
140140
when a user's permissions change.
141141
<li>Show project description on repository list.
142142
<li>Make [/help?cmd=/chat|/chat] better-behaved during server outages, reducing
143143
the frequency of reconnection attempts over time and providing feedback
144144
to the user when the connection is down.
145
- <li>The [/doc/trunk/www/th1.md|TH1 script language] now makes a distinction
146
- between [/doc/trunk/www/th1.md#taint|tainted and untainted string values].
147
- This is a security enhancement that makes it more difficult to write
148
- custom TH1 scripts that contain XSS or SQL-injection bugs. As part of
149
- this enhancement, the [/help?cmd=vuln-report|vuln-report] setting was
150
- added to control what Fossil does when it encounters a potential TH1
151
- security problem.
152
- <li>Diverse minor fixes and additions.
145
+ <li>The [/doc/trunk/www/th1.md|TH1 script language] is enhanced for improved
146
+ security:
147
+ <ol type="a">
148
+ <li> TH1 now makes a distinction between
149
+ [/doc/trunk/www/th1.md#taint|tainted and untainted string values].
150
+ This makes it more difficult to write custom TH1 scripts that
151
+ contain XSS or SQL-injection bugs. The
152
+ [/help?cmd=vuln-report|vuln-report] setting was added to control
153
+ what Fossil does when it encounters a potential TH1
154
+ security problem.
155
+ <li> The "--th" option was removed from the [/help?cmd=pikchr|fossil pikchr]
156
+ command.
157
+ <li> The "enable_htmlify" TH1 command was removed.
158
+ </ol>
159
+ <li>Many other minor fixes and additions.
153160
</ol>
154161
155162
<h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
156163
157164
* The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
158165
--- www/changes.wiki
+++ www/changes.wiki
@@ -140,18 +140,25 @@
140 when a user's permissions change.
141 <li>Show project description on repository list.
142 <li>Make [/help?cmd=/chat|/chat] better-behaved during server outages, reducing
143 the frequency of reconnection attempts over time and providing feedback
144 to the user when the connection is down.
145 <li>The [/doc/trunk/www/th1.md|TH1 script language] now makes a distinction
146 between [/doc/trunk/www/th1.md#taint|tainted and untainted string values].
147 This is a security enhancement that makes it more difficult to write
148 custom TH1 scripts that contain XSS or SQL-injection bugs. As part of
149 this enhancement, the [/help?cmd=vuln-report|vuln-report] setting was
150 added to control what Fossil does when it encounters a potential TH1
151 security problem.
152 <li>Diverse minor fixes and additions.
 
 
 
 
 
 
 
153 </ol>
154
155 <h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
156
157 * The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
158
--- www/changes.wiki
+++ www/changes.wiki
@@ -140,18 +140,25 @@
140 when a user's permissions change.
141 <li>Show project description on repository list.
142 <li>Make [/help?cmd=/chat|/chat] better-behaved during server outages, reducing
143 the frequency of reconnection attempts over time and providing feedback
144 to the user when the connection is down.
145 <li>The [/doc/trunk/www/th1.md|TH1 script language] is enhanced for improved
146 security:
147 <ol type="a">
148 <li> TH1 now makes a distinction between
149 [/doc/trunk/www/th1.md#taint|tainted and untainted string values].
150 This makes it more difficult to write custom TH1 scripts that
151 contain XSS or SQL-injection bugs. The
152 [/help?cmd=vuln-report|vuln-report] setting was added to control
153 what Fossil does when it encounters a potential TH1
154 security problem.
155 <li> The "--th" option was removed from the [/help?cmd=pikchr|fossil pikchr]
156 command.
157 <li> The "enable_htmlify" TH1 command was removed.
158 </ol>
159 <li>Many other minor fixes and additions.
160 </ol>
161
162 <h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
163
164 * The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
165
-18
--- www/th1.md
+++ www/th1.md
@@ -224,11 +224,10 @@
224224
* [copybtn](#copybtn)
225225
* [date](#date)
226226
* [decorate](#decorate)
227227
* [defHeader](#defHeader)
228228
* [dir](#dir)
229
- * [enable\_htmlify](#enable_htmlify)
230229
* [enable\_output](#enable_output)
231230
* [encode64](#encode64)
232231
* [getParameter](#getParameter)
233232
* [glob\_match](#glob_match)
234233
* [globalState](#globalState)
@@ -457,28 +456,10 @@
457456
the files matching the pattern GLOB within CHECKIN will be returned.
458457
If DETAILS is non-zero, the result will be a list-of-lists, with each
459458
element containing at least three elements: the file name, the file
460459
size (in bytes), and the file last modification time (relative to the
461460
time zone configured for the repository).
462
-
463
-<a id="enable_htmlify"></a>TH1 enable\_htmlify Command
-------------------------------------------------------
464
-
465
- * enable\_htmlify
466
- * enable\_htmlify ?TRACE-LABEL? BOOLEAN
467
-
468
-By default, certain output from `puts` and similar commands is escaped
469
-for HTML. The first call form returns the current state of that
470
-feature: `1` for on and `0` for off. The second call form enables
471
-(non-0) or disables (0) that feature and returns the *pre-call* state
472
-of that feature (so that a second call can pass that value to restore
473
-it to its previous state). The optional `TRACE-LABEL` argument causes
474
-the TH1 tracing output (if enabled) to add a marker when the second
475
-form of this command is invoked, and includes that label and the
476
-boolean argument's value in the trace. If tracing is disabled, that
477
-argument has no effect.
478
-
479461
480462
<a id="enable_output"></a>TH1 enable\_output Command
481463
------------------------------------------------------
482464
483465
* enable\_output BOOLEAN
484466
--- www/th1.md
+++ www/th1.md
@@ -224,11 +224,10 @@
224 * [copybtn](#copybtn)
225 * [date](#date)
226 * [decorate](#decorate)
227 * [defHeader](#defHeader)
228 * [dir](#dir)
229 * [enable\_htmlify](#enable_htmlify)
230 * [enable\_output](#enable_output)
231 * [encode64](#encode64)
232 * [getParameter](#getParameter)
233 * [glob\_match](#glob_match)
234 * [globalState](#globalState)
@@ -457,28 +456,10 @@
457 the files matching the pattern GLOB within CHECKIN will be returned.
458 If DETAILS is non-zero, the result will be a list-of-lists, with each
459 element containing at least three elements: the file name, the file
460 size (in bytes), and the file last modification time (relative to the
461 time zone configured for the repository).
462
463 <a id="enable_htmlify"></a>TH1 enable\_htmlify Command
-------------------------------------------------------
464
465 * enable\_htmlify
466 * enable\_htmlify ?TRACE-LABEL? BOOLEAN
467
468 By default, certain output from `puts` and similar commands is escaped
469 for HTML. The first call form returns the current state of that
470 feature: `1` for on and `0` for off. The second call form enables
471 (non-0) or disables (0) that feature and returns the *pre-call* state
472 of that feature (so that a second call can pass that value to restore
473 it to its previous state). The optional `TRACE-LABEL` argument causes
474 the TH1 tracing output (if enabled) to add a marker when the second
475 form of this command is invoked, and includes that label and the
476 boolean argument's value in the trace. If tracing is disabled, that
477 argument has no effect.
478
479
480 <a id="enable_output"></a>TH1 enable\_output Command
481 ------------------------------------------------------
482
483 * enable\_output BOOLEAN
484
--- www/th1.md
+++ www/th1.md
@@ -224,11 +224,10 @@
224 * [copybtn](#copybtn)
225 * [date](#date)
226 * [decorate](#decorate)
227 * [defHeader](#defHeader)
228 * [dir](#dir)
 
229 * [enable\_output](#enable_output)
230 * [encode64](#encode64)
231 * [getParameter](#getParameter)
232 * [glob\_match](#glob_match)
233 * [globalState](#globalState)
@@ -457,28 +456,10 @@
456 the files matching the pattern GLOB within CHECKIN will be returned.
457 If DETAILS is non-zero, the result will be a list-of-lists, with each
458 element containing at least three elements: the file name, the file
459 size (in bytes), and the file last modification time (relative to the
460 time zone configured for the repository).
 
 
-------------------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
462 <a id="enable_output"></a>TH1 enable\_output Command
463 ------------------------------------------------------
464
465 * enable\_output BOOLEAN
466

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button