zend_operators.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1998-2016 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. +----------------------------------------------------------------------+
  18. */
  19. /* $Id$ */
  20. #include <ctype.h>
  21. #include "zend.h"
  22. #include "zend_operators.h"
  23. #include "zend_variables.h"
  24. #include "zend_globals.h"
  25. #include "zend_list.h"
  26. #include "zend_API.h"
  27. #include "zend_strtod.h"
  28. #include "zend_exceptions.h"
  29. #include "zend_closures.h"
  30. #if ZEND_USE_TOLOWER_L
  31. #include <locale.h>
  32. static _locale_t current_locale = NULL;
  33. /* this is true global! may lead to strange effects on ZTS, but so may setlocale() */
  34. #define zend_tolower(c) _tolower_l(c, current_locale)
  35. #else
  36. #define zend_tolower(c) tolower(c)
  37. #endif
  38. #define TYPE_PAIR(t1,t2) (((t1) << 4) | (t2))
  39. static const unsigned char tolower_map[256] = {
  40. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
  41. 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
  42. 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
  43. 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
  44. 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
  45. 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x5b,0x5c,0x5d,0x5e,0x5f,
  46. 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
  47. 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
  48. 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
  49. 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
  50. 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
  51. 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
  52. 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
  53. 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
  54. 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
  55. 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
  56. };
  57. #define zend_tolower_ascii(c) (tolower_map[(unsigned char)(c)])
  58. /**
  59. * Functions using locale lowercase:
  60. zend_binary_strncasecmp_l
  61. zend_binary_strcasecmp_l
  62. zend_binary_zval_strcasecmp
  63. zend_binary_zval_strncasecmp
  64. string_compare_function_ex
  65. string_case_compare_function
  66. * Functions using ascii lowercase:
  67. zend_str_tolower_copy
  68. zend_str_tolower_dup
  69. zend_str_tolower
  70. zend_binary_strcasecmp
  71. zend_binary_strncasecmp
  72. */
  73. ZEND_API int zend_atoi(const char *str, int str_len) /* {{{ */
  74. {
  75. int retval;
  76. if (!str_len) {
  77. str_len = strlen(str);
  78. }
  79. retval = strtol(str, NULL, 0);
  80. if (str_len>0) {
  81. switch (str[str_len-1]) {
  82. case 'g':
  83. case 'G':
  84. retval *= 1024;
  85. /* break intentionally missing */
  86. case 'm':
  87. case 'M':
  88. retval *= 1024;
  89. /* break intentionally missing */
  90. case 'k':
  91. case 'K':
  92. retval *= 1024;
  93. break;
  94. }
  95. }
  96. return retval;
  97. }
  98. /* }}} */
  99. ZEND_API long zend_atol(const char *str, int str_len) /* {{{ */
  100. {
  101. long retval;
  102. if (!str_len) {
  103. str_len = strlen(str);
  104. }
  105. retval = strtol(str, NULL, 0);
  106. if (str_len>0) {
  107. switch (str[str_len-1]) {
  108. case 'g':
  109. case 'G':
  110. retval *= 1024;
  111. /* break intentionally missing */
  112. case 'm':
  113. case 'M':
  114. retval *= 1024;
  115. /* break intentionally missing */
  116. case 'k':
  117. case 'K':
  118. retval *= 1024;
  119. break;
  120. }
  121. }
  122. return retval;
  123. }
  124. /* }}} */
  125. ZEND_API double zend_string_to_double(const char *number, zend_uint length) /* {{{ */
  126. {
  127. double divisor = 10.0;
  128. double result = 0.0;
  129. double exponent;
  130. const char *end = number+length;
  131. const char *digit = number;
  132. if (!length) {
  133. return result;
  134. }
  135. while (digit < end) {
  136. if ((*digit <= '9' && *digit >= '0')) {
  137. result *= 10;
  138. result += *digit - '0';
  139. } else if (*digit == '.') {
  140. digit++;
  141. break;
  142. } else if (toupper(*digit) == 'E') {
  143. exponent = (double) atoi(digit+1);
  144. result *= pow(10.0, exponent);
  145. return result;
  146. } else {
  147. return result;
  148. }
  149. digit++;
  150. }
  151. while (digit < end) {
  152. if ((*digit <= '9' && *digit >= '0')) {
  153. result += (*digit - '0') / divisor;
  154. divisor *= 10;
  155. } else if (toupper(*digit) == 'E') {
  156. exponent = (double) atoi(digit+1);
  157. result *= pow(10.0, exponent);
  158. return result;
  159. } else {
  160. return result;
  161. }
  162. digit++;
  163. }
  164. return result;
  165. }
  166. /* }}} */
  167. ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
  168. {
  169. switch (Z_TYPE_P(op)) {
  170. case IS_STRING:
  171. {
  172. char *strval;
  173. strval = Z_STRVAL_P(op);
  174. if ((Z_TYPE_P(op)=is_numeric_string(strval, Z_STRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
  175. ZVAL_LONG(op, 0);
  176. }
  177. str_efree(strval);
  178. break;
  179. }
  180. case IS_BOOL:
  181. Z_TYPE_P(op) = IS_LONG;
  182. break;
  183. case IS_RESOURCE:
  184. zend_list_delete(Z_LVAL_P(op));
  185. Z_TYPE_P(op) = IS_LONG;
  186. break;
  187. case IS_OBJECT:
  188. convert_to_long_base(op, 10);
  189. break;
  190. case IS_NULL:
  191. ZVAL_LONG(op, 0);
  192. break;
  193. }
  194. }
  195. /* }}} */
  196. /* {{{ zendi_convert_scalar_to_number */
  197. #define zendi_convert_scalar_to_number(op, holder, result) \
  198. if (op==result) { \
  199. if (Z_TYPE_P(op) != IS_LONG) { \
  200. convert_scalar_to_number(op TSRMLS_CC); \
  201. } \
  202. } else { \
  203. switch (Z_TYPE_P(op)) { \
  204. case IS_STRING: \
  205. { \
  206. if ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) { \
  207. ZVAL_LONG(&(holder), 0); \
  208. } \
  209. (op) = &(holder); \
  210. break; \
  211. } \
  212. case IS_BOOL: \
  213. case IS_RESOURCE: \
  214. ZVAL_LONG(&(holder), Z_LVAL_P(op)); \
  215. (op) = &(holder); \
  216. break; \
  217. case IS_NULL: \
  218. ZVAL_LONG(&(holder), 0); \
  219. (op) = &(holder); \
  220. break; \
  221. case IS_OBJECT: \
  222. (holder) = (*(op)); \
  223. zval_copy_ctor(&(holder)); \
  224. convert_to_long_base(&(holder), 10); \
  225. if (Z_TYPE(holder) == IS_LONG) { \
  226. (op) = &(holder); \
  227. } \
  228. break; \
  229. } \
  230. }
  231. /* }}} */
  232. /* {{{ zendi_convert_to_long */
  233. #define zendi_convert_to_long(op, holder, result) \
  234. if (op == result) { \
  235. convert_to_long(op); \
  236. } else if (Z_TYPE_P(op) != IS_LONG) { \
  237. switch (Z_TYPE_P(op)) { \
  238. case IS_NULL: \
  239. Z_LVAL(holder) = 0; \
  240. break; \
  241. case IS_DOUBLE: \
  242. Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op)); \
  243. break; \
  244. case IS_STRING: \
  245. Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10); \
  246. break; \
  247. case IS_ARRAY: \
  248. Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0); \
  249. break; \
  250. case IS_OBJECT: \
  251. (holder) = (*(op)); \
  252. zval_copy_ctor(&(holder)); \
  253. convert_to_long_base(&(holder), 10); \
  254. break; \
  255. case IS_BOOL: \
  256. case IS_RESOURCE: \
  257. Z_LVAL(holder) = Z_LVAL_P(op); \
  258. break; \
  259. default: \
  260. zend_error(E_WARNING, "Cannot convert to ordinal value"); \
  261. Z_LVAL(holder) = 0; \
  262. break; \
  263. } \
  264. Z_TYPE(holder) = IS_LONG; \
  265. (op) = &(holder); \
  266. }
  267. /* }}} */
  268. /* {{{ zendi_convert_to_boolean */
  269. #define zendi_convert_to_boolean(op, holder, result) \
  270. if (op==result) { \
  271. convert_to_boolean(op); \
  272. } else if (Z_TYPE_P(op) != IS_BOOL) { \
  273. switch (Z_TYPE_P(op)) { \
  274. case IS_NULL: \
  275. Z_LVAL(holder) = 0; \
  276. break; \
  277. case IS_RESOURCE: \
  278. case IS_LONG: \
  279. Z_LVAL(holder) = (Z_LVAL_P(op) ? 1 : 0); \
  280. break; \
  281. case IS_DOUBLE: \
  282. Z_LVAL(holder) = (Z_DVAL_P(op) ? 1 : 0); \
  283. break; \
  284. case IS_STRING: \
  285. if (Z_STRLEN_P(op) == 0 \
  286. || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) { \
  287. Z_LVAL(holder) = 0; \
  288. } else { \
  289. Z_LVAL(holder) = 1; \
  290. } \
  291. break; \
  292. case IS_ARRAY: \
  293. Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0); \
  294. break; \
  295. case IS_OBJECT: \
  296. (holder) = (*(op)); \
  297. zval_copy_ctor(&(holder)); \
  298. convert_to_boolean(&(holder)); \
  299. break; \
  300. default: \
  301. Z_LVAL(holder) = 0; \
  302. break; \
  303. } \
  304. Z_TYPE(holder) = IS_BOOL; \
  305. (op) = &(holder); \
  306. }
  307. /* }}} */
  308. /* {{{ convert_object_to_type */
  309. #define convert_object_to_type(op, ctype, conv_func) \
  310. if (Z_OBJ_HT_P(op)->cast_object) { \
  311. zval dst; \
  312. if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) { \
  313. zend_error(E_RECOVERABLE_ERROR, \
  314. "Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name, \
  315. zend_get_type_by_const(ctype)); \
  316. } else { \
  317. zval_dtor(op); \
  318. Z_TYPE_P(op) = ctype; \
  319. op->value = dst.value; \
  320. } \
  321. } else { \
  322. if (Z_OBJ_HT_P(op)->get) { \
  323. zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC); \
  324. if (Z_TYPE_P(newop) != IS_OBJECT) { \
  325. /* for safety - avoid loop */ \
  326. zval_dtor(op); \
  327. *op = *newop; \
  328. FREE_ZVAL(newop); \
  329. conv_func(op); \
  330. } \
  331. } \
  332. }
  333. /* }}} */
  334. ZEND_API void convert_to_long(zval *op) /* {{{ */
  335. {
  336. if (Z_TYPE_P(op) != IS_LONG) {
  337. convert_to_long_base(op, 10);
  338. }
  339. }
  340. /* }}} */
  341. ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
  342. {
  343. long tmp;
  344. switch (Z_TYPE_P(op)) {
  345. case IS_NULL:
  346. Z_LVAL_P(op) = 0;
  347. break;
  348. case IS_RESOURCE: {
  349. TSRMLS_FETCH();
  350. zend_list_delete(Z_LVAL_P(op));
  351. }
  352. /* break missing intentionally */
  353. case IS_BOOL:
  354. case IS_LONG:
  355. break;
  356. case IS_DOUBLE:
  357. Z_LVAL_P(op) = zend_dval_to_lval(Z_DVAL_P(op));
  358. break;
  359. case IS_STRING:
  360. {
  361. char *strval = Z_STRVAL_P(op);
  362. Z_LVAL_P(op) = strtol(strval, NULL, base);
  363. str_efree(strval);
  364. }
  365. break;
  366. case IS_ARRAY:
  367. tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
  368. zval_dtor(op);
  369. Z_LVAL_P(op) = tmp;
  370. break;
  371. case IS_OBJECT:
  372. {
  373. int retval = 1;
  374. TSRMLS_FETCH();
  375. convert_object_to_type(op, IS_LONG, convert_to_long);
  376. if (Z_TYPE_P(op) == IS_LONG) {
  377. return;
  378. }
  379. zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);
  380. zval_dtor(op);
  381. ZVAL_LONG(op, retval);
  382. return;
  383. }
  384. default:
  385. zend_error(E_WARNING, "Cannot convert to ordinal value");
  386. zval_dtor(op);
  387. Z_LVAL_P(op) = 0;
  388. break;
  389. }
  390. Z_TYPE_P(op) = IS_LONG;
  391. }
  392. /* }}} */
  393. ZEND_API void convert_to_double(zval *op) /* {{{ */
  394. {
  395. double tmp;
  396. switch (Z_TYPE_P(op)) {
  397. case IS_NULL:
  398. Z_DVAL_P(op) = 0.0;
  399. break;
  400. case IS_RESOURCE: {
  401. TSRMLS_FETCH();
  402. zend_list_delete(Z_LVAL_P(op));
  403. }
  404. /* break missing intentionally */
  405. case IS_BOOL:
  406. case IS_LONG:
  407. Z_DVAL_P(op) = (double) Z_LVAL_P(op);
  408. break;
  409. case IS_DOUBLE:
  410. break;
  411. case IS_STRING:
  412. {
  413. char *strval = Z_STRVAL_P(op);
  414. Z_DVAL_P(op) = zend_strtod(strval, NULL);
  415. str_efree(strval);
  416. }
  417. break;
  418. case IS_ARRAY:
  419. tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
  420. zval_dtor(op);
  421. Z_DVAL_P(op) = tmp;
  422. break;
  423. case IS_OBJECT:
  424. {
  425. double retval = 1.0;
  426. TSRMLS_FETCH();
  427. convert_object_to_type(op, IS_DOUBLE, convert_to_double);
  428. if (Z_TYPE_P(op) == IS_DOUBLE) {
  429. return;
  430. }
  431. zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name);
  432. zval_dtor(op);
  433. ZVAL_DOUBLE(op, retval);
  434. break;
  435. }
  436. default:
  437. zend_error(E_WARNING, "Cannot convert to real value (type=%d)", Z_TYPE_P(op));
  438. zval_dtor(op);
  439. Z_DVAL_P(op) = 0;
  440. break;
  441. }
  442. Z_TYPE_P(op) = IS_DOUBLE;
  443. }
  444. /* }}} */
  445. ZEND_API void convert_to_null(zval *op) /* {{{ */
  446. {
  447. if (Z_TYPE_P(op) == IS_OBJECT) {
  448. if (Z_OBJ_HT_P(op)->cast_object) {
  449. zval *org;
  450. TSRMLS_FETCH();
  451. ALLOC_ZVAL(org);
  452. *org = *op;
  453. if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
  454. zval_dtor(org);
  455. return;
  456. }
  457. *op = *org;
  458. FREE_ZVAL(org);
  459. }
  460. }
  461. zval_dtor(op);
  462. Z_TYPE_P(op) = IS_NULL;
  463. }
  464. /* }}} */
  465. ZEND_API void convert_to_boolean(zval *op) /* {{{ */
  466. {
  467. int tmp;
  468. switch (Z_TYPE_P(op)) {
  469. case IS_BOOL:
  470. break;
  471. case IS_NULL:
  472. Z_LVAL_P(op) = 0;
  473. break;
  474. case IS_RESOURCE: {
  475. TSRMLS_FETCH();
  476. zend_list_delete(Z_LVAL_P(op));
  477. }
  478. /* break missing intentionally */
  479. case IS_LONG:
  480. Z_LVAL_P(op) = (Z_LVAL_P(op) ? 1 : 0);
  481. break;
  482. case IS_DOUBLE:
  483. Z_LVAL_P(op) = (Z_DVAL_P(op) ? 1 : 0);
  484. break;
  485. case IS_STRING:
  486. {
  487. char *strval = Z_STRVAL_P(op);
  488. if (Z_STRLEN_P(op) == 0
  489. || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
  490. Z_LVAL_P(op) = 0;
  491. } else {
  492. Z_LVAL_P(op) = 1;
  493. }
  494. str_efree(strval);
  495. }
  496. break;
  497. case IS_ARRAY:
  498. tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
  499. zval_dtor(op);
  500. Z_LVAL_P(op) = tmp;
  501. break;
  502. case IS_OBJECT:
  503. {
  504. zend_bool retval = 1;
  505. TSRMLS_FETCH();
  506. convert_object_to_type(op, IS_BOOL, convert_to_boolean);
  507. if (Z_TYPE_P(op) == IS_BOOL) {
  508. return;
  509. }
  510. zval_dtor(op);
  511. ZVAL_BOOL(op, retval);
  512. break;
  513. }
  514. default:
  515. zval_dtor(op);
  516. Z_LVAL_P(op) = 0;
  517. break;
  518. }
  519. Z_TYPE_P(op) = IS_BOOL;
  520. }
  521. /* }}} */
  522. ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* {{{ */
  523. {
  524. double dval;
  525. switch (Z_TYPE_P(op)) {
  526. case IS_DOUBLE: {
  527. TSRMLS_FETCH();
  528. dval = Z_DVAL_P(op);
  529. Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*H", (int) EG(precision), dval);
  530. /* %H already handles removing trailing zeros from the fractional part, yay */
  531. break;
  532. }
  533. default:
  534. _convert_to_string(op ZEND_FILE_LINE_CC);
  535. }
  536. Z_TYPE_P(op) = IS_STRING;
  537. }
  538. /* }}} */
  539. ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
  540. {
  541. long lval;
  542. double dval;
  543. switch (Z_TYPE_P(op)) {
  544. case IS_NULL:
  545. Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
  546. Z_STRLEN_P(op) = 0;
  547. break;
  548. case IS_STRING:
  549. break;
  550. case IS_BOOL:
  551. if (Z_LVAL_P(op)) {
  552. Z_STRVAL_P(op) = estrndup_rel("1", 1);
  553. Z_STRLEN_P(op) = 1;
  554. } else {
  555. Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
  556. Z_STRLEN_P(op) = 0;
  557. }
  558. break;
  559. case IS_RESOURCE: {
  560. long tmp = Z_LVAL_P(op);
  561. TSRMLS_FETCH();
  562. zend_list_delete(Z_LVAL_P(op));
  563. Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "Resource id #%ld", tmp);
  564. break;
  565. }
  566. case IS_LONG:
  567. lval = Z_LVAL_P(op);
  568. Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%ld", lval);
  569. break;
  570. case IS_DOUBLE: {
  571. TSRMLS_FETCH();
  572. dval = Z_DVAL_P(op);
  573. Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), dval);
  574. /* %G already handles removing trailing zeros from the fractional part, yay */
  575. break;
  576. }
  577. case IS_ARRAY:
  578. zend_error(E_NOTICE, "Array to string conversion");
  579. zval_dtor(op);
  580. Z_STRVAL_P(op) = estrndup_rel("Array", sizeof("Array")-1);
  581. Z_STRLEN_P(op) = sizeof("Array")-1;
  582. break;
  583. case IS_OBJECT: {
  584. TSRMLS_FETCH();
  585. convert_object_to_type(op, IS_STRING, convert_to_string);
  586. if (Z_TYPE_P(op) == IS_STRING) {
  587. return;
  588. }
  589. zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name);
  590. zval_dtor(op);
  591. Z_STRVAL_P(op) = estrndup_rel("Object", sizeof("Object")-1);
  592. Z_STRLEN_P(op) = sizeof("Object")-1;
  593. break;
  594. }
  595. default:
  596. zval_dtor(op);
  597. ZVAL_BOOL(op, 0);
  598. break;
  599. }
  600. Z_TYPE_P(op) = IS_STRING;
  601. }
  602. /* }}} */
  603. static void convert_scalar_to_array(zval *op, int type TSRMLS_DC) /* {{{ */
  604. {
  605. zval *entry;
  606. ALLOC_ZVAL(entry);
  607. *entry = *op;
  608. INIT_PZVAL(entry);
  609. switch (type) {
  610. case IS_ARRAY:
  611. ALLOC_HASHTABLE(Z_ARRVAL_P(op));
  612. zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
  613. zend_hash_index_update(Z_ARRVAL_P(op), 0, (void *) &entry, sizeof(zval *), NULL);
  614. Z_TYPE_P(op) = IS_ARRAY;
  615. break;
  616. case IS_OBJECT:
  617. object_init(op);
  618. zend_hash_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar"), (void *) &entry, sizeof(zval *), NULL);
  619. break;
  620. }
  621. }
  622. /* }}} */
  623. ZEND_API void convert_to_array(zval *op) /* {{{ */
  624. {
  625. TSRMLS_FETCH();
  626. switch (Z_TYPE_P(op)) {
  627. case IS_ARRAY:
  628. break;
  629. /* OBJECTS_OPTIMIZE */
  630. case IS_OBJECT:
  631. {
  632. zval *tmp;
  633. HashTable *ht;
  634. ALLOC_HASHTABLE(ht);
  635. zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
  636. if (Z_OBJCE_P(op) == zend_ce_closure) {
  637. convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
  638. if (Z_TYPE_P(op) == IS_ARRAY) {
  639. zend_hash_destroy(ht);
  640. FREE_HASHTABLE(ht);
  641. return;
  642. }
  643. } else if (Z_OBJ_HT_P(op)->get_properties) {
  644. HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
  645. if (obj_ht) {
  646. zend_hash_copy(ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
  647. }
  648. } else {
  649. convert_object_to_type(op, IS_ARRAY, convert_to_array);
  650. if (Z_TYPE_P(op) == IS_ARRAY) {
  651. zend_hash_destroy(ht);
  652. FREE_HASHTABLE(ht);
  653. return;
  654. }
  655. }
  656. zval_dtor(op);
  657. Z_TYPE_P(op) = IS_ARRAY;
  658. Z_ARRVAL_P(op) = ht;
  659. }
  660. break;
  661. case IS_NULL:
  662. ALLOC_HASHTABLE(Z_ARRVAL_P(op));
  663. zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
  664. Z_TYPE_P(op) = IS_ARRAY;
  665. break;
  666. default:
  667. convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
  668. break;
  669. }
  670. }
  671. /* }}} */
  672. ZEND_API void convert_to_object(zval *op) /* {{{ */
  673. {
  674. TSRMLS_FETCH();
  675. switch (Z_TYPE_P(op)) {
  676. case IS_ARRAY:
  677. {
  678. object_and_properties_init(op, zend_standard_class_def, Z_ARRVAL_P(op));
  679. break;
  680. }
  681. case IS_OBJECT:
  682. break;
  683. case IS_NULL:
  684. object_init(op);
  685. break;
  686. default:
  687. convert_scalar_to_array(op, IS_OBJECT TSRMLS_CC);
  688. break;
  689. }
  690. }
  691. /* }}} */
  692. ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
  693. {
  694. zval **arg;
  695. va_list ap;
  696. va_start(ap, argc);
  697. while (argc--) {
  698. arg = va_arg(ap, zval **);
  699. convert_to_long_ex(arg);
  700. }
  701. va_end(ap);
  702. }
  703. /* }}} */
  704. ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
  705. {
  706. zval **arg;
  707. va_list ap;
  708. va_start(ap, argc);
  709. while (argc--) {
  710. arg = va_arg(ap, zval **);
  711. convert_to_double_ex(arg);
  712. }
  713. va_end(ap);
  714. }
  715. /* }}} */
  716. ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
  717. {
  718. zval **arg;
  719. va_list ap;
  720. va_start(ap, argc);
  721. while (argc--) {
  722. arg = va_arg(ap, zval **);
  723. convert_to_string_ex(arg);
  724. }
  725. va_end(ap);
  726. }
  727. /* }}} */
  728. ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  729. {
  730. zval op1_copy, op2_copy;
  731. int converted = 0;
  732. while (1) {
  733. switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
  734. case TYPE_PAIR(IS_LONG, IS_LONG): {
  735. long lval = Z_LVAL_P(op1) + Z_LVAL_P(op2);
  736. /* check for overflow by comparing sign bits */
  737. if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
  738. && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
  739. ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
  740. } else {
  741. ZVAL_LONG(result, lval);
  742. }
  743. return SUCCESS;
  744. }
  745. case TYPE_PAIR(IS_LONG, IS_DOUBLE):
  746. ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
  747. return SUCCESS;
  748. case TYPE_PAIR(IS_DOUBLE, IS_LONG):
  749. ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
  750. return SUCCESS;
  751. case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
  752. ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
  753. return SUCCESS;
  754. case TYPE_PAIR(IS_ARRAY, IS_ARRAY): {
  755. zval *tmp;
  756. if ((result == op1) && (result == op2)) {
  757. /* $a += $a */
  758. return SUCCESS;
  759. }
  760. if (result != op1) {
  761. *result = *op1;
  762. zval_copy_ctor(result);
  763. }
  764. zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), (void (*)(void *pData)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
  765. return SUCCESS;
  766. }
  767. default:
  768. if (!converted) {
  769. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD);
  770. zendi_convert_scalar_to_number(op1, op1_copy, result);
  771. zendi_convert_scalar_to_number(op2, op2_copy, result);
  772. converted = 1;
  773. } else {
  774. zend_error(E_ERROR, "Unsupported operand types");
  775. return FAILURE; /* unknown datatype */
  776. }
  777. }
  778. }
  779. }
  780. /* }}} */
  781. ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  782. {
  783. zval op1_copy, op2_copy;
  784. int converted = 0;
  785. while (1) {
  786. switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
  787. case TYPE_PAIR(IS_LONG, IS_LONG): {
  788. long lval = Z_LVAL_P(op1) - Z_LVAL_P(op2);
  789. /* check for overflow by comparing sign bits */
  790. if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
  791. && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
  792. ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
  793. } else {
  794. ZVAL_LONG(result, lval);
  795. }
  796. return SUCCESS;
  797. }
  798. case TYPE_PAIR(IS_LONG, IS_DOUBLE):
  799. ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
  800. return SUCCESS;
  801. case TYPE_PAIR(IS_DOUBLE, IS_LONG):
  802. ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
  803. return SUCCESS;
  804. case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
  805. ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
  806. return SUCCESS;
  807. default:
  808. if (!converted) {
  809. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB);
  810. zendi_convert_scalar_to_number(op1, op1_copy, result);
  811. zendi_convert_scalar_to_number(op2, op2_copy, result);
  812. converted = 1;
  813. } else {
  814. zend_error(E_ERROR, "Unsupported operand types");
  815. return FAILURE; /* unknown datatype */
  816. }
  817. }
  818. }
  819. }
  820. /* }}} */
  821. ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  822. {
  823. zval op1_copy, op2_copy;
  824. int converted = 0;
  825. while (1) {
  826. switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
  827. case TYPE_PAIR(IS_LONG, IS_LONG): {
  828. long overflow;
  829. ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow);
  830. Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG;
  831. return SUCCESS;
  832. }
  833. case TYPE_PAIR(IS_LONG, IS_DOUBLE):
  834. ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
  835. return SUCCESS;
  836. case TYPE_PAIR(IS_DOUBLE, IS_LONG):
  837. ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
  838. return SUCCESS;
  839. case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
  840. ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
  841. return SUCCESS;
  842. default:
  843. if (!converted) {
  844. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL);
  845. zendi_convert_scalar_to_number(op1, op1_copy, result);
  846. zendi_convert_scalar_to_number(op2, op2_copy, result);
  847. converted = 1;
  848. } else {
  849. zend_error(E_ERROR, "Unsupported operand types");
  850. return FAILURE; /* unknown datatype */
  851. }
  852. }
  853. }
  854. }
  855. /* }}} */
  856. ZEND_API int pow_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  857. {
  858. zval op1_copy, op2_copy;
  859. int converted = 0;
  860. while (1) {
  861. switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
  862. case TYPE_PAIR(IS_LONG, IS_LONG):
  863. if (Z_LVAL_P(op2) >= 0) {
  864. long l1 = 1, l2 = Z_LVAL_P(op1), i = Z_LVAL_P(op2);
  865. if (i == 0) {
  866. ZVAL_LONG(result, 1L);
  867. return SUCCESS;
  868. } else if (l2 == 0) {
  869. ZVAL_LONG(result, 0);
  870. return SUCCESS;
  871. }
  872. while (i >= 1) {
  873. long overflow;
  874. double dval = 0.0;
  875. if (i % 2) {
  876. --i;
  877. ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
  878. if (overflow) {
  879. ZVAL_DOUBLE(result, dval * pow(l2, i));
  880. return SUCCESS;
  881. }
  882. } else {
  883. i /= 2;
  884. ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval, overflow);
  885. if (overflow) {
  886. ZVAL_DOUBLE(result, (double)l1 * pow(dval, i));
  887. return SUCCESS;
  888. }
  889. }
  890. }
  891. /* i == 0 */
  892. ZVAL_LONG(result, l1);
  893. } else {
  894. ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2)));
  895. }
  896. return SUCCESS;
  897. case TYPE_PAIR(IS_LONG, IS_DOUBLE):
  898. ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), Z_DVAL_P(op2)));
  899. return SUCCESS;
  900. case TYPE_PAIR(IS_DOUBLE, IS_LONG):
  901. ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), (double)Z_LVAL_P(op2)));
  902. return SUCCESS;
  903. case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
  904. ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), Z_DVAL_P(op2)));
  905. return SUCCESS;
  906. default:
  907. if (!converted) {
  908. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW);
  909. if (Z_TYPE_P(op1) == IS_ARRAY) {
  910. ZVAL_LONG(result, 0);
  911. return SUCCESS;
  912. } else {
  913. zendi_convert_scalar_to_number(op1, op1_copy, result);
  914. }
  915. if (Z_TYPE_P(op2) == IS_ARRAY) {
  916. ZVAL_LONG(result, 1L);
  917. return SUCCESS;
  918. } else {
  919. zendi_convert_scalar_to_number(op2, op2_copy, result);
  920. }
  921. converted = 1;
  922. } else {
  923. zend_error(E_ERROR, "Unsupported operand types");
  924. return FAILURE;
  925. }
  926. }
  927. }
  928. }
  929. /* }}} */
  930. ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  931. {
  932. zval op1_copy, op2_copy;
  933. int converted = 0;
  934. while (1) {
  935. switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
  936. case TYPE_PAIR(IS_LONG, IS_LONG):
  937. if (Z_LVAL_P(op2) == 0) {
  938. zend_error(E_WARNING, "Division by zero");
  939. ZVAL_BOOL(result, 0);
  940. return FAILURE; /* division by zero */
  941. } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) {
  942. /* Prevent overflow error/crash */
  943. ZVAL_DOUBLE(result, (double) LONG_MIN / -1);
  944. return SUCCESS;
  945. }
  946. if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
  947. ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
  948. } else {
  949. ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
  950. }
  951. return SUCCESS;
  952. case TYPE_PAIR(IS_DOUBLE, IS_LONG):
  953. if (Z_LVAL_P(op2) == 0) {
  954. zend_error(E_WARNING, "Division by zero");
  955. ZVAL_BOOL(result, 0);
  956. return FAILURE; /* division by zero */
  957. }
  958. ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
  959. return SUCCESS;
  960. case TYPE_PAIR(IS_LONG, IS_DOUBLE):
  961. if (Z_DVAL_P(op2) == 0) {
  962. zend_error(E_WARNING, "Division by zero");
  963. ZVAL_BOOL(result, 0);
  964. return FAILURE; /* division by zero */
  965. }
  966. ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
  967. return SUCCESS;
  968. case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
  969. if (Z_DVAL_P(op2) == 0) {
  970. zend_error(E_WARNING, "Division by zero");
  971. ZVAL_BOOL(result, 0);
  972. return FAILURE; /* division by zero */
  973. }
  974. ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
  975. return SUCCESS;
  976. default:
  977. if (!converted) {
  978. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV);
  979. zendi_convert_scalar_to_number(op1, op1_copy, result);
  980. zendi_convert_scalar_to_number(op2, op2_copy, result);
  981. converted = 1;
  982. } else {
  983. zend_error(E_ERROR, "Unsupported operand types");
  984. return FAILURE; /* unknown datatype */
  985. }
  986. }
  987. }
  988. }
  989. /* }}} */
  990. ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  991. {
  992. zval op1_copy, op2_copy;
  993. long op1_lval;
  994. if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
  995. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MOD);
  996. zendi_convert_to_long(op1, op1_copy, result);
  997. op1_lval = Z_LVAL_P(op1);
  998. zendi_convert_to_long(op2, op2_copy, result);
  999. } else {
  1000. op1_lval = Z_LVAL_P(op1);
  1001. }
  1002. if (Z_LVAL_P(op2) == 0) {
  1003. zend_error(E_WARNING, "Division by zero");
  1004. ZVAL_BOOL(result, 0);
  1005. return FAILURE; /* modulus by zero */
  1006. }
  1007. if (Z_LVAL_P(op2) == -1) {
  1008. /* Prevent overflow error/crash if op1==LONG_MIN */
  1009. ZVAL_LONG(result, 0);
  1010. return SUCCESS;
  1011. }
  1012. ZVAL_LONG(result, op1_lval % Z_LVAL_P(op2));
  1013. return SUCCESS;
  1014. }
  1015. /* }}} */
  1016. ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1017. {
  1018. zval op1_copy, op2_copy;
  1019. long op1_lval;
  1020. if (Z_TYPE_P(op1) != IS_BOOL || Z_TYPE_P(op2) != IS_BOOL) {
  1021. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BOOL_XOR);
  1022. zendi_convert_to_boolean(op1, op1_copy, result);
  1023. op1_lval = Z_LVAL_P(op1);
  1024. zendi_convert_to_boolean(op2, op2_copy, result);
  1025. } else {
  1026. op1_lval = Z_LVAL_P(op1);
  1027. }
  1028. ZVAL_BOOL(result, op1_lval ^ Z_LVAL_P(op2));
  1029. return SUCCESS;
  1030. }
  1031. /* }}} */
  1032. ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
  1033. {
  1034. zval op1_copy;
  1035. if (Z_TYPE_P(op1) != IS_BOOL) {
  1036. ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT);
  1037. zendi_convert_to_boolean(op1, op1_copy, result);
  1038. }
  1039. ZVAL_BOOL(result, !Z_LVAL_P(op1));
  1040. return SUCCESS;
  1041. }
  1042. /* }}} */
  1043. ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
  1044. {
  1045. switch (Z_TYPE_P(op1)) {
  1046. case IS_LONG:
  1047. ZVAL_LONG(result, ~Z_LVAL_P(op1));
  1048. return SUCCESS;
  1049. case IS_DOUBLE:
  1050. ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
  1051. return SUCCESS;
  1052. case IS_STRING: {
  1053. int i;
  1054. zval op1_copy = *op1;
  1055. Z_TYPE_P(result) = IS_STRING;
  1056. Z_STRVAL_P(result) = estrndup(Z_STRVAL(op1_copy), Z_STRLEN(op1_copy));
  1057. Z_STRLEN_P(result) = Z_STRLEN(op1_copy);
  1058. for (i = 0; i < Z_STRLEN(op1_copy); i++) {
  1059. Z_STRVAL_P(result)[i] = ~Z_STRVAL(op1_copy)[i];
  1060. }
  1061. return SUCCESS;
  1062. }
  1063. default:
  1064. ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT);
  1065. zend_error(E_ERROR, "Unsupported operand types");
  1066. return FAILURE;
  1067. }
  1068. }
  1069. /* }}} */
  1070. ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1071. {
  1072. zval op1_copy, op2_copy;
  1073. long op1_lval;
  1074. if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
  1075. zval *longer, *shorter;
  1076. char *result_str;
  1077. int i, result_len;
  1078. if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
  1079. longer = op1;
  1080. shorter = op2;
  1081. } else {
  1082. longer = op2;
  1083. shorter = op1;
  1084. }
  1085. Z_TYPE_P(result) = IS_STRING;
  1086. result_len = Z_STRLEN_P(longer);
  1087. result_str = estrndup(Z_STRVAL_P(longer), Z_STRLEN_P(longer));
  1088. for (i = 0; i < Z_STRLEN_P(shorter); i++) {
  1089. result_str[i] |= Z_STRVAL_P(shorter)[i];
  1090. }
  1091. if (result==op1) {
  1092. str_efree(Z_STRVAL_P(result));
  1093. }
  1094. Z_STRVAL_P(result) = result_str;
  1095. Z_STRLEN_P(result) = result_len;
  1096. return SUCCESS;
  1097. }
  1098. if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
  1099. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_OR);
  1100. zendi_convert_to_long(op1, op1_copy, result);
  1101. op1_lval = Z_LVAL_P(op1);
  1102. zendi_convert_to_long(op2, op2_copy, result);
  1103. } else {
  1104. op1_lval = Z_LVAL_P(op1);
  1105. }
  1106. ZVAL_LONG(result, op1_lval | Z_LVAL_P(op2));
  1107. return SUCCESS;
  1108. }
  1109. /* }}} */
  1110. ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1111. {
  1112. zval op1_copy, op2_copy;
  1113. long op1_lval;
  1114. if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
  1115. zval *longer, *shorter;
  1116. char *result_str;
  1117. int i, result_len;
  1118. if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
  1119. longer = op1;
  1120. shorter = op2;
  1121. } else {
  1122. longer = op2;
  1123. shorter = op1;
  1124. }
  1125. Z_TYPE_P(result) = IS_STRING;
  1126. result_len = Z_STRLEN_P(shorter);
  1127. result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
  1128. for (i = 0; i < Z_STRLEN_P(shorter); i++) {
  1129. result_str[i] &= Z_STRVAL_P(longer)[i];
  1130. }
  1131. if (result==op1) {
  1132. str_efree(Z_STRVAL_P(result));
  1133. }
  1134. Z_STRVAL_P(result) = result_str;
  1135. Z_STRLEN_P(result) = result_len;
  1136. return SUCCESS;
  1137. }
  1138. if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
  1139. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_AND);
  1140. zendi_convert_to_long(op1, op1_copy, result);
  1141. op1_lval = Z_LVAL_P(op1);
  1142. zendi_convert_to_long(op2, op2_copy, result);
  1143. } else {
  1144. op1_lval = Z_LVAL_P(op1);
  1145. }
  1146. ZVAL_LONG(result, op1_lval & Z_LVAL_P(op2));
  1147. return SUCCESS;
  1148. }
  1149. /* }}} */
  1150. ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1151. {
  1152. zval op1_copy, op2_copy;
  1153. long op1_lval;
  1154. if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
  1155. zval *longer, *shorter;
  1156. char *result_str;
  1157. int i, result_len;
  1158. if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
  1159. longer = op1;
  1160. shorter = op2;
  1161. } else {
  1162. longer = op2;
  1163. shorter = op1;
  1164. }
  1165. Z_TYPE_P(result) = IS_STRING;
  1166. result_len = Z_STRLEN_P(shorter);
  1167. result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
  1168. for (i = 0; i < Z_STRLEN_P(shorter); i++) {
  1169. result_str[i] ^= Z_STRVAL_P(longer)[i];
  1170. }
  1171. if (result==op1) {
  1172. str_efree(Z_STRVAL_P(result));
  1173. }
  1174. Z_STRVAL_P(result) = result_str;
  1175. Z_STRLEN_P(result) = result_len;
  1176. return SUCCESS;
  1177. }
  1178. if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
  1179. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_XOR);
  1180. zendi_convert_to_long(op1, op1_copy, result);
  1181. op1_lval = Z_LVAL_P(op1);
  1182. zendi_convert_to_long(op2, op2_copy, result);
  1183. } else {
  1184. op1_lval = Z_LVAL_P(op1);
  1185. }
  1186. ZVAL_LONG(result, op1_lval ^ Z_LVAL_P(op2));
  1187. return SUCCESS;
  1188. }
  1189. /* }}} */
  1190. ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1191. {
  1192. zval op1_copy, op2_copy;
  1193. long op1_lval;
  1194. if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
  1195. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SL);
  1196. zendi_convert_to_long(op1, op1_copy, result);
  1197. op1_lval = Z_LVAL_P(op1);
  1198. zendi_convert_to_long(op2, op2_copy, result);
  1199. } else {
  1200. op1_lval = Z_LVAL_P(op1);
  1201. }
  1202. ZVAL_LONG(result, op1_lval << Z_LVAL_P(op2));
  1203. return SUCCESS;
  1204. }
  1205. /* }}} */
  1206. ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1207. {
  1208. zval op1_copy, op2_copy;
  1209. long op1_lval;
  1210. if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
  1211. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SR);
  1212. zendi_convert_to_long(op1, op1_copy, result);
  1213. op1_lval = Z_LVAL_P(op1);
  1214. zendi_convert_to_long(op2, op2_copy, result);
  1215. } else {
  1216. op1_lval = Z_LVAL_P(op1);
  1217. }
  1218. ZVAL_LONG(result, op1_lval >> Z_LVAL_P(op2));
  1219. return SUCCESS;
  1220. }
  1221. /* }}} */
  1222. /* must support result==op1 */
  1223. ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
  1224. {
  1225. int length = Z_STRLEN_P(op1) + 1;
  1226. char *buf;
  1227. if (UNEXPECTED(length < 0)) {
  1228. zend_error(E_ERROR, "String size overflow");
  1229. }
  1230. buf = str_erealloc(Z_STRVAL_P(op1), length + 1);
  1231. buf[length - 1] = (char) Z_LVAL_P(op2);
  1232. buf[length] = 0;
  1233. ZVAL_STRINGL(result, buf, length, 0);
  1234. return SUCCESS;
  1235. }
  1236. /* }}} */
  1237. /* must support result==op1 */
  1238. ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
  1239. {
  1240. int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
  1241. char *buf;
  1242. if (UNEXPECTED(length < 0)) {
  1243. zend_error(E_ERROR, "String size overflow");
  1244. }
  1245. buf = str_erealloc(Z_STRVAL_P(op1), length + 1);
  1246. memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
  1247. buf[length] = 0;
  1248. ZVAL_STRINGL(result, buf, length, 0);
  1249. return SUCCESS;
  1250. }
  1251. /* }}} */
  1252. ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1253. {
  1254. zval op1_copy, op2_copy;
  1255. int use_copy1 = 0, use_copy2 = 0;
  1256. if (Z_TYPE_P(op1) != IS_STRING || Z_TYPE_P(op2) != IS_STRING) {
  1257. ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT);
  1258. if (Z_TYPE_P(op1) != IS_STRING) {
  1259. zend_make_printable_zval(op1, &op1_copy, &use_copy1);
  1260. }
  1261. if (Z_TYPE_P(op2) != IS_STRING) {
  1262. zend_make_printable_zval(op2, &op2_copy, &use_copy2);
  1263. }
  1264. }
  1265. if (use_copy1) {
  1266. /* We have created a converted copy of op1. Therefore, op1 won't become the result so
  1267. * we have to free it.
  1268. */
  1269. if (result == op1) {
  1270. zval_dtor(op1);
  1271. }
  1272. op1 = &op1_copy;
  1273. }
  1274. if (use_copy2) {
  1275. op2 = &op2_copy;
  1276. }
  1277. if (result==op1 && !IS_INTERNED(Z_STRVAL_P(op1))) { /* special case, perform operations on result */
  1278. uint res_len = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
  1279. if (Z_STRLEN_P(result) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
  1280. efree(Z_STRVAL_P(result));
  1281. ZVAL_EMPTY_STRING(result);
  1282. zend_error(E_ERROR, "String size overflow");
  1283. }
  1284. Z_STRVAL_P(result) = safe_erealloc(Z_STRVAL_P(result), res_len, 1, 1);
  1285. memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(result), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
  1286. Z_STRVAL_P(result)[res_len]=0;
  1287. Z_STRLEN_P(result) = res_len;
  1288. } else {
  1289. int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
  1290. char *buf;
  1291. if (Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op2) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
  1292. zend_error(E_ERROR, "String size overflow");
  1293. }
  1294. buf = (char *) safe_emalloc(length, 1, 1);
  1295. memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
  1296. memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
  1297. buf[length] = 0;
  1298. ZVAL_STRINGL(result, buf, length, 0);
  1299. }
  1300. if (use_copy1) {
  1301. zval_dtor(op1);
  1302. }
  1303. if (use_copy2) {
  1304. zval_dtor(op2);
  1305. }
  1306. return SUCCESS;
  1307. }
  1308. /* }}} */
  1309. ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */
  1310. {
  1311. zval op1_copy, op2_copy;
  1312. int use_copy1 = 0, use_copy2 = 0;
  1313. if (Z_TYPE_P(op1) != IS_STRING) {
  1314. zend_make_printable_zval(op1, &op1_copy, &use_copy1);
  1315. }
  1316. if (Z_TYPE_P(op2) != IS_STRING) {
  1317. zend_make_printable_zval(op2, &op2_copy, &use_copy2);
  1318. }
  1319. if (use_copy1) {
  1320. op1 = &op1_copy;
  1321. }
  1322. if (use_copy2) {
  1323. op2 = &op2_copy;
  1324. }
  1325. if (case_insensitive) {
  1326. ZVAL_LONG(result, zend_binary_zval_strcasecmp(op1, op2));
  1327. } else {
  1328. ZVAL_LONG(result, zend_binary_zval_strcmp(op1, op2));
  1329. }
  1330. if (use_copy1) {
  1331. zval_dtor(op1);
  1332. }
  1333. if (use_copy2) {
  1334. zval_dtor(op2);
  1335. }
  1336. return SUCCESS;
  1337. }
  1338. /* }}} */
  1339. ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1340. {
  1341. return string_compare_function_ex(result, op1, op2, 0 TSRMLS_CC);
  1342. }
  1343. /* }}} */
  1344. ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1345. {
  1346. return string_compare_function_ex(result, op1, op2, 1 TSRMLS_CC);
  1347. }
  1348. /* }}} */
  1349. #if HAVE_STRCOLL
  1350. ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1351. {
  1352. zval op1_copy, op2_copy;
  1353. int use_copy1 = 0, use_copy2 = 0;
  1354. if (Z_TYPE_P(op1) != IS_STRING) {
  1355. zend_make_printable_zval(op1, &op1_copy, &use_copy1);
  1356. }
  1357. if (Z_TYPE_P(op2) != IS_STRING) {
  1358. zend_make_printable_zval(op2, &op2_copy, &use_copy2);
  1359. }
  1360. if (use_copy1) {
  1361. op1 = &op1_copy;
  1362. }
  1363. if (use_copy2) {
  1364. op2 = &op2_copy;
  1365. }
  1366. ZVAL_LONG(result, strcoll(Z_STRVAL_P(op1), Z_STRVAL_P(op2)));
  1367. if (use_copy1) {
  1368. zval_dtor(op1);
  1369. }
  1370. if (use_copy2) {
  1371. zval_dtor(op2);
  1372. }
  1373. return SUCCESS;
  1374. }
  1375. /* }}} */
  1376. #endif
  1377. ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1378. {
  1379. zval op1_copy, op2_copy;
  1380. op1_copy = *op1;
  1381. zval_copy_ctor(&op1_copy);
  1382. op2_copy = *op2;
  1383. zval_copy_ctor(&op2_copy);
  1384. convert_to_double(&op1_copy);
  1385. convert_to_double(&op2_copy);
  1386. ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL(op1_copy)-Z_DVAL(op2_copy)));
  1387. return SUCCESS;
  1388. }
  1389. /* }}} */
  1390. static inline void zend_free_obj_get_result(zval *op TSRMLS_DC) /* {{{ */
  1391. {
  1392. if (Z_REFCOUNT_P(op) == 0) {
  1393. GC_REMOVE_ZVAL_FROM_BUFFER(op);
  1394. zval_dtor(op);
  1395. FREE_ZVAL(op);
  1396. } else {
  1397. zval_ptr_dtor(&op);
  1398. }
  1399. }
  1400. /* }}} */
  1401. ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1402. {
  1403. int ret;
  1404. int converted = 0;
  1405. zval op1_copy, op2_copy;
  1406. zval *op_free;
  1407. while (1) {
  1408. switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
  1409. case TYPE_PAIR(IS_LONG, IS_LONG):
  1410. ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
  1411. return SUCCESS;
  1412. case TYPE_PAIR(IS_DOUBLE, IS_LONG):
  1413. Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
  1414. ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
  1415. return SUCCESS;
  1416. case TYPE_PAIR(IS_LONG, IS_DOUBLE):
  1417. Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
  1418. ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
  1419. return SUCCESS;
  1420. case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
  1421. if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
  1422. ZVAL_LONG(result, 0);
  1423. } else {
  1424. Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
  1425. ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
  1426. }
  1427. return SUCCESS;
  1428. case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
  1429. zend_compare_arrays(result, op1, op2 TSRMLS_CC);
  1430. return SUCCESS;
  1431. case TYPE_PAIR(IS_NULL, IS_NULL):
  1432. ZVAL_LONG(result, 0);
  1433. return SUCCESS;
  1434. case TYPE_PAIR(IS_NULL, IS_BOOL):
  1435. ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
  1436. return SUCCESS;
  1437. case TYPE_PAIR(IS_BOOL, IS_NULL):
  1438. ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
  1439. return SUCCESS;
  1440. case TYPE_PAIR(IS_BOOL, IS_BOOL):
  1441. ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
  1442. return SUCCESS;
  1443. case TYPE_PAIR(IS_STRING, IS_STRING):
  1444. zendi_smart_strcmp(result, op1, op2);
  1445. return SUCCESS;
  1446. case TYPE_PAIR(IS_NULL, IS_STRING):
  1447. ZVAL_LONG(result, zend_binary_strcmp("", 0, Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
  1448. return SUCCESS;
  1449. case TYPE_PAIR(IS_STRING, IS_NULL):
  1450. ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), "", 0));
  1451. return SUCCESS;
  1452. case TYPE_PAIR(IS_OBJECT, IS_NULL):
  1453. ZVAL_LONG(result, 1);
  1454. return SUCCESS;
  1455. case TYPE_PAIR(IS_NULL, IS_OBJECT):
  1456. ZVAL_LONG(result, -1);
  1457. return SUCCESS;
  1458. default:
  1459. if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
  1460. return Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2 TSRMLS_CC);
  1461. } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) {
  1462. return Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2 TSRMLS_CC);
  1463. }
  1464. if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
  1465. if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
  1466. /* object handles are identical, apparently this is the same object */
  1467. ZVAL_LONG(result, 0);
  1468. return SUCCESS;
  1469. }
  1470. if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) {
  1471. ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2 TSRMLS_CC));
  1472. return SUCCESS;
  1473. }
  1474. }
  1475. if (Z_TYPE_P(op1) == IS_OBJECT) {
  1476. if (Z_OBJ_HT_P(op1)->get) {
  1477. op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
  1478. ret = compare_function(result, op_free, op2 TSRMLS_CC);
  1479. zend_free_obj_get_result(op_free TSRMLS_CC);
  1480. return ret;
  1481. } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
  1482. ALLOC_INIT_ZVAL(op_free);
  1483. if (Z_OBJ_HT_P(op1)->cast_object(op1, op_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
  1484. ZVAL_LONG(result, 1);
  1485. zend_free_obj_get_result(op_free TSRMLS_CC);
  1486. return SUCCESS;
  1487. }
  1488. ret = compare_function(result, op_free, op2 TSRMLS_CC);
  1489. zend_free_obj_get_result(op_free TSRMLS_CC);
  1490. return ret;
  1491. }
  1492. }
  1493. if (Z_TYPE_P(op2) == IS_OBJECT) {
  1494. if (Z_OBJ_HT_P(op2)->get) {
  1495. op_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
  1496. ret = compare_function(result, op1, op_free TSRMLS_CC);
  1497. zend_free_obj_get_result(op_free TSRMLS_CC);
  1498. return ret;
  1499. } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
  1500. ALLOC_INIT_ZVAL(op_free);
  1501. if (Z_OBJ_HT_P(op2)->cast_object(op2, op_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
  1502. ZVAL_LONG(result, -1);
  1503. zend_free_obj_get_result(op_free TSRMLS_CC);
  1504. return SUCCESS;
  1505. }
  1506. ret = compare_function(result, op1, op_free TSRMLS_CC);
  1507. zend_free_obj_get_result(op_free TSRMLS_CC);
  1508. return ret;
  1509. } else if (Z_TYPE_P(op1) == IS_OBJECT) {
  1510. ZVAL_LONG(result, 1);
  1511. return SUCCESS;
  1512. }
  1513. }
  1514. if (!converted) {
  1515. if (Z_TYPE_P(op1) == IS_NULL) {
  1516. zendi_convert_to_boolean(op2, op2_copy, result);
  1517. ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
  1518. return SUCCESS;
  1519. } else if (Z_TYPE_P(op2) == IS_NULL) {
  1520. zendi_convert_to_boolean(op1, op1_copy, result);
  1521. ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
  1522. return SUCCESS;
  1523. } else if (Z_TYPE_P(op1) == IS_BOOL) {
  1524. zendi_convert_to_boolean(op2, op2_copy, result);
  1525. ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
  1526. return SUCCESS;
  1527. } else if (Z_TYPE_P(op2) == IS_BOOL) {
  1528. zendi_convert_to_boolean(op1, op1_copy, result);
  1529. ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
  1530. return SUCCESS;
  1531. } else {
  1532. zendi_convert_scalar_to_number(op1, op1_copy, result);
  1533. zendi_convert_scalar_to_number(op2, op2_copy, result);
  1534. converted = 1;
  1535. }
  1536. } else if (Z_TYPE_P(op1)==IS_ARRAY) {
  1537. ZVAL_LONG(result, 1);
  1538. return SUCCESS;
  1539. } else if (Z_TYPE_P(op2)==IS_ARRAY) {
  1540. ZVAL_LONG(result, -1);
  1541. return SUCCESS;
  1542. } else if (Z_TYPE_P(op1)==IS_OBJECT) {
  1543. ZVAL_LONG(result, 1);
  1544. return SUCCESS;
  1545. } else if (Z_TYPE_P(op2)==IS_OBJECT) {
  1546. ZVAL_LONG(result, -1);
  1547. return SUCCESS;
  1548. } else {
  1549. ZVAL_LONG(result, 0);
  1550. return FAILURE;
  1551. }
  1552. }
  1553. }
  1554. }
  1555. /* }}} */
  1556. static int hash_zval_identical_function(const zval **z1, const zval **z2) /* {{{ */
  1557. {
  1558. zval result;
  1559. TSRMLS_FETCH();
  1560. /* is_identical_function() returns 1 in case of identity and 0 in case
  1561. * of a difference;
  1562. * whereas this comparison function is expected to return 0 on identity,
  1563. * and non zero otherwise.
  1564. */
  1565. if (is_identical_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
  1566. return 1;
  1567. }
  1568. return !Z_LVAL(result);
  1569. }
  1570. /* }}} */
  1571. ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1572. {
  1573. Z_TYPE_P(result) = IS_BOOL;
  1574. if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
  1575. Z_LVAL_P(result) = 0;
  1576. return SUCCESS;
  1577. }
  1578. switch (Z_TYPE_P(op1)) {
  1579. case IS_NULL:
  1580. Z_LVAL_P(result) = 1;
  1581. break;
  1582. case IS_BOOL:
  1583. case IS_LONG:
  1584. case IS_RESOURCE:
  1585. Z_LVAL_P(result) = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
  1586. break;
  1587. case IS_DOUBLE:
  1588. Z_LVAL_P(result) = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
  1589. break;
  1590. case IS_STRING:
  1591. Z_LVAL_P(result) = ((Z_STRLEN_P(op1) == Z_STRLEN_P(op2))
  1592. && (!memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1))));
  1593. break;
  1594. case IS_ARRAY:
  1595. Z_LVAL_P(result) = (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) ||
  1596. zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1 TSRMLS_CC)==0);
  1597. break;
  1598. case IS_OBJECT:
  1599. if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
  1600. Z_LVAL_P(result) = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
  1601. } else {
  1602. Z_LVAL_P(result) = 0;
  1603. }
  1604. break;
  1605. default:
  1606. Z_LVAL_P(result) = 0;
  1607. return FAILURE;
  1608. }
  1609. return SUCCESS;
  1610. }
  1611. /* }}} */
  1612. ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1613. {
  1614. if (is_identical_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
  1615. return FAILURE;
  1616. }
  1617. Z_LVAL_P(result) = !Z_LVAL_P(result);
  1618. return SUCCESS;
  1619. }
  1620. /* }}} */
  1621. ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1622. {
  1623. if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
  1624. return FAILURE;
  1625. }
  1626. ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
  1627. return SUCCESS;
  1628. }
  1629. /* }}} */
  1630. ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1631. {
  1632. if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
  1633. return FAILURE;
  1634. }
  1635. ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
  1636. return SUCCESS;
  1637. }
  1638. /* }}} */
  1639. ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1640. {
  1641. if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
  1642. return FAILURE;
  1643. }
  1644. ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
  1645. return SUCCESS;
  1646. }
  1647. /* }}} */
  1648. ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
  1649. {
  1650. if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
  1651. return FAILURE;
  1652. }
  1653. ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
  1654. return SUCCESS;
  1655. }
  1656. /* }}} */
  1657. ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC) /* {{{ */
  1658. {
  1659. zend_uint i;
  1660. for (i=0; i<instance_ce->num_interfaces; i++) {
  1661. if (instanceof_function(instance_ce->interfaces[i], ce TSRMLS_CC)) {
  1662. return 1;
  1663. }
  1664. }
  1665. if (!interfaces_only) {
  1666. while (instance_ce) {
  1667. if (instance_ce == ce) {
  1668. return 1;
  1669. }
  1670. instance_ce = instance_ce->parent;
  1671. }
  1672. }
  1673. return 0;
  1674. }
  1675. /* }}} */
  1676. ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce TSRMLS_DC) /* {{{ */
  1677. {
  1678. return instanceof_function_ex(instance_ce, ce, 0 TSRMLS_CC);
  1679. }
  1680. /* }}} */
  1681. #define LOWER_CASE 1
  1682. #define UPPER_CASE 2
  1683. #define NUMERIC 3
  1684. static void increment_string(zval *str) /* {{{ */
  1685. {
  1686. int carry=0;
  1687. int pos=Z_STRLEN_P(str)-1;
  1688. char *s=Z_STRVAL_P(str);
  1689. char *t;
  1690. int last=0; /* Shut up the compiler warning */
  1691. int ch;
  1692. if (Z_STRLEN_P(str) == 0) {
  1693. str_efree(Z_STRVAL_P(str));
  1694. Z_STRVAL_P(str) = estrndup("1", sizeof("1")-1);
  1695. Z_STRLEN_P(str) = 1;
  1696. return;
  1697. }
  1698. if (IS_INTERNED(s)) {
  1699. Z_STRVAL_P(str) = s = estrndup(s, Z_STRLEN_P(str));
  1700. }
  1701. while (pos >= 0) {
  1702. ch = s[pos];
  1703. if (ch >= 'a' && ch <= 'z') {
  1704. if (ch == 'z') {
  1705. s[pos] = 'a';
  1706. carry=1;
  1707. } else {
  1708. s[pos]++;
  1709. carry=0;
  1710. }
  1711. last=LOWER_CASE;
  1712. } else if (ch >= 'A' && ch <= 'Z') {
  1713. if (ch == 'Z') {
  1714. s[pos] = 'A';
  1715. carry=1;
  1716. } else {
  1717. s[pos]++;
  1718. carry=0;
  1719. }
  1720. last=UPPER_CASE;
  1721. } else if (ch >= '0' && ch <= '9') {
  1722. if (ch == '9') {
  1723. s[pos] = '0';
  1724. carry=1;
  1725. } else {
  1726. s[pos]++;
  1727. carry=0;
  1728. }
  1729. last = NUMERIC;
  1730. } else {
  1731. carry=0;
  1732. break;
  1733. }
  1734. if (carry == 0) {
  1735. break;
  1736. }
  1737. pos--;
  1738. }
  1739. if (carry) {
  1740. t = (char *) emalloc(Z_STRLEN_P(str)+1+1);
  1741. memcpy(t+1, Z_STRVAL_P(str), Z_STRLEN_P(str));
  1742. Z_STRLEN_P(str)++;
  1743. t[Z_STRLEN_P(str)] = '\0';
  1744. switch (last) {
  1745. case NUMERIC:
  1746. t[0] = '1';
  1747. break;
  1748. case UPPER_CASE:
  1749. t[0] = 'A';
  1750. break;
  1751. case LOWER_CASE:
  1752. t[0] = 'a';
  1753. break;
  1754. }
  1755. str_efree(Z_STRVAL_P(str));
  1756. Z_STRVAL_P(str) = t;
  1757. }
  1758. }
  1759. /* }}} */
  1760. ZEND_API int increment_function(zval *op1) /* {{{ */
  1761. {
  1762. switch (Z_TYPE_P(op1)) {
  1763. case IS_LONG:
  1764. if (Z_LVAL_P(op1) == LONG_MAX) {
  1765. /* switch to double */
  1766. double d = (double)Z_LVAL_P(op1);
  1767. ZVAL_DOUBLE(op1, d+1);
  1768. } else {
  1769. Z_LVAL_P(op1)++;
  1770. }
  1771. break;
  1772. case IS_DOUBLE:
  1773. Z_DVAL_P(op1) = Z_DVAL_P(op1) + 1;
  1774. break;
  1775. case IS_NULL:
  1776. ZVAL_LONG(op1, 1);
  1777. break;
  1778. case IS_STRING: {
  1779. long lval;
  1780. double dval;
  1781. switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
  1782. case IS_LONG:
  1783. str_efree(Z_STRVAL_P(op1));
  1784. if (lval == LONG_MAX) {
  1785. /* switch to double */
  1786. double d = (double)lval;
  1787. ZVAL_DOUBLE(op1, d+1);
  1788. } else {
  1789. ZVAL_LONG(op1, lval+1);
  1790. }
  1791. break;
  1792. case IS_DOUBLE:
  1793. str_efree(Z_STRVAL_P(op1));
  1794. ZVAL_DOUBLE(op1, dval+1);
  1795. break;
  1796. default:
  1797. /* Perl style string increment */
  1798. increment_string(op1);
  1799. break;
  1800. }
  1801. }
  1802. break;
  1803. case IS_OBJECT:
  1804. if (Z_OBJ_HANDLER_P(op1, do_operation)) {
  1805. zval *op2;
  1806. int res;
  1807. TSRMLS_FETCH();
  1808. MAKE_STD_ZVAL(op2);
  1809. ZVAL_LONG(op2, 1);
  1810. res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, op2 TSRMLS_CC);
  1811. zval_ptr_dtor(&op2);
  1812. return res;
  1813. }
  1814. return FAILURE;
  1815. default:
  1816. return FAILURE;
  1817. }
  1818. return SUCCESS;
  1819. }
  1820. /* }}} */
  1821. ZEND_API int decrement_function(zval *op1) /* {{{ */
  1822. {
  1823. long lval;
  1824. double dval;
  1825. switch (Z_TYPE_P(op1)) {
  1826. case IS_LONG:
  1827. if (Z_LVAL_P(op1) == LONG_MIN) {
  1828. double d = (double)Z_LVAL_P(op1);
  1829. ZVAL_DOUBLE(op1, d-1);
  1830. } else {
  1831. Z_LVAL_P(op1)--;
  1832. }
  1833. break;
  1834. case IS_DOUBLE:
  1835. Z_DVAL_P(op1) = Z_DVAL_P(op1) - 1;
  1836. break;
  1837. case IS_STRING: /* Like perl we only support string increment */
  1838. if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */
  1839. str_efree(Z_STRVAL_P(op1));
  1840. ZVAL_LONG(op1, -1);
  1841. break;
  1842. }
  1843. switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
  1844. case IS_LONG:
  1845. str_efree(Z_STRVAL_P(op1));
  1846. if (lval == LONG_MIN) {
  1847. double d = (double)lval;
  1848. ZVAL_DOUBLE(op1, d-1);
  1849. } else {
  1850. ZVAL_LONG(op1, lval-1);
  1851. }
  1852. break;
  1853. case IS_DOUBLE:
  1854. str_efree(Z_STRVAL_P(op1));
  1855. ZVAL_DOUBLE(op1, dval - 1);
  1856. break;
  1857. }
  1858. break;
  1859. case IS_OBJECT:
  1860. if (Z_OBJ_HANDLER_P(op1, do_operation)) {
  1861. zval *op2;
  1862. int res;
  1863. TSRMLS_FETCH();
  1864. MAKE_STD_ZVAL(op2);
  1865. ZVAL_LONG(op2, 1);
  1866. res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, op2 TSRMLS_CC);
  1867. zval_ptr_dtor(&op2);
  1868. return res;
  1869. }
  1870. return FAILURE;
  1871. default:
  1872. return FAILURE;
  1873. }
  1874. return SUCCESS;
  1875. }
  1876. /* }}} */
  1877. ZEND_API int zval_is_true(zval *op) /* {{{ */
  1878. {
  1879. convert_to_boolean(op);
  1880. return (Z_LVAL_P(op) ? 1 : 0);
  1881. }
  1882. /* }}} */
  1883. #ifdef ZEND_USE_TOLOWER_L
  1884. ZEND_API void zend_update_current_locale(void) /* {{{ */
  1885. {
  1886. current_locale = _get_current_locale();
  1887. }
  1888. /* }}} */
  1889. #endif
  1890. ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) /* {{{ */
  1891. {
  1892. register unsigned char *str = (unsigned char*)source;
  1893. register unsigned char *result = (unsigned char*)dest;
  1894. register unsigned char *end = str + length;
  1895. while (str < end) {
  1896. *result++ = zend_tolower_ascii(*str++);
  1897. }
  1898. *result = '\0';
  1899. return dest;
  1900. }
  1901. /* }}} */
  1902. ZEND_API char *zend_str_tolower_dup(const char *source, unsigned int length) /* {{{ */
  1903. {
  1904. return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
  1905. }
  1906. /* }}} */
  1907. ZEND_API void zend_str_tolower(char *str, unsigned int length) /* {{{ */
  1908. {
  1909. register unsigned char *p = (unsigned char*)str;
  1910. register unsigned char *end = p + length;
  1911. while (p < end) {
  1912. *p = zend_tolower_ascii(*p);
  1913. p++;
  1914. }
  1915. }
  1916. /* }}} */
  1917. ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
  1918. {
  1919. int retval;
  1920. if (s1 == s2) {
  1921. return 0;
  1922. }
  1923. retval = memcmp(s1, s2, MIN(len1, len2));
  1924. if (!retval) {
  1925. return (len1 - len2);
  1926. } else {
  1927. return retval;
  1928. }
  1929. }
  1930. /* }}} */
  1931. ZEND_API int zend_binary_strncmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
  1932. {
  1933. int retval;
  1934. if (s1 == s2) {
  1935. return 0;
  1936. }
  1937. retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
  1938. if (!retval) {
  1939. return (MIN(length, len1) - MIN(length, len2));
  1940. } else {
  1941. return retval;
  1942. }
  1943. }
  1944. /* }}} */
  1945. ZEND_API int zend_binary_strcasecmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
  1946. {
  1947. int len;
  1948. int c1, c2;
  1949. if (s1 == s2) {
  1950. return 0;
  1951. }
  1952. len = MIN(len1, len2);
  1953. while (len--) {
  1954. c1 = zend_tolower_ascii(*(unsigned char *)s1++);
  1955. c2 = zend_tolower_ascii(*(unsigned char *)s2++);
  1956. if (c1 != c2) {
  1957. return c1 - c2;
  1958. }
  1959. }
  1960. return len1 - len2;
  1961. }
  1962. /* }}} */
  1963. ZEND_API int zend_binary_strncasecmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
  1964. {
  1965. int len;
  1966. int c1, c2;
  1967. if (s1 == s2) {
  1968. return 0;
  1969. }
  1970. len = MIN(length, MIN(len1, len2));
  1971. while (len--) {
  1972. c1 = zend_tolower_ascii(*(unsigned char *)s1++);
  1973. c2 = zend_tolower_ascii(*(unsigned char *)s2++);
  1974. if (c1 != c2) {
  1975. return c1 - c2;
  1976. }
  1977. }
  1978. return MIN(length, len1) - MIN(length, len2);
  1979. }
  1980. /* }}} */
  1981. ZEND_API int zend_binary_strcasecmp_l(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
  1982. {
  1983. int len;
  1984. int c1, c2;
  1985. if (s1 == s2) {
  1986. return 0;
  1987. }
  1988. len = MIN(len1, len2);
  1989. while (len--) {
  1990. c1 = zend_tolower((int)*(unsigned char *)s1++);
  1991. c2 = zend_tolower((int)*(unsigned char *)s2++);
  1992. if (c1 != c2) {
  1993. return c1 - c2;
  1994. }
  1995. }
  1996. return len1 - len2;
  1997. }
  1998. /* }}} */
  1999. ZEND_API int zend_binary_strncasecmp_l(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
  2000. {
  2001. int len;
  2002. int c1, c2;
  2003. if (s1 == s2) {
  2004. return 0;
  2005. }
  2006. len = MIN(length, MIN(len1, len2));
  2007. while (len--) {
  2008. c1 = zend_tolower((int)*(unsigned char *)s1++);
  2009. c2 = zend_tolower((int)*(unsigned char *)s2++);
  2010. if (c1 != c2) {
  2011. return c1 - c2;
  2012. }
  2013. }
  2014. return MIN(length, len1) - MIN(length, len2);
  2015. }
  2016. /* }}} */
  2017. ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
  2018. {
  2019. return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
  2020. }
  2021. /* }}} */
  2022. ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
  2023. {
  2024. return zend_binary_strncmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2), Z_LVAL_P(s3));
  2025. }
  2026. /* }}} */
  2027. ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2) /* {{{ */
  2028. {
  2029. return zend_binary_strcasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
  2030. }
  2031. /* }}} */
  2032. ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ */
  2033. {
  2034. return zend_binary_strncasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2), Z_LVAL_P(s3));
  2035. }
  2036. /* }}} */
  2037. ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
  2038. {
  2039. int ret1, ret2;
  2040. int oflow1, oflow2;
  2041. long lval1 = 0, lval2 = 0;
  2042. double dval1 = 0.0, dval2 = 0.0;
  2043. if ((ret1=is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) &&
  2044. (ret2=is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) {
  2045. #if ULONG_MAX == 0xFFFFFFFF
  2046. if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
  2047. ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
  2048. || (oflow1 == -1 && dval1 < -9007199254740991.))) {
  2049. #else
  2050. if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) {
  2051. #endif
  2052. /* both values are integers overflown to the same side, and the
  2053. * double comparison may have resulted in crucial accuracy lost */
  2054. goto string_cmp;
  2055. }
  2056. if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
  2057. if (ret1!=IS_DOUBLE) {
  2058. if (oflow2) {
  2059. /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
  2060. ZVAL_LONG(result, -1 * oflow2);
  2061. return;
  2062. }
  2063. dval1 = (double) lval1;
  2064. } else if (ret2!=IS_DOUBLE) {
  2065. if (oflow1) {
  2066. ZVAL_LONG(result, oflow1);
  2067. return;
  2068. }
  2069. dval2 = (double) lval2;
  2070. } else if (dval1 == dval2 && !zend_finite(dval1)) {
  2071. /* Both values overflowed and have the same sign,
  2072. * so a numeric comparison would be inaccurate */
  2073. goto string_cmp;
  2074. }
  2075. Z_DVAL_P(result) = dval1 - dval2;
  2076. ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
  2077. } else { /* they both have to be long's */
  2078. ZVAL_LONG(result, lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0));
  2079. }
  2080. } else {
  2081. string_cmp:
  2082. Z_LVAL_P(result) = zend_binary_zval_strcmp(s1, s2);
  2083. ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(result)));
  2084. }
  2085. }
  2086. /* }}} */
  2087. static int hash_zval_compare_function(const zval **z1, const zval **z2 TSRMLS_DC) /* {{{ */
  2088. {
  2089. zval result;
  2090. if (compare_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
  2091. return 1;
  2092. }
  2093. return Z_LVAL(result);
  2094. }
  2095. /* }}} */
  2096. ZEND_API int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
  2097. {
  2098. return ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
  2099. }
  2100. /* }}} */
  2101. ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
  2102. {
  2103. ZVAL_LONG(result, ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC));
  2104. }
  2105. /* }}} */
  2106. ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC) /* {{{ */
  2107. {
  2108. zend_compare_symbol_tables(result, Z_ARRVAL_P(a1), Z_ARRVAL_P(a2) TSRMLS_CC);
  2109. }
  2110. /* }}} */
  2111. ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
  2112. {
  2113. Z_TYPE_P(result) = IS_LONG;
  2114. if (Z_OBJ_HANDLE_P(o1) == Z_OBJ_HANDLE_P(o2)) {
  2115. Z_LVAL_P(result) = 0;
  2116. return;
  2117. }
  2118. if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
  2119. Z_LVAL_P(result) = 1;
  2120. } else {
  2121. Z_LVAL_P(result) = Z_OBJ_HT_P(o1)->compare_objects(o1, o2 TSRMLS_CC);
  2122. }
  2123. }
  2124. /* }}} */
  2125. ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
  2126. {
  2127. TSRMLS_FETCH();
  2128. Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
  2129. }
  2130. /* }}} */
  2131. /*
  2132. * Local variables:
  2133. * tab-width: 4
  2134. * c-basic-offset: 4
  2135. * indent-tabs-mode: t
  2136. * End:
  2137. */