Fossil SCM

fossil-scm / www / th1.md
1
TH1 Scripts
2
===========
3
4
TH1 is a very small scripting language used to help generate web-page
5
content in Fossil.
6
7
Origins
8
-------
9
10
TH1 began as a minimalist re-implementation of the Tcl scripting language.
11
There was a need to test the SQLite library on Symbian phones, but at that
12
time all of the test cases for SQLite were written in Tcl and Tcl could not
13
be easily compiled on the SymbianOS. So TH1 was developed as a cut-down
14
version of Tcl that would facilitate running the SQLite test scripts on
15
SymbianOS.
16
17
Fossil was first being designed at about the same time.
18
Early prototypes of Fossil were written in pure Tcl. But as the development
19
shifted toward the use of C-code, the need arose to have a Tcl-like
20
scripting language to help with code generation. TH1 was small and
21
light-weight and used minimal resources and seemed ideally suited for the
22
task.
23
24
The name "TH1" stands for "Test Harness 1",
25
since its original purpose was to serve as testing harness
26
for SQLite.
27
28
Where TH1 Is Used In Fossil
29
---------------------------
30
31
* In the header and footer for [skins](./customskin.md)
32
text within `<th1>...</th1>` is run as a TH1 script.
33
([example](/builtin/skins/default/header.txt))
34
35
* This display of [tickets](./bugtheory.wiki) is controlled by TH1
36
scripts, so that the ticket format can be customized for each
37
project. Administrators can visit the <b>/tktsetup</b> page in
38
their repositories to view and customize these scripts.
39
([example usage](./custom_ticket.wiki))
40
41
Overview Of The Tcl/TH1 Language
42
--------------------------------
43
44
TH1 is a string-processing language. All values are strings. Any numerical
45
operations are accomplished by converting from string to numeric, performing
46
the computation, then converting the result back into a string. (This might
47
seem inefficient, but it is faster than people imagine, and numeric
48
computations do not come up very often for the kinds of work that TH1 does,
49
so it has never been an issue.)
50
51
A TH1 script consists of a sequence of commands.
52
Each command is terminated by the first *unescaped* newline or ";" character.
53
The text of the command (excluding the newline or semicolon terminator)
54
is broken into space-separated tokens. The first token is the command
55
name and subsequent tokens are the arguments. In this sense, TH1 syntax
56
is similar to the familiar command-line shell syntax.
57
58
A token is any sequence of characters other than whitespace and semicolons.
59
Text inside double-quotes is a single token even if it includes
60
whitespace and semicolons. Text within {...} pairs is also a
61
single token, which is useful because curly braces are easier to “pair”
62
and nest properly than double-quotes.
63
64
The nested {...} form of tokens is important because it allows TH1 commands
65
to have an appearance similar to C/C++. It is important to remember, though,
66
that a TH1 script is really just a list of text commands, not a context-free
67
language with a grammar like C/C++. This can be confusing to long-time
68
C/C++ programmers because TH1 does look a lot like C/C++, but the semantics
69
of TH1 are closer to FORTH or Lisp than they are to C.
70
71
Consider the `if` command in TH1.
72
73
if {$current eq "dev"} {
74
puts "hello"
75
} else {
76
puts "world"
77
}
78
79
The example above is a single command. The first token, and the name
80
of the command, is `if`.
81
The second token is `$current eq "dev"` - an expression. (The outer {...}
82
are removed from each token by the command parser.) The third token
83
is the `puts "hello"`, with its whitespace and newlines. The fourth token
84
is `else` and the fifth and last token is `puts "world"`.
85
86
The `if` command evaluates its first argument (the second token)
87
as an expression, and if that expression is true, it evaluates its
88
second argument (the third token) as a TH1 script.
89
If the expression is false and the third argument is `else`, then
90
the fourth argument is evaluated as a TH1 expression.
91
92
So, you see, even though the example above spans five lines, it is really
93
just a single command.
94
95
All of this also explains the emphasis on *unescaped* characters above:
96
the curly braces `{ }` are string quoting characters in Tcl/TH1, not
97
block delimiters as in C. This is how we can have a command that extends
98
over multiple lines. It is also why the `else` keyword must be cuddled
99
up with the closing brace for the `if` clause's scriptlet. The following
100
is invalid Tcl/TH1:
101
102
if {$current eq "dev"} {
103
puts "hello"
104
}
105
else {
106
puts "world"
107
}
108
109
If you try to run this under either Tcl or TH1, the interpreter will
110
tell you that there is no `else` command, because with the newline on
111
the third line, you terminated the `if` command.
112
113
Occasionally in Tcl/TH1 scripts, you may need to use a backslash at the
114
end of a line to allow a command to extend over multiple lines without
115
being considered two separate commands. Here's an example from one of
116
Fossil's test scripts:
117
118
return [lindex [regexp -line -inline -nocase -- \
119
{^uuid:\s+([0-9A-F]{40}) } [eval [getFossilCommand \
120
$repository "" info trunk]]] end]
121
122
Those backslashes allow the command to wrap nicely within a standard
123
terminal width while telling the interpreter to consider those three
124
lines as a single command.
125
126
<a id="taint"></a>Tainted And Untainted Strings
127
-----------------------------------------------
128
129
Beginning with Fossil version 2.26 (circa 2025), TH1 distinguishes between
130
"tainted" and "untainted" strings. Tainted strings are strings that are
131
derived from user inputs that might contain text that is designed to subvert
132
the script. Untainted strings are known to come from secure sources and
133
are assumed to contain no malicious content.
134
135
Beginning with Fossil version 2.26, and depending on the value of the
136
[vuln-report setting](/help/vuln-report), TH1 will prevent tainted
137
strings from being used in ways that might lead to XSS or SQL-injection
138
attacks. This feature helps to ensure that XSS and SQL-injection
139
vulnerabilities are not *accidentally* added to Fossil when
140
custom TH1 scripts for headers or footers or tickets are added to a
141
repository. Note that the tainted/untainted distinction in strings does
142
not make it impossible to introduce XSS and SQL-injections vulnerabilities
143
using poorly-written TH1 scripts; it just makes it more difficult and
144
less likely to happen by accident. Developers must still consider the
145
security implications of TH1 customizations they add to Fossil, and take
146
appropriate precautions when writing custom TH1. Peer review of TH1
147
script changes is encouraged.
148
149
In Fossil version 2.26, if the vuln-report setting is set to "block"
150
or "fatal", the [html](#html) and [query](#query) TH1 commands will
151
fail with an error if their argument is a tainted string. This helps
152
to prevent XSS and SQL-injection attacks, respectively. Note that
153
the default value of the vuln-report setting is "log", which allows those
154
commands to continue working and only writes a warning message into the
155
error log. <b>Future versions of Fossil may change the default value
156
of the vuln-report setting to "block" or "fatal".</b> Fossil users
157
with customized TH1 scripts are encouraged to audit their customizations
158
and fix any potential vulnerabilities soon, so as to avoid breakage
159
caused by future upgrades. <b>Future versions of Fossil might also
160
place additional restrictions on the use of tainted strings.</b>
161
For example, it is likely that future versions of Fossil will disallow
162
using tainted strings as script, for example as the body of a "for"
163
loop or of a "proc".
164
165
166
Summary of Core TH1 Commands
167
----------------------------
168
169
The original Tcl language (after which TH1 is modeled) has a very rich
170
repertoire of commands. TH1, as it is designed to be minimalist and
171
embedded has a greatly reduced command set. The following bullets
172
summarize the commands available in TH1:
173
174
* array exists VARNAME
175
* array names VARNAME
176
* break
177
* catch SCRIPT ?VARIABLE?
178
* continue
179
* error ?STRING?
180
* expr EXPR
181
* for INIT-SCRIPT TEST-EXPR NEXT-SCRIPT BODY-SCRIPT
182
* foreach VARIABLE-LIST VALUE-LIST BODY-SCRIPT
183
* if EXPR SCRIPT (elseif EXPR SCRIPT)* ?else SCRIPT?
184
* info commands
185
* info exists VARNAME
186
* info vars
187
* lappend VARIABLE TERM ...
188
* lindex LIST INDEX
189
* list ARG ...
190
* llength LIST
191
* lsearch LIST STRING
192
* proc NAME ARG-LIST BODY-SCRIPT
193
* rename OLD NEW
194
* return ?-code CODE? ?VALUE?
195
* set VARNAME VALUE
196
* string compare STR1 STR2
197
* string first NEEDLE HAYSTACK ?START-INDEX?
198
* string index STRING INDEX
199
* string is CLASS STRING
200
* string last NEEDLE HAYSTACK ?START-INDEX?
201
* string match PATTERN STRING
202
* string length STRING
203
* string range STRING FIRST LAST
204
* string repeat STRING COUNT
205
* string trim STRING
206
* string trimleft STRING
207
* string trimright STRING
208
* unset VARNAME
209
* uplevel ?LEVEL? SCRIPT
210
* upvar ?FRAME? OTHERVAR MYVAR ?OTHERVAR MYVAR?
211
212
All of the above commands work as in the original Tcl. Refer to the
213
<a href="https://www.tcl-lang.org/man/tcl/contents.htm">Tcl documentation</a>
214
for details.
215
216
Summary of Core TH1 Variables
217
-----------------------------
218
219
* tcl\_platform(engine) -- _This will always have the value "TH1"._
220
* tcl\_platform(platform) -- _This will have the value "windows" or "unix"._
221
* th\_stack\_trace -- _This will contain error stack information._
222
223
TH1 Extended Commands
224
---------------------
225
226
There are many new commands added to TH1 and used to access the special
227
features of Fossil. The following is a summary of the extended commands:
228
229
* [anoncap](#anoncap)
230
* [anycap](#anycap)
231
* [artifact](#artifact)
232
* [builtin_request_js](#bireqjs)
233
* [capexpr](#capexpr)
234
* [captureTh1](#captureTh1)
235
* [cgiHeaderLine](#cgiHeaderLine)
236
* [checkout](#checkout)
237
* [combobox](#combobox)
238
* [copybtn](#copybtn)
239
* [date](#date)
240
* [decorate](#decorate)
241
* [defHeader](#defHeader)
242
* [dir](#dir)
243
* [enable\_output](#enable_output)
244
* [encode64](#encode64)
245
* [getParameter](#getParameter)
246
* [glob\_match](#glob_match)
247
* [globalState](#globalState)
248
* [hascap](#hascap)
249
* [hasfeature](#hasfeature)
250
* [html](#html)
251
* [htmlize](#htmlize)
252
* [http](#http)
253
* [httpize](#httpize)
254
* [insertCsrf](#insertCsrf)
255
* [linecount](#linecount)
256
* [markdown](#markdown)
257
* [nonce](#nonce)
258
* [puts](#puts)
259
* [query](#query)
260
* [randhex](#randhex)
261
* [redirect](#redirect)
262
* [regexp](#regexp)
263
* [reinitialize](#reinitialize)
264
* [render](#render)
265
* [repository](#repository)
266
* [searchable](#searchable)
267
* [setParameter](#setParameter)
268
* [setting](#setting)
269
* [stime](#stime)
270
* [styleHeader](#styleHeader)
271
* [styleFooter](#styleFooter)
272
* [styleScript](#styleScript)
273
* [submenu](#submenu)
274
* [taint](#taintCmd)
275
* [tclEval](#tclEval)
276
* [tclExpr](#tclExpr)
277
* [tclInvoke](#tclInvoke)
278
* [tclIsSafe](#tclIsSafe)
279
* [tclMakeSafe](#tclMakeSafe)
280
* [tclReady](#tclReady)
281
* [trace](#trace)
282
* [untaint](#untaintCmd)
283
* [unversioned content](#unversioned_content)
284
* [unversioned list](#unversioned_list)
285
* [utime](#utime)
286
* [verifyCsrf](#verifyCsrf)
287
* [verifyLogin](#verifyLogin)
288
* [wiki](#wiki)
289
* [wiki_assoc](#wiki_assoc)
290
291
Each of the commands above is documented by a block comment above their
292
implementation in the th\_main.c or th\_tcl.c source files.
293
294
All commands starting with "tcl", with the exception of "tclReady",
295
require the Tcl integration subsystem be included at compile-time.
296
Additionally, the "tcl" repository setting must be enabled at runtime
297
in order to successfully make use of these commands.
298
299
<a id="anoncap"></a>TH1 anoncap Command
300
-----------------------------------------
301
302
Deprecated: prefer [capexpr](#capexpr) instead.
303
304
* anoncap STRING...
305
306
Returns true if the anonymous user has all of the capabilities listed
307
in STRING.
308
309
<a id="anycap"></a>TH1 anycap Command
310
---------------------------------------
311
312
Deprecated: prefer [capexpr](#capexpr) instead.
313
314
* anycap STRING
315
316
Returns true if the current user user has any one of the capabilities
317
listed in STRING.
318
319
<a id="artifact"></a>TH1 artifact Command
320
-------------------------------------------
321
322
* artifact ID ?FILENAME?
323
324
Attempts to locate the specified artifact and return its contents. An
325
error is generated if the repository is not open or the artifact cannot
326
be found.
327
328
329
<a id="bireqjs"></a>TH1 builtin_request_js Command
330
--------------------------------------------------
331
332
* builtin_request_js NAME
333
334
NAME must be the name of one of the
335
[built-in javascript source files](/dir?ci=trunk&type=flat&name=src&re=js$).
336
This command causes that javascript file to be appended to the delivered
337
document.
338
339
340
341
<a id="capexpr"></a>TH1 capexpr Command
342
-----------------------------------------------------
343
344
* capexpr CAPABILITY-EXPR
345
346
The capability expression is a list. Each term of the list is a
347
cluster of [capability letters](./caps/ref.html).
348
The overall expression is true if any
349
one term is true. A single term is true if all letters within that
350
term are true. Or, if the term begins with "!", then the term is true
351
if none of the terms are true. Or, if the term begins with "@" then
352
the term is true if all of the capability letters in that term are
353
available to the "anonymous" user. Or, if the term is "*" then it is
354
always true.
355
356
Examples:
357
358
```
359
capexpr {j o r} True if any one of j, o, or r are available
360
capexpr {oh} True if both o and h are available
361
capexpr {@2 @3 4 5 6} 2 or 3 available for anonymous or one of
362
4, 5 or 6 is available for the user
363
capexpr L True if the user is logged in
364
capexpr !L True if the user is not logged in
365
```
366
367
The `L` pseudo-capability is intended only to be used on its own or with
368
the `!` prefix for implementing login/logout menus via the `mainmenu`
369
site configuration option:
370
371
```
372
Login /login !L {}
373
Logout /logout L {}
374
```
375
376
i.e. if the user is logged in, show the "Logout" link, else show the
377
"Login" link.
378
379
<a id="captureTh1"></a>TH1 captureTh1 Command
380
-----------------------------------------------------
381
382
* captureTh1 STRING
383
384
Executes its single argument as TH1 code and captures any
385
TH1-generated output as a string, which becomes the result of the
386
function call. e.g. any `puts` calls made from that block will not
387
generate any output, and instead their output will become part of the
388
result string.
389
390
391
<a id="cgiHeaderLine"></a>TH1 cgiHeaderLine Command
392
-----------------------------------------------------
393
394
* cgiHeaderLine line
395
396
Adds the specified line to the CGI header.
397
398
<a id="checkout"></a>TH1 checkout Command
399
-------------------------------------------
400
401
* checkout ?BOOLEAN?
402
403
Return the fully qualified directory name of the current checkout or an
404
empty string if it is not available. Optionally, it will attempt to find
405
the current checkout, opening the configuration ("user") database and the
406
repository as necessary, if the boolean argument is non-zero.
407
408
<a id="combobox"></a>TH1 combobox Command
409
-------------------------------------------
410
411
* combobox NAME TEXT-LIST NUMLINES
412
413
Generates and emits an HTML combobox. NAME is both the name of the
414
CGI parameter and the name of a variable that contains the currently
415
selected value. TEXT-LIST is a list of possible values for the
416
combobox. NUMLINES is 1 for a true combobox. If NUMLINES is greater
417
than one then the display is a listbox with the number of lines given.
418
419
<a id="copybtn"></a>TH1 copybtn Command
420
-----------------------------------------
421
422
* copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?
423
424
Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
425
Javascript module, and generates HTML elements with the following IDs:
426
427
* TARGETID: The `<span>` wrapper around TEXT.
428
* copy-TARGETID: The `<span>` for the copy button.
429
430
If the FLIPPED argument is non-zero, the copy button is displayed after TEXT.
431
432
The optional COPYLENGTH argument defines the length of the substring of TEXT
433
copied to clipboard:
434
435
* <= 0: No limit (default if the argument is omitted).
436
* >= 3: Truncate TEXT after COPYLENGTH (single-byte) characters.
437
* 1: Use the "hash-digits" setting as the limit.
438
* 2: Use the length appropriate for URLs as the limit (defined at
439
compile-time by `FOSSIL_HASH_DIGITS_URL`, defaults to 16).
440
441
<a id="date"></a>TH1 date Command
442
-----------------------------------
443
444
* date ?-local?
445
446
Return a string which is the current time and date. If the -local
447
option is used, the date appears using localtime instead of UTC.
448
449
<a id="decorate"></a>TH1 decorate Command
450
-------------------------------------------
451
452
* decorate STRING
453
454
Renders STRING as wiki content; however, only links are handled. No
455
other markup is processed.
456
457
<a id="defHeader"></a>TH1 defHeader Command
458
---------------------------------------------
459
460
* defHeader
461
462
Returns the default page header.
463
464
<a id="dir"></a>TH1 dir Command
465
---------------------------------
466
467
* dir CHECKIN ?GLOB? ?DETAILS?
468
469
Returns a list containing all files in CHECKIN. If GLOB is given only
470
the files matching the pattern GLOB within CHECKIN will be returned.
471
If DETAILS is non-zero, the result will be a list-of-lists, with each
472
element containing at least three elements: the file name, the file
473
size (in bytes), and the file last modification time (relative to the
474
time zone configured for the repository).
475
476
<a id="enable_output"></a>TH1 enable\_output Command
477
------------------------------------------------------
478
479
* enable\_output BOOLEAN
480
481
Enable or disable sending output when the combobox, copybtn, puts, or wiki
482
commands are used.
483
484
<a id="encode64"></a>TH1 encode64 Command
485
-------------------------------------------
486
487
* encode64 STRING
488
489
Encode the specified string using Base64 and return the result.
490
491
<a id="getParameter"></a>TH1 getParameter Command
492
---------------------------------------------------
493
494
* getParameter NAME ?DEFAULT?
495
496
Returns the value of the specified query parameter or the specified
497
default value when there is no matching query parameter.
498
499
<a id="glob_match"></a>TH1 glob\_match Command
500
------------------------------------------------
501
502
* glob\_match ?-one? ?--? patternList string
503
504
Checks the string against the specified glob pattern -OR- list of glob
505
patterns and returns non-zero if there is a match.
506
507
<a id="globalState"></a>TH1 globalState Command
508
-------------------------------------------------
509
510
* globalState NAME ?DEFAULT?
511
512
Returns a string containing the value of the specified global state
513
variable -OR- the specified default value. The supported items are:
514
515
1. **checkout** -- _Active local checkout directory, if any._
516
1. **configuration** -- _Active configuration database file name, if any._
517
1. **executable** -- _Fully qualified executable file name._
518
1. **flags** -- _TH1 initialization flags._
519
1. **log** -- _Error log file name, if any._
520
1. **repository** -- _Active local repository file name, if any._
521
1. **top** -- _Base path for the active server instance, if applicable._
522
1. **user** -- _Active user name, if any._
523
1. **vfs** -- _SQLite VFS in use, if overridden._
524
525
Attempts to query for unsupported global state variables will result
526
in a script error. Additional global state variables may be exposed
527
in the future.
528
529
<a id="hascap"></a>TH1 hascap Command
530
---------------------------------------
531
532
Deprecated: prefer [capexpr](#capexpr) instead.
533
534
* hascap STRING...
535
536
Returns true if the current user has all of the capabilities listed
537
in STRING.
538
539
<a id="hasfeature"></a>TH1 hasfeature Command
540
-----------------------------------------------
541
542
* hasfeature STRING
543
544
Returns true if the binary has the given compile-time feature enabled.
545
The possible features are:
546
547
1. **ssl** -- _Support for the HTTPS transport._
548
1. **legacyMvRm** -- _Support for legacy mv/rm command behavior._
549
1. **execRelPaths** -- _Use relative paths with external diff/gdiff._
550
1. **th1Docs** -- _Support for TH1 in embedded documentation._
551
1. **th1Hooks** -- _Support for TH1 command and web page hooks._
552
1. **tcl** -- _Support for Tcl integration._
553
1. **useTclStubs** -- _Tcl stubs enabled in the Tcl headers._
554
1. **tclStubs** -- _Uses Tcl stubs (i.e. linking with stubs library)._
555
1. **tclPrivateStubs** -- _Uses Tcl private stubs (i.e. header-only)._
556
1. **json** -- _Support for the JSON APIs._
557
1. **markdown** -- _Support for Markdown documentation format._
558
1. **unicodeCmdLine** -- _The command line arguments are Unicode._
559
1. **dynamicBuild** -- _Dynamically linked to libraries._
560
1. **mman** -- _Uses POSIX memory APIs from "sys/mman.h"._
561
1. **see** -- _Uses the SQLite Encryption Extension._
562
563
Specifying an unknown feature will return a value of false, it will not
564
raise a script error.
565
566
<a id="html"></a>TH1 html Command
567
-----------------------------------
568
569
* html STRING
570
571
Outputs the STRING literally. It is assumed that STRING contains
572
valid HTML, or that if STRING contains any characters that are
573
significant to HTML (such as `<`, `>`, `'`, or `&`) have already
574
been escaped, perhaps by the [htmlize](#htmlize) command. Use the
575
[puts](#puts) command to output text that might contain unescaped
576
HTML markup.
577
578
**Beware of XSS attacks!** If the STRING value to the html command
579
can be controlled by a hostile user, then he might be able to sneak
580
in malicious HTML or Javascript which could result in a
581
cross-site scripting (XSS) attack. Be careful that all text that
582
in STRING that might come from user input has been sanitized by the
583
[htmlize](#htmlize) command or similar. In recent versions of Fossil,
584
the STRING value must be [untainted](#taint) or else the "html" command
585
will fail.
586
587
<a id="htmlize"></a>TH1 htmlize Command
588
-----------------------------------------
589
590
* htmlize STRING
591
592
Escape all characters of STRING which have special meaning in HTML.
593
Returns the escaped string.
594
595
<a id="http"></a>TH1 http Command
596
-----------------------------------
597
598
* http ?-asynchronous? ?--? url ?payload?
599
600
Performs an HTTP or HTTPS request for the specified URL. If a
601
payload is present, it will be interpreted as text/plain and
602
the POST method will be used; otherwise, the GET method will
603
be used. Upon success, if the -asynchronous option is used, an
604
empty string is returned as the result; otherwise, the response
605
from the server is returned as the result. Synchronous requests
606
are not currently implemented.
607
608
<a id="httpize"></a>TH1 httpize Command
609
-----------------------------------------
610
611
* httpize STRING
612
613
Escape all characters of STRING which have special meaning in URI
614
components. Returns the escaped string.
615
616
<a id="insertCsrf"></a>TH1 insertCsrf Command
617
-----------------------------------------------
618
619
* insertCsrf
620
621
While rendering a form, call this command to add the Anti-CSRF token
622
as a hidden element of the form.
623
624
<a id="linecount"></a>TH1 linecount Command
625
---------------------------------------------
626
627
* linecount STRING MAX MIN
628
629
Returns one more than the number of `\n` characters in STRING. But
630
never returns less than MIN or more than MAX.
631
632
<a id="markdown"></a>TH1 markdown Command
633
-------------------------------------------
634
635
* markdown STRING
636
637
Renders the input string as markdown. The result is a two-element list.
638
The first element contains the body, rendered as HTML. The second element
639
is the text-only title string.
640
641
<a id="nonce"></a>TH1 nonce Command
642
-------------------------------------
643
644
* nonce
645
646
Returns the value of the cryptographic nonce for the request being processed.
647
648
<a id="puts"></a>TH1 puts Command
649
-----------------------------------
650
651
* puts STRING
652
653
Outputs STRING. Characters within STRING that have special meaning
654
in HTML are escaped prior to being output. Thus is it safe for STRING
655
to be derived from user inputs. See also the [html](#html) command
656
which behaves similarly except does not escape HTML markup. This
657
command ("puts") is safe to use on [tainted strings](#taint), but the "html"
658
command is not.
659
660
<a id="query"></a>TH1 query Command
661
-------------------------------------
662
663
* query ?-nocomplain? SQL CODE
664
665
Runs the SQL query given by the SQL argument. For each row in the result
666
set, run CODE.
667
668
In SQL, parameters such as $var are filled in using the value of variable
669
"var". Result values are stored in variables with the column name prior
670
to each invocation of CODE. The names of the variables in which results
671
are stored can be controlled using "AS name" clauses in the SQL. As
672
the database will often contain content that originates from untrusted
673
users, all result values are marked as [tainted](#taint).
674
675
**Beware of SQL injections in the `query` command!**
676
The SQL argument to the query command should always be literal SQL
677
text enclosed in {...}. The SQL argument should never be a double-quoted
678
string or the value of a \$variable, as those constructs can lead to
679
an SQL Injection attack. If you need to include the values of one or
680
more TH1 variables as part of the SQL, then put \$variable inside the
681
{...}. The \$variable keyword will then get passed down into the SQLite
682
parser which knows to look up the value of \$variable in the TH1 symbol
683
table. For example:
684
685
~~~
686
query {SELECT res FROM tab1 WHERE key=$mykey} {...}
687
~~~
688
689
SQLite will see the \$mykey token in the SQL and will know to resolve it
690
to the value of the "mykey" TH1 variable, safely and without the possibility
691
of SQL injection. The following is unsafe:
692
693
~~~
694
query "SELECT res FROM tab1 WHERE key='$mykey'" {...} ;# <-- UNSAFE!
695
~~~
696
697
In this second example, TH1 does the expansion of `$mykey` prior to passing
698
the text down into SQLite. So if `$mykey` contains a single-quote character,
699
followed by additional hostile text, that will result in an SQL injection.
700
701
To help guard against SQL-injections, recent versions of Fossil require
702
that the SQL argument be [untainted](#taint) or else the "query" command
703
will fail.
704
705
<a id="randhex"></a>TH1 randhex Command
706
-----------------------------------------
707
708
* randhex N
709
710
Returns a string of N*2 random hexadecimal digits with N<50. If N is
711
omitted, use a value of 10.
712
713
<a id="redirect"></a>TH1 redirect Command
714
-------------------------------------------
715
716
* redirect URL ?withMethod?
717
718
Issues an HTTP redirect to the specified URL and then exits the process.
719
By default, an HTTP status code of 302 is used. If the optional withMethod
720
argument is present and non-zero, an HTTP status code of 307 is used, which
721
should force the user agent to preserve the original method for the request
722
(e.g. GET, POST) instead of (possibly) forcing the user agent to change the
723
method to GET.
724
725
<a id="regexp"></a>TH1 regexp Command
726
---------------------------------------
727
728
* regexp ?-nocase? ?--? exp string
729
730
Checks the string against the specified regular expression and returns
731
non-zero if it matches. If the regular expression is invalid or cannot
732
be compiled, an error will be generated.
733
734
See [fossil grep](./grep.md) for details on the regexp syntax.
735
736
<a id="reinitialize"></a>TH1 reinitialize Command
737
---------------------------------------------------
738
739
* reinitialize ?FLAGS?
740
741
Reinitializes the TH1 interpreter using the specified flags.
742
743
<a id="render"></a>TH1 render Command
744
---------------------------------------
745
746
* render STRING
747
748
Renders the TH1 template and writes the results.
749
750
<a id="repository"></a>TH1 repository Command
751
-----------------------------------------------
752
753
* repository ?BOOLEAN?
754
755
Returns the fully qualified file name of the open repository or an empty
756
string if one is not currently open. Optionally, it will attempt to open
757
the repository if the boolean argument is non-zero.
758
759
<a id="searchable"></a>TH1 searchable Command
760
-----------------------------------------------
761
762
* searchable STRING...
763
764
Return true if searching in any of the document classes identified
765
by STRING is enabled for the repository and user has the necessary
766
capabilities to perform the search. The possible document classes
767
are:
768
769
1. **c** -- _Check-in comments_
770
1. **d** -- _Embedded documentation_
771
1. **t** -- _Tickets_
772
1. **w** -- _Wiki_
773
774
To be clear, only one of the document classes identified by each STRING
775
needs to be searchable in order for that argument to be true. But all
776
arguments must be true for this routine to return true. Hence, to see
777
if ALL document classes are searchable:
778
779
if {[searchable c d t w]} {...}
780
781
But to see if ANY document class is searchable:
782
783
if {[searchable cdtw]} {...}
784
785
This command is useful for enabling or disabling a "Search" entry on the
786
menu bar.
787
788
<a id="setParameter"></a>TH1 setParameter Command
789
---------------------------------------------------
790
791
* setParameter NAME VALUE
792
793
Sets the value of the specified query parameter.
794
795
<a id="setting"></a>TH1 setting Command
796
-----------------------------------------
797
798
* setting name
799
800
Gets and returns the value of the specified setting.
801
802
<a id="stime"></a>TH1 stime Command
803
-------------------------------------
804
805
* stime
806
807
Returns the number of microseconds of CPU time consumed by the current
808
process in system space.
809
810
<a id="styleHeader"></a>TH1 styleHeader Command
811
-------------------------------------------------
812
813
* styleHeader TITLE
814
815
Render the configured style header for the selected skin.
816
817
<a id="styleFooter"></a>TH1 styleFooter Command
818
-------------------------------------------------
819
820
* styleFooter
821
822
Render the configured style footer for the selected skin.
823
824
<a id="styleScript"></a>TH1 styleScript Command
825
-------------------------------------------------
826
827
* styleScript
828
829
Render the configured JavaScript for the selected skin.
830
831
<a id="submenu"></a>TH1 submenu Command
832
-----------------------------------------
833
834
* submenu link LABEL URL
835
836
Add hyperlink to the submenu of the current page.
837
838
<a id="taintCmd"></a>TH1 taint Command
839
-----------------------------------------
840
841
* taint STRING
842
843
This command returns a copy of STRING that has been marked as
844
[tainted](#taint). Tainted strings are strings which might be
845
controlled by an attacker and might contain hostile inputs and
846
are thus unsafe to use in certain contexts. For example, tainted
847
strings should not be output as part of a webpage as they might
848
contain rogue HTML or Javascript that could lead to an XSS
849
vulnerability. Similarly, tainted strings should not be run as
850
SQL since they might contain an SQL-injection vulerability.
851
852
<a id="tclEval"></a>TH1 tclEval Command
853
-----------------------------------------
854
855
**This command requires the Tcl integration feature.**
856
857
* tclEval arg ?arg ...?
858
859
Evaluates the Tcl script and returns its result verbatim. If a Tcl script
860
error is generated, it will be transformed into a TH1 script error. The
861
Tcl interpreter will be created automatically if it has not been already.
862
863
<a id="tclExpr"></a>TH1 tclExpr Command
864
-----------------------------------------
865
866
**This command requires the Tcl integration feature.**
867
868
* tclExpr arg ?arg ...?
869
870
Evaluates the Tcl expression and returns its result verbatim. If a Tcl
871
script error is generated, it will be transformed into a TH1 script
872
error. The Tcl interpreter will be created automatically if it has not
873
been already.
874
875
<a id="tclInvoke"></a>TH1 tclInvoke Command
876
---------------------------------------------
877
878
**This command requires the Tcl integration feature.**
879
880
* tclInvoke command ?arg ...?
881
882
Invokes the Tcl command using the supplied arguments. No additional
883
substitutions are performed on the arguments. The Tcl interpreter
884
will be created automatically if it has not been already.
885
886
<a id="tclIsSafe"></a>TH1 tclIsSafe Command
887
---------------------------------------------
888
889
**This command requires the Tcl integration feature.**
890
891
* tclIsSafe
892
893
Returns non-zero if the Tcl interpreter is "safe". The Tcl interpreter
894
will be created automatically if it has not been already.
895
896
<a id="tclMakeSafe"></a>TH1 tclMakeSafe Command
897
-------------------------------------------------
898
899
**This command requires the Tcl integration feature.**
900
901
* tclMakeSafe
902
903
Forces the Tcl interpreter into "safe" mode by removing all "unsafe"
904
commands and variables. This operation cannot be undone. The Tcl
905
interpreter will remain "safe" until the process terminates. The Tcl
906
interpreter will be created automatically if it has not been already.
907
908
<a id="tclReady"></a>TH1 tclReady Command
909
-------------------------------------------
910
911
* tclReady
912
913
Returns true if the binary has the Tcl integration feature enabled and it
914
is currently available for use by TH1 scripts.
915
916
<a id="trace"></a>TH1 trace Command
917
-------------------------------------
918
919
* trace STRING
920
921
Generates a TH1 trace message if TH1 tracing is enabled.
922
923
<a id="untaintCmd"></a>TH1 untaint Command
924
------------------------------------------
925
926
* untaint STRING
927
928
This command returns a copy of STRING that has been marked as
929
[untainted](#taint). Untainted strings are strings which are
930
believed to be free of potentially hostile content. Use this
931
command with caution, as it overwrites the tainted-string protection
932
mechanisms that are built into TH1. If you do not understand all
933
the implications of executing this command, then do not use it.
934
935
<a id="unversioned_content"></a>TH1 unversioned content Command
936
-----------------------------------------------------------------
937
938
* unversioned content FILENAME
939
940
Attempts to locate the specified unversioned file and return its contents.
941
An error is generated if the repository is not open or the unversioned file
942
cannot be found.
943
944
<a id="unversioned_list"></a>TH1 unversioned list Command
945
-----------------------------------------------------------
946
947
* unversioned list
948
949
Returns a list of the names of all unversioned files held in the local
950
repository. An error is generated if the repository is not open.
951
952
<a id="utime"></a>TH1 utime Command
953
-------------------------------------
954
955
* utime
956
957
Returns the number of microseconds of CPU time consumed by the current
958
process in user space.
959
960
<a id="verifyCsrf"></a>TH1 verifyCsrf Command
961
-----------------------------------------------
962
963
* verifyCsrf
964
965
Before using the results of a form, first call this command to verify
966
that the Anti-CSRF token is present and is valid. If the Anti-CSRF token
967
is missing or is incorrect, that indicates a cross-site scripting attack.
968
If the event of an attack is detected, an error message is generated and
969
all further processing is aborted.
970
971
<a id="verifyLogin"></a>TH1 verifyLogin Command
972
-------------------------------------------------
973
974
* verifyLogin
975
976
Returns non-zero if the specified user name and password represent a
977
valid login for the repository.
978
979
<a id="wiki"></a>TH1 wiki Command
980
-----------------------------------
981
982
* wiki STRING
983
984
Renders STRING as wiki content.
985
986
<a id="wiki_assoc"></a>TH1 wiki_assoc Command
987
-----------------------------------
988
989
* wiki_assoc STRING STRING
990
991
Renders the special wiki. The first string refers to the namespace
992
(checkin, branch, tag, ticket). The second string specifies the
993
concrete wiki page to be rendered.
994
995
Tcl Integration Commands
996
------------------------
997
998
When the Tcl integration subsystem is enabled, several commands are added
999
to the Tcl interpreter. They are used to allow Tcl scripts access to the
1000
Fossil functionality provided via TH1. The following is a summary of the
1001
Tcl commands:
1002
1003
* th1Eval
1004
* th1Expr
1005
1006
<a id="th1Eval"></a>Tcl th1Eval Command
1007
-----------------------------------------
1008
1009
**This command requires the Tcl integration feature.**
1010
1011
* th1Eval arg
1012
1013
Evaluates the TH1 script and returns its result verbatim. If a TH1 script
1014
error is generated, it will be transformed into a Tcl script error.
1015
1016
<a id="th1Expr"></a>Tcl th1Expr Command
1017
-----------------------------------------
1018
1019
**This command requires the Tcl integration feature.**
1020
1021
* th1Expr arg
1022
1023
Evaluates the TH1 expression and returns its result verbatim. If a TH1
1024
script error is generated, it will be transformed into a Tcl script error.
1025

Keyboard Shortcuts

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