pbx_ael should not abuse cw_expr() as a syntax checker
Expression evaluation is a two stage process, substitution then
evaluation. Just calling cw_expr() is simply wrong because it isn't
parsing what it would under true evaluation. Worse, you don't want to
expand or evaluate things with possible side effects when simply loading
a dialplan!
Removing this means that some syntax errors will only be detectable at
run-time rather than (possibly) load-time. But that's the nature of the
beast. Dialplan isn't a language. AEL is a text transformation tool that
transforms text into dialplan. AEL is not a language either. IMHO no one
should use AEL and it shouldn't even exist. At the very least it should
exist as a separate "compiler" and not be embedded.
Affected files:
callweaver/trunk/corelib/callweaver_expr2.l
callweaver/trunk/corelib/callweaver_expr2.y
callweaver/trunk/pbx/pbx_ael.c (diff)
callweaver/trunk/pbx/pbx_ael.c (unified diff)
| r5688 | r5714 | |
|---|---|---|
| 50 | 50 | |
| 51 | 51 | #include "ael/ael_structs.h" |
| 52 | 52 | |
| 53 | static struct cw_dynstr expr_output = CW_DYNSTR_INIT; | |
| 54 | 53 | |
| 55 | /* these functions are in ../cw_expr2.fl */ | |
| 56 | ||
| 57 | ||
| 58 | 54 | #ifdef __CW_DEBUG_MALLOC |
| 59 | 55 | static void FREE(void *ptr) |
| 60 | 56 | { |
| --- | --- | |
| 101 | 97 | void check_pval(struct pval *item, struct argapp *apps, int in_globals); |
| 102 | 98 | void check_pval_item(struct pval *item, struct argapp *apps, int in_globals); |
| 103 | 99 | void check_switch_expr(struct pval *item, struct argapp *apps); |
| 104 | extern CW_API_PUBLIC void cw_expr_register_extra_error_info(char *errmsg); | |
| 105 | extern CW_API_PUBLIC void cw_expr_clear_extra_error_info(void); | |
| 106 | extern CW_API_PUBLIC int cw_expr(struct cw_channel *chan, char *expr, struct cw_dynstr *result); | |
| 107 | 100 | struct pval *find_proc(char *name); |
| 108 | 101 | struct pval *find_context(char *name); |
| 109 | 102 | struct ael_priority *new_prio(void); |
| --- | --- | |
| 2007 | 2000 | #endif |
| 2008 | 2001 | struct pval *proc_def; |
| 2009 | 2002 | struct pval *app_def; |
| 2010 | ||
| 2011 | char errmsg[4096]; | |
| 2012 | char *strp; | |
| 2013 | ||
| 2003 | ||
| 2014 | 2004 | switch (item->type) { |
| 2015 | 2005 | case PV_WORD: |
| 2016 | 2006 | /* fields: item->u1.str == string associated with this (word). |
| --- | --- | |
| 2203 | 2193 | */ |
| 2204 | 2194 | /* the RHS of a vardec is encapsulated in a $[] expr. Is it legal? */ |
| 2205 | 2195 | if( !in_globals ) { /* don't check stuff inside the globals context; no wrapping in $[ ] there... */ |
| 2206 | snprintf(errmsg,sizeof(errmsg), "file %s, line %d, columns %d-%d, variable declaration expr '%s':", config, item->startline, item->startcol, item->endcol, item->u2.val); | |
| 2207 | cw_expr_register_extra_error_info(errmsg); | |
| 2208 | cw_expr(NULL, item->u2.val, &expr_output); | |
| 2209 | cw_expr_clear_extra_error_info(); | |
| 2210 | 2196 | if ( strpbrk(item->u2.val,"~!-+<>=*/&^") && !strstr(item->u2.val,"${") ) { |
| 2211 | 2197 | cw_log(CW_LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", |
| 2212 | 2198 | item->filename, item->startline, item->endline, item->u2.val); |
| --- | --- | |
| 2244 | 2230 | |
| 2245 | 2231 | item->u4.for_statements == a struct pval list of statements in the for () |
| 2246 | 2232 | */ |
| 2247 | snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, for test expr '%s':", config, item->startline, item->startcol, item->endcol, item->u2.for_test); | |
| 2248 | cw_expr_register_extra_error_info(errmsg); | |
| 2249 | ||
| 2250 | strp = strchr(item->u1.for_init, '='); | |
| 2251 | if (strp) { | |
| 2252 | cw_expr(NULL, strp+1, &expr_output); | |
| 2253 | } | |
| 2254 | cw_expr(NULL, item->u2.for_test, &expr_output); | |
| 2255 | strp = strchr(item->u3.for_inc, '='); | |
| 2256 | if (strp) { | |
| 2257 | cw_expr(NULL, strp+1, &expr_output); | |
| 2258 | } | |
| 2259 | 2233 | if ( strpbrk(item->u2.for_test,"~!-+<>=*/&^") && !strstr(item->u2.for_test,"${") ) { |
| 2260 | 2234 | cw_log(CW_LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", |
| 2261 | 2235 | item->filename, item->startline, item->endline, item->u2.for_test); |
| --- | --- | |
| 2269 | 2243 | check_expr2_input(item,item->u2.for_test); |
| 2270 | 2244 | check_expr2_input(item,item->u3.for_inc); |
| 2271 | 2245 | |
| 2272 | cw_expr_clear_extra_error_info(); | |
| 2273 | 2246 | check_pval(item->u4.for_statements, apps,in_globals); |
| 2274 | 2247 | break; |
| 2275 | 2248 | |
| --- | --- | |
| 2278 | 2251 | |
| 2279 | 2252 | item->u2.statements == a struct pval list of statements in the while () |
| 2280 | 2253 | */ |
| 2281 | snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, while expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str); | |
| 2282 | cw_expr_register_extra_error_info(errmsg); | |
| 2283 | cw_expr(NULL, item->u1.str, &expr_output); | |
| 2284 | cw_expr_clear_extra_error_info(); | |
| 2285 | 2254 | if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) { |
| 2286 | 2255 | cw_log(CW_LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", |
| 2287 | 2256 | item->filename, item->startline, item->endline, item->u1.str); |
| --- | --- | |
| 2313 | 2282 | item->u3.else_statements == a struct pval list of statements in the else |
| 2314 | 2283 | (could be zero) |
| 2315 | 2284 | */ |
| 2316 | snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, random expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str); | |
| 2317 | cw_expr_register_extra_error_info(errmsg); | |
| 2318 | cw_expr(NULL, item->u1.str, &expr_output); | |
| 2319 | cw_expr_clear_extra_error_info(); | |
| 2320 | 2285 | if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) { |
| 2321 | 2286 | cw_log(CW_LOG_WARNING,"Warning: file %s, line %d-%d: random expression '%s' has operators, but no variables. Interesting...\n", |
| 2322 | 2287 | item->filename, item->startline, item->endline, item->u1.str); |
| --- | --- | |
| 2356 | 2321 | item->u3.else_statements == a struct pval list of statements in the else |
| 2357 | 2322 | (could be zero) |
| 2358 | 2323 | */ |
| 2359 | snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, if expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str); | |
| 2360 | cw_expr_register_extra_error_info(errmsg); | |
| 2361 | cw_expr(NULL, item->u1.str, &expr_output); | |
| 2362 | cw_expr_clear_extra_error_info(); | |
| 2363 | 2324 | if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) { |
| 2364 | 2325 | cw_log(CW_LOG_WARNING,"Warning: file %s, line %d-%d: expression '%s' has operators, but no variables. Interesting...\n", |
| 2365 | 2326 | item->filename, item->startline, item->endline, item->u1.str); |
| --- | --- | |
| 2410 | 2371 | default: |
| 2411 | 2372 | break; |
| 2412 | 2373 | } |
| 2413 | ||
| 2414 | cw_dynstr_reset(&expr_output); | |
| 2415 | 2374 | } |
| 2416 | 2375 | |
| 2417 | 2376 | void check_pval(struct pval *item, struct argapp *apps, int in_globals) |
![Home changeset 5714 [home]](/images/logo.png?1180520111)

RSS Feeds