zend_builtin_functions.c 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503
  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 "zend.h"
  21. #include "zend_API.h"
  22. #include "zend_builtin_functions.h"
  23. #include "zend_constants.h"
  24. #include "zend_ini.h"
  25. #include "zend_exceptions.h"
  26. #include "zend_extensions.h"
  27. #include "zend_closures.h"
  28. #undef ZEND_TEST_EXCEPTIONS
  29. static ZEND_FUNCTION(zend_version);
  30. static ZEND_FUNCTION(func_num_args);
  31. static ZEND_FUNCTION(func_get_arg);
  32. static ZEND_FUNCTION(func_get_args);
  33. static ZEND_FUNCTION(strlen);
  34. static ZEND_FUNCTION(strcmp);
  35. static ZEND_FUNCTION(strncmp);
  36. static ZEND_FUNCTION(strcasecmp);
  37. static ZEND_FUNCTION(strncasecmp);
  38. static ZEND_FUNCTION(each);
  39. static ZEND_FUNCTION(error_reporting);
  40. static ZEND_FUNCTION(define);
  41. static ZEND_FUNCTION(defined);
  42. static ZEND_FUNCTION(get_class);
  43. static ZEND_FUNCTION(get_called_class);
  44. static ZEND_FUNCTION(get_parent_class);
  45. static ZEND_FUNCTION(method_exists);
  46. static ZEND_FUNCTION(property_exists);
  47. static ZEND_FUNCTION(class_exists);
  48. static ZEND_FUNCTION(interface_exists);
  49. static ZEND_FUNCTION(trait_exists);
  50. static ZEND_FUNCTION(function_exists);
  51. static ZEND_FUNCTION(class_alias);
  52. #if ZEND_DEBUG
  53. static ZEND_FUNCTION(leak);
  54. static ZEND_FUNCTION(leak_variable);
  55. #ifdef ZEND_TEST_EXCEPTIONS
  56. static ZEND_FUNCTION(crash);
  57. #endif
  58. #endif
  59. static ZEND_FUNCTION(get_included_files);
  60. static ZEND_FUNCTION(is_subclass_of);
  61. static ZEND_FUNCTION(is_a);
  62. static ZEND_FUNCTION(get_class_vars);
  63. static ZEND_FUNCTION(get_object_vars);
  64. static ZEND_FUNCTION(get_class_methods);
  65. static ZEND_FUNCTION(trigger_error);
  66. static ZEND_FUNCTION(set_error_handler);
  67. static ZEND_FUNCTION(restore_error_handler);
  68. static ZEND_FUNCTION(set_exception_handler);
  69. static ZEND_FUNCTION(restore_exception_handler);
  70. static ZEND_FUNCTION(get_declared_classes);
  71. static ZEND_FUNCTION(get_declared_traits);
  72. static ZEND_FUNCTION(get_declared_interfaces);
  73. static ZEND_FUNCTION(get_defined_functions);
  74. static ZEND_FUNCTION(get_defined_vars);
  75. static ZEND_FUNCTION(create_function);
  76. static ZEND_FUNCTION(get_resource_type);
  77. static ZEND_FUNCTION(get_loaded_extensions);
  78. static ZEND_FUNCTION(extension_loaded);
  79. static ZEND_FUNCTION(get_extension_funcs);
  80. static ZEND_FUNCTION(get_defined_constants);
  81. static ZEND_FUNCTION(debug_backtrace);
  82. static ZEND_FUNCTION(debug_print_backtrace);
  83. #if ZEND_DEBUG
  84. static ZEND_FUNCTION(zend_test_func);
  85. #ifdef ZTS
  86. static ZEND_FUNCTION(zend_thread_id);
  87. #endif
  88. #endif
  89. static ZEND_FUNCTION(gc_collect_cycles);
  90. static ZEND_FUNCTION(gc_enabled);
  91. static ZEND_FUNCTION(gc_enable);
  92. static ZEND_FUNCTION(gc_disable);
  93. /* {{{ arginfo */
  94. ZEND_BEGIN_ARG_INFO(arginfo_zend__void, 0)
  95. ZEND_END_ARG_INFO()
  96. ZEND_BEGIN_ARG_INFO_EX(arginfo_func_get_arg, 0, 0, 1)
  97. ZEND_ARG_INFO(0, arg_num)
  98. ZEND_END_ARG_INFO()
  99. ZEND_BEGIN_ARG_INFO_EX(arginfo_strlen, 0, 0, 1)
  100. ZEND_ARG_INFO(0, str)
  101. ZEND_END_ARG_INFO()
  102. ZEND_BEGIN_ARG_INFO_EX(arginfo_strcmp, 0, 0, 2)
  103. ZEND_ARG_INFO(0, str1)
  104. ZEND_ARG_INFO(0, str2)
  105. ZEND_END_ARG_INFO()
  106. ZEND_BEGIN_ARG_INFO_EX(arginfo_strncmp, 0, 0, 3)
  107. ZEND_ARG_INFO(0, str1)
  108. ZEND_ARG_INFO(0, str2)
  109. ZEND_ARG_INFO(0, len)
  110. ZEND_END_ARG_INFO()
  111. ZEND_BEGIN_ARG_INFO_EX(arginfo_each, 0, 0, 1)
  112. ZEND_ARG_INFO(1, arr)
  113. ZEND_END_ARG_INFO()
  114. ZEND_BEGIN_ARG_INFO_EX(arginfo_error_reporting, 0, 0, 0)
  115. ZEND_ARG_INFO(0, new_error_level)
  116. ZEND_END_ARG_INFO()
  117. ZEND_BEGIN_ARG_INFO_EX(arginfo_define, 0, 0, 3)
  118. ZEND_ARG_INFO(0, constant_name)
  119. ZEND_ARG_INFO(0, value)
  120. ZEND_ARG_INFO(0, case_insensitive)
  121. ZEND_END_ARG_INFO()
  122. ZEND_BEGIN_ARG_INFO_EX(arginfo_defined, 0, 0, 1)
  123. ZEND_ARG_INFO(0, constant_name)
  124. ZEND_END_ARG_INFO()
  125. ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class, 0, 0, 0)
  126. ZEND_ARG_INFO(0, object)
  127. ZEND_END_ARG_INFO()
  128. ZEND_BEGIN_ARG_INFO_EX(arginfo_is_subclass_of, 0, 0, 2)
  129. ZEND_ARG_INFO(0, object)
  130. ZEND_ARG_INFO(0, class_name)
  131. ZEND_ARG_INFO(0, allow_string)
  132. ZEND_END_ARG_INFO()
  133. ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_vars, 0, 0, 1)
  134. ZEND_ARG_INFO(0, class_name)
  135. ZEND_END_ARG_INFO()
  136. ZEND_BEGIN_ARG_INFO_EX(arginfo_get_object_vars, 0, 0, 1)
  137. ZEND_ARG_INFO(0, obj)
  138. ZEND_END_ARG_INFO()
  139. ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_methods, 0, 0, 1)
  140. ZEND_ARG_INFO(0, class)
  141. ZEND_END_ARG_INFO()
  142. ZEND_BEGIN_ARG_INFO_EX(arginfo_method_exists, 0, 0, 2)
  143. ZEND_ARG_INFO(0, object)
  144. ZEND_ARG_INFO(0, method)
  145. ZEND_END_ARG_INFO()
  146. ZEND_BEGIN_ARG_INFO_EX(arginfo_property_exists, 0, 0, 2)
  147. ZEND_ARG_INFO(0, object_or_class)
  148. ZEND_ARG_INFO(0, property_name)
  149. ZEND_END_ARG_INFO()
  150. ZEND_BEGIN_ARG_INFO_EX(arginfo_class_exists, 0, 0, 1)
  151. ZEND_ARG_INFO(0, classname)
  152. ZEND_ARG_INFO(0, autoload)
  153. ZEND_END_ARG_INFO()
  154. ZEND_BEGIN_ARG_INFO_EX(arginfo_trait_exists, 0, 0, 1)
  155. ZEND_ARG_INFO(0, traitname)
  156. ZEND_ARG_INFO(0, autoload)
  157. ZEND_END_ARG_INFO()
  158. ZEND_BEGIN_ARG_INFO_EX(arginfo_function_exists, 0, 0, 1)
  159. ZEND_ARG_INFO(0, function_name)
  160. ZEND_END_ARG_INFO()
  161. ZEND_BEGIN_ARG_INFO_EX(arginfo_class_alias, 0, 0, 2)
  162. ZEND_ARG_INFO(0, user_class_name)
  163. ZEND_ARG_INFO(0, alias_name)
  164. ZEND_ARG_INFO(0, autoload)
  165. ZEND_END_ARG_INFO()
  166. #if ZEND_DEBUG
  167. ZEND_BEGIN_ARG_INFO_EX(arginfo_leak_variable, 0, 0, 1)
  168. ZEND_ARG_INFO(0, variable)
  169. ZEND_ARG_INFO(0, leak_data)
  170. ZEND_END_ARG_INFO()
  171. #endif
  172. ZEND_BEGIN_ARG_INFO_EX(arginfo_trigger_error, 0, 0, 1)
  173. ZEND_ARG_INFO(0, message)
  174. ZEND_ARG_INFO(0, error_type)
  175. ZEND_END_ARG_INFO()
  176. ZEND_BEGIN_ARG_INFO_EX(arginfo_set_error_handler, 0, 0, 1)
  177. ZEND_ARG_INFO(0, error_handler)
  178. ZEND_ARG_INFO(0, error_types)
  179. ZEND_END_ARG_INFO()
  180. ZEND_BEGIN_ARG_INFO_EX(arginfo_set_exception_handler, 0, 0, 1)
  181. ZEND_ARG_INFO(0, exception_handler)
  182. ZEND_END_ARG_INFO()
  183. ZEND_BEGIN_ARG_INFO_EX(arginfo_create_function, 0, 0, 2)
  184. ZEND_ARG_INFO(0, args)
  185. ZEND_ARG_INFO(0, code)
  186. ZEND_END_ARG_INFO()
  187. ZEND_BEGIN_ARG_INFO_EX(arginfo_get_resource_type, 0, 0, 1)
  188. ZEND_ARG_INFO(0, res)
  189. ZEND_END_ARG_INFO()
  190. ZEND_BEGIN_ARG_INFO_EX(arginfo_get_loaded_extensions, 0, 0, 0)
  191. ZEND_ARG_INFO(0, zend_extensions)
  192. ZEND_END_ARG_INFO()
  193. ZEND_BEGIN_ARG_INFO_EX(arginfo_get_defined_constants, 0, 0, 0)
  194. ZEND_ARG_INFO(0, categorize)
  195. ZEND_END_ARG_INFO()
  196. ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_backtrace, 0, 0, 0)
  197. ZEND_ARG_INFO(0, options)
  198. ZEND_ARG_INFO(0, limit)
  199. ZEND_END_ARG_INFO()
  200. ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_print_backtrace, 0, 0, 0)
  201. ZEND_ARG_INFO(0, options)
  202. ZEND_END_ARG_INFO()
  203. ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
  204. ZEND_ARG_INFO(0, extension_name)
  205. ZEND_END_ARG_INFO()
  206. /* }}} */
  207. static const zend_function_entry builtin_functions[] = { /* {{{ */
  208. ZEND_FE(zend_version, arginfo_zend__void)
  209. ZEND_FE(func_num_args, arginfo_zend__void)
  210. ZEND_FE(func_get_arg, arginfo_func_get_arg)
  211. ZEND_FE(func_get_args, arginfo_zend__void)
  212. ZEND_FE(strlen, arginfo_strlen)
  213. ZEND_FE(strcmp, arginfo_strcmp)
  214. ZEND_FE(strncmp, arginfo_strncmp)
  215. ZEND_FE(strcasecmp, arginfo_strcmp)
  216. ZEND_FE(strncasecmp, arginfo_strncmp)
  217. ZEND_FE(each, arginfo_each)
  218. ZEND_FE(error_reporting, arginfo_error_reporting)
  219. ZEND_FE(define, arginfo_define)
  220. ZEND_FE(defined, arginfo_defined)
  221. ZEND_FE(get_class, arginfo_get_class)
  222. ZEND_FE(get_called_class, arginfo_zend__void)
  223. ZEND_FE(get_parent_class, arginfo_get_class)
  224. ZEND_FE(method_exists, arginfo_method_exists)
  225. ZEND_FE(property_exists, arginfo_property_exists)
  226. ZEND_FE(class_exists, arginfo_class_exists)
  227. ZEND_FE(interface_exists, arginfo_class_exists)
  228. ZEND_FE(trait_exists, arginfo_trait_exists)
  229. ZEND_FE(function_exists, arginfo_function_exists)
  230. ZEND_FE(class_alias, arginfo_class_alias)
  231. #if ZEND_DEBUG
  232. ZEND_FE(leak, NULL)
  233. ZEND_FE(leak_variable, arginfo_leak_variable)
  234. #ifdef ZEND_TEST_EXCEPTIONS
  235. ZEND_FE(crash, NULL)
  236. #endif
  237. #endif
  238. ZEND_FE(get_included_files, arginfo_zend__void)
  239. ZEND_FALIAS(get_required_files, get_included_files, arginfo_zend__void)
  240. ZEND_FE(is_subclass_of, arginfo_is_subclass_of)
  241. ZEND_FE(is_a, arginfo_is_subclass_of)
  242. ZEND_FE(get_class_vars, arginfo_get_class_vars)
  243. ZEND_FE(get_object_vars, arginfo_get_object_vars)
  244. ZEND_FE(get_class_methods, arginfo_get_class_methods)
  245. ZEND_FE(trigger_error, arginfo_trigger_error)
  246. ZEND_FALIAS(user_error, trigger_error, arginfo_trigger_error)
  247. ZEND_FE(set_error_handler, arginfo_set_error_handler)
  248. ZEND_FE(restore_error_handler, arginfo_zend__void)
  249. ZEND_FE(set_exception_handler, arginfo_set_exception_handler)
  250. ZEND_FE(restore_exception_handler, arginfo_zend__void)
  251. ZEND_FE(get_declared_classes, arginfo_zend__void)
  252. ZEND_FE(get_declared_traits, arginfo_zend__void)
  253. ZEND_FE(get_declared_interfaces, arginfo_zend__void)
  254. ZEND_FE(get_defined_functions, arginfo_zend__void)
  255. ZEND_FE(get_defined_vars, arginfo_zend__void)
  256. ZEND_FE(create_function, arginfo_create_function)
  257. ZEND_FE(get_resource_type, arginfo_get_resource_type)
  258. ZEND_FE(get_loaded_extensions, arginfo_get_loaded_extensions)
  259. ZEND_FE(extension_loaded, arginfo_extension_loaded)
  260. ZEND_FE(get_extension_funcs, arginfo_extension_loaded)
  261. ZEND_FE(get_defined_constants, arginfo_get_defined_constants)
  262. ZEND_FE(debug_backtrace, arginfo_debug_backtrace)
  263. ZEND_FE(debug_print_backtrace, arginfo_debug_print_backtrace)
  264. #if ZEND_DEBUG
  265. ZEND_FE(zend_test_func, NULL)
  266. #ifdef ZTS
  267. ZEND_FE(zend_thread_id, NULL)
  268. #endif
  269. #endif
  270. ZEND_FE(gc_collect_cycles, arginfo_zend__void)
  271. ZEND_FE(gc_enabled, arginfo_zend__void)
  272. ZEND_FE(gc_enable, arginfo_zend__void)
  273. ZEND_FE(gc_disable, arginfo_zend__void)
  274. ZEND_FE_END
  275. };
  276. /* }}} */
  277. ZEND_MINIT_FUNCTION(core) { /* {{{ */
  278. zend_class_entry class_entry;
  279. INIT_CLASS_ENTRY(class_entry, "stdClass", NULL);
  280. zend_standard_class_def = zend_register_internal_class(&class_entry TSRMLS_CC);
  281. zend_register_default_classes(TSRMLS_C);
  282. return SUCCESS;
  283. }
  284. /* }}} */
  285. zend_module_entry zend_builtin_module = { /* {{{ */
  286. STANDARD_MODULE_HEADER,
  287. "Core",
  288. builtin_functions,
  289. ZEND_MINIT(core),
  290. NULL,
  291. NULL,
  292. NULL,
  293. NULL,
  294. ZEND_VERSION,
  295. STANDARD_MODULE_PROPERTIES
  296. };
  297. /* }}} */
  298. int zend_startup_builtin_functions(TSRMLS_D) /* {{{ */
  299. {
  300. zend_builtin_module.module_number = 0;
  301. zend_builtin_module.type = MODULE_PERSISTENT;
  302. return (EG(current_module) = zend_register_module_ex(&zend_builtin_module TSRMLS_CC)) == NULL ? FAILURE : SUCCESS;
  303. }
  304. /* }}} */
  305. /* {{{ proto string zend_version(void)
  306. Get the version of the Zend Engine */
  307. ZEND_FUNCTION(zend_version)
  308. {
  309. RETURN_STRINGL(ZEND_VERSION, sizeof(ZEND_VERSION)-1, 1);
  310. }
  311. /* }}} */
  312. /* {{{ proto int gc_collect_cycles(void)
  313. Forces collection of any existing garbage cycles.
  314. Returns number of freed zvals */
  315. ZEND_FUNCTION(gc_collect_cycles)
  316. {
  317. RETURN_LONG(gc_collect_cycles(TSRMLS_C));
  318. }
  319. /* }}} */
  320. /* {{{ proto void gc_enabled(void)
  321. Returns status of the circular reference collector */
  322. ZEND_FUNCTION(gc_enabled)
  323. {
  324. RETURN_BOOL(GC_G(gc_enabled));
  325. }
  326. /* }}} */
  327. /* {{{ proto void gc_enable(void)
  328. Activates the circular reference collector */
  329. ZEND_FUNCTION(gc_enable)
  330. {
  331. zend_alter_ini_entry("zend.enable_gc", sizeof("zend.enable_gc"), "1", sizeof("1")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
  332. }
  333. /* }}} */
  334. /* {{{ proto void gc_disable(void)
  335. Deactivates the circular reference collector */
  336. ZEND_FUNCTION(gc_disable)
  337. {
  338. zend_alter_ini_entry("zend.enable_gc", sizeof("zend.enable_gc"), "0", sizeof("0")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
  339. }
  340. /* }}} */
  341. /* {{{ proto int func_num_args(void)
  342. Get the number of arguments that were passed to the function */
  343. ZEND_FUNCTION(func_num_args)
  344. {
  345. zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
  346. if (ex && ex->function_state.arguments) {
  347. RETURN_LONG((long)(zend_uintptr_t)*(ex->function_state.arguments));
  348. } else {
  349. zend_error(E_WARNING, "func_num_args(): Called from the global scope - no function context");
  350. RETURN_LONG(-1);
  351. }
  352. }
  353. /* }}} */
  354. /* {{{ proto mixed func_get_arg(int arg_num)
  355. Get the $arg_num'th argument that was passed to the function */
  356. ZEND_FUNCTION(func_get_arg)
  357. {
  358. void **p;
  359. int arg_count;
  360. zval *arg;
  361. long requested_offset;
  362. zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
  363. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &requested_offset) == FAILURE) {
  364. return;
  365. }
  366. if (requested_offset < 0) {
  367. zend_error(E_WARNING, "func_get_arg(): The argument number should be >= 0");
  368. RETURN_FALSE;
  369. }
  370. if (!ex || !ex->function_state.arguments) {
  371. zend_error(E_WARNING, "func_get_arg(): Called from the global scope - no function context");
  372. RETURN_FALSE;
  373. }
  374. p = ex->function_state.arguments;
  375. arg_count = (int)(zend_uintptr_t) *p; /* this is the amount of arguments passed to func_get_arg(); */
  376. if (requested_offset >= arg_count) {
  377. zend_error(E_WARNING, "func_get_arg(): Argument %ld not passed to function", requested_offset);
  378. RETURN_FALSE;
  379. }
  380. arg = *(p-(arg_count-requested_offset));
  381. RETURN_ZVAL_FAST(arg);
  382. }
  383. /* }}} */
  384. /* {{{ proto array func_get_args()
  385. Get an array of the arguments that were passed to the function */
  386. ZEND_FUNCTION(func_get_args)
  387. {
  388. void **p;
  389. int arg_count;
  390. int i;
  391. zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
  392. if (!ex || !ex->function_state.arguments) {
  393. zend_error(E_WARNING, "func_get_args(): Called from the global scope - no function context");
  394. RETURN_FALSE;
  395. }
  396. p = ex->function_state.arguments;
  397. arg_count = (int)(zend_uintptr_t) *p; /* this is the amount of arguments passed to func_get_args(); */
  398. array_init_size(return_value, arg_count);
  399. for (i=0; i<arg_count; i++) {
  400. zval *element, *arg;
  401. arg = *((zval **) (p-(arg_count-i)));
  402. if (!Z_ISREF_P(arg)) {
  403. element = arg;
  404. Z_ADDREF_P(element);
  405. } else {
  406. ALLOC_ZVAL(element);
  407. INIT_PZVAL_COPY(element, arg);
  408. zval_copy_ctor(element);
  409. }
  410. zend_hash_next_index_insert(return_value->value.ht, &element, sizeof(zval *), NULL);
  411. }
  412. }
  413. /* }}} */
  414. /* {{{ proto int strlen(string str)
  415. Get string length */
  416. ZEND_FUNCTION(strlen)
  417. {
  418. char *s1;
  419. int s1_len;
  420. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s1, &s1_len) == FAILURE) {
  421. return;
  422. }
  423. RETVAL_LONG(s1_len);
  424. }
  425. /* }}} */
  426. /* {{{ proto int strcmp(string str1, string str2)
  427. Binary safe string comparison */
  428. ZEND_FUNCTION(strcmp)
  429. {
  430. char *s1, *s2;
  431. int s1_len, s2_len;
  432. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {
  433. return;
  434. }
  435. RETURN_LONG(zend_binary_strcmp(s1, s1_len, s2, s2_len));
  436. }
  437. /* }}} */
  438. /* {{{ proto int strncmp(string str1, string str2, int len)
  439. Binary safe string comparison */
  440. ZEND_FUNCTION(strncmp)
  441. {
  442. char *s1, *s2;
  443. int s1_len, s2_len;
  444. long len;
  445. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &s1, &s1_len, &s2, &s2_len, &len) == FAILURE) {
  446. return;
  447. }
  448. if (len < 0) {
  449. zend_error(E_WARNING, "Length must be greater than or equal to 0");
  450. RETURN_FALSE;
  451. }
  452. RETURN_LONG(zend_binary_strncmp(s1, s1_len, s2, s2_len, len));
  453. }
  454. /* }}} */
  455. /* {{{ proto int strcasecmp(string str1, string str2)
  456. Binary safe case-insensitive string comparison */
  457. ZEND_FUNCTION(strcasecmp)
  458. {
  459. char *s1, *s2;
  460. int s1_len, s2_len;
  461. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {
  462. return;
  463. }
  464. RETURN_LONG(zend_binary_strcasecmp(s1, s1_len, s2, s2_len));
  465. }
  466. /* }}} */
  467. /* {{{ proto int strncasecmp(string str1, string str2, int len)
  468. Binary safe string comparison */
  469. ZEND_FUNCTION(strncasecmp)
  470. {
  471. char *s1, *s2;
  472. int s1_len, s2_len;
  473. long len;
  474. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &s1, &s1_len, &s2, &s2_len, &len) == FAILURE) {
  475. return;
  476. }
  477. if (len < 0) {
  478. zend_error(E_WARNING, "Length must be greater than or equal to 0");
  479. RETURN_FALSE;
  480. }
  481. RETURN_LONG(zend_binary_strncasecmp(s1, s1_len, s2, s2_len, len));
  482. }
  483. /* }}} */
  484. /* {{{ proto array each(array arr)
  485. Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element */
  486. ZEND_FUNCTION(each)
  487. {
  488. zval *array, *entry, **entry_ptr, *tmp;
  489. char *string_key;
  490. uint string_key_len;
  491. ulong num_key;
  492. zval **inserted_pointer;
  493. HashTable *target_hash;
  494. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &array) == FAILURE) {
  495. return;
  496. }
  497. target_hash = HASH_OF(array);
  498. if (!target_hash) {
  499. zend_error(E_WARNING,"Variable passed to each() is not an array or object");
  500. return;
  501. }
  502. if (zend_hash_get_current_data(target_hash, (void **) &entry_ptr)==FAILURE) {
  503. RETURN_FALSE;
  504. }
  505. array_init(return_value);
  506. entry = *entry_ptr;
  507. /* add value elements */
  508. if (Z_ISREF_P(entry)) {
  509. ALLOC_ZVAL(tmp);
  510. *tmp = *entry;
  511. zval_copy_ctor(tmp);
  512. Z_UNSET_ISREF_P(tmp);
  513. Z_SET_REFCOUNT_P(tmp, 0);
  514. entry=tmp;
  515. }
  516. zend_hash_index_update(return_value->value.ht, 1, &entry, sizeof(zval *), NULL);
  517. Z_ADDREF_P(entry);
  518. zend_hash_update(return_value->value.ht, "value", sizeof("value"), &entry, sizeof(zval *), NULL);
  519. Z_ADDREF_P(entry);
  520. /* add the key elements */
  521. switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, NULL)) {
  522. case HASH_KEY_IS_STRING:
  523. add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, !IS_INTERNED(string_key));
  524. break;
  525. case HASH_KEY_IS_LONG:
  526. add_get_index_long(return_value, 0, num_key, (void **) &inserted_pointer);
  527. break;
  528. }
  529. zend_hash_update(return_value->value.ht, "key", sizeof("key"), inserted_pointer, sizeof(zval *), NULL);
  530. Z_ADDREF_PP(inserted_pointer);
  531. zend_hash_move_forward(target_hash);
  532. }
  533. /* }}} */
  534. /* {{{ proto int error_reporting([int new_error_level])
  535. Return the current error_reporting level, and if an argument was passed - change to the new level */
  536. ZEND_FUNCTION(error_reporting)
  537. {
  538. char *err;
  539. int err_len;
  540. int old_error_reporting;
  541. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &err, &err_len) == FAILURE) {
  542. return;
  543. }
  544. old_error_reporting = EG(error_reporting);
  545. if(ZEND_NUM_ARGS() != 0) {
  546. zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), err, err_len, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
  547. }
  548. RETVAL_LONG(old_error_reporting);
  549. }
  550. /* }}} */
  551. /* {{{ proto bool define(string constant_name, mixed value, boolean case_insensitive=false)
  552. Define a new constant */
  553. ZEND_FUNCTION(define)
  554. {
  555. char *name;
  556. int name_len;
  557. zval *val;
  558. zval *val_free = NULL;
  559. zend_bool non_cs = 0;
  560. int case_sensitive = CONST_CS;
  561. zend_constant c;
  562. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len, &val, &non_cs) == FAILURE) {
  563. return;
  564. }
  565. if(non_cs) {
  566. case_sensitive = 0;
  567. }
  568. /* class constant, check if there is name and make sure class is valid & exists */
  569. if (zend_memnstr(name, "::", sizeof("::") - 1, name + name_len)) {
  570. zend_error(E_WARNING, "Class constants cannot be defined or redefined");
  571. RETURN_FALSE;
  572. }
  573. repeat:
  574. switch (Z_TYPE_P(val)) {
  575. case IS_LONG:
  576. case IS_DOUBLE:
  577. case IS_STRING:
  578. case IS_BOOL:
  579. case IS_RESOURCE:
  580. case IS_NULL:
  581. break;
  582. case IS_OBJECT:
  583. if (!val_free) {
  584. if (Z_OBJ_HT_P(val)->get) {
  585. val_free = val = Z_OBJ_HT_P(val)->get(val TSRMLS_CC);
  586. goto repeat;
  587. } else if (Z_OBJ_HT_P(val)->cast_object) {
  588. ALLOC_INIT_ZVAL(val_free);
  589. if (Z_OBJ_HT_P(val)->cast_object(val, val_free, IS_STRING TSRMLS_CC) == SUCCESS) {
  590. val = val_free;
  591. break;
  592. }
  593. }
  594. }
  595. /* no break */
  596. default:
  597. zend_error(E_WARNING,"Constants may only evaluate to scalar values");
  598. if (val_free) {
  599. zval_ptr_dtor(&val_free);
  600. }
  601. RETURN_FALSE;
  602. }
  603. c.value = *val;
  604. zval_copy_ctor(&c.value);
  605. if (val_free) {
  606. zval_ptr_dtor(&val_free);
  607. }
  608. c.flags = case_sensitive; /* non persistent */
  609. c.name = str_strndup(name, name_len);
  610. if(c.name == NULL) {
  611. RETURN_FALSE;
  612. }
  613. c.name_len = name_len+1;
  614. c.module_number = PHP_USER_CONSTANT;
  615. if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {
  616. RETURN_TRUE;
  617. } else {
  618. RETURN_FALSE;
  619. }
  620. }
  621. /* }}} */
  622. /* {{{ proto bool defined(string constant_name)
  623. Check whether a constant exists */
  624. ZEND_FUNCTION(defined)
  625. {
  626. char *name;
  627. int name_len;
  628. zval c;
  629. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
  630. return;
  631. }
  632. if (zend_get_constant_ex(name, name_len, &c, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) {
  633. zval_dtor(&c);
  634. RETURN_TRUE;
  635. } else {
  636. RETURN_FALSE;
  637. }
  638. }
  639. /* }}} */
  640. /* {{{ proto string get_class([object object])
  641. Retrieves the class name */
  642. ZEND_FUNCTION(get_class)
  643. {
  644. zval *obj = NULL;
  645. const char *name = "";
  646. zend_uint name_len = 0;
  647. int dup;
  648. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o!", &obj) == FAILURE) {
  649. RETURN_FALSE;
  650. }
  651. if (!obj) {
  652. if (EG(scope)) {
  653. RETURN_STRINGL(EG(scope)->name, EG(scope)->name_length, 1);
  654. } else {
  655. zend_error(E_WARNING, "get_class() called without object from outside a class");
  656. RETURN_FALSE;
  657. }
  658. }
  659. dup = zend_get_object_classname(obj, &name, &name_len TSRMLS_CC);
  660. RETURN_STRINGL(name, name_len, dup);
  661. }
  662. /* }}} */
  663. /* {{{ proto string get_called_class()
  664. Retrieves the "Late Static Binding" class name */
  665. ZEND_FUNCTION(get_called_class)
  666. {
  667. if (zend_parse_parameters_none() == FAILURE) {
  668. return;
  669. }
  670. if (EG(called_scope)) {
  671. RETURN_STRINGL(EG(called_scope)->name, EG(called_scope)->name_length, 1);
  672. } else if (!EG(scope)) {
  673. zend_error(E_WARNING, "get_called_class() called from outside a class");
  674. }
  675. RETURN_FALSE;
  676. }
  677. /* }}} */
  678. /* {{{ proto string get_parent_class([mixed object])
  679. Retrieves the parent class name for object or class or current scope. */
  680. ZEND_FUNCTION(get_parent_class)
  681. {
  682. zval *arg;
  683. zend_class_entry *ce = NULL;
  684. const char *name;
  685. zend_uint name_length;
  686. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &arg) == FAILURE) {
  687. return;
  688. }
  689. if (!ZEND_NUM_ARGS()) {
  690. ce = EG(scope);
  691. if (ce && ce->parent) {
  692. RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
  693. } else {
  694. RETURN_FALSE;
  695. }
  696. }
  697. if (Z_TYPE_P(arg) == IS_OBJECT) {
  698. if (Z_OBJ_HT_P(arg)->get_class_name
  699. && Z_OBJ_HT_P(arg)->get_class_name(arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) {
  700. RETURN_STRINGL(name, name_length, 0);
  701. } else {
  702. ce = zend_get_class_entry(arg TSRMLS_CC);
  703. }
  704. } else if (Z_TYPE_P(arg) == IS_STRING) {
  705. zend_class_entry **pce;
  706. if (zend_lookup_class(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &pce TSRMLS_CC) == SUCCESS) {
  707. ce = *pce;
  708. }
  709. }
  710. if (ce && ce->parent) {
  711. RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
  712. } else {
  713. RETURN_FALSE;
  714. }
  715. }
  716. /* }}} */
  717. static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
  718. {
  719. zval *obj;
  720. char *class_name;
  721. int class_name_len;
  722. zend_class_entry *instance_ce;
  723. zend_class_entry **ce;
  724. zend_bool allow_string = only_subclass;
  725. zend_bool retval;
  726. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|b", &obj, &class_name, &class_name_len, &allow_string) == FAILURE) {
  727. return;
  728. }
  729. /*
  730. * allow_string - is_a default is no, is_subclass_of is yes.
  731. * if it's allowed, then the autoloader will be called if the class does not exist.
  732. * default behaviour is different, as 'is_a' used to be used to test mixed return values
  733. * and there is no easy way to deprecate this.
  734. */
  735. if (allow_string && Z_TYPE_P(obj) == IS_STRING) {
  736. zend_class_entry **the_ce;
  737. if (zend_lookup_class(Z_STRVAL_P(obj), Z_STRLEN_P(obj), &the_ce TSRMLS_CC) == FAILURE) {
  738. RETURN_FALSE;
  739. }
  740. instance_ce = *the_ce;
  741. } else if (Z_TYPE_P(obj) == IS_OBJECT && HAS_CLASS_ENTRY(*obj)) {
  742. instance_ce = Z_OBJCE_P(obj);
  743. } else {
  744. RETURN_FALSE;
  745. }
  746. if (zend_lookup_class_ex(class_name, class_name_len, NULL, 0, &ce TSRMLS_CC) == FAILURE) {
  747. retval = 0;
  748. } else {
  749. if (only_subclass && instance_ce == *ce) {
  750. retval = 0;
  751. } else {
  752. retval = instanceof_function(instance_ce, *ce TSRMLS_CC);
  753. }
  754. }
  755. RETURN_BOOL(retval);
  756. }
  757. /* {{{ proto bool is_subclass_of(mixed object_or_string, string class_name [, bool allow_string=true])
  758. Returns true if the object has this class as one of its parents */
  759. ZEND_FUNCTION(is_subclass_of)
  760. {
  761. is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
  762. }
  763. /* }}} */
  764. /* {{{ proto bool is_a(mixed object_or_string, string class_name [, bool allow_string=false])
  765. Returns true if the first argument is an object and is this class or has this class as one of its parents, */
  766. ZEND_FUNCTION(is_a)
  767. {
  768. is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  769. }
  770. /* }}} */
  771. /* {{{ add_class_vars */
  772. static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value TSRMLS_DC)
  773. {
  774. HashPosition pos;
  775. zend_property_info *prop_info;
  776. zval *prop, *prop_copy;
  777. char *key;
  778. uint key_len;
  779. ulong num_index;
  780. zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
  781. while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop_info, &pos) == SUCCESS) {
  782. zend_hash_get_current_key_ex(&ce->properties_info, &key, &key_len, &num_index, 0, &pos);
  783. zend_hash_move_forward_ex(&ce->properties_info, &pos);
  784. if (((prop_info->flags & ZEND_ACC_SHADOW) &&
  785. prop_info->ce != EG(scope)) ||
  786. ((prop_info->flags & ZEND_ACC_PROTECTED) &&
  787. !zend_check_protected(prop_info->ce, EG(scope))) ||
  788. ((prop_info->flags & ZEND_ACC_PRIVATE) &&
  789. ce != EG(scope) &&
  790. prop_info->ce != EG(scope))) {
  791. continue;
  792. }
  793. prop = NULL;
  794. if (prop_info->offset >= 0) {
  795. if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
  796. prop = ce->default_static_members_table[prop_info->offset];
  797. } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
  798. prop = ce->default_properties_table[prop_info->offset];
  799. }
  800. }
  801. if (!prop) {
  802. continue;
  803. }
  804. /* copy: enforce read only access */
  805. ALLOC_ZVAL(prop_copy);
  806. *prop_copy = *prop;
  807. zval_copy_ctor(prop_copy);
  808. INIT_PZVAL(prop_copy);
  809. /* this is necessary to make it able to work with default array
  810. * properties, returned to user */
  811. if (IS_CONSTANT_TYPE(Z_TYPE_P(prop_copy))) {
  812. zval_update_constant(&prop_copy, 0 TSRMLS_CC);
  813. }
  814. zend_hash_update(Z_ARRVAL_P(return_value), key, key_len, &prop_copy, sizeof(zval*), NULL);
  815. }
  816. }
  817. /* }}} */
  818. /* {{{ proto array get_class_vars(string class_name)
  819. Returns an array of default properties of the class. */
  820. ZEND_FUNCTION(get_class_vars)
  821. {
  822. char *class_name;
  823. int class_name_len;
  824. zend_class_entry **pce;
  825. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &class_name, &class_name_len) == FAILURE) {
  826. return;
  827. }
  828. if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC) == FAILURE) {
  829. RETURN_FALSE;
  830. } else {
  831. array_init(return_value);
  832. zend_update_class_constants(*pce TSRMLS_CC);
  833. add_class_vars(*pce, 0, return_value TSRMLS_CC);
  834. add_class_vars(*pce, 1, return_value TSRMLS_CC);
  835. }
  836. }
  837. /* }}} */
  838. /* {{{ proto array get_object_vars(object obj)
  839. Returns an array of object properties */
  840. ZEND_FUNCTION(get_object_vars)
  841. {
  842. zval *obj;
  843. zval **value;
  844. HashTable *properties;
  845. HashPosition pos;
  846. char *key;
  847. const char *prop_name, *class_name;
  848. uint key_len, prop_len;
  849. ulong num_index;
  850. zend_object *zobj;
  851. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
  852. return;
  853. }
  854. if (Z_OBJ_HT_P(obj)->get_properties == NULL) {
  855. RETURN_FALSE;
  856. }
  857. properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC);
  858. if (properties == NULL) {
  859. RETURN_FALSE;
  860. }
  861. zobj = zend_objects_get_address(obj TSRMLS_CC);
  862. array_init(return_value);
  863. zend_hash_internal_pointer_reset_ex(properties, &pos);
  864. while (zend_hash_get_current_data_ex(properties, (void **) &value, &pos) == SUCCESS) {
  865. if (zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos) == HASH_KEY_IS_STRING) {
  866. if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) == SUCCESS) {
  867. zend_unmangle_property_name_ex(key, key_len - 1, &class_name, &prop_name, (int*) &prop_len);
  868. /* Not separating references */
  869. Z_ADDREF_PP(value);
  870. if (IS_INTERNED(key) && prop_name != key) {
  871. /* we can't use substring of interned string as a new key */
  872. char *tmp = estrndup(prop_name, prop_len);
  873. add_assoc_zval_ex(return_value, tmp, prop_len + 1, *value);
  874. efree(tmp);
  875. } else {
  876. add_assoc_zval_ex(return_value, prop_name, prop_len + 1, *value);
  877. }
  878. }
  879. }
  880. zend_hash_move_forward_ex(properties, &pos);
  881. }
  882. }
  883. /* }}} */
  884. static int same_name(const char *key, const char *name, zend_uint name_len)
  885. {
  886. char *lcname = zend_str_tolower_dup(name, name_len);
  887. int ret = memcmp(lcname, key, name_len) == 0;
  888. efree(lcname);
  889. return ret;
  890. }
  891. /* {{{ proto array get_class_methods(mixed class)
  892. Returns an array of method names for class or class instance. */
  893. ZEND_FUNCTION(get_class_methods)
  894. {
  895. zval *klass;
  896. zval *method_name;
  897. zend_class_entry *ce = NULL, **pce;
  898. HashPosition pos;
  899. zend_function *mptr;
  900. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &klass) == FAILURE) {
  901. return;
  902. }
  903. if (Z_TYPE_P(klass) == IS_OBJECT) {
  904. /* TBI!! new object handlers */
  905. if (!HAS_CLASS_ENTRY(*klass)) {
  906. RETURN_FALSE;
  907. }
  908. ce = Z_OBJCE_P(klass);
  909. } else if (Z_TYPE_P(klass) == IS_STRING) {
  910. if (zend_lookup_class(Z_STRVAL_P(klass), Z_STRLEN_P(klass), &pce TSRMLS_CC) == SUCCESS) {
  911. ce = *pce;
  912. }
  913. }
  914. if (!ce) {
  915. RETURN_NULL();
  916. }
  917. array_init(return_value);
  918. zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
  919. while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
  920. if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC)
  921. || (EG(scope) &&
  922. (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
  923. zend_check_protected(mptr->common.scope, EG(scope)))
  924. || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
  925. EG(scope) == mptr->common.scope)))) {
  926. char *key;
  927. uint key_len;
  928. ulong num_index;
  929. uint len = strlen(mptr->common.function_name);
  930. /* Do not display old-style inherited constructors */
  931. if (zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING) {
  932. MAKE_STD_ZVAL(method_name);
  933. ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
  934. zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
  935. } else if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
  936. mptr->common.scope == ce ||
  937. zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) {
  938. if (mptr->type == ZEND_USER_FUNCTION &&
  939. *mptr->op_array.refcount > 1 &&
  940. (len != key_len - 1 ||
  941. !same_name(key, mptr->common.function_name, len))) {
  942. MAKE_STD_ZVAL(method_name);
  943. ZVAL_STRINGL(method_name, zend_find_alias_name(mptr->common.scope, key, key_len - 1), key_len - 1, 1);
  944. zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
  945. } else {
  946. MAKE_STD_ZVAL(method_name);
  947. ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
  948. zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
  949. }
  950. }
  951. }
  952. zend_hash_move_forward_ex(&ce->function_table, &pos);
  953. }
  954. }
  955. /* }}} */
  956. /* {{{ proto bool method_exists(object object, string method)
  957. Checks if the class method exists */
  958. ZEND_FUNCTION(method_exists)
  959. {
  960. zval *klass;
  961. char *method_name;
  962. int method_len;
  963. char *lcname;
  964. zend_class_entry * ce, **pce;
  965. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &klass, &method_name, &method_len) == FAILURE) {
  966. return;
  967. }
  968. if (Z_TYPE_P(klass) == IS_OBJECT) {
  969. ce = Z_OBJCE_P(klass);
  970. } else if (Z_TYPE_P(klass) == IS_STRING) {
  971. if (zend_lookup_class(Z_STRVAL_P(klass), Z_STRLEN_P(klass), &pce TSRMLS_CC) == FAILURE) {
  972. RETURN_FALSE;
  973. }
  974. ce = *pce;
  975. } else {
  976. RETURN_FALSE;
  977. }
  978. lcname = zend_str_tolower_dup(method_name, method_len);
  979. if (zend_hash_exists(&ce->function_table, lcname, method_len+1)) {
  980. efree(lcname);
  981. RETURN_TRUE;
  982. } else {
  983. union _zend_function *func = NULL;
  984. if (Z_TYPE_P(klass) == IS_OBJECT
  985. && Z_OBJ_HT_P(klass)->get_method != NULL
  986. && (func = Z_OBJ_HT_P(klass)->get_method(&klass, method_name, method_len, NULL TSRMLS_CC)) != NULL
  987. ) {
  988. if (func->type == ZEND_INTERNAL_FUNCTION
  989. && (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0
  990. ) {
  991. /* Returns true to the fake Closure's __invoke */
  992. RETVAL_BOOL((func->common.scope == zend_ce_closure
  993. && (method_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
  994. && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) ? 1 : 0);
  995. efree(lcname);
  996. efree((char*)((zend_internal_function*)func)->function_name);
  997. efree(func);
  998. return;
  999. }
  1000. efree(lcname);
  1001. RETURN_TRUE;
  1002. }
  1003. }
  1004. efree(lcname);
  1005. RETURN_FALSE;
  1006. }
  1007. /* }}} */
  1008. /* {{{ proto bool property_exists(mixed object_or_class, string property_name)
  1009. Checks if the object or class has a property */
  1010. ZEND_FUNCTION(property_exists)
  1011. {
  1012. zval *object;
  1013. char *property;
  1014. int property_len;
  1015. zend_class_entry *ce, **pce;
  1016. zend_property_info *property_info;
  1017. zval property_z;
  1018. ulong h;
  1019. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &object, &property, &property_len) == FAILURE) {
  1020. return;
  1021. }
  1022. if (property_len == 0) {
  1023. RETURN_FALSE;
  1024. }
  1025. if (Z_TYPE_P(object) == IS_STRING) {
  1026. if (zend_lookup_class(Z_STRVAL_P(object), Z_STRLEN_P(object), &pce TSRMLS_CC) == FAILURE) {
  1027. RETURN_FALSE;
  1028. }
  1029. ce = *pce;
  1030. } else if (Z_TYPE_P(object) == IS_OBJECT) {
  1031. ce = Z_OBJCE_P(object);
  1032. } else {
  1033. zend_error(E_WARNING, "First parameter must either be an object or the name of an existing class");
  1034. RETURN_NULL();
  1035. }
  1036. h = zend_get_hash_value(property, property_len+1);
  1037. if (zend_hash_quick_find(&ce->properties_info, property, property_len+1, h, (void **) &property_info) == SUCCESS
  1038. && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
  1039. RETURN_TRUE;
  1040. }
  1041. ZVAL_STRINGL(&property_z, property, property_len, 0);
  1042. if (Z_TYPE_P(object) == IS_OBJECT &&
  1043. Z_OBJ_HANDLER_P(object, has_property) &&
  1044. Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2, 0 TSRMLS_CC)) {
  1045. RETURN_TRUE;
  1046. }
  1047. RETURN_FALSE;
  1048. }
  1049. /* }}} */
  1050. /* {{{ proto bool class_exists(string classname [, bool autoload])
  1051. Checks if the class exists */
  1052. ZEND_FUNCTION(class_exists)
  1053. {
  1054. char *class_name, *lc_name;
  1055. zend_class_entry **ce;
  1056. int class_name_len;
  1057. int found;
  1058. zend_bool autoload = 1;
  1059. ALLOCA_FLAG(use_heap)
  1060. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &class_name, &class_name_len, &autoload) == FAILURE) {
  1061. return;
  1062. }
  1063. if (!autoload) {
  1064. char *name;
  1065. int len;
  1066. lc_name = do_alloca(class_name_len + 1, use_heap);
  1067. zend_str_tolower_copy(lc_name, class_name, class_name_len);
  1068. /* Ignore leading "\" */
  1069. name = lc_name;
  1070. len = class_name_len;
  1071. if (lc_name[0] == '\\') {
  1072. name = &lc_name[1];
  1073. len--;
  1074. }
  1075. found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
  1076. free_alloca(lc_name, use_heap);
  1077. RETURN_BOOL(found == SUCCESS && !(((*ce)->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
  1078. }
  1079. if (zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC) == SUCCESS) {
  1080. RETURN_BOOL(((*ce)->ce_flags & (ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT - ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) == 0);
  1081. } else {
  1082. RETURN_FALSE;
  1083. }
  1084. }
  1085. /* }}} */
  1086. /* {{{ proto bool interface_exists(string classname [, bool autoload])
  1087. Checks if the class exists */
  1088. ZEND_FUNCTION(interface_exists)
  1089. {
  1090. char *iface_name, *lc_name;
  1091. zend_class_entry **ce;
  1092. int iface_name_len;
  1093. int found;
  1094. zend_bool autoload = 1;
  1095. ALLOCA_FLAG(use_heap)
  1096. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &iface_name, &iface_name_len, &autoload) == FAILURE) {
  1097. return;
  1098. }
  1099. if (!autoload) {
  1100. char *name;
  1101. int len;
  1102. lc_name = do_alloca(iface_name_len + 1, use_heap);
  1103. zend_str_tolower_copy(lc_name, iface_name, iface_name_len);
  1104. /* Ignore leading "\" */
  1105. name = lc_name;
  1106. len = iface_name_len;
  1107. if (lc_name[0] == '\\') {
  1108. name = &lc_name[1];
  1109. len--;
  1110. }
  1111. found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
  1112. free_alloca(lc_name, use_heap);
  1113. RETURN_BOOL(found == SUCCESS && (*ce)->ce_flags & ZEND_ACC_INTERFACE);
  1114. }
  1115. if (zend_lookup_class(iface_name, iface_name_len, &ce TSRMLS_CC) == SUCCESS) {
  1116. RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) > 0);
  1117. } else {
  1118. RETURN_FALSE;
  1119. }
  1120. }
  1121. /* }}} */
  1122. /* {{{ proto bool trait_exists(string traitname [, bool autoload])
  1123. Checks if the trait exists */
  1124. ZEND_FUNCTION(trait_exists)
  1125. {
  1126. char *trait_name, *lc_name;
  1127. zend_class_entry **ce;
  1128. int trait_name_len;
  1129. int found;
  1130. zend_bool autoload = 1;
  1131. ALLOCA_FLAG(use_heap)
  1132. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &trait_name, &trait_name_len, &autoload) == FAILURE) {
  1133. return;
  1134. }
  1135. if (!autoload) {
  1136. char *name;
  1137. int len;
  1138. lc_name = do_alloca(trait_name_len + 1, use_heap);
  1139. zend_str_tolower_copy(lc_name, trait_name, trait_name_len);
  1140. /* Ignore leading "\" */
  1141. name = lc_name;
  1142. len = trait_name_len;
  1143. if (lc_name[0] == '\\') {
  1144. name = &lc_name[1];
  1145. len--;
  1146. }
  1147. found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
  1148. free_alloca(lc_name, use_heap);
  1149. RETURN_BOOL(found == SUCCESS && (((*ce)->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
  1150. }
  1151. if (zend_lookup_class(trait_name, trait_name_len, &ce TSRMLS_CC) == SUCCESS) {
  1152. RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
  1153. } else {
  1154. RETURN_FALSE;
  1155. }
  1156. }
  1157. /* }}} */
  1158. /* {{{ proto bool function_exists(string function_name)
  1159. Checks if the function exists */
  1160. ZEND_FUNCTION(function_exists)
  1161. {
  1162. char *name;
  1163. int name_len;
  1164. zend_function *func;
  1165. char *lcname;
  1166. zend_bool retval;
  1167. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
  1168. return;
  1169. }
  1170. lcname = zend_str_tolower_dup(name, name_len);
  1171. /* Ignore leading "\" */
  1172. name = lcname;
  1173. if (lcname[0] == '\\') {
  1174. name = &lcname[1];
  1175. name_len--;
  1176. }
  1177. retval = (zend_hash_find(EG(function_table), name, name_len+1, (void **)&func) == SUCCESS);
  1178. efree(lcname);
  1179. /*
  1180. * A bit of a hack, but not a bad one: we see if the handler of the function
  1181. * is actually one that displays "function is disabled" message.
  1182. */
  1183. if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
  1184. func->internal_function.handler == zif_display_disabled_function) {
  1185. retval = 0;
  1186. }
  1187. RETURN_BOOL(retval);
  1188. }
  1189. /* }}} */
  1190. /* {{{ proto bool class_alias(string user_class_name , string alias_name [, bool autoload])
  1191. Creates an alias for user defined class */
  1192. ZEND_FUNCTION(class_alias)
  1193. {
  1194. char *class_name, *alias_name;
  1195. zend_class_entry **ce;
  1196. int class_name_len, alias_name_len;
  1197. int found;
  1198. zend_bool autoload = 1;
  1199. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &class_name, &class_name_len, &alias_name, &alias_name_len, &autoload) == FAILURE) {
  1200. return;
  1201. }
  1202. found = zend_lookup_class_ex(class_name, class_name_len, NULL, autoload, &ce TSRMLS_CC);
  1203. if (found == SUCCESS) {
  1204. if ((*ce)->type == ZEND_USER_CLASS) {
  1205. if (zend_register_class_alias_ex(alias_name, alias_name_len, *ce TSRMLS_CC) == SUCCESS) {
  1206. RETURN_TRUE;
  1207. } else {
  1208. zend_error(E_WARNING, "Cannot redeclare class %s", alias_name);
  1209. RETURN_FALSE;
  1210. }
  1211. } else {
  1212. zend_error(E_WARNING, "First argument of class_alias() must be a name of user defined class");
  1213. RETURN_FALSE;
  1214. }
  1215. } else {
  1216. zend_error(E_WARNING, "Class '%s' not found", class_name);
  1217. RETURN_FALSE;
  1218. }
  1219. }
  1220. /* }}} */
  1221. #if ZEND_DEBUG
  1222. /* {{{ proto void leak(int num_bytes=3)
  1223. Cause an intentional memory leak, for testing/debugging purposes */
  1224. ZEND_FUNCTION(leak)
  1225. {
  1226. long leakbytes=3;
  1227. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &leakbytes) == FAILURE) {
  1228. return;
  1229. }
  1230. emalloc(leakbytes);
  1231. }
  1232. /* }}} */
  1233. /* {{{ proto leak_variable(mixed variable [, bool leak_data]) */
  1234. ZEND_FUNCTION(leak_variable)
  1235. {
  1236. zval *zv;
  1237. zend_bool leak_data = 0;
  1238. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &zv, &leak_data) == FAILURE) {
  1239. return;
  1240. }
  1241. if (!leak_data) {
  1242. zval_add_ref(&zv);
  1243. } else if (Z_TYPE_P(zv) == IS_RESOURCE) {
  1244. zend_list_addref(Z_RESVAL_P(zv));
  1245. } else if (Z_TYPE_P(zv) == IS_OBJECT) {
  1246. Z_OBJ_HANDLER_P(zv, add_ref)(zv TSRMLS_CC);
  1247. } else {
  1248. zend_error(E_WARNING, "Leaking non-zval data is only applicable to resources and objects");
  1249. }
  1250. }
  1251. /* }}} */
  1252. #ifdef ZEND_TEST_EXCEPTIONS
  1253. ZEND_FUNCTION(crash)
  1254. {
  1255. char *nowhere=NULL;
  1256. memcpy(nowhere, "something", sizeof("something"));
  1257. }
  1258. #endif
  1259. #endif /* ZEND_DEBUG */
  1260. /* {{{ proto array get_included_files(void)
  1261. Returns an array with the file names that were include_once()'d */
  1262. ZEND_FUNCTION(get_included_files)
  1263. {
  1264. char *entry;
  1265. uint entry_len;
  1266. if (zend_parse_parameters_none() == FAILURE) {
  1267. return;
  1268. }
  1269. array_init(return_value);
  1270. zend_hash_internal_pointer_reset(&EG(included_files));
  1271. while (zend_hash_get_current_key_ex(&EG(included_files), &entry, &entry_len, NULL, 0, NULL) == HASH_KEY_IS_STRING) {
  1272. add_next_index_stringl(return_value, entry, entry_len-1, !IS_INTERNED(entry));
  1273. zend_hash_move_forward(&EG(included_files));
  1274. }
  1275. }
  1276. /* }}} */
  1277. /* {{{ proto void trigger_error(string message [, int error_type])
  1278. Generates a user-level error/warning/notice message */
  1279. ZEND_FUNCTION(trigger_error)
  1280. {
  1281. long error_type = E_USER_NOTICE;
  1282. char *message;
  1283. int message_len;
  1284. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &message, &message_len, &error_type) == FAILURE) {
  1285. return;
  1286. }
  1287. switch (error_type) {
  1288. case E_USER_ERROR:
  1289. case E_USER_WARNING:
  1290. case E_USER_NOTICE:
  1291. case E_USER_DEPRECATED:
  1292. break;
  1293. default:
  1294. zend_error(E_WARNING, "Invalid error type specified");
  1295. RETURN_FALSE;
  1296. break;
  1297. }
  1298. zend_error((int)error_type, "%s", message);
  1299. RETURN_TRUE;
  1300. }
  1301. /* }}} */
  1302. /* {{{ proto string set_error_handler(string error_handler [, int error_types])
  1303. Sets a user-defined error handler function. Returns the previously defined error handler, or false on error */
  1304. ZEND_FUNCTION(set_error_handler)
  1305. {
  1306. zval *error_handler;
  1307. char *error_handler_name = NULL;
  1308. long error_type = E_ALL;
  1309. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &error_handler, &error_type) == FAILURE) {
  1310. return;
  1311. }
  1312. if (Z_TYPE_P(error_handler) != IS_NULL) { /* NULL == unset */
  1313. if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) {
  1314. zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
  1315. get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown");
  1316. efree(error_handler_name);
  1317. return;
  1318. }
  1319. efree(error_handler_name);
  1320. }
  1321. if (EG(user_error_handler)) {
  1322. RETVAL_ZVAL(EG(user_error_handler), 1, 0);
  1323. zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
  1324. zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
  1325. }
  1326. if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */
  1327. EG(user_error_handler) = NULL;
  1328. return;
  1329. }
  1330. ALLOC_ZVAL(EG(user_error_handler));
  1331. MAKE_COPY_ZVAL(&error_handler, EG(user_error_handler));
  1332. EG(user_error_handler_error_reporting) = (int)error_type;
  1333. }
  1334. /* }}} */
  1335. /* {{{ proto void restore_error_handler(void)
  1336. Restores the previously defined error handler function */
  1337. ZEND_FUNCTION(restore_error_handler)
  1338. {
  1339. if (EG(user_error_handler)) {
  1340. zval *zeh = EG(user_error_handler);
  1341. EG(user_error_handler) = NULL;
  1342. zval_ptr_dtor(&zeh);
  1343. }
  1344. if (zend_ptr_stack_num_elements(&EG(user_error_handlers))==0) {
  1345. EG(user_error_handler) = NULL;
  1346. } else {
  1347. EG(user_error_handler_error_reporting) = zend_stack_int_top(&EG(user_error_handlers_error_reporting));
  1348. zend_stack_del_top(&EG(user_error_handlers_error_reporting));
  1349. EG(user_error_handler) = zend_ptr_stack_pop(&EG(user_error_handlers));
  1350. }
  1351. RETURN_TRUE;
  1352. }
  1353. /* }}} */
  1354. /* {{{ proto string set_exception_handler(callable exception_handler)
  1355. Sets a user-defined exception handler function. Returns the previously defined exception handler, or false on error */
  1356. ZEND_FUNCTION(set_exception_handler)
  1357. {
  1358. zval *exception_handler;
  1359. char *exception_handler_name = NULL;
  1360. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception_handler) == FAILURE) {
  1361. return;
  1362. }
  1363. if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */
  1364. if (!zend_is_callable(exception_handler, 0, &exception_handler_name TSRMLS_CC)) {
  1365. zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
  1366. get_active_function_name(TSRMLS_C), exception_handler_name?exception_handler_name:"unknown");
  1367. efree(exception_handler_name);
  1368. return;
  1369. }
  1370. efree(exception_handler_name);
  1371. }
  1372. if (EG(user_exception_handler)) {
  1373. RETVAL_ZVAL(EG(user_exception_handler), 1, 0);
  1374. zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler));
  1375. }
  1376. if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
  1377. EG(user_exception_handler) = NULL;
  1378. return;
  1379. }
  1380. ALLOC_ZVAL(EG(user_exception_handler));
  1381. MAKE_COPY_ZVAL(&exception_handler, EG(user_exception_handler))
  1382. }
  1383. /* }}} */
  1384. /* {{{ proto void restore_exception_handler(void)
  1385. Restores the previously defined exception handler function */
  1386. ZEND_FUNCTION(restore_exception_handler)
  1387. {
  1388. if (EG(user_exception_handler)) {
  1389. zval_ptr_dtor(&EG(user_exception_handler));
  1390. }
  1391. if (zend_ptr_stack_num_elements(&EG(user_exception_handlers))==0) {
  1392. EG(user_exception_handler) = NULL;
  1393. } else {
  1394. EG(user_exception_handler) = zend_ptr_stack_pop(&EG(user_exception_handlers));
  1395. }
  1396. RETURN_TRUE;
  1397. }
  1398. /* }}} */
  1399. static int copy_class_or_interface_name(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
  1400. {
  1401. zval *array = va_arg(args, zval *);
  1402. zend_uint mask = va_arg(args, zend_uint);
  1403. zend_uint comply = va_arg(args, zend_uint);
  1404. zend_uint comply_mask = (comply)? mask:0;
  1405. zend_class_entry *ce = *pce;
  1406. if ((hash_key->nKeyLength==0 || hash_key->arKey[0]!=0)
  1407. && (comply_mask == (ce->ce_flags & mask))) {
  1408. if (ce->refcount > 1 &&
  1409. (ce->name_length != hash_key->nKeyLength - 1 ||
  1410. !same_name(hash_key->arKey, ce->name, ce->name_length))) {
  1411. add_next_index_stringl(array, hash_key->arKey, hash_key->nKeyLength - 1, 1);
  1412. } else {
  1413. add_next_index_stringl(array, ce->name, ce->name_length, 1);
  1414. }
  1415. }
  1416. return ZEND_HASH_APPLY_KEEP;
  1417. }
  1418. /* {{{ proto array get_declared_traits()
  1419. Returns an array of all declared traits. */
  1420. ZEND_FUNCTION(get_declared_traits)
  1421. {
  1422. zend_uint mask = ZEND_ACC_TRAIT;
  1423. zend_uint comply = 1;
  1424. if (zend_parse_parameters_none() == FAILURE) {
  1425. return;
  1426. }
  1427. array_init(return_value);
  1428. zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
  1429. }
  1430. /* }}} */
  1431. /* {{{ proto array get_declared_classes()
  1432. Returns an array of all declared classes. */
  1433. ZEND_FUNCTION(get_declared_classes)
  1434. {
  1435. zend_uint mask = ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
  1436. zend_uint comply = 0;
  1437. if (zend_parse_parameters_none() == FAILURE) {
  1438. return;
  1439. }
  1440. array_init(return_value);
  1441. zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
  1442. }
  1443. /* }}} */
  1444. /* {{{ proto array get_declared_interfaces()
  1445. Returns an array of all declared interfaces. */
  1446. ZEND_FUNCTION(get_declared_interfaces)
  1447. {
  1448. zend_uint mask = ZEND_ACC_INTERFACE;
  1449. zend_uint comply = 1;
  1450. if (zend_parse_parameters_none() == FAILURE) {
  1451. return;
  1452. }
  1453. array_init(return_value);
  1454. zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
  1455. }
  1456. /* }}} */
  1457. static int copy_function_name(zend_function *func TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
  1458. {
  1459. zval *internal_ar = va_arg(args, zval *),
  1460. *user_ar = va_arg(args, zval *);
  1461. if (hash_key->nKeyLength == 0 || hash_key->arKey[0] == 0) {
  1462. return 0;
  1463. }
  1464. if (func->type == ZEND_INTERNAL_FUNCTION) {
  1465. add_next_index_stringl(internal_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
  1466. } else if (func->type == ZEND_USER_FUNCTION) {
  1467. add_next_index_stringl(user_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
  1468. }
  1469. return 0;
  1470. }
  1471. /* {{{ proto array get_defined_functions(void)
  1472. Returns an array of all defined functions */
  1473. ZEND_FUNCTION(get_defined_functions)
  1474. {
  1475. zval *internal;
  1476. zval *user;
  1477. if (zend_parse_parameters_none() == FAILURE) {
  1478. return;
  1479. }
  1480. MAKE_STD_ZVAL(internal);
  1481. MAKE_STD_ZVAL(user);
  1482. array_init(internal);
  1483. array_init(user);
  1484. array_init(return_value);
  1485. zend_hash_apply_with_arguments(EG(function_table) TSRMLS_CC, (apply_func_args_t) copy_function_name, 2, internal, user);
  1486. if (zend_hash_add(Z_ARRVAL_P(return_value), "internal", sizeof("internal"), (void **)&internal, sizeof(zval *), NULL) == FAILURE) {
  1487. zval_ptr_dtor(&internal);
  1488. zval_ptr_dtor(&user);
  1489. zval_dtor(return_value);
  1490. zend_error(E_WARNING, "Cannot add internal functions to return value from get_defined_functions()");
  1491. RETURN_FALSE;
  1492. }
  1493. if (zend_hash_add(Z_ARRVAL_P(return_value), "user", sizeof("user"), (void **)&user, sizeof(zval *), NULL) == FAILURE) {
  1494. zval_ptr_dtor(&user);
  1495. zval_dtor(return_value);
  1496. zend_error(E_WARNING, "Cannot add user functions to return value from get_defined_functions()");
  1497. RETURN_FALSE;
  1498. }
  1499. }
  1500. /* }}} */
  1501. /* {{{ proto array get_defined_vars(void)
  1502. Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
  1503. ZEND_FUNCTION(get_defined_vars)
  1504. {
  1505. if (!EG(active_symbol_table)) {
  1506. zend_rebuild_symbol_table(TSRMLS_C);
  1507. }
  1508. array_init_size(return_value, zend_hash_num_elements(EG(active_symbol_table)));
  1509. zend_hash_copy(Z_ARRVAL_P(return_value), EG(active_symbol_table),
  1510. (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval *));
  1511. }
  1512. /* }}} */
  1513. #define LAMBDA_TEMP_FUNCNAME "__lambda_func"
  1514. /* {{{ proto string create_function(string args, string code)
  1515. Creates an anonymous function, and returns its name (funny, eh?) */
  1516. ZEND_FUNCTION(create_function)
  1517. {
  1518. char *eval_code, *function_name, *function_args, *function_code;
  1519. int eval_code_length, function_name_length, function_args_len, function_code_len;
  1520. int retval;
  1521. char *eval_name;
  1522. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &function_args, &function_args_len, &function_code, &function_code_len) == FAILURE) {
  1523. return;
  1524. }
  1525. eval_code = (char *) emalloc(sizeof("function " LAMBDA_TEMP_FUNCNAME)
  1526. +function_args_len
  1527. +2 /* for the args parentheses */
  1528. +2 /* for the curly braces */
  1529. +function_code_len);
  1530. eval_code_length = sizeof("function " LAMBDA_TEMP_FUNCNAME "(") - 1;
  1531. memcpy(eval_code, "function " LAMBDA_TEMP_FUNCNAME "(", eval_code_length);
  1532. memcpy(eval_code + eval_code_length, function_args, function_args_len);
  1533. eval_code_length += function_args_len;
  1534. eval_code[eval_code_length++] = ')';
  1535. eval_code[eval_code_length++] = '{';
  1536. memcpy(eval_code + eval_code_length, function_code, function_code_len);
  1537. eval_code_length += function_code_len;
  1538. eval_code[eval_code_length++] = '}';
  1539. eval_code[eval_code_length] = '\0';
  1540. eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
  1541. retval = zend_eval_stringl(eval_code, eval_code_length, NULL, eval_name TSRMLS_CC);
  1542. efree(eval_code);
  1543. efree(eval_name);
  1544. if (retval==SUCCESS) {
  1545. zend_function new_function, *func;
  1546. if (zend_hash_find(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **) &func)==FAILURE) {
  1547. zend_error(E_ERROR, "Unexpected inconsistency in create_function()");
  1548. RETURN_FALSE;
  1549. }
  1550. new_function = *func;
  1551. function_add_ref(&new_function);
  1552. function_name = (char *) emalloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG);
  1553. function_name[0] = '\0';
  1554. do {
  1555. function_name_length = 1 + snprintf(function_name + 1, sizeof("lambda_")+MAX_LENGTH_OF_LONG, "lambda_%d", ++EG(lambda_count));
  1556. } while (zend_hash_add(EG(function_table), function_name, function_name_length+1, &new_function, sizeof(zend_function), NULL)==FAILURE);
  1557. zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
  1558. RETURN_STRINGL(function_name, function_name_length, 0);
  1559. } else {
  1560. zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
  1561. RETURN_FALSE;
  1562. }
  1563. }
  1564. /* }}} */
  1565. #if ZEND_DEBUG
  1566. ZEND_FUNCTION(zend_test_func)
  1567. {
  1568. zval *arg1, *arg2;
  1569. zend_get_parameters(ht, 2, &arg1, &arg2);
  1570. }
  1571. #ifdef ZTS
  1572. ZEND_FUNCTION(zend_thread_id)
  1573. {
  1574. RETURN_LONG((long)tsrm_thread_id());
  1575. }
  1576. #endif
  1577. #endif
  1578. /* {{{ proto string get_resource_type(resource res)
  1579. Get the resource type name for a given resource */
  1580. ZEND_FUNCTION(get_resource_type)
  1581. {
  1582. const char *resource_type;
  1583. zval *z_resource_type;
  1584. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_resource_type) == FAILURE) {
  1585. return;
  1586. }
  1587. resource_type = zend_rsrc_list_get_rsrc_type(Z_LVAL_P(z_resource_type) TSRMLS_CC);
  1588. if (resource_type) {
  1589. RETURN_STRING(resource_type, 1);
  1590. } else {
  1591. RETURN_STRING("Unknown", 1);
  1592. }
  1593. }
  1594. /* }}} */
  1595. static int add_extension_info(zend_module_entry *module, void *arg TSRMLS_DC)
  1596. {
  1597. zval *name_array = (zval *)arg;
  1598. add_next_index_string(name_array, module->name, 1);
  1599. return 0;
  1600. }
  1601. static int add_zendext_info(zend_extension *ext, void *arg TSRMLS_DC)
  1602. {
  1603. zval *name_array = (zval *)arg;
  1604. add_next_index_string(name_array, ext->name, 1);
  1605. return 0;
  1606. }
  1607. static int add_constant_info(zend_constant *constant, void *arg TSRMLS_DC)
  1608. {
  1609. zval *name_array = (zval *)arg;
  1610. zval *const_val;
  1611. if (!constant->name) {
  1612. /* skip special constants */
  1613. return 0;
  1614. }
  1615. MAKE_STD_ZVAL(const_val);
  1616. *const_val = constant->value;
  1617. zval_copy_ctor(const_val);
  1618. INIT_PZVAL(const_val);
  1619. add_assoc_zval_ex(name_array, constant->name, constant->name_len, const_val);
  1620. return 0;
  1621. }
  1622. /* {{{ proto array get_loaded_extensions([bool zend_extensions]) U
  1623. Return an array containing names of loaded extensions */
  1624. ZEND_FUNCTION(get_loaded_extensions)
  1625. {
  1626. zend_bool zendext = 0;
  1627. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &zendext) == FAILURE) {
  1628. return;
  1629. }
  1630. array_init(return_value);
  1631. if (zendext) {
  1632. zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) add_zendext_info, return_value TSRMLS_CC);
  1633. } else {
  1634. zend_hash_apply_with_argument(&module_registry, (apply_func_arg_t) add_extension_info, return_value TSRMLS_CC);
  1635. }
  1636. }
  1637. /* }}} */
  1638. /* {{{ proto array get_defined_constants([bool categorize])
  1639. Return an array containing the names and values of all defined constants */
  1640. ZEND_FUNCTION(get_defined_constants)
  1641. {
  1642. zend_bool categorize = 0;
  1643. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &categorize) == FAILURE) {
  1644. return;
  1645. }
  1646. array_init(return_value);
  1647. if (categorize) {
  1648. HashPosition pos;
  1649. zend_constant *val;
  1650. int module_number;
  1651. zval **modules;
  1652. char **module_names;
  1653. zend_module_entry *module;
  1654. int i = 1;
  1655. modules = ecalloc(zend_hash_num_elements(&module_registry) + 2, sizeof(zval *));
  1656. module_names = emalloc((zend_hash_num_elements(&module_registry) + 2) * sizeof(char *));
  1657. module_names[0] = "internal";
  1658. zend_hash_internal_pointer_reset_ex(&module_registry, &pos);
  1659. while (zend_hash_get_current_data_ex(&module_registry, (void *) &module, &pos) != FAILURE) {
  1660. module_names[module->module_number] = (char *)module->name;
  1661. i++;
  1662. zend_hash_move_forward_ex(&module_registry, &pos);
  1663. }
  1664. module_names[i] = "user";
  1665. zend_hash_internal_pointer_reset_ex(EG(zend_constants), &pos);
  1666. while (zend_hash_get_current_data_ex(EG(zend_constants), (void **) &val, &pos) != FAILURE) {
  1667. zval *const_val;
  1668. if (!val->name) {
  1669. /* skip special constants */
  1670. goto next_constant;
  1671. }
  1672. if (val->module_number == PHP_USER_CONSTANT) {
  1673. module_number = i;
  1674. } else if (val->module_number > i || val->module_number < 0) {
  1675. /* should not happen */
  1676. goto next_constant;
  1677. } else {
  1678. module_number = val->module_number;
  1679. }
  1680. if (!modules[module_number]) {
  1681. MAKE_STD_ZVAL(modules[module_number]);
  1682. array_init(modules[module_number]);
  1683. add_assoc_zval(return_value, module_names[module_number], modules[module_number]);
  1684. }
  1685. MAKE_STD_ZVAL(const_val);
  1686. *const_val = val->value;
  1687. zval_copy_ctor(const_val);
  1688. INIT_PZVAL(const_val);
  1689. add_assoc_zval_ex(modules[module_number], val->name, val->name_len, const_val);
  1690. next_constant:
  1691. zend_hash_move_forward_ex(EG(zend_constants), &pos);
  1692. }
  1693. efree(module_names);
  1694. efree(modules);
  1695. } else {
  1696. zend_hash_apply_with_argument(EG(zend_constants), (apply_func_arg_t) add_constant_info, return_value TSRMLS_CC);
  1697. }
  1698. }
  1699. /* }}} */
  1700. static zval *debug_backtrace_get_args(void **curpos TSRMLS_DC)
  1701. {
  1702. void **p = curpos;
  1703. zval *arg_array, **arg;
  1704. int arg_count = (int)(zend_uintptr_t) *p;
  1705. MAKE_STD_ZVAL(arg_array);
  1706. array_init_size(arg_array, arg_count);
  1707. p -= arg_count;
  1708. while (--arg_count >= 0) {
  1709. arg = (zval **) p++;
  1710. if (*arg) {
  1711. if (Z_TYPE_PP(arg) != IS_OBJECT) {
  1712. SEPARATE_ZVAL_TO_MAKE_IS_REF(arg);
  1713. }
  1714. Z_ADDREF_PP(arg);
  1715. add_next_index_zval(arg_array, *arg);
  1716. } else {
  1717. add_next_index_null(arg_array);
  1718. }
  1719. }
  1720. return arg_array;
  1721. }
  1722. void debug_print_backtrace_args(zval *arg_array TSRMLS_DC)
  1723. {
  1724. zval **tmp;
  1725. HashPosition iterator;
  1726. int i = 0;
  1727. zend_hash_internal_pointer_reset_ex(arg_array->value.ht, &iterator);
  1728. while (zend_hash_get_current_data_ex(arg_array->value.ht, (void **) &tmp, &iterator) == SUCCESS) {
  1729. if (i++) {
  1730. ZEND_PUTS(", ");
  1731. }
  1732. zend_print_flat_zval_r(*tmp TSRMLS_CC);
  1733. zend_hash_move_forward_ex(arg_array->value.ht, &iterator);
  1734. }
  1735. }
  1736. /* {{{ proto void debug_print_backtrace([int options[, int limit]]) */
  1737. ZEND_FUNCTION(debug_print_backtrace)
  1738. {
  1739. zend_execute_data *ptr, *skip;
  1740. int lineno, frameno = 0;
  1741. const char *function_name;
  1742. const char *filename;
  1743. const char *class_name = NULL;
  1744. char *call_type;
  1745. const char *include_filename = NULL;
  1746. zval *arg_array = NULL;
  1747. int indent = 0;
  1748. long options = 0;
  1749. long limit = 0;
  1750. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &options, &limit) == FAILURE) {
  1751. return;
  1752. }
  1753. ptr = EG(current_execute_data);
  1754. /* skip debug_backtrace() */
  1755. ptr = ptr->prev_execute_data;
  1756. while (ptr && (limit == 0 || frameno < limit)) {
  1757. const char *free_class_name = NULL;
  1758. frameno++;
  1759. class_name = call_type = NULL;
  1760. arg_array = NULL;
  1761. skip = ptr;
  1762. /* skip internal handler */
  1763. if (!skip->op_array &&
  1764. skip->prev_execute_data &&
  1765. skip->prev_execute_data->opline &&
  1766. skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
  1767. skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
  1768. skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
  1769. skip = skip->prev_execute_data;
  1770. }
  1771. if (skip->op_array) {
  1772. filename = skip->op_array->filename;
  1773. lineno = skip->opline->lineno;
  1774. } else {
  1775. filename = NULL;
  1776. lineno = 0;
  1777. }
  1778. function_name = (ptr->function_state.function->common.scope &&
  1779. ptr->function_state.function->common.scope->trait_aliases) ?
  1780. zend_resolve_method_name(
  1781. ptr->object ?
  1782. Z_OBJCE_P(ptr->object) :
  1783. ptr->function_state.function->common.scope,
  1784. ptr->function_state.function) :
  1785. ptr->function_state.function->common.function_name;
  1786. if (function_name) {
  1787. if (ptr->object) {
  1788. if (ptr->function_state.function->common.scope) {
  1789. class_name = ptr->function_state.function->common.scope->name;
  1790. } else {
  1791. zend_uint class_name_len;
  1792. int dup;
  1793. dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
  1794. if(!dup) {
  1795. free_class_name = class_name;
  1796. }
  1797. }
  1798. call_type = "->";
  1799. } else if (ptr->function_state.function->common.scope) {
  1800. class_name = ptr->function_state.function->common.scope->name;
  1801. call_type = "::";
  1802. } else {
  1803. class_name = NULL;
  1804. call_type = NULL;
  1805. }
  1806. if ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
  1807. if (ptr->function_state.arguments && (options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) {
  1808. arg_array = debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC);
  1809. }
  1810. }
  1811. } else {
  1812. /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
  1813. zend_bool build_filename_arg = 1;
  1814. if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
  1815. /* can happen when calling eval from a custom sapi */
  1816. function_name = "unknown";
  1817. build_filename_arg = 0;
  1818. } else
  1819. switch (ptr->opline->extended_value) {
  1820. case ZEND_EVAL:
  1821. function_name = "eval";
  1822. build_filename_arg = 0;
  1823. break;
  1824. case ZEND_INCLUDE:
  1825. function_name = "include";
  1826. break;
  1827. case ZEND_REQUIRE:
  1828. function_name = "require";
  1829. break;
  1830. case ZEND_INCLUDE_ONCE:
  1831. function_name = "include_once";
  1832. break;
  1833. case ZEND_REQUIRE_ONCE:
  1834. function_name = "require_once";
  1835. break;
  1836. default:
  1837. /* this can actually happen if you use debug_backtrace() in your error_handler and
  1838. * you're in the top-scope */
  1839. function_name = "unknown";
  1840. build_filename_arg = 0;
  1841. break;
  1842. }
  1843. if (build_filename_arg && include_filename) {
  1844. MAKE_STD_ZVAL(arg_array);
  1845. array_init(arg_array);
  1846. add_next_index_string(arg_array, (char*)include_filename, 1);
  1847. }
  1848. call_type = NULL;
  1849. }
  1850. zend_printf("#%-2d ", indent);
  1851. if (class_name) {
  1852. ZEND_PUTS(class_name);
  1853. ZEND_PUTS(call_type);
  1854. }
  1855. zend_printf("%s(", function_name);
  1856. if (arg_array) {
  1857. debug_print_backtrace_args(arg_array TSRMLS_CC);
  1858. zval_ptr_dtor(&arg_array);
  1859. }
  1860. if (filename) {
  1861. zend_printf(") called at [%s:%d]\n", filename, lineno);
  1862. } else {
  1863. zend_execute_data *prev = skip->prev_execute_data;
  1864. while (prev) {
  1865. if (prev->function_state.function &&
  1866. prev->function_state.function->common.type != ZEND_USER_FUNCTION) {
  1867. prev = NULL;
  1868. break;
  1869. }
  1870. if (prev->op_array) {
  1871. zend_printf(") called at [%s:%d]\n", prev->op_array->filename, prev->opline->lineno);
  1872. break;
  1873. }
  1874. prev = prev->prev_execute_data;
  1875. }
  1876. if (!prev) {
  1877. ZEND_PUTS(")\n");
  1878. }
  1879. }
  1880. include_filename = filename;
  1881. ptr = skip->prev_execute_data;
  1882. ++indent;
  1883. if (free_class_name) {
  1884. efree((char*)free_class_name);
  1885. }
  1886. }
  1887. }
  1888. /* }}} */
  1889. ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit TSRMLS_DC)
  1890. {
  1891. zend_execute_data *ptr, *skip;
  1892. int lineno, frameno = 0;
  1893. const char *function_name;
  1894. const char *filename;
  1895. const char *class_name;
  1896. const char *include_filename = NULL;
  1897. zval *stack_frame;
  1898. ptr = EG(current_execute_data);
  1899. /* skip "new Exception()" */
  1900. if (ptr && (skip_last == 0) && ptr->opline && (ptr->opline->opcode == ZEND_NEW)) {
  1901. ptr = ptr->prev_execute_data;
  1902. }
  1903. /* skip debug_backtrace() */
  1904. if (skip_last-- && ptr) {
  1905. ptr = ptr->prev_execute_data;
  1906. }
  1907. array_init(return_value);
  1908. while (ptr && (limit == 0 || frameno < limit)) {
  1909. frameno++;
  1910. MAKE_STD_ZVAL(stack_frame);
  1911. array_init(stack_frame);
  1912. skip = ptr;
  1913. /* skip internal handler */
  1914. if (!skip->op_array &&
  1915. skip->prev_execute_data &&
  1916. skip->prev_execute_data->opline &&
  1917. skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
  1918. skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
  1919. skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
  1920. skip = skip->prev_execute_data;
  1921. }
  1922. if (skip->op_array) {
  1923. filename = skip->op_array->filename;
  1924. lineno = skip->opline->lineno;
  1925. add_assoc_string_ex(stack_frame, "file", sizeof("file"), (char*)filename, 1);
  1926. add_assoc_long_ex(stack_frame, "line", sizeof("line"), lineno);
  1927. /* try to fetch args only if an FCALL was just made - elsewise we're in the middle of a function
  1928. * and debug_baktrace() might have been called by the error_handler. in this case we don't
  1929. * want to pop anything of the argument-stack */
  1930. } else {
  1931. zend_execute_data *prev = skip->prev_execute_data;
  1932. while (prev) {
  1933. if (prev->function_state.function &&
  1934. prev->function_state.function->common.type != ZEND_USER_FUNCTION &&
  1935. !(prev->function_state.function->common.type == ZEND_INTERNAL_FUNCTION &&
  1936. (prev->function_state.function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER))) {
  1937. break;
  1938. }
  1939. if (prev->op_array) {
  1940. add_assoc_string_ex(stack_frame, "file", sizeof("file"), (char*)prev->op_array->filename, 1);
  1941. add_assoc_long_ex(stack_frame, "line", sizeof("line"), prev->opline->lineno);
  1942. break;
  1943. }
  1944. prev = prev->prev_execute_data;
  1945. }
  1946. filename = NULL;
  1947. }
  1948. function_name = (ptr->function_state.function->common.scope &&
  1949. ptr->function_state.function->common.scope->trait_aliases) ?
  1950. zend_resolve_method_name(
  1951. ptr->object ?
  1952. Z_OBJCE_P(ptr->object) :
  1953. ptr->function_state.function->common.scope,
  1954. ptr->function_state.function) :
  1955. ptr->function_state.function->common.function_name;
  1956. if (function_name) {
  1957. add_assoc_string_ex(stack_frame, "function", sizeof("function"), (char*)function_name, 1);
  1958. if (ptr->object && Z_TYPE_P(ptr->object) == IS_OBJECT) {
  1959. if (ptr->function_state.function->common.scope) {
  1960. add_assoc_string_ex(stack_frame, "class", sizeof("class"), (char*)ptr->function_state.function->common.scope->name, 1);
  1961. } else {
  1962. zend_uint class_name_len;
  1963. int dup;
  1964. dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
  1965. add_assoc_string_ex(stack_frame, "class", sizeof("class"), (char*)class_name, dup);
  1966. }
  1967. if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) {
  1968. add_assoc_zval_ex(stack_frame, "object", sizeof("object"), ptr->object);
  1969. Z_ADDREF_P(ptr->object);
  1970. }
  1971. add_assoc_string_ex(stack_frame, "type", sizeof("type"), "->", 1);
  1972. } else if (ptr->function_state.function->common.scope) {
  1973. add_assoc_string_ex(stack_frame, "class", sizeof("class"), (char*)ptr->function_state.function->common.scope->name, 1);
  1974. add_assoc_string_ex(stack_frame, "type", sizeof("type"), "::", 1);
  1975. }
  1976. if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 &&
  1977. ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL)))) {
  1978. if (ptr->function_state.arguments) {
  1979. add_assoc_zval_ex(stack_frame, "args", sizeof("args"), debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC));
  1980. }
  1981. }
  1982. } else {
  1983. /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
  1984. zend_bool build_filename_arg = 1;
  1985. if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
  1986. /* can happen when calling eval from a custom sapi */
  1987. function_name = "unknown";
  1988. build_filename_arg = 0;
  1989. } else
  1990. switch (ptr->opline->extended_value) {
  1991. case ZEND_EVAL:
  1992. function_name = "eval";
  1993. build_filename_arg = 0;
  1994. break;
  1995. case ZEND_INCLUDE:
  1996. function_name = "include";
  1997. break;
  1998. case ZEND_REQUIRE:
  1999. function_name = "require";
  2000. break;
  2001. case ZEND_INCLUDE_ONCE:
  2002. function_name = "include_once";
  2003. break;
  2004. case ZEND_REQUIRE_ONCE:
  2005. function_name = "require_once";
  2006. break;
  2007. default:
  2008. /* this can actually happen if you use debug_backtrace() in your error_handler and
  2009. * you're in the top-scope */
  2010. function_name = "unknown";
  2011. build_filename_arg = 0;
  2012. break;
  2013. }
  2014. if (build_filename_arg && include_filename) {
  2015. zval *arg_array;
  2016. MAKE_STD_ZVAL(arg_array);
  2017. array_init(arg_array);
  2018. /* include_filename always points to the last filename of the last last called-function.
  2019. if we have called include in the frame above - this is the file we have included.
  2020. */
  2021. add_next_index_string(arg_array, (char*)include_filename, 1);
  2022. add_assoc_zval_ex(stack_frame, "args", sizeof("args"), arg_array);
  2023. }
  2024. add_assoc_string_ex(stack_frame, "function", sizeof("function"), (char*)function_name, 1);
  2025. }
  2026. add_next_index_zval(return_value, stack_frame);
  2027. include_filename = filename;
  2028. ptr = skip->prev_execute_data;
  2029. }
  2030. }
  2031. /* }}} */
  2032. /* {{{ proto array debug_backtrace([int options[, int limit]])
  2033. Return backtrace as array */
  2034. ZEND_FUNCTION(debug_backtrace)
  2035. {
  2036. long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
  2037. long limit = 0;
  2038. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &options, &limit) == FAILURE) {
  2039. return;
  2040. }
  2041. zend_fetch_debug_backtrace(return_value, 1, options, limit TSRMLS_CC);
  2042. }
  2043. /* }}} */
  2044. /* {{{ proto bool extension_loaded(string extension_name)
  2045. Returns true if the named extension is loaded */
  2046. ZEND_FUNCTION(extension_loaded)
  2047. {
  2048. char *extension_name;
  2049. int extension_name_len;
  2050. char *lcname;
  2051. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) {
  2052. return;
  2053. }
  2054. lcname = zend_str_tolower_dup(extension_name, extension_name_len);
  2055. if (zend_hash_exists(&module_registry, lcname, extension_name_len+1)) {
  2056. RETVAL_TRUE;
  2057. } else {
  2058. RETVAL_FALSE;
  2059. }
  2060. efree(lcname);
  2061. }
  2062. /* }}} */
  2063. /* {{{ proto array get_extension_funcs(string extension_name)
  2064. Returns an array with the names of functions belonging to the named extension */
  2065. ZEND_FUNCTION(get_extension_funcs)
  2066. {
  2067. char *extension_name, *lcname;
  2068. int extension_name_len, array;
  2069. zend_module_entry *module;
  2070. HashPosition iterator;
  2071. zend_function *zif;
  2072. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) {
  2073. return;
  2074. }
  2075. if (strncasecmp(extension_name, "zend", sizeof("zend"))) {
  2076. lcname = zend_str_tolower_dup(extension_name, extension_name_len);
  2077. } else {
  2078. lcname = estrdup("core");
  2079. }
  2080. if (zend_hash_find(&module_registry, lcname,
  2081. extension_name_len+1, (void**)&module) == FAILURE) {
  2082. efree(lcname);
  2083. RETURN_FALSE;
  2084. }
  2085. zend_hash_internal_pointer_reset_ex(CG(function_table), &iterator);
  2086. if (module->functions) {
  2087. /* avoid BC break, if functions list is empty, will return an empty array */
  2088. array_init(return_value);
  2089. array = 1;
  2090. } else {
  2091. array = 0;
  2092. }
  2093. while (zend_hash_get_current_data_ex(CG(function_table), (void **) &zif, &iterator) == SUCCESS) {
  2094. if (zif->common.type==ZEND_INTERNAL_FUNCTION
  2095. && zif->internal_function.module == module) {
  2096. if (!array) {
  2097. array_init(return_value);
  2098. array = 1;
  2099. }
  2100. add_next_index_string(return_value, zif->common.function_name, 1);
  2101. }
  2102. zend_hash_move_forward_ex(CG(function_table), &iterator);
  2103. }
  2104. efree(lcname);
  2105. if (!array) {
  2106. RETURN_FALSE;
  2107. }
  2108. }
  2109. /* }}} */
  2110. /*
  2111. * Local variables:
  2112. * tab-width: 4
  2113. * c-basic-offset: 4
  2114. * indent-tabs-mode: t
  2115. * End:
  2116. */