1
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5
6 #include "php.h"
7 #include "php_phalcon.h"
8 #include "phalcon.h"
9
10 #include <ext/standard/php_smart_string.h>
11 #include <zend_smart_str.h>
12
13 #include "parser.php7.h"
14 #include "scanner.h"
15 #include "volt.h"
16
17 #include "kernel/main.h"
18 #include "kernel/memory.h"
19 #include "kernel/fcall.h"
20 #include "kernel/exception.h"
21
22 #define phvolt_add_assoc_stringl(var, index, str, len, copy) add_assoc_stringl(var, index, str, len);
23
phvolt_ret_literal_zval(zval * ret,int type,phvolt_parser_token * T,phvolt_scanner_state * state)24 static void phvolt_ret_literal_zval(zval *ret, int type, phvolt_parser_token *T, phvolt_scanner_state *state)
25 {
26 array_init(ret);
27 add_assoc_long(ret, "type", type);
28 if (T) {
29 phvolt_add_assoc_stringl(ret, "value", T->token, T->token_len, 0);
30 efree(T->token);
31 efree(T);
32 }
33
34 Z_TRY_ADDREF_P(state->active_file);
35 add_assoc_zval(ret, "file", state->active_file);
36 add_assoc_long(ret, "line", state->active_line);
37 }
38
phvolt_ret_if_statement(zval * ret,zval * expr,zval * true_statements,zval * false_statements,phvolt_scanner_state * state)39 static void phvolt_ret_if_statement(zval *ret, zval *expr, zval *true_statements, zval *false_statements, phvolt_scanner_state *state)
40 {
41 array_init(ret);
42 add_assoc_long(ret, "type", PHVOLT_T_IF);
43 add_assoc_zval(ret, "expr", expr);
44
45 if (true_statements) {
46 add_assoc_zval(ret, "true_statements", true_statements);
47 }
48 if (false_statements) {
49 add_assoc_zval(ret, "false_statements", false_statements);
50 }
51
52 Z_TRY_ADDREF_P(state->active_file);
53 add_assoc_zval(ret, "file", state->active_file);
54 add_assoc_long(ret, "line", state->active_line);
55 }
56
phvolt_ret_elseif_statement(zval * ret,zval * expr,phvolt_scanner_state * state)57 static void phvolt_ret_elseif_statement(zval *ret, zval *expr, phvolt_scanner_state *state)
58 {
59 array_init(ret);
60 add_assoc_long(ret, "type", PHVOLT_T_ELSEIF);
61 add_assoc_zval(ret, "expr", expr);
62
63 Z_TRY_ADDREF_P(state->active_file);
64 add_assoc_zval(ret, "file", state->active_file);
65 add_assoc_long(ret, "line", state->active_line);
66 }
67
phvolt_ret_elsefor_statement(zval * ret,phvolt_scanner_state * state)68 static void phvolt_ret_elsefor_statement(zval *ret, phvolt_scanner_state *state)
69 {
70 array_init(ret);
71 add_assoc_long(ret, "type", PHVOLT_T_ELSEFOR);
72
73 Z_TRY_ADDREF_P(state->active_file);
74 add_assoc_zval(ret, "file", state->active_file);
75 add_assoc_long(ret, "line", state->active_line);
76 }
77
phvolt_ret_switch_statement(zval * ret,zval * expr,zval * case_clauses,phvolt_scanner_state * state)78 static void phvolt_ret_switch_statement(zval *ret, zval *expr, zval *case_clauses, phvolt_scanner_state *state)
79 {
80 array_init(ret);
81
82 add_assoc_long(ret, "type", PHVOLT_T_SWITCH);
83 add_assoc_zval(ret, "expr", expr);
84
85 if (case_clauses) {
86 add_assoc_zval(ret, "case_clauses", case_clauses);
87 }
88
89 Z_TRY_ADDREF_P(state->active_file);
90 add_assoc_zval(ret, "file", state->active_file);
91 add_assoc_long(ret, "line", state->active_line);
92 }
93
phvolt_ret_case_clause(zval * ret,zval * expr,phvolt_scanner_state * state)94 static void phvolt_ret_case_clause(zval *ret, zval *expr, phvolt_scanner_state *state)
95 {
96 array_init(ret);
97
98 if (expr) {
99 add_assoc_long(ret, "type", PHVOLT_T_CASE);
100 add_assoc_zval(ret, "expr", expr);
101 } else {
102 add_assoc_long(ret, "type", PHVOLT_T_DEFAULT);
103 }
104
105 Z_TRY_ADDREF_P(state->active_file);
106 add_assoc_zval(ret, "file", state->active_file);
107 add_assoc_long(ret, "line", state->active_line);
108 }
109
phvolt_ret_for_statement(zval * ret,phvolt_parser_token * variable,phvolt_parser_token * key,zval * expr,zval * if_expr,zval * block_statements,phvolt_scanner_state * state)110 static void phvolt_ret_for_statement(zval *ret, phvolt_parser_token *variable, phvolt_parser_token *key, zval *expr, zval *if_expr, zval *block_statements, phvolt_scanner_state *state)
111 {
112 array_init(ret);
113 add_assoc_long(ret, "type", PHVOLT_T_FOR);
114
115 phvolt_add_assoc_stringl(ret, "variable", variable->token, variable->token_len, 0);
116 efree(variable->token);
117 efree(variable);
118
119 if (key) {
120 phvolt_add_assoc_stringl(ret, "key", key->token, key->token_len, 0);
121 efree(key->token);
122 efree(key);
123 }
124
125 add_assoc_zval(ret, "expr", expr);
126 if (if_expr) {
127 add_assoc_zval(ret, "if_expr", if_expr);
128 }
129
130 add_assoc_zval(ret, "block_statements", block_statements);
131
132 Z_TRY_ADDREF_P(state->active_file);
133 add_assoc_zval(ret, "file", state->active_file);
134 add_assoc_long(ret, "line", state->active_line);
135 }
136
phvolt_ret_cache_statement(zval * ret,zval * expr,zval * lifetime,zval * block_statements,phvolt_scanner_state * state)137 static void phvolt_ret_cache_statement(zval *ret, zval *expr, zval *lifetime, zval *block_statements, phvolt_scanner_state *state)
138 {
139 array_init(ret);
140
141 add_assoc_long(ret, "type", PHVOLT_T_CACHE);
142 add_assoc_zval(ret, "expr", expr);
143
144 if (lifetime) {
145 add_assoc_zval(ret, "lifetime", lifetime);
146 }
147 add_assoc_zval(ret, "block_statements", block_statements);
148
149 Z_TRY_ADDREF_P(state->active_file);
150 add_assoc_zval(ret, "file", state->active_file);
151 add_assoc_long(ret, "line", state->active_line);
152 }
153
phvolt_ret_raw_statement(zval * ret,zval * statement,phvolt_scanner_state * state)154 static void phvolt_ret_raw_statement(zval *ret, zval *statement, phvolt_scanner_state *state)
155 {
156 array_init(ret);
157
158 add_assoc_long(ret, "type", PHVOLT_T_RAW);
159 add_assoc_zval(ret, "content", statement);
160
161 Z_TRY_ADDREF_P(state->active_file);
162 add_assoc_zval(ret, "file", state->active_file);
163 add_assoc_long(ret, "line", state->active_line);
164 }
165
phvolt_ret_set_statement(zval * ret,zval * assignments)166 static void phvolt_ret_set_statement(zval *ret, zval *assignments)
167 {
168 array_init(ret);
169 add_assoc_long(ret, "type", PHVOLT_T_SET);
170
171 add_assoc_zval(ret, "assignments", assignments);
172 }
173
phvolt_ret_set_assignment(zval * ret,zval * assignable_expr,int operator,zval * expr,phvolt_scanner_state * state)174 static void phvolt_ret_set_assignment(zval *ret, zval *assignable_expr, int operator, zval *expr, phvolt_scanner_state *state)
175 {
176
177 array_init(ret);
178
179 add_assoc_zval(ret, "variable", assignable_expr);
180 add_assoc_long(ret, "op", operator);
181 add_assoc_zval(ret, "expr", expr);
182
183 Z_TRY_ADDREF_P(state->active_file);
184 add_assoc_zval(ret, "file", state->active_file);
185 add_assoc_long(ret, "line", state->active_line);
186 }
187
phvolt_ret_echo_statement(zval * ret,zval * expr,phvolt_scanner_state * state)188 static void phvolt_ret_echo_statement(zval *ret, zval *expr, phvolt_scanner_state *state)
189 {
190 array_init(ret);
191 add_assoc_long(ret, "type", PHVOLT_T_ECHO);
192 add_assoc_zval(ret, "expr", expr);
193
194 Z_TRY_ADDREF_P(state->active_file);
195 add_assoc_zval(ret, "file", state->active_file);
196 add_assoc_long(ret, "line", state->active_line);
197 }
198
phvolt_ret_block_statement(zval * ret,phvolt_parser_token * name,zval * block_statements,phvolt_scanner_state * state)199 static void phvolt_ret_block_statement(zval *ret, phvolt_parser_token *name, zval *block_statements, phvolt_scanner_state *state)
200 {
201 array_init(ret);
202
203 add_assoc_long(ret, "type", PHVOLT_T_BLOCK);
204
205 phvolt_add_assoc_stringl(ret, "name", name->token, name->token_len, 0);
206 efree(name->token);
207 efree(name);
208
209 if (block_statements) {
210 add_assoc_zval(ret, "block_statements", block_statements);
211 }
212
213 Z_TRY_ADDREF_P(state->active_file);
214 add_assoc_zval(ret, "file", state->active_file);
215 add_assoc_long(ret, "line", state->active_line);
216 }
217
phvolt_ret_macro_statement(zval * ret,phvolt_parser_token * macro_name,zval * parameters,zval * block_statements,phvolt_scanner_state * state)218 static void phvolt_ret_macro_statement(zval *ret, phvolt_parser_token *macro_name, zval *parameters, zval *block_statements, phvolt_scanner_state *state)
219 {
220 array_init(ret);
221 add_assoc_long(ret, "type", PHVOLT_T_MACRO);
222
223 phvolt_add_assoc_stringl(ret, "name", macro_name->token, macro_name->token_len, 0);
224 efree(macro_name->token);
225 efree(macro_name);
226
227 if (parameters) {
228 add_assoc_zval(ret, "parameters", parameters);
229 }
230
231 if (block_statements) {
232 add_assoc_zval(ret, "block_statements", block_statements);
233 }
234
235 Z_TRY_ADDREF_P(state->active_file);
236 add_assoc_zval(ret, "file", state->active_file);
237 add_assoc_long(ret, "line", state->active_line);
238 }
239
phvolt_ret_macro_parameter(zval * ret,phvolt_parser_token * variable,zval * default_value,phvolt_scanner_state * state)240 static void phvolt_ret_macro_parameter(zval *ret, phvolt_parser_token *variable, zval *default_value, phvolt_scanner_state *state)
241 {
242 array_init(ret);
243
244 phvolt_add_assoc_stringl(ret, "variable", variable->token, variable->token_len, 0);
245 efree(variable->token);
246 efree(variable);
247
248 if (default_value) {
249 add_assoc_zval(ret, "default", default_value);
250 }
251
252 Z_TRY_ADDREF_P(state->active_file);
253 add_assoc_zval(ret, "file", state->active_file);
254 add_assoc_long(ret, "line", state->active_line);
255 }
256
phvolt_ret_extends_statement(zval * ret,zval * path,phvolt_scanner_state * state)257 static void phvolt_ret_extends_statement(zval *ret, zval *path, phvolt_scanner_state *state)
258 {
259 array_init(ret);
260
261 add_assoc_long(ret, "type", PHVOLT_T_EXTENDS);
262 add_assoc_zval(ret, "path", path);
263
264 Z_TRY_ADDREF_P(state->active_file);
265 add_assoc_zval(ret, "file", state->active_file);
266 add_assoc_long(ret, "line", state->active_line);
267 }
268
phvolt_ret_include_statement(zval * ret,zval * path,zval * params,phvolt_scanner_state * state)269 static void phvolt_ret_include_statement(zval *ret, zval *path, zval *params, phvolt_scanner_state *state)
270 {
271 array_init(ret);
272
273 add_assoc_long(ret, "type", PHVOLT_T_INCLUDE);
274
275 add_assoc_zval(ret, "path", path);
276 if (params) {
277 add_assoc_zval(ret, "params", params);
278 }
279
280 Z_TRY_ADDREF_P(state->active_file);
281 add_assoc_zval(ret, "file", state->active_file);
282 add_assoc_long(ret, "line", state->active_line);
283 }
284
phvolt_ret_do_statement(zval * ret,zval * expr,phvolt_scanner_state * state)285 static void phvolt_ret_do_statement(zval *ret, zval *expr, phvolt_scanner_state *state)
286 {
287 array_init(ret);
288
289 add_assoc_long(ret, "type", PHVOLT_T_DO);
290 add_assoc_zval(ret, "expr", expr);
291
292 Z_TRY_ADDREF_P(state->active_file);
293 add_assoc_zval(ret, "file", state->active_file);
294 add_assoc_long(ret, "line", state->active_line);
295 }
296
phvolt_ret_return_statement(zval * ret,zval * expr,phvolt_scanner_state * state)297 static void phvolt_ret_return_statement(zval *ret, zval *expr, phvolt_scanner_state *state)
298 {
299 array_init(ret);
300
301 add_assoc_long(ret, "type", PHVOLT_T_RETURN);
302 add_assoc_zval(ret, "expr", expr);
303
304 Z_TRY_ADDREF_P(state->active_file);
305 add_assoc_zval(ret, "file", state->active_file);
306 add_assoc_long(ret, "line", state->active_line);
307 }
308
phvolt_ret_autoescape_statement(zval * ret,int enable,zval * block_statements,phvolt_scanner_state * state)309 static void phvolt_ret_autoescape_statement(zval *ret, int enable, zval *block_statements, phvolt_scanner_state *state)
310 {
311 array_init(ret);
312
313 add_assoc_long(ret, "type", PHVOLT_T_AUTOESCAPE);
314 add_assoc_long(ret, "enable", enable);
315 add_assoc_zval(ret, "block_statements", block_statements);
316
317 Z_TRY_ADDREF_P(state->active_file);
318 add_assoc_zval(ret, "file", state->active_file);
319 add_assoc_long(ret, "line", state->active_line);
320 }
321
phvolt_ret_empty_statement(zval * ret,phvolt_scanner_state * state)322 static void phvolt_ret_empty_statement(zval *ret, phvolt_scanner_state *state)
323 {
324 array_init(ret);
325 add_assoc_long(ret, "type", PHVOLT_T_EMPTY_STATEMENT);
326
327 Z_TRY_ADDREF_P(state->active_file);
328 add_assoc_zval(ret, "file", state->active_file);
329 add_assoc_long(ret, "line", state->active_line);
330 }
331
phvolt_ret_break_statement(zval * ret,phvolt_scanner_state * state)332 static void phvolt_ret_break_statement(zval *ret, phvolt_scanner_state *state)
333 {
334 array_init(ret);
335 add_assoc_long(ret, "type", PHVOLT_T_BREAK);
336
337 Z_TRY_ADDREF_P(state->active_file);
338 add_assoc_zval(ret, "file", state->active_file);
339 add_assoc_long(ret, "line", state->active_line);
340 }
341
phvolt_ret_continue_statement(zval * ret,phvolt_scanner_state * state)342 static void phvolt_ret_continue_statement(zval *ret, phvolt_scanner_state *state)
343 {
344 array_init(ret);
345 add_assoc_long(ret, "type", PHVOLT_T_CONTINUE);
346
347 Z_TRY_ADDREF_P(state->active_file);
348 add_assoc_zval(ret, "file", state->active_file);
349 add_assoc_long(ret, "line", state->active_line);
350 }
351
phvolt_ret_zval_list(zval * ret,zval * list_left,zval * right_list)352 static void phvolt_ret_zval_list(zval *ret, zval *list_left, zval *right_list)
353 {
354 HashTable *list;
355
356 array_init(ret);
357
358 if (list_left) {
359
360 list = Z_ARRVAL_P(list_left);
361 if (zend_hash_index_exists(list, 0)) {
362 {
363 zval *item;
364 ZEND_HASH_FOREACH_VAL(list, item) {
365
366 Z_TRY_ADDREF_P(item);
367 add_next_index_zval(ret, item);
368
369 } ZEND_HASH_FOREACH_END();
370 }
371 zval_dtor(list_left);
372 } else {
373 add_next_index_zval(ret, list_left);
374 }
375 }
376
377 add_next_index_zval(ret, right_list);
378 }
379
phvolt_ret_named_item(zval * ret,phvolt_parser_token * name,zval * expr,phvolt_scanner_state * state)380 static void phvolt_ret_named_item(zval *ret, phvolt_parser_token *name, zval *expr, phvolt_scanner_state *state)
381 {
382 array_init(ret);
383 add_assoc_zval(ret, "expr", expr);
384 if (name != NULL) {
385 phvolt_add_assoc_stringl(ret, "name", name->token, name->token_len, 0);
386 efree(name->token);
387 efree(name);
388 }
389
390 Z_TRY_ADDREF_P(state->active_file);
391 add_assoc_zval(ret, "file", state->active_file);
392 add_assoc_long(ret, "line", state->active_line);
393 }
394
phvolt_ret_expr(zval * ret,int type,zval * left,zval * right,zval * ternary,phvolt_scanner_state * state)395 static void phvolt_ret_expr(zval *ret, int type, zval *left, zval *right, zval *ternary, phvolt_scanner_state *state)
396 {
397 array_init(ret);
398 add_assoc_long(ret, "type", type);
399
400 if (ternary) {
401 add_assoc_zval(ret, "ternary", ternary);
402 }
403
404 if (left) {
405 add_assoc_zval(ret, "left", left);
406 }
407
408 if (right) {
409 add_assoc_zval(ret, "right", right);
410 }
411
412 Z_TRY_ADDREF_P(state->active_file);
413 add_assoc_zval(ret, "file", state->active_file);
414 add_assoc_long(ret, "line", state->active_line);
415 }
416
phvolt_ret_slice(zval * ret,zval * left,zval * start,zval * end,phvolt_scanner_state * state)417 static void phvolt_ret_slice(zval *ret, zval *left, zval *start, zval *end, phvolt_scanner_state *state)
418 {
419 array_init(ret);
420 add_assoc_long(ret, "type", PHVOLT_T_SLICE);
421 add_assoc_zval(ret, "left", left);
422
423 if (start != NULL) {
424 add_assoc_zval(ret, "start", start);
425 }
426
427 if (end != NULL) {
428 add_assoc_zval(ret, "end", end);
429 }
430
431 Z_TRY_ADDREF_P(state->active_file);
432 add_assoc_zval(ret, "file", state->active_file);
433 add_assoc_long(ret, "line", state->active_line);
434 }
435
phvolt_ret_func_call(zval * ret,zval * expr,zval * arguments,phvolt_scanner_state * state)436 static void phvolt_ret_func_call(zval *ret, zval *expr, zval *arguments, phvolt_scanner_state *state)
437 {
438
439 array_init(ret);
440 add_assoc_long(ret, "type", PHVOLT_T_FCALL);
441 add_assoc_zval(ret, "name", expr);
442
443 if (arguments) {
444 add_assoc_zval(ret, "arguments", arguments);
445 }
446
447 Z_TRY_ADDREF_P(state->active_file);
448 add_assoc_zval(ret, "file", state->active_file);
449 add_assoc_long(ret, "line", state->active_line);
450 }
451
phvolt_ret_macro_call_statement(zval * ret,zval * expr,zval * arguments,zval * caller,phvolt_scanner_state * state)452 static void phvolt_ret_macro_call_statement(zval *ret, zval *expr, zval *arguments, zval *caller, phvolt_scanner_state *state)
453 {
454
455 array_init(ret);
456 add_assoc_long(ret, "type", PHVOLT_T_CALL);
457 add_assoc_zval(ret, "name", expr);
458
459 if (arguments) {
460 add_assoc_zval(ret, "arguments", arguments);
461 }
462
463 if (caller) {
464 add_assoc_zval(ret, "caller", caller);
465 }
466
467 Z_TRY_ADDREF_P(state->active_file);
468 add_assoc_zval(ret, "file", state->active_file);
469 add_assoc_long(ret, "line", state->active_line);
470 }
471