PageRenderTime 88ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/Zend/zend_API.c

http://github.com/infusion/PHP
C | 3561 lines | 2851 code | 478 blank | 232 comment | 721 complexity | 7ac15605f35356bce15a1814ce6d9a67 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1998-2011 Zend Technologies Ltd. (http://www.zend.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.00 of the Zend license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.zend.com/license/2_00.txt. |
  11. | If you did not receive a copy of the Zend license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@zend.com so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Andi Gutmans <andi@zend.com> |
  16. | Zeev Suraski <zeev@zend.com> |
  17. | Andrei Zmievski <andrei@php.net> |
  18. +----------------------------------------------------------------------+
  19. */
  20. /* $Id: zend_API.c 307424 2011-01-12 22:17:10Z felipe $ */
  21. #include "zend.h"
  22. #include "zend_execute.h"
  23. #include "zend_API.h"
  24. #include "zend_modules.h"
  25. #include "zend_constants.h"
  26. #include "zend_exceptions.h"
  27. #include "zend_closures.h"
  28. #ifdef HAVE_STDARG_H
  29. #include <stdarg.h>
  30. #endif
  31. /* these variables are true statics/globals, and have to be mutex'ed on every access */
  32. static int module_count=0;
  33. ZEND_API HashTable module_registry;
  34. /* this function doesn't check for too many parameters */
  35. ZEND_API int zend_get_parameters(int ht, int param_count, ...) /* {{{ */
  36. {
  37. void **p;
  38. int arg_count;
  39. va_list ptr;
  40. zval **param, *param_ptr;
  41. TSRMLS_FETCH();
  42. p = zend_vm_stack_top(TSRMLS_C) - 1;
  43. arg_count = (int)(zend_uintptr_t) *p;
  44. if (param_count>arg_count) {
  45. return FAILURE;
  46. }
  47. va_start(ptr, param_count);
  48. while (param_count-->0) {
  49. param = va_arg(ptr, zval **);
  50. param_ptr = *(p-arg_count);
  51. if (!PZVAL_IS_REF(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) {
  52. zval *new_tmp;
  53. ALLOC_ZVAL(new_tmp);
  54. *new_tmp = *param_ptr;
  55. zval_copy_ctor(new_tmp);
  56. INIT_PZVAL(new_tmp);
  57. param_ptr = new_tmp;
  58. Z_DELREF_P((zval *) *(p-arg_count));
  59. *(p-arg_count) = param_ptr;
  60. }
  61. *param = param_ptr;
  62. arg_count--;
  63. }
  64. va_end(ptr);
  65. return SUCCESS;
  66. }
  67. /* }}} */
  68. ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument_array TSRMLS_DC) /* {{{ */
  69. {
  70. void **p;
  71. int arg_count;
  72. zval *param_ptr;
  73. p = zend_vm_stack_top(TSRMLS_C) - 1;
  74. arg_count = (int)(zend_uintptr_t) *p;
  75. if (param_count>arg_count) {
  76. return FAILURE;
  77. }
  78. while (param_count-->0) {
  79. param_ptr = *(p-arg_count);
  80. if (!PZVAL_IS_REF(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) {
  81. zval *new_tmp;
  82. ALLOC_ZVAL(new_tmp);
  83. *new_tmp = *param_ptr;
  84. zval_copy_ctor(new_tmp);
  85. INIT_PZVAL(new_tmp);
  86. param_ptr = new_tmp;
  87. Z_DELREF_P((zval *) *(p-arg_count));
  88. *(p-arg_count) = param_ptr;
  89. }
  90. *(argument_array++) = param_ptr;
  91. arg_count--;
  92. }
  93. return SUCCESS;
  94. }
  95. /* }}} */
  96. /* Zend-optimized Extended functions */
  97. /* this function doesn't check for too many parameters */
  98. ZEND_API int zend_get_parameters_ex(int param_count, ...) /* {{{ */
  99. {
  100. void **p;
  101. int arg_count;
  102. va_list ptr;
  103. zval ***param;
  104. TSRMLS_FETCH();
  105. p = zend_vm_stack_top(TSRMLS_C) - 1;
  106. arg_count = (int)(zend_uintptr_t) *p;
  107. if (param_count>arg_count) {
  108. return FAILURE;
  109. }
  110. va_start(ptr, param_count);
  111. while (param_count-->0) {
  112. param = va_arg(ptr, zval ***);
  113. *param = (zval **) p-(arg_count--);
  114. }
  115. va_end(ptr);
  116. return SUCCESS;
  117. }
  118. /* }}} */
  119. ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_array TSRMLS_DC) /* {{{ */
  120. {
  121. void **p;
  122. int arg_count;
  123. p = zend_vm_stack_top(TSRMLS_C) - 1;
  124. arg_count = (int)(zend_uintptr_t) *p;
  125. if (param_count>arg_count) {
  126. return FAILURE;
  127. }
  128. while (param_count-->0) {
  129. zval **value = (zval**)(p-arg_count);
  130. *(argument_array++) = value;
  131. arg_count--;
  132. }
  133. return SUCCESS;
  134. }
  135. /* }}} */
  136. ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TSRMLS_DC) /* {{{ */
  137. {
  138. void **p;
  139. int arg_count;
  140. p = zend_vm_stack_top(TSRMLS_C) - 1;
  141. arg_count = (int)(zend_uintptr_t) *p;
  142. if (param_count>arg_count) {
  143. return FAILURE;
  144. }
  145. while (param_count-->0) {
  146. zval **param = (zval **) p-(arg_count--);
  147. zval_add_ref(param);
  148. add_next_index_zval(argument_array, *param);
  149. }
  150. return SUCCESS;
  151. }
  152. /* }}} */
  153. ZEND_API void zend_wrong_param_count(TSRMLS_D) /* {{{ */
  154. {
  155. char *space;
  156. char *class_name = get_active_class_name(&space TSRMLS_CC);
  157. zend_error(E_WARNING, "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name(TSRMLS_C));
  158. }
  159. /* }}} */
  160. /* Argument parsing API -- andrei */
  161. ZEND_API char *zend_get_type_by_const(int type) /* {{{ */
  162. {
  163. switch(type) {
  164. case IS_BOOL:
  165. return "boolean";
  166. case IS_LONG:
  167. return "integer";
  168. case IS_DOUBLE:
  169. return "double";
  170. case IS_STRING:
  171. return "string";
  172. case IS_OBJECT:
  173. return "object";
  174. case IS_RESOURCE:
  175. return "resource";
  176. case IS_NULL:
  177. return "null";
  178. case IS_ARRAY:
  179. return "array";
  180. default:
  181. return "unknown";
  182. }
  183. }
  184. /* }}} */
  185. ZEND_API char *zend_zval_type_name(const zval *arg) /* {{{ */
  186. {
  187. return zend_get_type_by_const(Z_TYPE_P(arg));
  188. }
  189. /* }}} */
  190. ZEND_API zend_class_entry *zend_get_class_entry(const zval *zobject TSRMLS_DC) /* {{{ */
  191. {
  192. if (Z_OBJ_HT_P(zobject)->get_class_entry) {
  193. return Z_OBJ_HT_P(zobject)->get_class_entry(zobject TSRMLS_CC);
  194. } else {
  195. zend_error(E_ERROR, "Class entry requested for an object without PHP class");
  196. return NULL;
  197. }
  198. }
  199. /* }}} */
  200. /* returns 1 if you need to copy result, 0 if it's already a copy */
  201. ZEND_API int zend_get_object_classname(const zval *object, char **class_name, zend_uint *class_name_len TSRMLS_DC) /* {{{ */
  202. {
  203. if (Z_OBJ_HT_P(object)->get_class_name == NULL ||
  204. Z_OBJ_HT_P(object)->get_class_name(object, class_name, class_name_len, 0 TSRMLS_CC) != SUCCESS) {
  205. zend_class_entry *ce = Z_OBJCE_P(object);
  206. *class_name = ce->name;
  207. *class_name_len = ce->name_length;
  208. return 1;
  209. }
  210. return 0;
  211. }
  212. /* }}} */
  213. static int parse_arg_object_to_string(zval **arg TSRMLS_DC) /* {{{ */
  214. {
  215. if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
  216. SEPARATE_ZVAL_IF_NOT_REF(arg);
  217. if (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_STRING TSRMLS_CC) == SUCCESS) {
  218. return SUCCESS;
  219. }
  220. }
  221. /* Standard PHP objects */
  222. if (Z_OBJ_HT_PP(arg) == &std_object_handlers || !Z_OBJ_HANDLER_PP(arg, cast_object)) {
  223. SEPARATE_ZVAL_IF_NOT_REF(arg);
  224. if (zend_std_cast_object_tostring(*arg, *arg, IS_STRING TSRMLS_CC) == SUCCESS) {
  225. return SUCCESS;
  226. }
  227. }
  228. if (!Z_OBJ_HANDLER_PP(arg, cast_object) && Z_OBJ_HANDLER_PP(arg, get)) {
  229. int use_copy;
  230. zval *z = Z_OBJ_HANDLER_PP(arg, get)(*arg TSRMLS_CC);
  231. Z_ADDREF_P(z);
  232. if(Z_TYPE_P(z) != IS_OBJECT) {
  233. zval_dtor(*arg);
  234. Z_TYPE_P(*arg) = IS_NULL;
  235. zend_make_printable_zval(z, *arg, &use_copy);
  236. if (!use_copy) {
  237. ZVAL_ZVAL(*arg, z, 1, 1);
  238. }
  239. return SUCCESS;
  240. }
  241. zval_ptr_dtor(&z);
  242. }
  243. return FAILURE;
  244. }
  245. /* }}} */
  246. static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **spec, char **error, int *severity TSRMLS_DC) /* {{{ */
  247. {
  248. char *spec_walk = *spec;
  249. char c = *spec_walk++;
  250. int return_null = 0;
  251. /* scan through modifiers */
  252. while (1) {
  253. if (*spec_walk == '/') {
  254. SEPARATE_ZVAL_IF_NOT_REF(arg);
  255. } else if (*spec_walk == '!') {
  256. if (Z_TYPE_PP(arg) == IS_NULL) {
  257. return_null = 1;
  258. }
  259. } else {
  260. break;
  261. }
  262. spec_walk++;
  263. }
  264. switch (c) {
  265. case 'l':
  266. case 'L':
  267. {
  268. long *p = va_arg(*va, long *);
  269. switch (Z_TYPE_PP(arg)) {
  270. case IS_STRING:
  271. {
  272. double d;
  273. int type;
  274. if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), p, &d, -1)) == 0) {
  275. return "long";
  276. } else if (type == IS_DOUBLE) {
  277. if (c == 'L') {
  278. if (d > LONG_MAX) {
  279. *p = LONG_MAX;
  280. break;
  281. } else if (d < LONG_MIN) {
  282. *p = LONG_MIN;
  283. break;
  284. }
  285. }
  286. *p = zend_dval_to_lval(d);
  287. }
  288. }
  289. break;
  290. case IS_DOUBLE:
  291. if (c == 'L') {
  292. if (Z_DVAL_PP(arg) > LONG_MAX) {
  293. *p = LONG_MAX;
  294. break;
  295. } else if (Z_DVAL_PP(arg) < LONG_MIN) {
  296. *p = LONG_MIN;
  297. break;
  298. }
  299. }
  300. case IS_NULL:
  301. case IS_LONG:
  302. case IS_BOOL:
  303. convert_to_long_ex(arg);
  304. *p = Z_LVAL_PP(arg);
  305. break;
  306. case IS_ARRAY:
  307. case IS_OBJECT:
  308. case IS_RESOURCE:
  309. default:
  310. return "long";
  311. }
  312. }
  313. break;
  314. case 'd':
  315. {
  316. double *p = va_arg(*va, double *);
  317. switch (Z_TYPE_PP(arg)) {
  318. case IS_STRING:
  319. {
  320. long l;
  321. int type;
  322. if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &l, p, -1)) == 0) {
  323. return "double";
  324. } else if (type == IS_LONG) {
  325. *p = (double) l;
  326. }
  327. }
  328. break;
  329. case IS_NULL:
  330. case IS_LONG:
  331. case IS_DOUBLE:
  332. case IS_BOOL:
  333. convert_to_double_ex(arg);
  334. *p = Z_DVAL_PP(arg);
  335. break;
  336. case IS_ARRAY:
  337. case IS_OBJECT:
  338. case IS_RESOURCE:
  339. default:
  340. return "double";
  341. }
  342. }
  343. break;
  344. case 's':
  345. {
  346. char **p = va_arg(*va, char **);
  347. int *pl = va_arg(*va, int *);
  348. switch (Z_TYPE_PP(arg)) {
  349. case IS_NULL:
  350. if (return_null) {
  351. *p = NULL;
  352. *pl = 0;
  353. break;
  354. }
  355. /* break omitted intentionally */
  356. case IS_STRING:
  357. case IS_LONG:
  358. case IS_DOUBLE:
  359. case IS_BOOL:
  360. convert_to_string_ex(arg);
  361. if (UNEXPECTED(Z_ISREF_PP(arg) != 0)) {
  362. /* it's dangerous to return pointers to string
  363. buffer of referenced variable, because it can
  364. be clobbered throug magic callbacks */
  365. SEPARATE_ZVAL(arg);
  366. }
  367. *p = Z_STRVAL_PP(arg);
  368. *pl = Z_STRLEN_PP(arg);
  369. break;
  370. case IS_OBJECT:
  371. case IS_ARRAY:
  372. case IS_RESOURCE:
  373. default:
  374. return "string";
  375. }
  376. }
  377. break;
  378. case 'b':
  379. {
  380. zend_bool *p = va_arg(*va, zend_bool *);
  381. switch (Z_TYPE_PP(arg)) {
  382. case IS_NULL:
  383. case IS_STRING:
  384. case IS_LONG:
  385. case IS_DOUBLE:
  386. case IS_BOOL:
  387. convert_to_boolean_ex(arg);
  388. *p = Z_BVAL_PP(arg);
  389. break;
  390. case IS_ARRAY:
  391. case IS_OBJECT:
  392. case IS_RESOURCE:
  393. default:
  394. return "boolean";
  395. }
  396. }
  397. break;
  398. case 'r':
  399. {
  400. zval **p = va_arg(*va, zval **);
  401. if (return_null) {
  402. *p = NULL;
  403. break;
  404. }
  405. if (Z_TYPE_PP(arg) == IS_RESOURCE) {
  406. *p = *arg;
  407. } else {
  408. return "resource";
  409. }
  410. }
  411. break;
  412. case 'A':
  413. case 'a':
  414. {
  415. zval **p = va_arg(*va, zval **);
  416. if (return_null) {
  417. *p = NULL;
  418. break;
  419. }
  420. if (Z_TYPE_PP(arg) == IS_ARRAY || (c == 'A' && Z_TYPE_PP(arg) == IS_OBJECT)) {
  421. *p = *arg;
  422. } else {
  423. return "array";
  424. }
  425. }
  426. break;
  427. case 'H':
  428. case 'h':
  429. {
  430. HashTable **p = va_arg(*va, HashTable **);
  431. if (return_null) {
  432. *p = NULL;
  433. break;
  434. }
  435. if (Z_TYPE_PP(arg) == IS_ARRAY) {
  436. *p = Z_ARRVAL_PP(arg);
  437. } else if(c == 'H' && Z_TYPE_PP(arg) == IS_OBJECT) {
  438. *p = HASH_OF(*arg);
  439. if(*p == NULL) {
  440. return "array";
  441. }
  442. } else {
  443. return "array";
  444. }
  445. }
  446. break;
  447. case 'o':
  448. {
  449. zval **p = va_arg(*va, zval **);
  450. if (return_null) {
  451. *p = NULL;
  452. break;
  453. }
  454. if (Z_TYPE_PP(arg) == IS_OBJECT) {
  455. *p = *arg;
  456. } else {
  457. return "object";
  458. }
  459. }
  460. break;
  461. case 'O':
  462. {
  463. zval **p = va_arg(*va, zval **);
  464. zend_class_entry *ce = va_arg(*va, zend_class_entry *);
  465. if (return_null) {
  466. *p = NULL;
  467. break;
  468. }
  469. if (Z_TYPE_PP(arg) == IS_OBJECT &&
  470. (!ce || instanceof_function(Z_OBJCE_PP(arg), ce TSRMLS_CC))) {
  471. *p = *arg;
  472. } else {
  473. if (ce) {
  474. return ce->name;
  475. } else {
  476. return "object";
  477. }
  478. }
  479. }
  480. break;
  481. case 'C':
  482. {
  483. zend_class_entry **lookup, **pce = va_arg(*va, zend_class_entry **);
  484. zend_class_entry *ce_base = *pce;
  485. if (return_null) {
  486. *pce = NULL;
  487. break;
  488. }
  489. convert_to_string_ex(arg);
  490. if (zend_lookup_class(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &lookup TSRMLS_CC) == FAILURE) {
  491. *pce = NULL;
  492. } else {
  493. *pce = *lookup;
  494. }
  495. if (ce_base) {
  496. if ((!*pce || !instanceof_function(*pce, ce_base TSRMLS_CC))) {
  497. zend_spprintf(error, 0, "to be a class name derived from %s, '%s' given",
  498. ce_base->name, Z_STRVAL_PP(arg));
  499. *pce = NULL;
  500. return "";
  501. }
  502. }
  503. if (!*pce) {
  504. zend_spprintf(error, 0, "to be a valid class name, '%s' given",
  505. Z_STRVAL_PP(arg));
  506. return "";
  507. }
  508. break;
  509. }
  510. break;
  511. case 'f':
  512. {
  513. zend_fcall_info *fci = va_arg(*va, zend_fcall_info *);
  514. zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *);
  515. char *is_callable_error = NULL;
  516. if (return_null) {
  517. fci->size = 0;
  518. fcc->initialized = 0;
  519. break;
  520. }
  521. if (zend_fcall_info_init(*arg, 0, fci, fcc, NULL, &is_callable_error TSRMLS_CC) == SUCCESS) {
  522. if (is_callable_error) {
  523. *severity = E_STRICT;
  524. zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
  525. efree(is_callable_error);
  526. *spec = spec_walk;
  527. return "";
  528. }
  529. break;
  530. } else {
  531. if (is_callable_error) {
  532. *severity = E_WARNING;
  533. zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
  534. efree(is_callable_error);
  535. return "";
  536. } else {
  537. return "valid callback";
  538. }
  539. }
  540. }
  541. case 'z':
  542. {
  543. zval **p = va_arg(*va, zval **);
  544. if (return_null) {
  545. *p = NULL;
  546. } else {
  547. *p = *arg;
  548. }
  549. }
  550. break;
  551. case 'Z':
  552. {
  553. zval ***p = va_arg(*va, zval ***);
  554. if (return_null) {
  555. *p = NULL;
  556. } else {
  557. *p = arg;
  558. }
  559. }
  560. break;
  561. default:
  562. return "unknown";
  563. }
  564. *spec = spec_walk;
  565. return NULL;
  566. }
  567. /* }}} */
  568. static int zend_parse_arg(int arg_num, zval **arg, va_list *va, char **spec, int quiet TSRMLS_DC) /* {{{ */
  569. {
  570. char *expected_type = NULL, *error = NULL;
  571. int severity = E_WARNING;
  572. expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, &error, &severity TSRMLS_CC);
  573. if (expected_type) {
  574. if (!quiet && (*expected_type || error)) {
  575. char *space;
  576. char *class_name = get_active_class_name(&space TSRMLS_CC);
  577. if (error) {
  578. zend_error(severity, "%s%s%s() expects parameter %d %s",
  579. class_name, space, get_active_function_name(TSRMLS_C), arg_num, error);
  580. efree(error);
  581. } else {
  582. zend_error(severity, "%s%s%s() expects parameter %d to be %s, %s given",
  583. class_name, space, get_active_function_name(TSRMLS_C), arg_num, expected_type,
  584. zend_zval_type_name(*arg));
  585. }
  586. }
  587. if (severity != E_STRICT) {
  588. return FAILURE;
  589. }
  590. }
  591. return SUCCESS;
  592. }
  593. /* }}} */
  594. static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int flags TSRMLS_DC) /* {{{ */
  595. {
  596. char *spec_walk;
  597. int c, i;
  598. int min_num_args = -1;
  599. int max_num_args = 0;
  600. int post_varargs = 0;
  601. zval **arg;
  602. int arg_count = (int)(zend_uintptr_t) *(zend_vm_stack_top(TSRMLS_C) - 1);
  603. int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
  604. zend_bool have_varargs = 0;
  605. zval ****varargs = NULL;
  606. int *n_varargs = NULL;
  607. for (spec_walk = type_spec; *spec_walk; spec_walk++) {
  608. c = *spec_walk;
  609. switch (c) {
  610. case 's':
  611. if (max_num_args < arg_count) {
  612. arg = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - max_num_args));
  613. if (Z_TYPE_PP(arg) == IS_OBJECT) {
  614. parse_arg_object_to_string(arg TSRMLS_CC);
  615. }
  616. }
  617. /* break missing intentionally */
  618. case 'l': case 'd':
  619. case 'H': case 'b':
  620. case 'r': case 'a':
  621. case 'o': case 'O':
  622. case 'z': case 'Z':
  623. case 'C': case 'h':
  624. case 'f': case 'A':
  625. max_num_args++;
  626. break;
  627. case '|':
  628. min_num_args = max_num_args;
  629. break;
  630. case '/':
  631. case '!':
  632. /* Pass */
  633. break;
  634. case '*':
  635. case '+':
  636. if (have_varargs) {
  637. if (!quiet) {
  638. zend_function *active_function = EG(current_execute_data)->function_state.function;
  639. char *class_name = active_function->common.scope ? active_function->common.scope->name : "";
  640. zend_error(E_WARNING, "%s%s%s(): only one varargs specifier (* or +) is permitted",
  641. class_name,
  642. class_name[0] ? "::" : "",
  643. active_function->common.function_name);
  644. }
  645. return FAILURE;
  646. }
  647. have_varargs = 1;
  648. /* we expect at least one parameter in varargs */
  649. if (c == '+') {
  650. max_num_args++;
  651. }
  652. /* mark the beginning of varargs */
  653. post_varargs = max_num_args;
  654. break;
  655. default:
  656. if (!quiet) {
  657. zend_function *active_function = EG(current_execute_data)->function_state.function;
  658. char *class_name = active_function->common.scope ? active_function->common.scope->name : "";
  659. zend_error(E_WARNING, "%s%s%s(): bad type specifier while parsing parameters",
  660. class_name,
  661. class_name[0] ? "::" : "",
  662. active_function->common.function_name);
  663. }
  664. return FAILURE;
  665. }
  666. }
  667. if (min_num_args < 0) {
  668. min_num_args = max_num_args;
  669. }
  670. if (have_varargs) {
  671. /* calculate how many required args are at the end of the specifier list */
  672. post_varargs = max_num_args - post_varargs;
  673. max_num_args = -1;
  674. }
  675. if (num_args < min_num_args || (num_args > max_num_args && max_num_args > 0)) {
  676. if (!quiet) {
  677. zend_function *active_function = EG(current_execute_data)->function_state.function;
  678. char *class_name = active_function->common.scope ? active_function->common.scope->name : "";
  679. zend_error(E_WARNING, "%s%s%s() expects %s %d parameter%s, %d given",
  680. class_name,
  681. class_name[0] ? "::" : "",
  682. active_function->common.function_name,
  683. min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
  684. num_args < min_num_args ? min_num_args : max_num_args,
  685. (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
  686. num_args);
  687. }
  688. return FAILURE;
  689. }
  690. if (num_args > arg_count) {
  691. zend_error(E_WARNING, "%s(): could not obtain parameters for parsing",
  692. get_active_function_name(TSRMLS_C));
  693. return FAILURE;
  694. }
  695. i = 0;
  696. while (num_args-- > 0) {
  697. if (*type_spec == '|') {
  698. type_spec++;
  699. }
  700. if (*type_spec == '*' || *type_spec == '+') {
  701. int num_varargs = num_args + 1 - post_varargs;
  702. /* eat up the passed in storage even if it won't be filled in with varargs */
  703. varargs = va_arg(*va, zval ****);
  704. n_varargs = va_arg(*va, int *);
  705. type_spec++;
  706. if (num_varargs > 0) {
  707. int iv = 0;
  708. zval **p = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - i));
  709. *n_varargs = num_varargs;
  710. /* allocate space for array and store args */
  711. *varargs = safe_emalloc(num_varargs, sizeof(zval **), 0);
  712. while (num_varargs-- > 0) {
  713. (*varargs)[iv++] = p++;
  714. }
  715. /* adjust how many args we have left and restart loop */
  716. num_args = num_args + 1 - iv;
  717. i += iv;
  718. continue;
  719. } else {
  720. *varargs = NULL;
  721. *n_varargs = 0;
  722. }
  723. }
  724. arg = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count-i));
  725. if (zend_parse_arg(i+1, arg, va, &type_spec, quiet TSRMLS_CC) == FAILURE) {
  726. /* clean up varargs array if it was used */
  727. if (varargs && *varargs) {
  728. efree(*varargs);
  729. *varargs = NULL;
  730. }
  731. return FAILURE;
  732. }
  733. i++;
  734. }
  735. return SUCCESS;
  736. }
  737. /* }}} */
  738. #define RETURN_IF_ZERO_ARGS(num_args, type_spec, quiet) { \
  739. int __num_args = (num_args); \
  740. \
  741. if (0 == (type_spec)[0] && 0 != __num_args && !(quiet)) { \
  742. char *__space; \
  743. char * __class_name = get_active_class_name(&__space TSRMLS_CC); \
  744. zend_error(E_WARNING, "%s%s%s() expects exactly 0 parameters, %d given", \
  745. __class_name, __space, \
  746. get_active_function_name(TSRMLS_C), __num_args); \
  747. return FAILURE; \
  748. }\
  749. }
  750. ZEND_API int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...) /* {{{ */
  751. {
  752. va_list va;
  753. int retval;
  754. RETURN_IF_ZERO_ARGS(num_args, type_spec, flags & ZEND_PARSE_PARAMS_QUIET);
  755. va_start(va, type_spec);
  756. retval = zend_parse_va_args(num_args, type_spec, &va, flags TSRMLS_CC);
  757. va_end(va);
  758. return retval;
  759. }
  760. /* }}} */
  761. ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...) /* {{{ */
  762. {
  763. va_list va;
  764. int retval;
  765. RETURN_IF_ZERO_ARGS(num_args, type_spec, 0);
  766. va_start(va, type_spec);
  767. retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
  768. va_end(va);
  769. return retval;
  770. }
  771. /* }}} */
  772. ZEND_API int zend_parse_method_parameters(int num_args TSRMLS_DC, zval *this_ptr, char *type_spec, ...) /* {{{ */
  773. {
  774. va_list va;
  775. int retval;
  776. char *p = type_spec;
  777. zval **object;
  778. zend_class_entry *ce;
  779. if (!this_ptr) {
  780. RETURN_IF_ZERO_ARGS(num_args, p, 0);
  781. va_start(va, type_spec);
  782. retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
  783. va_end(va);
  784. } else {
  785. p++;
  786. RETURN_IF_ZERO_ARGS(num_args, p, 0);
  787. va_start(va, type_spec);
  788. object = va_arg(va, zval **);
  789. ce = va_arg(va, zend_class_entry *);
  790. *object = this_ptr;
  791. if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) {
  792. zend_error(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
  793. ce->name, get_active_function_name(TSRMLS_C), Z_OBJCE_P(this_ptr)->name, get_active_function_name(TSRMLS_C));
  794. }
  795. retval = zend_parse_va_args(num_args, p, &va, 0 TSRMLS_CC);
  796. va_end(va);
  797. }
  798. return retval;
  799. }
  800. /* }}} */
  801. ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args TSRMLS_DC, zval *this_ptr, char *type_spec, ...) /* {{{ */
  802. {
  803. va_list va;
  804. int retval;
  805. char *p = type_spec;
  806. zval **object;
  807. zend_class_entry *ce;
  808. int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
  809. if (!this_ptr) {
  810. RETURN_IF_ZERO_ARGS(num_args, p, quiet);
  811. va_start(va, type_spec);
  812. retval = zend_parse_va_args(num_args, type_spec, &va, flags TSRMLS_CC);
  813. va_end(va);
  814. } else {
  815. p++;
  816. RETURN_IF_ZERO_ARGS(num_args, p, quiet);
  817. va_start(va, type_spec);
  818. object = va_arg(va, zval **);
  819. ce = va_arg(va, zend_class_entry *);
  820. *object = this_ptr;
  821. if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) {
  822. if (!quiet) {
  823. zend_error(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
  824. ce->name, get_active_function_name(TSRMLS_C), Z_OBJCE_P(this_ptr)->name, get_active_function_name(TSRMLS_C));
  825. }
  826. return FAILURE;
  827. }
  828. retval = zend_parse_va_args(num_args, p, &va, flags TSRMLS_CC);
  829. va_end(va);
  830. }
  831. return retval;
  832. }
  833. /* }}} */
  834. /* Argument parsing API -- andrei */
  835. ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC) /* {{{ */
  836. {
  837. ALLOC_HASHTABLE_REL(Z_ARRVAL_P(arg));
  838. _zend_hash_init(Z_ARRVAL_P(arg), size, NULL, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
  839. Z_TYPE_P(arg) = IS_ARRAY;
  840. return SUCCESS;
  841. }
  842. /* }}} */
  843. static int zend_merge_property(zval **value TSRMLS_DC, int num_args, va_list args, const zend_hash_key *hash_key) /* {{{ */
  844. {
  845. /* which name should a numeric property have ? */
  846. if (hash_key->nKeyLength) {
  847. zval *obj = va_arg(args, zval *);
  848. zend_object_handlers *obj_ht = va_arg(args, zend_object_handlers *);
  849. zval *member;
  850. MAKE_STD_ZVAL(member);
  851. ZVAL_STRINGL(member, hash_key->arKey, hash_key->nKeyLength-1, 1);
  852. obj_ht->write_property(obj, member, *value TSRMLS_CC);
  853. zval_ptr_dtor(&member);
  854. }
  855. return ZEND_HASH_APPLY_KEEP;
  856. }
  857. /* }}} */
  858. /* This function should be called after the constructor has been called
  859. * because it may call __set from the uninitialized object otherwise. */
  860. ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destroy_ht TSRMLS_DC) /* {{{ */
  861. {
  862. zend_object_handlers *obj_ht = Z_OBJ_HT_P(obj);
  863. zend_class_entry *old_scope = EG(scope);
  864. EG(scope) = Z_OBJCE_P(obj);
  865. zend_hash_apply_with_arguments(properties TSRMLS_CC, (apply_func_args_t)zend_merge_property, 2, obj, obj_ht);
  866. EG(scope) = old_scope;
  867. if (destroy_ht) {
  868. zend_hash_destroy(properties);
  869. FREE_HASHTABLE(properties);
  870. }
  871. }
  872. /* }}} */
  873. ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
  874. {
  875. if (!class_type->constants_updated || !CE_STATIC_MEMBERS(class_type)) {
  876. zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry);
  877. zend_class_entry *old_scope = *scope;
  878. *scope = class_type;
  879. zend_hash_apply_with_argument(&class_type->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
  880. zend_hash_apply_with_argument(&class_type->default_properties, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
  881. if (!CE_STATIC_MEMBERS(class_type)) {
  882. HashPosition pos;
  883. zval **p;
  884. if (class_type->parent) {
  885. zend_update_class_constants(class_type->parent TSRMLS_CC);
  886. }
  887. #if ZTS
  888. ALLOC_HASHTABLE(CG(static_members)[(zend_intptr_t)(class_type->static_members)]);
  889. #else
  890. ALLOC_HASHTABLE(class_type->static_members);
  891. #endif
  892. zend_hash_init(CE_STATIC_MEMBERS(class_type), zend_hash_num_elements(&class_type->default_static_members), NULL, ZVAL_PTR_DTOR, 0);
  893. zend_hash_internal_pointer_reset_ex(&class_type->default_static_members, &pos);
  894. while (zend_hash_get_current_data_ex(&class_type->default_static_members, (void**)&p, &pos) == SUCCESS) {
  895. char *str_index;
  896. uint str_length;
  897. ulong num_index;
  898. zval **q;
  899. zend_hash_get_current_key_ex(&class_type->default_static_members, &str_index, &str_length, &num_index, 0, &pos);
  900. if (Z_ISREF_PP(p) &&
  901. class_type->parent &&
  902. zend_hash_find(&class_type->parent->default_static_members, str_index, str_length, (void**)&q) == SUCCESS &&
  903. *p == *q &&
  904. zend_hash_find(CE_STATIC_MEMBERS(class_type->parent), str_index, str_length, (void**)&q) == SUCCESS
  905. ) {
  906. Z_ADDREF_PP(q);
  907. Z_SET_ISREF_PP(q);
  908. zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)q, sizeof(zval*), NULL);
  909. } else {
  910. zval *r;
  911. ALLOC_ZVAL(r);
  912. *r = **p;
  913. INIT_PZVAL(r);
  914. zval_copy_ctor(r);
  915. zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)&r, sizeof(zval*), NULL);
  916. }
  917. zend_hash_move_forward_ex(&class_type->default_static_members, &pos);
  918. }
  919. }
  920. zend_hash_apply_with_argument(CE_STATIC_MEMBERS(class_type), (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
  921. *scope = old_scope;
  922. class_type->constants_updated = 1;
  923. }
  924. }
  925. /* }}} */
  926. /* This function requires 'properties' to contain all props declared in the
  927. * class and all props being public. If only a subset is given or the class
  928. * has protected members then you need to merge the properties seperately by
  929. * calling zend_merge_properties(). */
  930. ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC) /* {{{ */
  931. {
  932. zval *tmp;
  933. zend_object *object;
  934. if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
  935. char *what = class_type->ce_flags & ZEND_ACC_INTERFACE ? "interface" : "abstract class";
  936. zend_error(E_ERROR, "Cannot instantiate %s %s", what, class_type->name);
  937. }
  938. zend_update_class_constants(class_type TSRMLS_CC);
  939. Z_TYPE_P(arg) = IS_OBJECT;
  940. if (class_type->create_object == NULL) {
  941. Z_OBJVAL_P(arg) = zend_objects_new(&object, class_type TSRMLS_CC);
  942. if (properties) {
  943. object->properties = properties;
  944. } else {
  945. ALLOC_HASHTABLE_REL(object->properties);
  946. zend_hash_init(object->properties, zend_hash_num_elements(&class_type->default_properties), NULL, ZVAL_PTR_DTOR, 0);
  947. zend_hash_copy(object->properties, &class_type->default_properties, zval_copy_property_ctor(class_type), (void *) &tmp, sizeof(zval *));
  948. }
  949. } else {
  950. Z_OBJVAL_P(arg) = class_type->create_object(class_type TSRMLS_CC);
  951. }
  952. return SUCCESS;
  953. }
  954. /* }}} */
  955. ZEND_API int _object_init_ex(zval *arg, zend_class_entry *class_type ZEND_FILE_LINE_DC TSRMLS_DC) /* {{{ */
  956. {
  957. return _object_and_properties_init(arg, class_type, 0 ZEND_FILE_LINE_RELAY_CC TSRMLS_CC);
  958. }
  959. /* }}} */
  960. ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC TSRMLS_DC) /* {{{ */
  961. {
  962. return _object_init_ex(arg, zend_standard_class_def ZEND_FILE_LINE_RELAY_CC TSRMLS_CC);
  963. }
  964. /* }}} */
  965. ZEND_API int add_assoc_function(zval *arg, const char *key, void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS)) /* {{{ */
  966. {
  967. zend_error(E_WARNING, "add_assoc_function() is no longer supported");
  968. return FAILURE;
  969. }
  970. /* }}} */
  971. ZEND_API int add_assoc_long_ex(zval *arg, const char *key, uint key_len, long n) /* {{{ */
  972. {
  973. zval *tmp;
  974. MAKE_STD_ZVAL(tmp);
  975. ZVAL_LONG(tmp, n);
  976. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
  977. }
  978. /* }}} */
  979. ZEND_API int add_assoc_null_ex(zval *arg, const char *key, uint key_len) /* {{{ */
  980. {
  981. zval *tmp;
  982. MAKE_STD_ZVAL(tmp);
  983. ZVAL_NULL(tmp);
  984. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
  985. }
  986. /* }}} */
  987. ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, uint key_len, int b) /* {{{ */
  988. {
  989. zval *tmp;
  990. MAKE_STD_ZVAL(tmp);
  991. ZVAL_BOOL(tmp, b);
  992. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
  993. }
  994. /* }}} */
  995. ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, uint key_len, int r) /* {{{ */
  996. {
  997. zval *tmp;
  998. MAKE_STD_ZVAL(tmp);
  999. ZVAL_RESOURCE(tmp, r);
  1000. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
  1001. }
  1002. /* }}} */
  1003. ZEND_API int add_assoc_double_ex(zval *arg, const char *key, uint key_len, double d) /* {{{ */
  1004. {
  1005. zval *tmp;
  1006. MAKE_STD_ZVAL(tmp);
  1007. ZVAL_DOUBLE(tmp, d);
  1008. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
  1009. }
  1010. /* }}} */
  1011. ZEND_API int add_assoc_string_ex(zval *arg, const char *key, uint key_len, char *str, int duplicate) /* {{{ */
  1012. {
  1013. zval *tmp;
  1014. MAKE_STD_ZVAL(tmp);
  1015. ZVAL_STRING(tmp, str, duplicate);
  1016. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
  1017. }
  1018. /* }}} */
  1019. ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, uint key_len, char *str, uint length, int duplicate) /* {{{ */
  1020. {
  1021. zval *tmp;
  1022. MAKE_STD_ZVAL(tmp);
  1023. ZVAL_STRINGL(tmp, str, length, duplicate);
  1024. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
  1025. }
  1026. /* }}} */
  1027. ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, uint key_len, zval *value) /* {{{ */
  1028. {
  1029. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &value, sizeof(zval *), NULL);
  1030. }
  1031. /* }}} */
  1032. ZEND_API int add_index_long(zval *arg, ulong index, long n) /* {{{ */
  1033. {
  1034. zval *tmp;
  1035. MAKE_STD_ZVAL(tmp);
  1036. ZVAL_LONG(tmp, n);
  1037. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
  1038. }
  1039. /* }}} */
  1040. ZEND_API int add_index_null(zval *arg, ulong index) /* {{{ */
  1041. {
  1042. zval *tmp;
  1043. MAKE_STD_ZVAL(tmp);
  1044. ZVAL_NULL(tmp);
  1045. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
  1046. }
  1047. /* }}} */
  1048. ZEND_API int add_index_bool(zval *arg, ulong index, int b) /* {{{ */
  1049. {
  1050. zval *tmp;
  1051. MAKE_STD_ZVAL(tmp);
  1052. ZVAL_BOOL(tmp, b);
  1053. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
  1054. }
  1055. /* }}} */
  1056. ZEND_API int add_index_resource(zval *arg, ulong index, int r) /* {{{ */
  1057. {
  1058. zval *tmp;
  1059. MAKE_STD_ZVAL(tmp);
  1060. ZVAL_RESOURCE(tmp, r);
  1061. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
  1062. }
  1063. /* }}} */
  1064. ZEND_API int add_index_double(zval *arg, ulong index, double d) /* {{{ */
  1065. {
  1066. zval *tmp;
  1067. MAKE_STD_ZVAL(tmp);
  1068. ZVAL_DOUBLE(tmp, d);
  1069. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
  1070. }
  1071. /* }}} */
  1072. ZEND_API int add_index_string(zval *arg, ulong index, const char *str, int duplicate) /* {{{ */
  1073. {
  1074. zval *tmp;
  1075. MAKE_STD_ZVAL(tmp);
  1076. ZVAL_STRING(tmp, str, duplicate);
  1077. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
  1078. }
  1079. /* }}} */
  1080. ZEND_API int add_index_stringl(zval *arg, ulong index, const char *str, uint length, int duplicate) /* {{{ */
  1081. {
  1082. zval *tmp;
  1083. MAKE_STD_ZVAL(tmp);
  1084. ZVAL_STRINGL(tmp, str, length, duplicate);
  1085. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
  1086. }
  1087. /* }}} */
  1088. ZEND_API int add_index_zval(zval *arg, ulong index, zval *value) /* {{{ */
  1089. {
  1090. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &value, sizeof(zval *), NULL);
  1091. }
  1092. /* }}} */
  1093. ZEND_API int add_next_index_long(zval *arg, long n) /* {{{ */
  1094. {
  1095. zval *tmp;
  1096. MAKE_STD_ZVAL(tmp);
  1097. ZVAL_LONG(tmp, n);
  1098. return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
  1099. }
  1100. /* }}} */
  1101. ZEND_API int add_next_index_null(zval *arg) /* {{{ */
  1102. {
  1103. zval *tmp;
  1104. MAKE_STD_ZVAL(tmp);
  1105. ZVAL_NULL(tmp);
  1106. return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
  1107. }
  1108. /* }}} */
  1109. ZEND_API int add_next_index_bool(zval *arg, int b) /* {{{ */
  1110. {
  1111. zval *tmp;
  1112. MAKE_STD_ZVAL(tmp);
  1113. ZVAL_BOOL(tmp, b);
  1114. return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
  1115. }
  1116. /* }}} */
  1117. ZEND_API int add_next_index_resource(zval *arg, int r) /* {{{ */
  1118. {
  1119. zval *tmp;
  1120. MAKE_STD_ZVAL(tmp);
  1121. ZVAL_RESOURCE(tmp, r);
  1122. return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
  1123. }
  1124. /* }}} */
  1125. ZEND_API int add_next_index_double(zval *arg, double d) /* {{{ */
  1126. {
  1127. zval *tmp;
  1128. MAKE_STD_ZVAL(tmp);
  1129. ZVAL_DOUBLE(tmp, d);
  1130. return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
  1131. }
  1132. /* }}} */
  1133. ZEND_API int add_next_index_string(zval *arg, const char *str, int duplicate) /* {{{ */
  1134. {
  1135. zval *tmp;
  1136. MAKE_STD_ZVAL(tmp);
  1137. ZVAL_STRING(tmp, str, duplicate);
  1138. return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
  1139. }
  1140. /* }}} */
  1141. ZEND_API int add_next_index_stringl(zval *arg, const char *str, uint length, int duplicate) /* {{{ */
  1142. {
  1143. zval *tmp;
  1144. MAKE_STD_ZVAL(tmp);
  1145. ZVAL_STRINGL(tmp, str, length, duplicate);
  1146. return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
  1147. }
  1148. /* }}} */
  1149. ZEND_API int add_next_index_zval(zval *arg, zval *value) /* {{{ */
  1150. {
  1151. return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &value, sizeof(zval *), NULL);
  1152. }
  1153. /* }}} */
  1154. ZEND_API int add_get_assoc_string_ex(zval *arg, const char *key, uint key_len, const char *str, void **dest, int duplicate) /* {{{ */
  1155. {
  1156. zval *tmp;
  1157. MAKE_STD_ZVAL(tmp);
  1158. ZVAL_STRING(tmp, str, duplicate);
  1159. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), dest);
  1160. }
  1161. /* }}} */
  1162. ZEND_API int add_get_assoc_stringl_ex(zval *arg, const char *key, uint key_len, const char *str, uint length, void **dest, int duplicate) /* {{{ */
  1163. {
  1164. zval *tmp;
  1165. MAKE_STD_ZVAL(tmp);
  1166. ZVAL_STRINGL(tmp, str, length, duplicate);
  1167. return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), dest);
  1168. }
  1169. /* }}} */
  1170. ZEND_API int add_get_index_long(zval *arg, ulong index, long l, void **dest) /* {{{ */
  1171. {
  1172. zval *tmp;
  1173. MAKE_STD_ZVAL(tmp);
  1174. ZVAL_LONG(tmp, l);
  1175. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
  1176. }
  1177. /* }}} */
  1178. ZEND_API int add_get_index_double(zval *arg, ulong index, double d, void **dest) /* {{{ */
  1179. {
  1180. zval *tmp;
  1181. MAKE_STD_ZVAL(tmp);
  1182. ZVAL_DOUBLE(tmp, d);
  1183. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
  1184. }
  1185. /* }}} */
  1186. ZEND_API int add_get_index_string(zval *arg, ulong index, const char *str, void **dest, int duplicate) /* {{{ */
  1187. {
  1188. zval *tmp;
  1189. MAKE_STD_ZVAL(tmp);
  1190. ZVAL_STRING(tmp, str, duplicate);
  1191. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
  1192. }
  1193. /* }}} */
  1194. ZEND_API int add_get_index_stringl(zval *arg, ulong index, const char *str, uint length, void **dest, int duplicate) /* {{{ */
  1195. {
  1196. zval *tmp;
  1197. MAKE_STD_ZVAL(tmp);
  1198. ZVAL_STRINGL(tmp, str, length, duplicate);
  1199. return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
  1200. }
  1201. /* }}} */
  1202. ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, long n TSRMLS_DC) /* {{{ */
  1203. {
  1204. zval *tmp;
  1205. zval *z_key;
  1206. MAKE_STD_ZVAL(tmp);
  1207. ZVAL_LONG(tmp, n);
  1208. MAKE_STD_ZVAL(z_key);
  1209. ZVAL_STRINGL(z_key, key, key_len-1, 1);
  1210. Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
  1211. zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
  1212. zval_ptr_dtor(&z_key);
  1213. return SUCCESS;
  1214. }
  1215. /* }}} */
  1216. ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, int b TSRMLS_DC) /* {{{ */
  1217. {
  1218. zval *tmp;
  1219. zval *z_key;
  1220. MAKE_STD_ZVAL(tmp);
  1221. ZVAL_BOOL(tmp, b);
  1222. MAKE_STD_ZVAL(z_key);
  1223. ZVAL_STRINGL(z_key, key, key_len-1, 1);
  1224. Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
  1225. zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
  1226. zval_ptr_dtor(&z_key);
  1227. return SUCCESS;
  1228. }
  1229. /* }}} */
  1230. ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRMLS_DC) /* {{{ */
  1231. {
  1232. zval *tmp;
  1233. zval *z_key;
  1234. MAKE_STD_ZVAL(tmp);
  1235. ZVAL_NULL(tmp);
  1236. MAKE_STD_ZVAL(z_key);
  1237. ZVAL_STRINGL(z_key, key, key_len-1, 1);
  1238. Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
  1239. zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
  1240. zval_ptr_dtor(&z_key);
  1241. return SUCCESS;
  1242. }
  1243. /* }}} */
  1244. ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len, long n TSRMLS_DC) /* {{{ */
  1245. {
  1246. zval *tmp;
  1247. zval *z_key;
  1248. MAKE_STD_ZVAL(tmp);
  1249. ZVAL_RESOURCE(tmp, n);
  1250. MAKE_STD_ZVAL(z_key);
  1251. ZVAL_STRINGL(z_key, key, key_len-1, 1);
  1252. Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
  1253. zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
  1254. zval_ptr_dtor(&z_key);
  1255. return SUCCESS;
  1256. }
  1257. /* }}} */
  1258. ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, double d TSRMLS_DC) /* {{{ */
  1259. {
  1260. zval *tmp;
  1261. zval *z_key;
  1262. MAKE_STD_ZVAL(tmp);
  1263. ZVAL_DOUBLE(tmp, d);
  1264. MAKE_STD_ZVAL(z_key);
  1265. ZVAL_STRINGL(z_key, key, key_len-1, 1);
  1266. Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
  1267. zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
  1268. zval_ptr_dtor(&z_key);
  1269. return SUCCESS;
  1270. }
  1271. /* }}} */
  1272. ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, char *str, int duplicate TSRMLS_DC) /* {{{ */
  1273. {
  1274. zval *tmp;
  1275. zval *z_key;
  1276. MAKE_STD_ZVAL(tmp);
  1277. ZVAL_STRING(tmp, str, duplicate);
  1278. MAKE_STD_ZVAL(z_key);
  1279. ZVAL_STRINGL(z_key, key, key_len-1, 1);
  1280. Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
  1281. zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
  1282. zval_ptr_dtor(&z_key);
  1283. return SUCCESS;
  1284. }
  1285. /* }}} */
  1286. ZEND_API int add_property_stringl_ex(zval *arg, const char *key, uint key_len, char *str, uint length, int duplicate TSRMLS_DC) /* {{{ */
  1287. {
  1288. zval *tmp;
  1289. zval *z_key;
  1290. MAKE_STD_ZVAL(tmp);
  1291. ZVAL_STRINGL(tmp, str, length, duplicate);
  1292. MAKE_STD_ZVAL(z_key);
  1293. ZVAL_STRINGL(z_key, key, key_len-1, 1);
  1294. Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
  1295. zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
  1296. zval_ptr_dtor(&z_key);
  1297. return SUCCESS;
  1298. }
  1299. /* }}} */
  1300. ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval *value TSRMLS_DC) /* {{{ */
  1301. {
  1302. zval *z_key;
  1303. MAKE_STD_ZVAL(z_key);
  1304. ZVAL_STRINGL(z_key, key, key_len-1, 1);
  1305. Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, value TSRMLS_CC);
  1306. zval_ptr_dtor(&z_key);
  1307. return SUCCESS;
  1308. }
  1309. /* }}} */
  1310. ZEND_API int zend_startup_module_ex(zend_module_entry *module TSRMLS_DC) /* {{{ */
  1311. {
  1312. int name_len;
  1313. char *lcname;
  1314. if (module->module_started) {
  1315. return SUCCESS;
  1316. }
  1317. module->module_started = 1;
  1318. /* Check module dependencies */
  1319. if (module->deps) {
  1320. const zend_module_dep *dep = module->deps;
  1321. while (dep->name) {
  1322. if (dep->type == MODULE_DEP_REQUIRED) {
  1323. zend_module_entry *req_mod;
  1324. name_len = strlen(dep->name);
  1325. lcname = zend_str_tolower_dup(dep->name, name_len);
  1326. if (zend_hash_find(&module_registry, lcname, name_len+1, (void**)&req_mod) == FAILURE || !req_mod->module_started) {
  1327. efree(lcname);
  1328. /* TODO: Check version relationship */
  1329. zend_error(E_CORE_WARNING, "Cannot load module '%s' because required module '%s' is not loaded", module->name, dep->name);
  1330. module->module_started = 0;
  1331. return FAILURE;
  1332. }
  1333. efree(lcname);
  1334. }
  1335. ++dep;
  1336. }
  1337. }
  1338. /* Initialize module globals */
  1339. if (module->globals_size) {
  1340. #ifdef ZTS
  1341. ts_allocate_id(module->globals_id_ptr, module->globals_size, (ts_allocate_ctor) module->globals_ctor, (ts_allocate_dtor) module->globals_dtor);
  1342. #else
  1343. if (module->globals_ctor) {
  1344. module->globals_ctor(module->globals_ptr TSRMLS_CC);
  1345. }
  1346. #endif
  1347. }
  1348. if (module->module_startup_func) {
  1349. EG(current_module) = module;
  1350. if (module->module_startup_func(module->type, module->module_number TSRMLS_CC)==FAILURE) {
  1351. zend_error(E_CORE_ERROR,"Unable to start %s module", module->name);
  1352. EG(current_module) = NULL;
  1353. return FAILURE;
  1354. }
  1355. EG(current_module) = NULL;
  1356. }
  1357. return SUCCESS;
  1358. }
  1359. /* }}} */
  1360. static void zend_sort_modules(void *base, size_t count, size_t siz, compare_func_t compare TSRMLS_DC) /* {{{ */
  1361. {
  1362. Bucket **b1 = base;
  1363. Bucket **b2;
  1364. Bucket **end = b1 + count;
  1365. Bucket *tmp;
  1366. zend_module_entry *m, *r;
  1367. while (b1 < end) {
  1368. try_again:
  1369. m = (zend_module_entry*)(*b1)->pData;
  1370. if (!m->module_started && m->deps) {
  1371. const zend_module_dep *dep = m->deps;
  1372. while (dep->name) {
  1373. if (dep->type == MODULE_DEP_REQUIRED || dep->type == MODULE_DEP_OPTIONAL) {
  1374. b2 = b1 + 1;
  1375. while (b2 < end) {
  1376. r = (zend_module_entry*)(*b2)->pData;
  1377. if (strcasecmp(dep->name, r->name) == 0) {
  1378. tmp = *b1;
  1379. *b1 = *b2;
  1380. *b2 = tmp;
  1381. goto try_again;
  1382. }
  1383. b2++;
  1384. }
  1385. }
  1386. dep++;
  1387. }
  1388. }
  1389. b1++;
  1390. }
  1391. }
  1392. /* }}} */
  1393. ZEND_API int zend_startup_modules(TSRMLS_D) /* {{{ */
  1394. {
  1395. zend_hash_sort(&module_registry, zend_sort_modules, NULL, 0 TSRMLS_CC);
  1396. zend_hash_apply(&module_registry, (apply_func_t)zend_startup_module_ex TSRMLS_CC);
  1397. return SUCCESS;
  1398. }
  1399. /* }}} */
  1400. ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TSRMLS_DC) /* {{{ */
  1401. {
  1402. int name_len;
  1403. char *lcname;
  1404. zend_module_entry *module_ptr;
  1405. if (!module) {
  1406. return NULL;
  1407. }
  1408. #if 0
  1409. zend_printf("%s: Registering module %d\n", module->name, module->module_number);
  1410. #endif
  1411. /* Check module dependencies */
  1412. if (module->deps) {
  1413. const zend_module_dep *dep = module->deps;
  1414. while (dep->name) {
  1415. if (dep->type == MODULE_DEP_CONFLICTS) {
  1416. name_len = strlen(dep->name);
  1417. lcname = zend_str_tolower_dup(dep->name, name_len);
  1418. if (zend_hash_exists(&module_registry, lcname, name_len+1)) {
  1419. efree(lcname);
  1420. /* TODO: Check version relationship */
  1421. zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name);
  1422. return NULL;
  1423. }
  1424. efree(lcname);
  1425. }
  1426. ++dep;
  1427. }
  1428. }
  1429. name_len = strlen(module->name);
  1430. lcname = zend_str_tolower_dup(module->name, name_len);
  1431. if (zend_hash_add(&module_registry, lcname, name_len+1, (void *)module, sizeof(zend_module_entry), (void**)&module_ptr)==FAILURE) {
  1432. zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
  1433. efree(lcname);
  1434. return NULL;
  1435. }
  1436. efree(lcname);
  1437. module = module_ptr;
  1438. EG(current_module) = module;
  1439. if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type TSRMLS_CC)==FAILURE) {
  1440. EG(current_module) = NULL;
  1441. zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name);
  1442. return NULL;
  1443. }
  1444. EG(current_module) = NULL;
  1445. return module;
  1446. }
  1447. /* }}} */
  1448. ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *module TSRMLS_DC) /* {{{ */
  1449. {
  1450. module->module_number = zend_next_free_module();
  1451. module->type = MODULE_PERSISTENT;
  1452. return zend_register_module_ex(module TSRMLS_CC);
  1453. }
  1454. /* }}} */
  1455. ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, int error_type TSRMLS_DC) /* {{{ */
  1456. {
  1457. char lcname[16];
  1458. int name_len;
  1459. /* we don't care if the function name is longer, in fact lowercasing only
  1460. * the beginning of the name speeds up the check process */
  1461. name_len = strlen(fptr->common.function_name);
  1462. zend_str_tolower_copy(lcname, fptr->common.function_name, MIN(name_len, sizeof(lcname)-1));
  1463. lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */
  1464. if (name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME)) && fptr->common.num_args != 0) {
  1465. zend_error(error_type, "Destructor %s::%s() cannot take arguments", ce->name, ZEND_DESTRUCTOR_FUNC_NAME);
  1466. } else if (name_len == sizeof(ZEND_CLONE_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)) && fptr->common.num_args != 0) {
  1467. zend_error(error_type, "Method %s::%s() cannot accept any arguments", ce->name, ZEND_CLONE_FUNC_NAME);
  1468. } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME))) {
  1469. if (fptr->common.num_args != 1) {
  1470. zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_GET_FUNC_NAME);
  1471. } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
  1472. zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_GET_FUNC_NAME);
  1473. }
  1474. } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME))) {
  1475. if (fptr->common.num_args != 2) {
  1476. zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_SET_FUNC_NAME);
  1477. } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
  1478. zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_SET_FUNC_NAME);
  1479. }
  1480. } else if (name_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME))) {
  1481. if (fptr->common.num_args != 1) {
  1482. zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_UNSET_FUNC_NAME);
  1483. } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
  1484. zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_UNSET_FUNC_NAME);
  1485. }
  1486. } else if (name_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME))) {
  1487. if (fptr->common.num_args != 1) {
  1488. zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_ISSET_FUNC_NAME);
  1489. } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
  1490. zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_ISSET_FUNC_NAME);
  1491. }
  1492. } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME))) {
  1493. if (fptr->common.num_args != 2) {
  1494. zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_CALL_FUNC_NAME);
  1495. } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
  1496. zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_CALL_FUNC_NAME);
  1497. }
  1498. } else if (name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1 &&
  1499. !memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1)
  1500. ) {
  1501. if (fptr->common.num_args != 2) {
  1502. zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_CALLSTATIC_FUNC_NAME);
  1503. } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
  1504. zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_CALLSTATIC_FUNC_NAME);
  1505. }
  1506. } else if (name_len == sizeof(ZEND_TOSTRING_FUNC_NAME) - 1 &&
  1507. !memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && fptr->common.num_args != 0
  1508. ) {
  1509. zend_error(error_type, "Method %s::%s() cannot take arguments", ce->name, ZEND_TOSTRING_FUNC_NAME);
  1510. }
  1511. }
  1512. /* }}} */
  1513. /* registers all functions in *library_functions in the function hash */
  1514. ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type TSRMLS_DC) /* {{{ */
  1515. {
  1516. const zend_function_entry *ptr = functions;
  1517. zend_function function, *reg_function;
  1518. zend_internal_function *internal_function = (zend_internal_function *)&function;
  1519. int count=0, unload=0;
  1520. HashTable *target_function_table = function_table;
  1521. int error_type;
  1522. zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL;
  1523. char *lowercase_name;
  1524. int fname_len;
  1525. char *lc_class_name = NULL;
  1526. int class_name_len = 0;
  1527. if (type==MODULE_PERSISTENT) {
  1528. error_type = E_CORE_WARNING;
  1529. } else {
  1530. error_type = E_WARNING;
  1531. }
  1532. if (!target_function_table) {
  1533. target_function_table = CG(function_table);
  1534. }
  1535. internal_function->type = ZEND_INTERNAL_FUNCTION;
  1536. internal_function->module = EG(current_module);
  1537. if (scope) {
  1538. class_name_len = strlen(scope->name);
  1539. if ((lc_class_name = zend_memrchr(scope->name, '\\', class_name_len))) {
  1540. ++lc_class_name;
  1541. class_name_len -= (lc_class_name - scope->name);
  1542. lc_class_name = zend_str_tolower_dup(lc_class_name, class_name_len);
  1543. } else {
  1544. lc_class_name = zend_str_tolower_dup(scope->name, class_name_len);
  1545. }
  1546. }
  1547. while (ptr->fname) {
  1548. internal_function->handler = ptr->handler;
  1549. internal_function->function_name = (char*)ptr->fname;
  1550. internal_function->scope = scope;
  1551. internal_function->prototype = NULL;
  1552. if (ptr->arg_info) {
  1553. internal_function->arg_info = (zend_arg_info*)ptr->arg_info+1;
  1554. internal_function->num_args = ptr->num_args;
  1555. /* Currently you cannot denote that the function can accept less arguments than num_args */
  1556. if (ptr->arg_info[0].required_num_args == -1)

Large files files are truncated, but you can click here to view the full file