Advertisement
Guest User

Untitled

a guest
Dec 6th, 2016
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.43 KB | None | 0 0
  1. diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
  2. index a2df1ef..5205360 100644
  3. --- a/Zend/zend_execute.c
  4. +++ b/Zend/zend_execute.c
  5. @@ -1369,6 +1369,7 @@ static zend_never_inline void zend_post_incdec_overloaded_property(zval *object,
  6. z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
  7. if (UNEXPECTED(EG(exception))) {
  8. OBJ_RELEASE(Z_OBJ(obj));
  9. + ZVAL_UNDEF(result);
  10. return;
  11. }
  12.  
  13. @@ -1414,6 +1415,9 @@ static zend_never_inline void zend_pre_incdec_overloaded_property(zval *object,
  14. zptr = z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
  15. if (UNEXPECTED(EG(exception))) {
  16. OBJ_RELEASE(Z_OBJ(obj));
  17. + if (result) {
  18. + ZVAL_UNDEF(result);
  19. + }
  20. return;
  21. }
  22.  
  23. @@ -1459,6 +1463,9 @@ static zend_never_inline void zend_assign_op_overloaded_property(zval *object, z
  24. z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
  25. if (UNEXPECTED(EG(exception))) {
  26. OBJ_RELEASE(Z_OBJ(obj));
  27. + if (result) {
  28. + ZVAL_UNDEF(result);
  29. + }
  30. return;
  31. }
  32. if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
  33. @@ -3024,6 +3031,11 @@ ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zva
  34. #define GET_OP2_UNDEF_CV(ptr, type) \
  35. _get_zval_cv_lookup_ ## type(ptr, opline->op2.var, execute_data)
  36.  
  37. +#define ZEND_VM_UNDEF_RETVAL() \
  38. + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { \
  39. + ZVAL_UNDEF(EX_VAR(opline->result.var)); \
  40. + }
  41. +
  42. #include "zend_vm_execute.h"
  43.  
  44. ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
  45. diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
  46. index 2d6df66..d3acc4e 100644
  47. --- a/Zend/zend_operators.c
  48. +++ b/Zend/zend_operators.c
  49. @@ -936,6 +936,9 @@ ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* {
  50. zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
  51. converted = 1;
  52. } else {
  53. + if (result != op1) {
  54. + ZVAL_UNDEF(result);
  55. + }
  56. zend_throw_error(NULL, "Unsupported operand types");
  57. return FAILURE; /* unknown datatype */
  58. }
  59. @@ -978,6 +981,9 @@ ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* {
  60. zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
  61. converted = 1;
  62. } else {
  63. + if (result != op1) {
  64. + ZVAL_UNDEF(result);
  65. + }
  66. zend_throw_error(NULL, "Unsupported operand types");
  67. return FAILURE; /* unknown datatype */
  68. }
  69. @@ -1025,6 +1031,9 @@ ZEND_API int ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2) /* {
  70. zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
  71. converted = 1;
  72. } else {
  73. + if (result != op1) {
  74. + ZVAL_UNDEF(result);
  75. + }
  76. zend_throw_error(NULL, "Unsupported operand types");
  77. return FAILURE; /* unknown datatype */
  78. }
  79. @@ -1113,6 +1122,9 @@ ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2) /* {
  80. }
  81. converted = 1;
  82. } else {
  83. + if (result != op1) {
  84. + ZVAL_UNDEF(result);
  85. + }
  86. zend_throw_error(NULL, "Unsupported operand types");
  87. return FAILURE;
  88. }
  89. @@ -1178,6 +1190,9 @@ ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {
  90. zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
  91. converted = 1;
  92. } else {
  93. + if (result != op1) {
  94. + ZVAL_UNDEF(result);
  95. + }
  96. zend_throw_error(NULL, "Unsupported operand types");
  97. return FAILURE; /* unknown datatype */
  98. }
  99. @@ -1330,6 +1345,9 @@ try_again:
  100. default:
  101. ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT);
  102.  
  103. + if (result != op1) {
  104. + ZVAL_UNDEF(result);
  105. + }
  106. zend_throw_error(NULL, "Unsupported operand types");
  107. return FAILURE;
  108. }
  109. diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
  110. index 6f2592b..2ebef3d 100644
  111. --- a/Zend/zend_vm_def.h
  112. +++ b/Zend/zend_vm_def.h
  113. @@ -893,6 +893,9 @@ ZEND_VM_C_LABEL(assign_dim_op_convert_to_array):
  114. zend_check_string_offset(dim, BP_VAR_RW);
  115. zend_wrong_string_offset();
  116. }
  117. + if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
  118. + ZVAL_UNDEF(EX_VAR(opline->result.var));
  119. + }
  120. } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
  121. ZEND_VM_C_GOTO(assign_dim_op_convert_to_array);
  122. } else {
  123. @@ -1406,9 +1409,11 @@ ZEND_VM_C_LABEL(fetch_this):
  124. break;
  125. case BP_VAR_RW:
  126. case BP_VAR_W:
  127. + ZVAL_UNDEF(result);
  128. zend_throw_error(NULL, "Cannot re-assign $this");
  129. break;
  130. case BP_VAR_UNSET:
  131. + ZVAL_UNDEF(result);
  132. zend_throw_error(NULL, "Cannot unset $this");
  133. break;
  134. EMPTY_SWITCH_DEFAULT_CASE()
  135. @@ -2213,7 +2218,7 @@ ZEND_VM_C_LABEL(fast_assign_obj):
  136.  
  137. Z_OBJ_HT_P(object)->write_property(object, property_name, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL);
  138.  
  139. - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) {
  140. + if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
  141. ZVAL_COPY(EX_VAR(opline->result.var), value);
  142. }
  143. FREE_OP_DATA();
  144. @@ -2275,7 +2280,7 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
  145.  
  146. zend_assign_to_object_dim(object_ptr, dim, value);
  147.  
  148. - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) {
  149. + if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
  150. ZVAL_COPY(EX_VAR(opline->result.var), value);
  151. }
  152.  
  153. @@ -2427,11 +2432,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
  154. execute_data = EX(prev_execute_data);
  155.  
  156. if (UNEXPECTED(EG(exception) != NULL)) {
  157. - const zend_op *old_opline = EX(opline);
  158. zend_throw_exception_internal(NULL);
  159. - if (RETURN_VALUE_USED(old_opline)) {
  160. - zval_ptr_dtor(EX_VAR(old_opline->result.var));
  161. - }
  162. HANDLE_EXCEPTION_LEAVE();
  163. }
  164.  
  165. @@ -2465,11 +2466,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
  166. zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
  167.  
  168. if (UNEXPECTED(EG(exception) != NULL)) {
  169. - const zend_op *old_opline = EX(opline);
  170. zend_throw_exception_internal(NULL);
  171. - if (RETURN_VALUE_USED(old_opline)) {
  172. - zval_ptr_dtor(EX_VAR(old_opline->result.var));
  173. - }
  174. HANDLE_EXCEPTION_LEAVE();
  175. }
  176.  
  177. @@ -3790,12 +3787,6 @@ ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED)
  178. retval_ptr = retval_ref;
  179. }
  180. zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num));
  181. -
  182. - if (UNEXPECTED(EG(exception) != NULL)) {
  183. - if (OP1_TYPE == IS_CONST) {
  184. - zval_ptr_dtor_nogc(retval_ptr);
  185. - }
  186. - }
  187. #endif
  188. }
  189. ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
  190. @@ -4867,7 +4858,6 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
  191. USE_OPLINE
  192. zend_free_op free_op1;
  193. zval *obj;
  194. - zend_object *clone_obj;
  195. zend_class_entry *ce, *scope;
  196. zend_function *clone;
  197. zend_object_clone_obj_t clone_call;
  198. @@ -4932,12 +4922,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
  199. }
  200. }
  201.  
  202. - clone_obj = clone_call(obj);
  203. - if (EXPECTED(EG(exception) == NULL)) {
  204. - ZVAL_OBJ(EX_VAR(opline->result.var), clone_obj);
  205. - } else {
  206. - OBJ_RELEASE(clone_obj);
  207. - }
  208. + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
  209.  
  210. FREE_OP1();
  211. ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
  212. @@ -5674,10 +5659,14 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
  213. Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
  214.  
  215. FREE_OP1();
  216. - if (is_empty) {
  217. - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
  218. + if (UNEXPECTED(EG(exception))) {
  219. + OBJ_RELEASE(&iter->std);
  220. + HANDLE_EXCEPTION();
  221. + } else if (is_empty) {
  222. + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
  223. + ZEND_VM_CONTINUE();
  224. } else {
  225. - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
  226. + ZEND_VM_NEXT_OPCODE();
  227. }
  228. }
  229. } else {
  230. @@ -5842,10 +5831,14 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
  231. } else {
  232. FREE_OP1();
  233. }
  234. - if (is_empty) {
  235. - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
  236. + if (UNEXPECTED(EG(exception))) {
  237. + OBJ_RELEASE(&iter->std);
  238. + HANDLE_EXCEPTION();
  239. + } else if (is_empty) {
  240. + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
  241. + ZEND_VM_CONTINUE();
  242. } else {
  243. - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
  244. + ZEND_VM_NEXT_OPCODE();
  245. }
  246. }
  247. } else {
  248. @@ -7065,7 +7063,8 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca
  249.  
  250. ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
  251. {
  252. - uint32_t throw_op_num = EG(opline_before_exception) - EX(func)->op_array.opcodes;
  253. + const zend_op *throw_op = EG(opline_before_exception);
  254. + uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes;
  255. int i, current_try_catch_offset = -1;
  256.  
  257. {
  258. @@ -7094,6 +7093,27 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
  259.  
  260. cleanup_unfinished_calls(execute_data, throw_op_num);
  261.  
  262. + if (throw_op->result_type & (IS_VAR | IS_TMP_VAR)) {
  263. + switch (throw_op->opcode) {
  264. + case ZEND_ADD_ARRAY_ELEMENT:
  265. + case ZEND_ROPE_ADD:
  266. + break; /* exception while building structures, live range handling will free those */
  267. +
  268. + case ZEND_FETCH_CLASS:
  269. + case ZEND_DECLARE_CLASS:
  270. + case ZEND_DECLARE_INHERITED_CLASS:
  271. + case ZEND_DECLARE_ANON_CLASS:
  272. + case ZEND_DECLARE_ANON_INHERITED_CLASS:
  273. + break; /* return value is zend_class_entry pointer */
  274. +
  275. + case ZEND_JMP_SET:
  276. + break; /* takes care of handling itself */
  277. +
  278. + default:
  279. + zval_ptr_dtor_nogc(EX_VAR(throw_op->result.var));
  280. + }
  281. + }
  282. +
  283. ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper, try_catch_offset, current_try_catch_offset, op_num, throw_op_num);
  284. }
  285.  
  286. @@ -7857,9 +7877,6 @@ ZEND_VM_C_LABEL(call_trampoline_end):
  287.  
  288. if (UNEXPECTED(EG(exception) != NULL)) {
  289. zend_throw_exception_internal(NULL);
  290. - if (RETURN_VALUE_USED(opline)) {
  291. - zval_ptr_dtor(EX_VAR(opline->result.var));
  292. - }
  293. HANDLE_EXCEPTION_LEAVE();
  294. }
  295.  
  296. diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
  297. index d5115c8..2fe96fa 100644
  298. --- a/Zend/zend_vm_gen.php
  299. +++ b/Zend/zend_vm_gen.php
  300. @@ -1612,7 +1612,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
  301. out($f,"#endif\n");
  302. out($f,"#undef HANDLE_EXCEPTION\n");
  303. out($f,"#undef HANDLE_EXCEPTION_LEAVE\n");
  304. - out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
  305. + out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
  306. out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
  307. out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG)\n");
  308. out($f,"# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
  309. @@ -1651,7 +1651,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
  310. out($f,"#define SAVE_OPLINE() EX(opline) = opline\n");
  311. out($f,"#undef HANDLE_EXCEPTION\n");
  312. out($f,"#undef HANDLE_EXCEPTION_LEAVE\n");
  313. - out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
  314. + out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
  315. out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
  316. out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n");
  317. out($f,"#define ZEND_VM_RETURN() return\n");
  318. @@ -1683,10 +1683,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
  319. out($f,"#undef HANDLE_EXCEPTION\n");
  320. out($f,"#undef HANDLE_EXCEPTION_LEAVE\n");
  321. if (ZEND_VM_SPEC) {
  322. - out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n");
  323. + out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n");
  324. out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n");
  325. } else {
  326. - out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_HANDLER\n");
  327. + out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); goto ZEND_HANDLE_EXCEPTION_HANDLER\n");
  328. out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_HANDLER\n");
  329. }
  330. out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
  331. @@ -2451,7 +2451,7 @@ function gen_vm($def, $skel) {
  332. out($f,"#define SAVE_OPLINE()\n");
  333. out($f,"#undef HANDLE_EXCEPTION\n");
  334. out($f,"#undef HANDLE_EXCEPTION_LEAVE\n");
  335. - out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
  336. + out($f,"#define HANDLE_EXCEPTION() ZEND_VM_UNDEF_RETVAL(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
  337. out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
  338. out($f,"#undef ZEND_VM_CONTINUE\n");
  339. out($f,"#undef ZEND_VM_RETURN\n");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement