Fossil SCM

fossil-scm / src / th.h
Blame History Raw 277 lines
1
/* This header file defines the external interface to the custom Scripting
2
** Language (TH) interpreter. TH is very similar to Tcl but is not an
3
** exact clone.
4
**
5
** TH1 was original developed to run SQLite tests on SymbianOS. This version
6
** of TH1 was repurposed as a scripted language for Fossil, and was heavily
7
** modified for that purpose, beginning in early 2008.
8
**
9
** More recently, TH1 has been enhanced to distinguish between regular text
10
** and "tainted" text. "Tainted" text is text that might have originated
11
** from an outside source and hence might not be trustworthy. To prevent
12
** cross-site scripting (XSS) and SQL-injections and similar attacks,
13
** tainted text should not be used for the following purposes:
14
**
15
** * executed as TH1 script or expression.
16
** * output as HTML or Javascript
17
** * used as part of an SQL query
18
**
19
** Tainted text can be converted into a safe form using commands like
20
** "htmlize". And some commands ("query" and "expr") know how to use
21
** potentially tainted variable values directly, and thus can bypass
22
** the restrictions above.
23
**
24
** Whether a string is clean or tainted is determined by its length integer.
25
** TH1 limits strings to be no more than 0x0fffffff bytes bytes in length
26
** (about 268MB - more than sufficient for the purposes of Fossil). The top
27
** bit of the length integer is the sign bit, of course. The next three bits
28
** are reserved. One of those, the 0x10000000 bit, marks tainted strings.
29
*/
30
#define TH1_MX_STRLEN 0x0fffffff /* Maximum length of a TH1-C string */
31
#define TH1_TAINT_BIT 0x10000000 /* The taint bit */
32
#define TH1_SIGN 0x80000000
33
34
/* Convert an integer into a string length. Negative values remain negative */
35
#define TH1_LEN(X) ((TH1_SIGN|TH1_MX_STRLEN)&(X))
36
37
/* Return true if the string is tainted */
38
#define TH1_TAINTED(X) (((X)&TH1_TAINT_BIT)!=0)
39
40
/* Remove taint from a string */
41
#define TH1_RM_TAINT(X) ((X)&~TH1_TAINT_BIT)
42
43
/* Add taint to a string */
44
#define TH1_ADD_TAINT(X) ((X)|TH1_TAINT_BIT)
45
46
/* If B is tainted, make A tainted too */
47
#define TH1_XFER_TAINT(A,B) (A)|=(TH1_TAINT_BIT&(B))
48
49
/* Check to see if a string is too big for TH1 */
50
#define TH1_SIZECHECK(N) if((N)>TH1_MX_STRLEN){Th_OversizeString();}
51
void Th_OversizeString(void);
52
53
/*
54
** Before creating an interpreter, the application must allocate and
55
** populate an instance of the following structure. It must remain valid
56
** for the lifetime of the interpreter.
57
*/
58
typedef struct Th_Vtab Th_Vtab;
59
struct Th_Vtab {
60
void *(*xMalloc)(unsigned int);
61
void (*xFree)(void *);
62
};
63
64
/*
65
** Opaque handle for interpeter.
66
*/
67
typedef struct Th_Interp Th_Interp;
68
69
/*
70
** Create and delete interpreters.
71
*/
72
Th_Interp * Th_CreateInterp(Th_Vtab *);
73
void Th_DeleteInterp(Th_Interp *);
74
75
/*
76
** Report taint in the string zStr,nStr. That string represents "zTitle"
77
** If non-zero is returned error out of the caller.
78
*/
79
int Th_ReportTaint(Th_Interp*,const char*,const char*zStr,int nStr);
80
81
/*
82
** Evaluate an TH program in the stack frame identified by parameter
83
** iFrame, according to the following rules:
84
**
85
** * If iFrame is 0, this means the current frame.
86
**
87
** * If iFrame is negative, then the nth frame up the stack, where n is
88
** the absolute value of iFrame. A value of -1 means the calling
89
** procedure.
90
**
91
** * If iFrame is +ve, then the nth frame from the bottom of the stack.
92
** An iFrame value of 1 means the toplevel (global) frame.
93
*/
94
int Th_Eval(Th_Interp *interp, int iFrame, const char *zProg, int nProg);
95
96
/*
97
** Evaluate a TH expression. The result is stored in the
98
** interpreter result.
99
*/
100
int Th_Expr(Th_Interp *interp, const char *, int);
101
102
/*
103
** Access TH variables in the current stack frame. If the variable name
104
** begins with "::", the lookup is in the top level (global) frame.
105
*/
106
int Th_ExistsVar(Th_Interp *, const char *, int);
107
int Th_ExistsArrayVar(Th_Interp *, const char *, int);
108
int Th_GetVar(Th_Interp *, const char *, int);
109
int Th_SetVar(Th_Interp *, const char *, int, const char *, int);
110
int Th_LinkVar(Th_Interp *, const char *, int, int, const char *, int);
111
int Th_UnsetVar(Th_Interp *, const char *, int);
112
113
typedef int (*Th_CommandProc)(Th_Interp *, void *, int, const char **, int *);
114
115
/*
116
** Register new commands.
117
*/
118
int Th_CreateCommand(
119
Th_Interp *interp,
120
const char *zName,
121
/* int (*xProc)(Th_Interp *, void *, int, const char **, int *), */
122
Th_CommandProc xProc,
123
void *pContext,
124
void (*xDel)(Th_Interp *, void *)
125
);
126
127
/*
128
** Delete or rename commands.
129
*/
130
int Th_RenameCommand(Th_Interp *, const char *, int, const char *, int);
131
132
/*
133
** Push a new stack frame (local variable context) onto the interpreter
134
** stack, call the function supplied as parameter xCall with the two
135
** context arguments,
136
**
137
** xCall(interp, pContext1, pContext2)
138
**
139
** , then pop the frame off of the interpreter stack. The value returned
140
** by the xCall() function is returned as the result of this function.
141
**
142
** This is intended for use by the implementation of commands such as
143
** those created by [proc].
144
*/
145
int Th_InFrame(Th_Interp *interp,
146
int (*xCall)(Th_Interp *, void *pContext1, void *pContext2),
147
void *pContext1,
148
void *pContext2
149
);
150
151
/*
152
** Valid return codes for xProc callbacks.
153
*/
154
#define TH_OK 0
155
#define TH_ERROR 1
156
#define TH_BREAK 2
157
#define TH_RETURN 3
158
#define TH_CONTINUE 4
159
#define TH_RETURN2 5
160
161
/*
162
** Set and get the interpreter result.
163
*/
164
int Th_SetResult(Th_Interp *, const char *, int);
165
const char *Th_GetResult(Th_Interp *, int *);
166
char *Th_TakeResult(Th_Interp *, int *);
167
168
/*
169
** Set an error message as the interpreter result. This also
170
** sets the global stack-trace variable $::th_stack_trace.
171
*/
172
int Th_ErrorMessage(Th_Interp *, const char *, const char *, int);
173
174
/*
175
** Access the memory management functions associated with the specified
176
** interpreter.
177
*/
178
#if defined(TH_MEMDEBUG)
179
void *Th_DbgMalloc(Th_Interp *, int);
180
void Th_DbgFree(Th_Interp *, void *);
181
#endif
182
183
void *fossil_malloc_zero(size_t);
184
void *fossil_realloc(void *, size_t);
185
void fossil_free(void *);
186
187
#define Th_SysMalloc(I,N) fossil_malloc_zero((N))
188
#define Th_SysRealloc(I,P,N) fossil_realloc((P),(N))
189
#define Th_SysFree(I,P) fossil_free((P))
190
191
#if defined(TH_MEMDEBUG)
192
# define Th_Malloc(I,N) Th_DbgMalloc((I),(N))
193
# define Th_Free(I,P) Th_DbgFree((I),(P))
194
#else
195
# define Th_Malloc(I,N) Th_SysMalloc((I),(N))
196
# define Th_Realloc(I,P,N) Th_SysRealloc((I),(P),(N))
197
# define Th_Free(I,P) Th_SysFree((I),(P))
198
#endif
199
200
/*
201
** Functions for handling TH lists.
202
*/
203
int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
204
int Th_SplitList(Th_Interp *, const char *, int, char ***, int **, int *);
205
206
int Th_StringAppend(Th_Interp *, char **, int *, const char *, int);
207
208
/*
209
** Functions for handling numbers and pointers.
210
*/
211
int Th_ToInt(Th_Interp *, const char *, int, int *);
212
int Th_ToDouble(Th_Interp *, const char *, int, double *);
213
int Th_SetResultInt(Th_Interp *, int);
214
int Th_SetResultDouble(Th_Interp *, double);
215
216
/*
217
** Functions for handling command and variable introspection.
218
*/
219
int Th_ListAppendCommands(Th_Interp *, char **, int *);
220
int Th_ListAppendVariables(Th_Interp *, char **, int *);
221
int Th_ListAppendArray(Th_Interp *, const char *, int, char **, int *);
222
223
/*
224
** Drop in replacements for the corresponding standard library functions.
225
*/
226
int th_strlen(const char *);
227
int th_isdigit(char);
228
int th_isspace(char);
229
int th_isalnum(char);
230
int th_isalpha(char);
231
int th_isspecial(char);
232
int th_ishexdig(char);
233
int th_isoctdig(char);
234
int th_isbindig(char);
235
char *th_strdup(Th_Interp *interp, const char *z, int n);
236
237
/*
238
** Interfaces to register the language extensions.
239
*/
240
int th_register_language(Th_Interp *interp); /* th_lang.c */
241
int th_register_sqlite(Th_Interp *interp); /* th_sqlite.c */
242
int th_register_vfs(Th_Interp *interp); /* th_vfs.c */
243
int th_register_testvfs(Th_Interp *interp); /* th_testvfs.c */
244
245
#ifdef FOSSIL_ENABLE_TCL
246
/*
247
** Interfaces to the full Tcl core library from "th_tcl.c".
248
*/
249
int th_register_tcl(Th_Interp *, void *);
250
int unloadTcl(Th_Interp *, void *);
251
int evaluateTclWithEvents(Th_Interp *,void *,const char *,int,int,int,int);
252
#endif
253
254
/*
255
** General purpose hash table from th_lang.c.
256
*/
257
typedef struct Th_Hash Th_Hash;
258
typedef struct Th_HashEntry Th_HashEntry;
259
struct Th_HashEntry {
260
void *pData;
261
char *zKey;
262
int nKey;
263
Th_HashEntry *pNext; /* Internal use only */
264
};
265
Th_Hash *Th_HashNew(Th_Interp *);
266
void Th_HashDelete(Th_Interp *, Th_Hash *);
267
void Th_HashIterate(Th_Interp*,Th_Hash*,int (*x)(Th_HashEntry*, void*),void*);
268
Th_HashEntry *Th_HashFind(Th_Interp*, Th_Hash*, const char*, int, int);
269
270
/*
271
** Useful functions from th_lang.c.
272
*/
273
int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg);
274
275
typedef struct Th_SubCommand {const char *zName; Th_CommandProc xProc;} Th_SubCommand;
276
int Th_CallSubCommand(Th_Interp*,void*,int,const char**,int*,const Th_SubCommand*);
277

Keyboard Shortcuts

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