void load_file(FILE* source, vararray* lines) { char str[200]; line_t* cur_line = (line_t*)calloc(1, sizeof(line_t)); vararray* func_code = var_ctor(sizeof(line_t), 128); DBGPRINT("Lines: %d\n", (int)(lines->nmax)); while (fgets(str, 200, source)) { memset(cur_line, 0, sizeof(line_t)); if (!get_line(cur_line, str)) continue; if (!strcmp(cur_line->words[is_lable(cur_line->words[0])], "proc")) { var_push(func_code, cur_line); if(!load_function(source, func_code)) USERERR("No ret from function found."); } else { var_push(lines, cur_line); } DBGPRINT("Lines: %d\n", (int)(lines->nmax)); DBGPRINT("String: %s\nKeyword: \"%s\"\n", str, cur_line->words[0]); } for (int i = 0; i < func_code->nmax; i++) var_push(lines, var_get(func_code, i)); var_dtor(func_code); }
void put_lf(char str[], vararray* funcs, int shift) { func_t cur_func; strcpy(cur_func.name, str); cur_func.shift = shift; var_push(funcs, &cur_func); DBGPRINT("NAME: \"%s\", POS: %d;\n", str, shift); }
bool load_function(FILE* source, vararray* lines) { //return 0 if no ret found DBGPRINT("Function found.\n"); char str[200]; line_t* cur_line = (line_t*)calloc(1, sizeof(line_t)); while (fgets(str, 200, source)) { memset(cur_line, 0, sizeof(line_t)); if (!get_line(cur_line, str)) continue; var_push(lines, cur_line); if (!strcmp(cur_line->words[0], "ret")) return 1; } return 0; }
PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER) { const unsigned char *cursor, *limit, *marker, *start; zval *rval_ref; limit = max; cursor = *p; if (YYCURSOR >= YYLIMIT) { return 0; } if (var_hash && (*p)[0] != 'R') { var_push(var_hash, rval); } start = cursor; #line 518 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; switch (yych) { case 'C': case 'O': goto yy13; case 'N': goto yy5; case 'R': goto yy2; case 'S': goto yy10; case 'a': goto yy11; case 'b': goto yy6; case 'd': goto yy8; case 'i': goto yy7; case 'o': goto yy12; case 'r': goto yy4; case 's': goto yy9; case '}': goto yy14; default: goto yy16; } yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: #line 873 "ext/standard/var_unserializer.re" { return 0; } #line 580 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; goto yy3; yy5: yych = *++YYCURSOR; if (yych == ';') goto yy87; goto yy3; yy6: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy83; goto yy3; yy7: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy77; goto yy3; yy8: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy53; goto yy3; yy9: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy46; goto yy3; yy10: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy39; goto yy3; yy11: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy32; goto yy3; yy12: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy25; goto yy3; yy13: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy17; goto yy3; yy14: ++YYCURSOR; #line 867 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } #line 629 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; yy17: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } if (yych == '+') goto yy19; yy18: YYCURSOR = YYMARKER; goto yy3; yy19: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } goto yy18; yy20: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } if (yych <= '/') goto yy18; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 722 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; zend_long elements; char *str; zend_string *class_name; zend_class_entry *ce; int incomplete_class = 0; int custom_object = 0; zval user_func; zval retval; zval args[1]; if (!var_hash) return 0; if (*start == 'C') { custom_object = 1; } len2 = len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len || len == 0) { *p = start + 2; return 0; } str = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } if (*(YYCURSOR+1) != ':') { *p = YYCURSOR+1; return 0; } len3 = strspn(str, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\"); if (len3 != len) { *p = YYCURSOR + len3 - len; return 0; } class_name = zend_string_init(str, len, 0); do { if(!unserialize_allowed_class(class_name, classes)) { incomplete_class = 1; ce = PHP_IC_ENTRY; break; } /* Try to find class directly */ BG(serialize_lock)++; ce = zend_lookup_class(class_name); if (ce) { BG(serialize_lock)--; if (EG(exception)) { zend_string_release(class_name); return 0; } break; } BG(serialize_lock)--; if (EG(exception)) { zend_string_release(class_name); return 0; } /* Check for unserialize callback */ if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) { incomplete_class = 1; ce = PHP_IC_ENTRY; break; } /* Call unserialize callback */ ZVAL_STRING(&user_func, PG(unserialize_callback_func)); ZVAL_STR_COPY(&args[0], class_name); BG(serialize_lock)++; if (call_user_function_ex(CG(function_table), NULL, &user_func, &retval, 1, args, 0, NULL) != SUCCESS) { BG(serialize_lock)--; if (EG(exception)) { zend_string_release(class_name); zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); return 0; } php_error_docref(NULL, E_WARNING, "defined (%s) but not found", Z_STRVAL(user_func)); incomplete_class = 1; ce = PHP_IC_ENTRY; zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); break; } BG(serialize_lock)--; zval_ptr_dtor(&retval); if (EG(exception)) { zend_string_release(class_name); zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); return 0; } /* The callback function may have defined the class */ if ((ce = zend_lookup_class(class_name)) == NULL) { php_error_docref(NULL, E_WARNING, "Function %s() hasn't defined the class it was called for", Z_STRVAL(user_func)); incomplete_class = 1; ce = PHP_IC_ENTRY; } zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); break; } while (1); *p = YYCURSOR; if (custom_object) { int ret; ret = object_custom(UNSERIALIZE_PASSTHRU, ce); if (ret && incomplete_class) { php_store_class_name(rval, ZSTR_VAL(class_name), len2); } zend_string_release(class_name); return ret; } elements = object_common1(UNSERIALIZE_PASSTHRU, ce); if (incomplete_class) { php_store_class_name(rval, ZSTR_VAL(class_name), len2); } zend_string_release(class_name); return object_common2(UNSERIALIZE_PASSTHRU, elements); } #line 805 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy26; if (yych <= '/') goto yy18; if (yych <= '9') goto yy27; goto yy18; } yy26: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy27: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy27; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 715 "ext/standard/var_unserializer.re" { if (!var_hash) return 0; return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } #line 837 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; goto yy18; yy33: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy34: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; #line 691 "ext/standard/var_unserializer.re" { zend_long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ *p = YYCURSOR; if (!var_hash) return 0; if (elements < 0) { return 0; } array_init_size(rval, elements); //??? we can't convert from packed to hash during unserialization, because //??? reference to some zvals might be keept in var_hash (to support references) if (elements) { zend_hash_real_init(Z_ARRVAL_P(rval), 0); } if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) { return 0; } return finish_nested_data(UNSERIALIZE_PASSTHRU); } #line 882 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; if (yych <= '/') goto yy18; if (yych <= '9') goto yy41; goto yy18; yy40: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy41: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy41; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 663 "ext/standard/var_unserializer.re" { size_t len, maxlen; zend_string *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } if ((str = unserialize_str(&YYCURSOR, len, maxlen)) == NULL) { return 0; } if (*(YYCURSOR) != '"') { zend_string_free(str); *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; ZVAL_STR(rval, str); return 1; } #line 931 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; if (yych <= '/') goto yy18; if (yych <= '9') goto yy48; goto yy18; yy47: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy48: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy48; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 636 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } str = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; ZVAL_STRINGL(rval, str, len); return 1; } #line 979 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { if (yych <= ',') { if (yych == '+') goto yy57; goto yy18; } else { if (yych <= '-') goto yy55; if (yych <= '.') goto yy60; goto yy18; } } else { if (yych <= 'I') { if (yych <= '9') goto yy58; if (yych <= 'H') goto yy18; goto yy56; } else { if (yych != 'N') goto yy18; } } yych = *++YYCURSOR; if (yych == 'A') goto yy76; goto yy18; yy55: yych = *++YYCURSOR; if (yych <= '/') { if (yych == '.') goto yy60; goto yy18; } else { if (yych <= '9') goto yy58; if (yych != 'I') goto yy18; } yy56: yych = *++YYCURSOR; if (yych == 'N') goto yy72; goto yy18; yy57: yych = *++YYCURSOR; if (yych == '.') goto yy60; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy58: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ':') { if (yych <= '.') { if (yych <= '-') goto yy18; goto yy70; } else { if (yych <= '/') goto yy18; if (yych <= '9') goto yy58; goto yy18; } } else { if (yych <= 'E') { if (yych <= ';') goto yy63; if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy60: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy61: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ';') { if (yych <= '/') goto yy18; if (yych <= '9') goto yy61; if (yych <= ':') goto yy18; } else { if (yych <= 'E') { if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy63: ++YYCURSOR; #line 627 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 use_double: #endif *p = YYCURSOR; ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); return 1; } #line 1076 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy66; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; goto yy18; } yy66: yych = *++YYCURSOR; if (yych <= ',') { if (yych == '+') goto yy69; goto yy18; } else { if (yych <= '-') goto yy69; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; } yy67: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; if (yych == ';') goto yy63; goto yy18; yy69: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; goto yy18; yy70: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ';') { if (yych <= '/') goto yy18; if (yych <= '9') goto yy70; if (yych <= ':') goto yy18; goto yy63; } else { if (yych <= 'E') { if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy72: yych = *++YYCURSOR; if (yych != 'F') goto yy18; yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; #line 611 "ext/standard/var_unserializer.re" { *p = YYCURSOR; if (!strncmp((char*)start + 2, "NAN", 3)) { ZVAL_DOUBLE(rval, php_get_nan()); } else if (!strncmp((char*)start + 2, "INF", 3)) { ZVAL_DOUBLE(rval, php_get_inf()); } else if (!strncmp((char*)start + 2, "-INF", 4)) { ZVAL_DOUBLE(rval, -php_get_inf()); } else { ZVAL_NULL(rval); } return 1; } #line 1151 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; goto yy18; yy77: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy78; if (yych <= '/') goto yy18; if (yych <= '9') goto yy79; goto yy18; } yy78: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy79: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; #line 585 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 int digits = YYCURSOR - start - 3; if (start[2] == '-' || start[2] == '+') { digits--; } /* Use double for large zend_long values that were serialized on a 64-bit system */ if (digits >= MAX_LENGTH_OF_LONG - 1) { if (digits == MAX_LENGTH_OF_LONG - 1) { int cmp = strncmp((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1); if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) { goto use_double; } } else { goto use_double; } } #endif *p = YYCURSOR; ZVAL_LONG(rval, parse_iv(start + 2)); return 1; } #line 1204 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= '2') goto yy18; yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; #line 579 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_BOOL(rval, parse_iv(start + 2)); return 1; } #line 1218 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; #line 573 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_NULL(rval); return 1; } #line 1227 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy90; if (yych <= '/') goto yy18; if (yych <= '9') goto yy91; goto yy18; } yy90: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy91: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; #line 548 "ext/standard/var_unserializer.re" { zend_long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_iv(start + 2) - 1; if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } if (rval_ref == rval) { return 0; } if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { ZVAL_UNDEF(rval); return 1; } ZVAL_COPY(rval, rval_ref); return 1; } #line 1275 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy96; if (yych <= '/') goto yy18; if (yych <= '9') goto yy97; goto yy18; } yy96: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy97: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; #line 522 "ext/standard/var_unserializer.re" { zend_long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_iv(start + 2) - 1; if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } zval_ptr_dtor(rval); if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { ZVAL_UNDEF(rval); return 1; } if (Z_ISREF_P(rval_ref)) { ZVAL_COPY(rval, rval_ref); } else { ZVAL_NEW_REF(rval_ref, rval_ref); ZVAL_COPY(rval, rval_ref); } return 1; } #line 1324 "ext/standard/var_unserializer.c" } #line 875 "ext/standard/var_unserializer.re" return 0; }
PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) { const unsigned char *cursor, *limit, *marker, *start; zval **rval_ref; limit = max; cursor = *p; if (YYCURSOR >= YYLIMIT) { return 0; } if (var_hash && cursor[0] != 'R') { var_push(var_hash, rval); } start = cursor; #line 425 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; switch (yych) { case 'C': case 'O': goto yy13; case 'N': goto yy5; case 'R': goto yy2; case 'S': goto yy10; case 'a': goto yy11; case 'b': goto yy6; case 'd': goto yy8; case 'i': goto yy7; case 'o': goto yy12; case 'r': goto yy4; case 's': goto yy9; case '}': goto yy14; default: goto yy16; } yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: #line 747 "ext/standard/var_unserializer.re" { return 0; } #line 487 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; goto yy3; yy5: yych = *++YYCURSOR; if (yych == ';') goto yy87; goto yy3; yy6: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy83; goto yy3; yy7: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy77; goto yy3; yy8: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy53; goto yy3; yy9: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy46; goto yy3; yy10: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy39; goto yy3; yy11: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy32; goto yy3; yy12: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy25; goto yy3; yy13: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy17; goto yy3; yy14: ++YYCURSOR; #line 741 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } #line 536 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; yy17: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } if (yych == '+') goto yy19; yy18: YYCURSOR = YYMARKER; goto yy3; yy19: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } goto yy18; yy20: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } if (yych != ':') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 624 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; char *class_name; zend_class_entry *ce; zend_class_entry **pce; int incomplete_class = 0; int custom_object = 0; zval *user_func; zval *retval_ptr; zval **args[1]; zval *arg_func_name; if (*start == 'C') { custom_object = 1; } INIT_PZVAL(*rval); len2 = len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len || len == 0) { *p = start + 2; return 0; } class_name = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } if (*(YYCURSOR+1) != ':') { *p = YYCURSOR+1; return 0; } len3 = strspn(class_name, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\"); if (len3 != len) { *p = YYCURSOR + len3 - len; return 0; } class_name = estrndup(class_name, len); do { /* Try to find class directly */ if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { ce = *pce; break; } /* Check for unserialize callback */ if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) { incomplete_class = 1; ce = PHP_IC_ENTRY; break; } /* Call unserialize callback */ MAKE_STD_ZVAL(user_func); ZVAL_STRING(user_func, PG(unserialize_callback_func), 1); args[0] = &arg_func_name; MAKE_STD_ZVAL(arg_func_name); ZVAL_STRING(arg_func_name, class_name, 1); if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val); incomplete_class = 1; ce = PHP_IC_ENTRY; zval_ptr_dtor(&user_func); zval_ptr_dtor(&arg_func_name); break; } if (retval_ptr) { zval_ptr_dtor(&retval_ptr); } /* The callback function may have defined the class */ if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { ce = *pce; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val); incomplete_class = 1; ce = PHP_IC_ENTRY; } zval_ptr_dtor(&user_func); zval_ptr_dtor(&arg_func_name); break; } while (1); *p = YYCURSOR; if (custom_object) { int ret = object_custom(UNSERIALIZE_PASSTHRU, ce); if (ret && incomplete_class) { php_store_class_name(*rval, class_name, len2); } efree(class_name); return ret; } elements = object_common1(UNSERIALIZE_PASSTHRU, ce); if (incomplete_class) { php_store_class_name(*rval, class_name, len2); } efree(class_name); return object_common2(UNSERIALIZE_PASSTHRU, elements); } #line 683 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy26; if (yych <= '/') goto yy18; if (yych <= '9') goto yy27; goto yy18; } yy26: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy27: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy27; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 616 "ext/standard/var_unserializer.re" { INIT_PZVAL(*rval); return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } #line 716 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; goto yy18; yy33: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy34: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; #line 596 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ *p = YYCURSOR; if (elements < 0) { return 0; } INIT_PZVAL(*rval); array_init_size(*rval, elements); if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) { return 0; } return finish_nested_data(UNSERIALIZE_PASSTHRU); } #line 757 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; if (yych <= '/') goto yy18; if (yych <= '9') goto yy41; goto yy18; yy40: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy41: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy41; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 567 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) { return 0; } if (*(YYCURSOR) != '"') { efree(str); *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_STRINGL(*rval, str, len, 0); return 1; } #line 807 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; if (yych <= '/') goto yy18; if (yych <= '9') goto yy48; goto yy18; yy47: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy48: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy48; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 539 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } str = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_STRINGL(*rval, str, len, 1); return 1; } #line 856 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { if (yych <= ',') { if (yych == '+') goto yy57; goto yy18; } else { if (yych <= '-') goto yy55; if (yych <= '.') goto yy60; goto yy18; } } else { if (yych <= 'I') { if (yych <= '9') goto yy58; if (yych <= 'H') goto yy18; goto yy56; } else { if (yych != 'N') goto yy18; } } yych = *++YYCURSOR; if (yych == 'A') goto yy76; goto yy18; yy55: yych = *++YYCURSOR; if (yych <= '/') { if (yych == '.') goto yy60; goto yy18; } else { if (yych <= '9') goto yy58; if (yych != 'I') goto yy18; } yy56: yych = *++YYCURSOR; if (yych == 'N') goto yy72; goto yy18; yy57: yych = *++YYCURSOR; if (yych == '.') goto yy60; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy58: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ':') { if (yych <= '.') { if (yych <= '-') goto yy18; goto yy70; } else { if (yych <= '/') goto yy18; if (yych <= '9') goto yy58; goto yy18; } } else { if (yych <= 'E') { if (yych <= ';') goto yy63; if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy60: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy61: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ';') { if (yych <= '/') goto yy18; if (yych <= '9') goto yy61; if (yych <= ':') goto yy18; } else { if (yych <= 'E') { if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy63: ++YYCURSOR; #line 529 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 use_double: #endif *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); return 1; } #line 954 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy66; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; goto yy18; } yy66: yych = *++YYCURSOR; if (yych <= ',') { if (yych == '+') goto yy69; goto yy18; } else { if (yych <= '-') goto yy69; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; } yy67: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; if (yych == ';') goto yy63; goto yy18; yy69: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; goto yy18; yy70: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ';') { if (yych <= '/') goto yy18; if (yych <= '9') goto yy70; if (yych <= ':') goto yy18; goto yy63; } else { if (yych <= 'E') { if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy72: yych = *++YYCURSOR; if (yych != 'F') goto yy18; yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; #line 514 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); if (!strncmp(start + 2, "NAN", 3)) { ZVAL_DOUBLE(*rval, php_get_nan()); } else if (!strncmp(start + 2, "INF", 3)) { ZVAL_DOUBLE(*rval, php_get_inf()); } else if (!strncmp(start + 2, "-INF", 4)) { ZVAL_DOUBLE(*rval, -php_get_inf()); } return 1; } #line 1028 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; goto yy18; yy77: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy78; if (yych <= '/') goto yy18; if (yych <= '9') goto yy79; goto yy18; } yy78: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy79: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; #line 487 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 int digits = YYCURSOR - start - 3; if (start[2] == '-' || start[2] == '+') { digits--; } /* Use double for large long values that were serialized on a 64-bit system */ if (digits >= MAX_LENGTH_OF_LONG - 1) { if (digits == MAX_LENGTH_OF_LONG - 1) { int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1); if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) { goto use_double; } } else { goto use_double; } } #endif *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } #line 1082 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= '2') goto yy18; yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; #line 480 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } #line 1097 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; #line 473 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } #line 1107 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy90; if (yych <= '/') goto yy18; if (yych <= '9') goto yy91; goto yy18; } yy90: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy91: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; #line 450 "ext/standard/var_unserializer.re" { long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_iv(start + 2) - 1; if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) { return 0; } if (*rval == *rval_ref) return 0; if (*rval != NULL) { zval_ptr_dtor(rval); } *rval = *rval_ref; Z_ADDREF_PP(rval); Z_UNSET_ISREF_PP(rval); return 1; } #line 1153 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy96; if (yych <= '/') goto yy18; if (yych <= '9') goto yy97; goto yy18; } yy96: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy97: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; #line 429 "ext/standard/var_unserializer.re" { long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_iv(start + 2) - 1; if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) { return 0; } if (*rval != NULL) { zval_ptr_dtor(rval); } *rval = *rval_ref; Z_ADDREF_PP(rval); Z_SET_ISREF_PP(rval); return 1; } #line 1197 "ext/standard/var_unserializer.c" } #line 749 "ext/standard/var_unserializer.re" return 0; }
static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER) { const unsigned char *cursor, *limit, *marker, *start; zval *rval_ref; limit = max; cursor = *p; if (YYCURSOR >= YYLIMIT) { return 0; } if (var_hash && (*p)[0] != 'R') { var_push(var_hash, rval); } start = cursor; #line 656 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; switch (yych) { case 'C': case 'O': goto yy4; case 'N': goto yy5; case 'R': goto yy6; case 'S': goto yy7; case 'a': goto yy8; case 'b': goto yy9; case 'd': goto yy10; case 'i': goto yy11; case 'o': goto yy12; case 'r': goto yy13; case 's': goto yy14; case '}': goto yy15; default: goto yy2; } yy2: ++YYCURSOR; yy3: #line 1043 "ext/standard/var_unserializer.re" { return 0; } #line 716 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy17; goto yy3; yy5: yych = *++YYCURSOR; if (yych == ';') goto yy19; goto yy3; yy6: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy21; goto yy3; yy7: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy22; goto yy3; yy8: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy23; goto yy3; yy9: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy24; goto yy3; yy10: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy25; goto yy3; yy11: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy26; goto yy3; yy12: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy27; goto yy3; yy13: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy28; goto yy3; yy14: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy29; goto yy3; yy15: ++YYCURSOR; #line 1037 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } #line 769 "ext/standard/var_unserializer.c" yy17: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { goto yy30; } yy18: YYCURSOR = YYMARKER; goto yy3; yy19: ++YYCURSOR; #line 709 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_NULL(rval); return 1; } #line 786 "ext/standard/var_unserializer.c" yy21: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy32; goto yy18; yy22: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; goto yy18; yy23: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy36; goto yy18; yy24: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '1') goto yy38; goto yy18; yy25: yych = *++YYCURSOR; if (yych <= '/') { if (yych <= ',') { if (yych == '+') goto yy39; goto yy18; } else { if (yych <= '-') goto yy40; if (yych <= '.') goto yy41; goto yy18; } } else { if (yych <= 'I') { if (yych <= '9') goto yy42; if (yych <= 'H') goto yy18; goto yy44; } else { if (yych == 'N') goto yy45; goto yy18; } } yy26: yych = *++YYCURSOR; if (yych <= ',') { if (yych == '+') goto yy46; goto yy18; } else { if (yych <= '-') goto yy46; if (yych <= '/') goto yy18; if (yych <= '9') goto yy47; goto yy18; } yy27: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy49; goto yy18; yy28: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy51; goto yy18; yy29: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy53; goto yy18; yy30: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yybm[0+yych] & 128) { goto yy30; } if (yych <= '/') goto yy18; if (yych <= ':') goto yy55; goto yy18; yy32: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy32; if (yych == ';') goto yy56; goto yy18; yy34: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; if (yych <= ':') goto yy58; goto yy18; yy36: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy36; if (yych <= ':') goto yy59; goto yy18; yy38: yych = *++YYCURSOR; if (yych == ';') goto yy60; goto yy18; yy39: yych = *++YYCURSOR; if (yych == '.') goto yy41; if (yych <= '/') goto yy18; if (yych <= '9') goto yy42; goto yy18; yy40: yych = *++YYCURSOR; if (yych <= '/') { if (yych != '.') goto yy18; } else { if (yych <= '9') goto yy42; if (yych == 'I') goto yy44; goto yy18; } yy41: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy62; goto yy18; yy42: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; if (yych <= ':') { if (yych <= '.') { if (yych <= '-') goto yy18; goto yy62; } else { if (yych <= '/') goto yy18; if (yych <= '9') goto yy42; goto yy18; } } else { if (yych <= 'E') { if (yych <= ';') goto yy64; if (yych <= 'D') goto yy18; goto yy66; } else { if (yych == 'e') goto yy66; goto yy18; } } yy44: yych = *++YYCURSOR; if (yych == 'N') goto yy67; goto yy18; yy45: yych = *++YYCURSOR; if (yych == 'A') goto yy68; goto yy18; yy46: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy47: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy47; if (yych == ';') goto yy69; goto yy18; yy49: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy49; if (yych <= ':') goto yy71; goto yy18; yy51: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy51; if (yych == ';') goto yy72; goto yy18; yy53: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy53; if (yych <= ':') goto yy74; goto yy18; yy55: yych = *++YYCURSOR; if (yych == '"') goto yy75; goto yy18; yy56: ++YYCURSOR; #line 660 "ext/standard/var_unserializer.re" { zend_long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_uiv(start + 2) - 1; if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { return 0; } if (Z_ISREF_P(rval_ref)) { ZVAL_COPY(rval, rval_ref); } else { ZVAL_NEW_REF(rval_ref, rval_ref); ZVAL_COPY(rval, rval_ref); } return 1; } #line 1010 "ext/standard/var_unserializer.c" yy58: yych = *++YYCURSOR; if (yych == '"') goto yy77; goto yy18; yy59: yych = *++YYCURSOR; if (yych == '{') goto yy79; goto yy18; yy60: ++YYCURSOR; #line 715 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_BOOL(rval, parse_iv(start + 2)); return 1; } #line 1027 "ext/standard/var_unserializer.c" yy62: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; if (yych <= ';') { if (yych <= '/') goto yy18; if (yych <= '9') goto yy62; if (yych <= ':') goto yy18; } else { if (yych <= 'E') { if (yych <= 'D') goto yy18; goto yy66; } else { if (yych == 'e') goto yy66; goto yy18; } } yy64: ++YYCURSOR; #line 763 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 use_double: #endif *p = YYCURSOR; ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); return 1; } #line 1056 "ext/standard/var_unserializer.c" yy66: yych = *++YYCURSOR; if (yych <= ',') { if (yych == '+') goto yy81; goto yy18; } else { if (yych <= '-') goto yy81; if (yych <= '/') goto yy18; if (yych <= '9') goto yy82; goto yy18; } yy67: yych = *++YYCURSOR; if (yych == 'F') goto yy84; goto yy18; yy68: yych = *++YYCURSOR; if (yych == 'N') goto yy84; goto yy18; yy69: ++YYCURSOR; #line 721 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 int digits = YYCURSOR - start - 3; if (start[2] == '-' || start[2] == '+') { digits--; } /* Use double for large zend_long values that were serialized on a 64-bit system */ if (digits >= MAX_LENGTH_OF_LONG - 1) { if (digits == MAX_LENGTH_OF_LONG - 1) { int cmp = strncmp((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1); if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) { goto use_double; } } else { goto use_double; } } #endif *p = YYCURSOR; ZVAL_LONG(rval, parse_iv(start + 2)); return 1; } #line 1104 "ext/standard/var_unserializer.c" yy71: yych = *++YYCURSOR; if (yych == '"') goto yy85; goto yy18; yy72: ++YYCURSOR; #line 685 "ext/standard/var_unserializer.re" { zend_long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_uiv(start + 2) - 1; if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } if (rval_ref == rval) { return 0; } if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { return 0; } ZVAL_COPY(rval, rval_ref); return 1; } #line 1135 "ext/standard/var_unserializer.c" yy74: yych = *++YYCURSOR; if (yych == '"') goto yy87; goto yy18; yy75: ++YYCURSOR; #line 885 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; zend_long elements; char *str; zend_string *class_name; zend_class_entry *ce; int incomplete_class = 0; int custom_object = 0; zval user_func; zval retval; zval args[1]; if (!var_hash) return 0; if (*start == 'C') { custom_object = 1; } len2 = len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len || len == 0) { *p = start + 2; return 0; } str = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } if (*(YYCURSOR+1) != ':') { *p = YYCURSOR+1; return 0; } len3 = strspn(str, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\"); if (len3 != len) { *p = YYCURSOR + len3 - len; return 0; } class_name = zend_string_init(str, len, 0); do { if(!unserialize_allowed_class(class_name, var_hash)) { incomplete_class = 1; ce = PHP_IC_ENTRY; break; } /* Try to find class directly */ BG(serialize_lock)++; ce = zend_lookup_class(class_name); if (ce) { BG(serialize_lock)--; if (EG(exception)) { zend_string_release(class_name); return 0; } break; } BG(serialize_lock)--; if (EG(exception)) { zend_string_release(class_name); return 0; } /* Check for unserialize callback */ if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) { incomplete_class = 1; ce = PHP_IC_ENTRY; break; } /* Call unserialize callback */ ZVAL_STRING(&user_func, PG(unserialize_callback_func)); ZVAL_STR_COPY(&args[0], class_name); BG(serialize_lock)++; if (call_user_function_ex(CG(function_table), NULL, &user_func, &retval, 1, args, 0, NULL) != SUCCESS) { BG(serialize_lock)--; if (EG(exception)) { zend_string_release(class_name); zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); return 0; } php_error_docref(NULL, E_WARNING, "defined (%s) but not found", Z_STRVAL(user_func)); incomplete_class = 1; ce = PHP_IC_ENTRY; zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); break; } BG(serialize_lock)--; zval_ptr_dtor(&retval); if (EG(exception)) { zend_string_release(class_name); zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); return 0; } /* The callback function may have defined the class */ BG(serialize_lock)++; if ((ce = zend_lookup_class(class_name)) == NULL) { php_error_docref(NULL, E_WARNING, "Function %s() hasn't defined the class it was called for", Z_STRVAL(user_func)); incomplete_class = 1; ce = PHP_IC_ENTRY; } BG(serialize_lock)--; zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); break; } while (1); *p = YYCURSOR; if (custom_object) { int ret; ret = object_custom(UNSERIALIZE_PASSTHRU, ce); if (ret && incomplete_class) { php_store_class_name(rval, ZSTR_VAL(class_name), len2); } zend_string_release(class_name); return ret; } elements = object_common1(UNSERIALIZE_PASSTHRU, ce); if (elements < 0) { zend_string_release(class_name); return 0; } if (incomplete_class) { php_store_class_name(rval, ZSTR_VAL(class_name), len2); } zend_string_release(class_name); return object_common2(UNSERIALIZE_PASSTHRU, elements); } #line 1294 "ext/standard/var_unserializer.c" yy77: ++YYCURSOR; #line 810 "ext/standard/var_unserializer.re" { size_t len, maxlen; zend_string *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } if ((str = unserialize_str(&YYCURSOR, len, maxlen)) == NULL) { return 0; } if (*(YYCURSOR) != '"') { zend_string_free(str); *p = YYCURSOR; return 0; } if (*(YYCURSOR + 1) != ';') { efree(str); *p = YYCURSOR + 1; return 0; } YYCURSOR += 2; *p = YYCURSOR; ZVAL_STR(rval, str); return 1; } #line 1331 "ext/standard/var_unserializer.c" yy79: ++YYCURSOR; #line 844 "ext/standard/var_unserializer.re" { zend_long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ *p = YYCURSOR; if (!var_hash) return 0; if (elements < 0 || elements >= HT_MAX_SIZE) { return 0; } array_init_size(rval, elements); if (elements) { /* we can't convert from packed to hash during unserialization, because reference to some zvals might be keept in var_hash (to support references) */ zend_hash_real_init(Z_ARRVAL_P(rval), 0); } /* The array may contain references to itself, in which case we'll be modifying an * rc>1 array. This is okay, since the array is, ostensibly, only visible to * unserialize (in practice unserialization handlers also see it). Ideally we should * prohibit "r:" references to non-objects, as we only generate them for objects. */ HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(rval)); if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) { return 0; } return finish_nested_data(UNSERIALIZE_PASSTHRU); } #line 1364 "ext/standard/var_unserializer.c" yy81: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy82: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy82; if (yych == ';') goto yy64; goto yy18; yy84: yych = *++YYCURSOR; if (yych == ';') goto yy89; goto yy18; yy85: ++YYCURSOR; #line 874 "ext/standard/var_unserializer.re" { zend_long elements; if (!var_hash) return 0; elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR); if (elements < 0 || elements >= HT_MAX_SIZE) { return 0; } return object_common2(UNSERIALIZE_PASSTHRU, elements); } #line 1394 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; #line 772 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } str = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } if (*(YYCURSOR + 1) != ';') { *p = YYCURSOR + 1; return 0; } YYCURSOR += 2; *p = YYCURSOR; if (len == 0) { ZVAL_EMPTY_STRING(rval); } else if (len == 1) { ZVAL_INTERNED_STR(rval, ZSTR_CHAR((zend_uchar)*str)); } else { ZVAL_STRINGL(rval, str, len); } return 1; } #line 1435 "ext/standard/var_unserializer.c" yy89: ++YYCURSOR; #line 747 "ext/standard/var_unserializer.re" { *p = YYCURSOR; if (!strncmp((char*)start + 2, "NAN", 3)) { ZVAL_DOUBLE(rval, ZEND_NAN); } else if (!strncmp((char*)start + 2, "INF", 3)) { ZVAL_DOUBLE(rval, ZEND_INFINITY); } else if (!strncmp((char*)start + 2, "-INF", 4)) { ZVAL_DOUBLE(rval, -ZEND_INFINITY); } else { ZVAL_NULL(rval); } return 1; } #line 1454 "ext/standard/var_unserializer.c" } #line 1045 "ext/standard/var_unserializer.re" return 0; }
EE* eval_expr(Node* expr) { if (is_unary_op(expr)) return ee_new(UNTYPED, mem_asprintf("%s(%s)", unary_op_map(expr->type), eval_Value(node_get_child(expr, 0)))); if (is_binary_op(expr)) return ee_new (UNTYPED, mem_asprintf("%s(%s, %s)", binary_op_map(expr->type), eval_Value(node_get_child(expr, 0)), eval_Value(node_get_child(expr, 1)))); switch(expr->type){ case K_TRUE: return ee_new("Bool", "VALUE_TRUE"); case K_FALSE: return ee_new("Bool", "VALUE_FALSE"); case K_NIL: return ee_new("Nil", "VALUE_NIL"); case K_EOF: return ee_new("Eof", "VALUE_EOF"); case ID: if (context_block != NULL){ // If it's a block param, then OK. if (var_query_kind(expr->text) == VAR_BLOCK_PARAM) return ee_new(var_query_type(expr->text), var_query_c_name(expr->text)); else return ee_new(var_query_type(expr->text), closure_add(expr->text, var_query_c_name(expr->text))); } else return ee_new(var_query_type(expr->text), var_query_c_name(expr->text)); case SYMBOL: return ee_new("Integer", cache_dsym(expr->text + 1)); case INT: return ee_new("Integer", mem_asprintf("int64_to_val(%s)", expr->text)); case DOUBLE: return ee_new("Double", mem_asprintf("double_to_val(%s)", expr->text)); case STRING: { const char* str = expr->text; return ee_new("String", mem_asprintf("string_to_val(\"%s\")", str)); } break; case CHARACTER: { const char* str = expr->text; return ee_new("Integer", mem_asprintf("int64_to_val(%d)", (int) str[1])); } break; case EXPR_ARRAY: { Node* expr_list = node_get_child(expr, 0); return ee_new("Array", mem_asprintf("array1_to_val2(%u %s)", expr_list->children.size, eval_expr_list(expr_list, true))); } case EXPR_MAP: { Node* m_list = node_get_child(expr, 0); bool is_map = false, is_set = false; const char* args = ""; const int num_ms = node_num_children(m_list); assert(num_ms > 0); for (int i = 0; i < num_ms; i++){ Node* m = node_get_child(m_list, i); switch (node_num_children(m)){ case 2: is_map = true; args = mem_asprintf("%s, %s, %s", args, eval_Value(node_get_child(m, 0)), eval_Value(node_get_child(m, 1))); break; case 1: is_set = true; args = mem_asprintf("%s, %s", args, eval_Value(node_get_child(m, 0))); break; default: assert_never(); break; } } if (is_map and is_set){ fatal_node(expr, "invalid curly braces: is this a set or a map?"); } if (is_map) return ee_new("Map", mem_asprintf("ht_new_map(%d%s)", num_ms, args)); if (is_set) return ee_new("Set", mem_asprintf("ht_new_set(%d%s)", num_ms, args)); assert_never(); } break; case EXPR_INDEX: return ee_new(UNTYPED, eval_index(node_get_child(expr, 0), node_get_child(expr, 1), NULL)); case EXPR_CALL: { Node* callee = node_get_node(expr, "callee"); Node* args = node_get_node(expr, "args"); // If callee is a field, then we must check if its a method call. if (callee->type == EXPR_FIELD){ const char* field_name = node_get_string(callee, "name"); Node* left = node_get_child(callee, 0); const char* s = eval_expr_as_id(left); if (s == NULL or var_query(s)) return ee_new(UNTYPED, eval_obj_call(left, field_name, args)); } const char* s = eval_expr_as_id(callee); if (s != NULL){ // Could be a tuple constructor. if (strequal(s, "tuple")){ return ee_new("Tuple", mem_asprintf("tuple_to_val(%u %s)", node_num_children(args), eval_expr_list(args, true))); } // If all of callee can be evaluated as an id, then it must be a static // call. return ee_new(UNTYPED, eval_static_call(s, args)); } return ee_new(UNTYPED, mem_asprintf("func_call%d(%s %s)", node_num_children(args), eval_Value(callee), eval_expr_list(args, true))); } case EXPR_RANGE_BOUNDED: { Node* left = node_get_child(expr, 0); Node* right = node_get_child(expr, 1); return ee_new("Range", mem_asprintf("range_to_val(RANGE_BOUNDED, " "val_to_int64(%s), val_to_int64(%s))", eval_Value(left), eval_Value(right))); } case EXPR_RANGE_BOUNDED_LEFT: return ee_new("Range", mem_asprintf("range_to_val(RANGE_BOUNDED_LEFT, " "val_to_int64(%s), 0)", eval_Value(node_get_child(expr, 0)))); case EXPR_RANGE_BOUNDED_RIGHT: return ee_new("Range", mem_asprintf("range_to_val(RANGE_BOUNDED_RIGHT, " "0, val_to_int64(%s))", eval_Value(node_get_child(expr, 0)))); case EXPR_RANGE_UNBOUNDED: return ee_new("Range", "range_to_val(RANGE_UNBOUNDED, 0, 0)"); case EXPR_FIELD: { // Attempt to evaluate this field as a static symbol. Node* left = node_get_child(expr, 0); const char* s = eval_expr_as_id(left); if (s == NULL or var_query(s)){ // Dynamic field. const char* field = node_get_string(expr, "name"); return ee_new(UNTYPED, mem_asprintf("field_get(%s, %s)", eval_Value(left), cache_dsym(field))); } else { // Could be a global variable. s = eval_expr_as_id(expr); if (context_block != NULL){ return ee_new(var_query_type(s), closure_add(s, var_query_c_name(s))); } else return ee_new(var_query_type(s), var_query_c_name(s)); } } break; case EXPR_AT_VAR: { const char* name = node_get_string(expr, "name"); if (context_ci == NULL){ fatal_node(expr, "'@%s' in something that's not a class", name); } if (context_ci->type != CLASS_FIELD){ fatal_node(expr, "'@%s' in a class that's not a field class", name); } return ee_new(UNTYPED, mem_asprintf("field_get(__self, %s)", cache_dsym(name))); } case C_CODE: { const char* str = util_trim_ends(expr->text); if (strstr(expr->text, "return")){ fatal_warn("careless return in C code may disrupt the stack (use RRETURN)"); } if (context_fi != NULL){ if (context_fi->type == METHOD or context_fi->type == CONSTRUCTOR or context_fi->type == VIRTUAL_GET or context_fi->type == VIRTUAL_SET){ if (strchr(str, '@') != NULL and context_ci->type != CLASS_CDATA) fatal_node(expr, "@ in C code in a class that is not cdata"); str = util_replace(str, '@', "_c_data->"); } } return ee_new(UNTYPED, str); } case EXPR_IS_TYPE: { const char* type = eval_type(node_get_child(expr, 1)); if (var_query(type)){ fatal_node(expr, "type '%s' in 'is' expression is a variable", type); } return ee_new("Bool", mem_asprintf("pack_bool(obj_klass(%s) == %s)", eval_Value(node_get_child(expr, 0)), cache_type(type))); } case EXPR_BLOCK: { fatal_push("in anonymous block"); if (context_block != NULL){ fatal_node(expr, "nested blocks are not implemented yet"); } // Initialize context_block context_block = mem_new(BlockContext); sbuf_init(&(context_block->sbuf_code), ""); sarray_init(&(context_block->closure_names)); sarray_init(&(context_block->closure_exprs)); static int counter = 0; counter++; context_block->func_name = mem_asprintf("ripe_blk%d", counter); Node* param_list = node_get_node(expr, "param_list"); Node* stmt_list = node_get_node(expr, "stmt_list"); var_push(); // Print out the header of the anonymous function sbuf_printf(&(context_block->sbuf_code), "static Value %s(Value __block", context_block->func_name); for (int i = 0; i < node_num_children(param_list); i++){ Node* param = node_get_child(param_list, i); const char* name = node_get_string(param, "name"); const char* c_name = util_c_name(name); if (node_has_string(param, "array")) fatal_node(expr, "array parameters for blocks are not implemented yet"); const char* type = "?"; // TODO: Deal with type. var_add_local2(name, c_name, type, VAR_BLOCK_PARAM); sbuf_printf(&(context_block->sbuf_code), ", Value %s", c_name); } sbuf_printf(&(context_block->sbuf_code), ")\n"); // Generate block code sbuf_printf(&(context_block->sbuf_code), "{\n"); sbuf_printf(&(context_block->sbuf_code), " Func* _c_data = obj_c_data(__block);\n"); sbuf_printf(&(context_block->sbuf_code), " stack_annot_push(\"anonymous function\");\n"); sbuf_printf(&(context_block->sbuf_code), "%s", gen_block(stmt_list)); sbuf_printf(&(context_block->sbuf_code), "}\n"); // Now, print out the block function to WR_HEADER wr_print(WR_HEADER, "%s", context_block->sbuf_code.str); const char* result = mem_asprintf("block_to_val(%s, %d, %d", context_block->func_name, node_num_children(param_list), context_block->closure_names.size); for (uint i = 0; i < context_block->closure_names.size; i++){ const char* evaluated = sarray_get_ptr(&(context_block->closure_exprs), i); result = mem_asprintf("%s, %s", result, evaluated); } result = mem_asprintf("%s)", result); // End EXPR_BLOCK var_pop(); context_block = NULL; fatal_pop(); return ee_new("Function", result); } default: assert_never(); } return NULL; }
void put_cmd(vararray* binary, line_t* cur_line, int j, vararray* labels, vararray* funcs, int step) { int i = j, argc = 0, to_push = 0, pos = 0; char cmd_num = 0; char* keyword = cur_line->words[j]; char modif[4], words[2][MAX_WORD_LENGTH]; memset(modif, 0, sizeof(modif)); memset(words, 0, sizeof(words)); for (i = j+1; i < cur_line->num; (argc++, i++)) { DBGPRINT("1/Argument %d: %s\n", 0, words[0]);//What's this debugoutput tell you? strcpy(words[argc], cur_line->words[i]); DBGPRINT("2/Argument %d: %s\n", 0, words[0]); DBGPRINT("Argument %d: %s\n", argc, words[argc]);//QUESTION: Why you repeat the same dbgoutput here modif[argc] = get_modif(words[argc]); DBGPRINT("Argument %d: %s\n", 0, words[0]);// and here? } DBGPRINT("Argument %d: %s\n", 0, words[0]); DBGPRINT("Pre-define: Number: %d, keyword: \"%s\" MODIF: \"%s\" argc: %d\n", cmd_num, keyword, modif, argc); #define CMD_(number_, keyword_, argc_, modif_, code_)\ if ((!strcmp(keyword, #keyword_)) && (modif_cmp(modif, modif_)) && (argc_ == argc)) {\ strcpy(modif, modif_);\ cmd_num = number_;\ } else #include "../s_common/s_cmdlist.h" #undef CMD_ USERERR("No command found for \"%s\"\n", cur_line->words[0]); DBGPRINT("Number: %d, keyword: \"%s\" MODIF: \"%s\" argc: %d\n", cmd_num, keyword, modif, argc); pos = binary->nmax;//QUESTION: What's purpose of it? var_push(binary, &cmd_num); for (i = 0; i < argc; i++) { switch (modif[i]) { case 'r': { DBGPRINT("Call of get_reg_num.\n"); to_push = get_reg_num(words[i]); break; } case 'n': { to_push = get_digit(words[i]); break; } case 'f': { to_push = get_lf(words[i], funcs, pos, step); break; } case 'l': { to_push = get_lf(words[i], labels, pos, step); break; } default: { FATALERR("Modif failure. Act_modif: %s\n", modif);//I think it's debug error. User shouldn't know it break; } } DBGPRINT("ARGUMENT %d: %d\n", i, to_push); var_pushn(binary, &to_push, sizeof(int)); } DBGPRINT("Num of elems in bin: %d;\n"\ "-----------------------------\n", (int)binary->nmax); }