php_zip.c 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 7 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP 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.php.net/license/3_01.txt. |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Piere-Alain Joye <pierre@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include "config.h"
  20. #endif
  21. #include "php.h"
  22. #include "php_ini.h"
  23. #include "ext/standard/info.h"
  24. #include "ext/standard/file.h"
  25. #include "ext/standard/php_string.h"
  26. #include "ext/pcre/php_pcre.h"
  27. #include "ext/standard/php_filestat.h"
  28. #if PHP_VERSION_ID >= 70200
  29. #include "zend_interfaces.h"
  30. #elif defined(HAVE_SPL)
  31. #include "ext/spl/spl_iterators.h"
  32. #endif
  33. #include "php_zip.h"
  34. /* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */
  35. static PHP_NAMED_FUNCTION(zif_zip_open);
  36. static PHP_NAMED_FUNCTION(zif_zip_read);
  37. static PHP_NAMED_FUNCTION(zif_zip_close);
  38. static PHP_NAMED_FUNCTION(zif_zip_entry_read);
  39. static PHP_NAMED_FUNCTION(zif_zip_entry_filesize);
  40. static PHP_NAMED_FUNCTION(zif_zip_entry_name);
  41. static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize);
  42. static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod);
  43. static PHP_NAMED_FUNCTION(zif_zip_entry_open);
  44. static PHP_NAMED_FUNCTION(zif_zip_entry_close);
  45. #ifdef HAVE_GLOB
  46. #ifndef PHP_WIN32
  47. #include <glob.h>
  48. #else
  49. #include "win32/glob.h"
  50. #endif
  51. #endif
  52. /* {{{ Resource le */
  53. static int le_zip_dir;
  54. #define le_zip_dir_name "Zip Directory"
  55. static int le_zip_entry;
  56. #define le_zip_entry_name "Zip Entry"
  57. /* }}} */
  58. /* {{{ PHP_ZIP_STAT_INDEX(za, index, flags, sb) */
  59. #define PHP_ZIP_STAT_INDEX(za, index, flags, sb) \
  60. if (zip_stat_index(za, index, flags, &sb) != 0) { \
  61. RETURN_FALSE; \
  62. }
  63. /* }}} */
  64. /* {{{ PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) */
  65. #define PHP_ZIP_STAT_PATH(za, path, path_len, flags, sb) \
  66. if (path_len < 1) { \
  67. php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); \
  68. RETURN_FALSE; \
  69. } \
  70. if (zip_stat(za, path, flags, &sb) != 0) { \
  71. RETURN_FALSE; \
  72. }
  73. /* }}} */
  74. /* {{{ PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) */
  75. #define PHP_ZIP_SET_FILE_COMMENT(za, index, comment, comment_len) \
  76. if (comment_len == 0) { \
  77. /* Passing NULL remove the existing comment */ \
  78. if (zip_set_file_comment(za, index, NULL, 0) < 0) { \
  79. RETURN_FALSE; \
  80. } \
  81. } else if (zip_set_file_comment(za, index, comment, comment_len) < 0) { \
  82. RETURN_FALSE; \
  83. } \
  84. RETURN_TRUE;
  85. /* }}} */
  86. # define add_ascii_assoc_string add_assoc_string
  87. # define add_ascii_assoc_long add_assoc_long
  88. /* Flatten a path by making a relative path (to .)*/
  89. static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */
  90. {
  91. char *path_begin = path;
  92. size_t i;
  93. if (path_len < 1 || path == NULL) {
  94. return NULL;
  95. }
  96. if (IS_SLASH(path[0])) {
  97. return path + 1;
  98. }
  99. i = path_len;
  100. while (1) {
  101. while (i > 0 && !IS_SLASH(path[i])) {
  102. i--;
  103. }
  104. if (!i) {
  105. return path;
  106. }
  107. if (i >= 2 && (path[i -1] == '.' || path[i -1] == ':')) {
  108. /* i is the position of . or :, add 1 for / */
  109. path_begin = path + i + 1;
  110. break;
  111. }
  112. i--;
  113. }
  114. return path_begin;
  115. }
  116. /* }}} */
  117. # define CWD_STATE_ALLOC(l) emalloc(l)
  118. # define CWD_STATE_FREE(s) efree(s)
  119. /* {{{ php_zip_extract_file */
  120. static int php_zip_extract_file(struct zip * za, char *dest, char *file, size_t file_len)
  121. {
  122. php_stream_statbuf ssb;
  123. struct zip_file *zf;
  124. struct zip_stat sb;
  125. char b[8192];
  126. int n, ret;
  127. php_stream *stream;
  128. char *fullpath;
  129. char *file_dirname_fullpath;
  130. char file_dirname[MAXPATHLEN];
  131. size_t dir_len, len;
  132. int is_dir_only = 0;
  133. char *path_cleaned;
  134. size_t path_cleaned_len;
  135. cwd_state new_state;
  136. zend_string *file_basename;
  137. new_state.cwd = CWD_STATE_ALLOC(1);
  138. new_state.cwd[0] = '\0';
  139. new_state.cwd_length = 0;
  140. /* Clean/normlize the path and then transform any path (absolute or relative)
  141. to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt)
  142. */
  143. virtual_file_ex(&new_state, file, NULL, CWD_EXPAND);
  144. path_cleaned = php_zip_make_relative_path(new_state.cwd, new_state.cwd_length);
  145. if(!path_cleaned) {
  146. return 0;
  147. }
  148. path_cleaned_len = strlen(path_cleaned);
  149. if (path_cleaned_len >= MAXPATHLEN || zip_stat(za, file, 0, &sb) != 0) {
  150. return 0;
  151. }
  152. /* it is a directory only, see #40228 */
  153. if (path_cleaned_len > 1 && IS_SLASH(path_cleaned[path_cleaned_len - 1])) {
  154. len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, path_cleaned);
  155. is_dir_only = 1;
  156. } else {
  157. memcpy(file_dirname, path_cleaned, path_cleaned_len);
  158. dir_len = php_dirname(file_dirname, path_cleaned_len);
  159. if (!dir_len || (dir_len == 1 && file_dirname[0] == '.')) {
  160. len = spprintf(&file_dirname_fullpath, 0, "%s", dest);
  161. } else {
  162. len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname);
  163. }
  164. file_basename = php_basename(path_cleaned, path_cleaned_len, NULL, 0);
  165. if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) {
  166. efree(file_dirname_fullpath);
  167. zend_string_release_ex(file_basename, 0);
  168. CWD_STATE_FREE(new_state.cwd);
  169. return 0;
  170. }
  171. }
  172. /* let see if the path already exists */
  173. if (php_stream_stat_path_ex(file_dirname_fullpath, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) {
  174. ret = php_stream_mkdir(file_dirname_fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE|REPORT_ERRORS, NULL);
  175. if (!ret) {
  176. efree(file_dirname_fullpath);
  177. if (!is_dir_only) {
  178. zend_string_release_ex(file_basename, 0);
  179. CWD_STATE_FREE(new_state.cwd);
  180. }
  181. return 0;
  182. }
  183. }
  184. /* it is a standalone directory, job done */
  185. if (is_dir_only) {
  186. efree(file_dirname_fullpath);
  187. CWD_STATE_FREE(new_state.cwd);
  188. return 1;
  189. }
  190. len = spprintf(&fullpath, 0, "%s/%s", file_dirname_fullpath, ZSTR_VAL(file_basename));
  191. if (!len) {
  192. efree(file_dirname_fullpath);
  193. zend_string_release_ex(file_basename, 0);
  194. CWD_STATE_FREE(new_state.cwd);
  195. return 0;
  196. } else if (len > MAXPATHLEN) {
  197. php_error_docref(NULL, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN);
  198. efree(file_dirname_fullpath);
  199. zend_string_release_ex(file_basename, 0);
  200. CWD_STATE_FREE(new_state.cwd);
  201. return 0;
  202. }
  203. /* check again the full path, not sure if it
  204. * is required, does a file can have a different
  205. * safemode status as its parent folder?
  206. */
  207. if (ZIP_OPENBASEDIR_CHECKPATH(fullpath)) {
  208. efree(fullpath);
  209. efree(file_dirname_fullpath);
  210. zend_string_release_ex(file_basename, 0);
  211. CWD_STATE_FREE(new_state.cwd);
  212. return 0;
  213. }
  214. zf = zip_fopen(za, file, 0);
  215. if (zf == NULL) {
  216. n = -1;
  217. goto done;
  218. }
  219. stream = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS, NULL);
  220. if (stream == NULL) {
  221. n = -1;
  222. zip_fclose(zf);
  223. goto done;
  224. }
  225. n = 0;
  226. while ((n=zip_fread(zf, b, sizeof(b))) > 0) {
  227. php_stream_write(stream, b, n);
  228. }
  229. php_stream_close(stream);
  230. n = zip_fclose(zf);
  231. done:
  232. efree(fullpath);
  233. zend_string_release_ex(file_basename, 0);
  234. efree(file_dirname_fullpath);
  235. CWD_STATE_FREE(new_state.cwd);
  236. if (n<0) {
  237. return 0;
  238. } else {
  239. return 1;
  240. }
  241. }
  242. /* }}} */
  243. static int php_zip_add_file(struct zip *za, const char *filename, size_t filename_len,
  244. char *entry_name, size_t entry_name_len, long offset_start, long offset_len) /* {{{ */
  245. {
  246. struct zip_source *zs;
  247. char resolved_path[MAXPATHLEN];
  248. zval exists_flag;
  249. if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
  250. return -1;
  251. }
  252. if (!expand_filepath(filename, resolved_path)) {
  253. return -1;
  254. }
  255. php_stat(resolved_path, strlen(resolved_path), FS_EXISTS, &exists_flag);
  256. if (Z_TYPE(exists_flag) == IS_FALSE) {
  257. return -1;
  258. }
  259. zs = zip_source_file(za, resolved_path, offset_start, offset_len);
  260. if (!zs) {
  261. return -1;
  262. }
  263. if (zip_file_add(za, entry_name, zs, ZIP_FL_OVERWRITE) < 0) {
  264. zip_source_free(zs);
  265. return -1;
  266. } else {
  267. zip_error_clear(za);
  268. return 1;
  269. }
  270. }
  271. /* }}} */
  272. static int php_zip_parse_options(zval *options, zend_long *remove_all_path, char **remove_path, size_t *remove_path_len, char **add_path, size_t *add_path_len) /* {{{ */
  273. {
  274. zval *option;
  275. if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "remove_all_path", sizeof("remove_all_path") - 1)) != NULL) {
  276. *remove_all_path = zval_get_long(option);
  277. }
  278. /* If I add more options, it would make sense to create a nice static struct and loop over it. */
  279. if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "remove_path", sizeof("remove_path") - 1)) != NULL) {
  280. if (Z_TYPE_P(option) != IS_STRING) {
  281. php_error_docref(NULL, E_WARNING, "remove_path option expected to be a string");
  282. return -1;
  283. }
  284. if (Z_STRLEN_P(option) < 1) {
  285. php_error_docref(NULL, E_NOTICE, "Empty string given as remove_path option");
  286. return -1;
  287. }
  288. if (Z_STRLEN_P(option) >= MAXPATHLEN) {
  289. php_error_docref(NULL, E_WARNING, "remove_path string is too long (max: %d, %zd given)",
  290. MAXPATHLEN - 1, Z_STRLEN_P(option));
  291. return -1;
  292. }
  293. *remove_path_len = Z_STRLEN_P(option);
  294. *remove_path = Z_STRVAL_P(option);
  295. }
  296. if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "add_path", sizeof("add_path") - 1)) != NULL) {
  297. if (Z_TYPE_P(option) != IS_STRING) {
  298. php_error_docref(NULL, E_WARNING, "add_path option expected to be a string");
  299. return -1;
  300. }
  301. if (Z_STRLEN_P(option) < 1) {
  302. php_error_docref(NULL, E_NOTICE, "Empty string given as the add_path option");
  303. return -1;
  304. }
  305. if (Z_STRLEN_P(option) >= MAXPATHLEN) {
  306. php_error_docref(NULL, E_WARNING, "add_path string too long (max: %d, %zd given)",
  307. MAXPATHLEN - 1, Z_STRLEN_P(option));
  308. return -1;
  309. }
  310. *add_path_len = Z_STRLEN_P(option);
  311. *add_path = Z_STRVAL_P(option);
  312. }
  313. return 1;
  314. }
  315. /* }}} */
  316. /* {{{ REGISTER_ZIP_CLASS_CONST_LONG */
  317. #define REGISTER_ZIP_CLASS_CONST_LONG(const_name, value) \
  318. zend_declare_class_constant_long(zip_class_entry, const_name, sizeof(const_name)-1, (zend_long)value);
  319. /* }}} */
  320. /* {{{ ZIP_FROM_OBJECT */
  321. #define ZIP_FROM_OBJECT(intern, object) \
  322. { \
  323. ze_zip_object *obj = Z_ZIP_P(object); \
  324. intern = obj->za; \
  325. if (!intern) { \
  326. php_error_docref(NULL, E_WARNING, "Invalid or uninitialized Zip object"); \
  327. RETURN_FALSE; \
  328. } \
  329. }
  330. /* }}} */
  331. /* {{{ RETURN_SB(sb) */
  332. #ifdef HAVE_ENCRYPTION
  333. #define RETURN_SB(sb) \
  334. { \
  335. array_init(return_value); \
  336. add_ascii_assoc_string(return_value, "name", (char *)(sb)->name); \
  337. add_ascii_assoc_long(return_value, "index", (zend_long) (sb)->index); \
  338. add_ascii_assoc_long(return_value, "crc", (zend_long) (sb)->crc); \
  339. add_ascii_assoc_long(return_value, "size", (zend_long) (sb)->size); \
  340. add_ascii_assoc_long(return_value, "mtime", (zend_long) (sb)->mtime); \
  341. add_ascii_assoc_long(return_value, "comp_size", (zend_long) (sb)->comp_size); \
  342. add_ascii_assoc_long(return_value, "comp_method", (zend_long) (sb)->comp_method); \
  343. add_ascii_assoc_long(return_value, "encryption_method", (zend_long) (sb)->encryption_method); \
  344. }
  345. #else
  346. #define RETURN_SB(sb) \
  347. { \
  348. array_init(return_value); \
  349. add_ascii_assoc_string(return_value, "name", (char *)(sb)->name); \
  350. add_ascii_assoc_long(return_value, "index", (zend_long) (sb)->index); \
  351. add_ascii_assoc_long(return_value, "crc", (zend_long) (sb)->crc); \
  352. add_ascii_assoc_long(return_value, "size", (zend_long) (sb)->size); \
  353. add_ascii_assoc_long(return_value, "mtime", (zend_long) (sb)->mtime); \
  354. add_ascii_assoc_long(return_value, "comp_size", (zend_long) (sb)->comp_size); \
  355. add_ascii_assoc_long(return_value, "comp_method", (zend_long) (sb)->comp_method); \
  356. }
  357. #endif
  358. /* }}} */
  359. static int php_zip_status(struct zip *za) /* {{{ */
  360. {
  361. #if LIBZIP_VERSION_MAJOR < 1
  362. int zep, syp;
  363. zip_error_get(za, &zep, &syp);
  364. #else
  365. int zep;
  366. zip_error_t *err;
  367. err = zip_get_error(za);
  368. zep = zip_error_code_zip(err);
  369. zip_error_fini(err);
  370. #endif
  371. return zep;
  372. }
  373. /* }}} */
  374. static int php_zip_status_sys(struct zip *za) /* {{{ */
  375. {
  376. #if LIBZIP_VERSION_MAJOR < 1
  377. int zep, syp;
  378. zip_error_get(za, &zep, &syp);
  379. #else
  380. int syp;
  381. zip_error_t *err;
  382. err = zip_get_error(za);
  383. syp = zip_error_code_system(err);
  384. zip_error_fini(err);
  385. #endif
  386. return syp;
  387. }
  388. /* }}} */
  389. static int php_zip_get_num_files(struct zip *za) /* {{{ */
  390. {
  391. return zip_get_num_files(za);
  392. }
  393. /* }}} */
  394. static char * php_zipobj_get_filename(ze_zip_object *obj) /* {{{ */
  395. {
  396. if (!obj) {
  397. return NULL;
  398. }
  399. if (obj->filename) {
  400. return obj->filename;
  401. }
  402. return NULL;
  403. }
  404. /* }}} */
  405. static char * php_zipobj_get_zip_comment(struct zip *za, int *len) /* {{{ */
  406. {
  407. if (za) {
  408. return (char *)zip_get_archive_comment(za, len, 0);
  409. }
  410. return NULL;
  411. }
  412. /* }}} */
  413. #ifdef HAVE_GLOB /* {{{ */
  414. #ifndef GLOB_ONLYDIR
  415. #define GLOB_ONLYDIR (1<<30)
  416. #define GLOB_EMULATE_ONLYDIR
  417. #define GLOB_FLAGMASK (~GLOB_ONLYDIR)
  418. #else
  419. #define GLOB_FLAGMASK (~0)
  420. #endif
  421. #ifndef GLOB_BRACE
  422. # define GLOB_BRACE 0
  423. #endif
  424. #ifndef GLOB_MARK
  425. # define GLOB_MARK 0
  426. #endif
  427. #ifndef GLOB_NOSORT
  428. # define GLOB_NOSORT 0
  429. #endif
  430. #ifndef GLOB_NOCHECK
  431. # define GLOB_NOCHECK 0
  432. #endif
  433. #ifndef GLOB_NOESCAPE
  434. # define GLOB_NOESCAPE 0
  435. #endif
  436. #ifndef GLOB_ERR
  437. # define GLOB_ERR 0
  438. #endif
  439. /* This is used for checking validity of passed flags (passing invalid flags causes segfault in glob()!! */
  440. #define GLOB_AVAILABLE_FLAGS (0 | GLOB_BRACE | GLOB_MARK | GLOB_NOSORT | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ERR | GLOB_ONLYDIR)
  441. #endif /* }}} */
  442. int php_zip_glob(char *pattern, int pattern_len, zend_long flags, zval *return_value) /* {{{ */
  443. {
  444. #ifdef HAVE_GLOB
  445. char cwd[MAXPATHLEN];
  446. int cwd_skip = 0;
  447. #ifdef ZTS
  448. char work_pattern[MAXPATHLEN];
  449. char *result;
  450. #endif
  451. glob_t globbuf;
  452. size_t n;
  453. int ret;
  454. if (pattern_len >= MAXPATHLEN) {
  455. php_error_docref(NULL, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
  456. return -1;
  457. }
  458. if ((GLOB_AVAILABLE_FLAGS & flags) != flags) {
  459. php_error_docref(NULL, E_WARNING, "At least one of the passed flags is invalid or not supported on this platform");
  460. return -1;
  461. }
  462. #ifdef ZTS
  463. if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
  464. result = VCWD_GETCWD(cwd, MAXPATHLEN);
  465. if (!result) {
  466. cwd[0] = '\0';
  467. }
  468. #ifdef PHP_WIN32
  469. if (IS_SLASH(*pattern)) {
  470. cwd[2] = '\0';
  471. }
  472. #endif
  473. cwd_skip = strlen(cwd)+1;
  474. snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
  475. pattern = work_pattern;
  476. }
  477. #endif
  478. globbuf.gl_offs = 0;
  479. if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
  480. #ifdef GLOB_NOMATCH
  481. if (GLOB_NOMATCH == ret) {
  482. /* Some glob implementation simply return no data if no matches
  483. were found, others return the GLOB_NOMATCH error code.
  484. We don't want to treat GLOB_NOMATCH as an error condition
  485. so that PHP glob() behaves the same on both types of
  486. implementations and so that 'foreach (glob() as ...'
  487. can be used for simple glob() calls without further error
  488. checking.
  489. */
  490. array_init(return_value);
  491. return 0;
  492. }
  493. #endif
  494. return 0;
  495. }
  496. /* now catch the FreeBSD style of "no matches" */
  497. if (!globbuf.gl_pathc || !globbuf.gl_pathv) {
  498. array_init(return_value);
  499. return 0;
  500. }
  501. /* we assume that any glob pattern will match files from one directory only
  502. so checking the dirname of the first match should be sufficient */
  503. strncpy(cwd, globbuf.gl_pathv[0], MAXPATHLEN);
  504. if (ZIP_OPENBASEDIR_CHECKPATH(cwd)) {
  505. return -1;
  506. }
  507. array_init(return_value);
  508. for (n = 0; n < globbuf.gl_pathc; n++) {
  509. /* we need to do this every time since GLOB_ONLYDIR does not guarantee that
  510. * all directories will be filtered. GNU libc documentation states the
  511. * following:
  512. * If the information about the type of the file is easily available
  513. * non-directories will be rejected but no extra work will be done to
  514. * determine the information for each file. I.e., the caller must still be
  515. * able to filter directories out.
  516. */
  517. if (flags & GLOB_ONLYDIR) {
  518. zend_stat_t s;
  519. if (0 != VCWD_STAT(globbuf.gl_pathv[n], &s)) {
  520. continue;
  521. }
  522. if (S_IFDIR != (s.st_mode & S_IFMT)) {
  523. continue;
  524. }
  525. }
  526. add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip);
  527. }
  528. ret = globbuf.gl_pathc;
  529. globfree(&globbuf);
  530. return ret;
  531. #else
  532. zend_throw_error(NULL, "Glob support is not available");
  533. return 0;
  534. #endif /* HAVE_GLOB */
  535. }
  536. /* }}} */
  537. int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_value) /* {{{ */
  538. {
  539. #ifdef ZTS
  540. char cwd[MAXPATHLEN];
  541. int cwd_skip = 0;
  542. char work_path[MAXPATHLEN];
  543. char *result;
  544. #endif
  545. int files_cnt;
  546. zend_string **namelist;
  547. pcre2_match_context *mctx = php_pcre_mctx();
  548. #ifdef ZTS
  549. if (!IS_ABSOLUTE_PATH(path, path_len)) {
  550. result = VCWD_GETCWD(cwd, MAXPATHLEN);
  551. if (!result) {
  552. cwd[0] = '\0';
  553. }
  554. #ifdef PHP_WIN32
  555. if (IS_SLASH(*path)) {
  556. cwd[2] = '\0';
  557. }
  558. #endif
  559. cwd_skip = strlen(cwd)+1;
  560. snprintf(work_path, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, path);
  561. path = work_path;
  562. }
  563. #endif
  564. if (ZIP_OPENBASEDIR_CHECKPATH(path)) {
  565. return -1;
  566. }
  567. files_cnt = php_stream_scandir(path, &namelist, NULL, (void *) php_stream_dirent_alphasort);
  568. if (files_cnt > 0) {
  569. pcre2_code *re = NULL;
  570. pcre2_match_data *match_data = NULL;
  571. uint32_t preg_options = 0, i, capture_count;
  572. int rc;
  573. re = pcre_get_compiled_regex(regexp, &capture_count, &preg_options);
  574. if (!re) {
  575. php_error_docref(NULL, E_WARNING, "Invalid expression");
  576. return -1;
  577. }
  578. array_init(return_value);
  579. /* only the files, directories are ignored */
  580. for (i = 0; i < files_cnt; i++) {
  581. zend_stat_t s;
  582. char fullpath[MAXPATHLEN];
  583. size_t namelist_len = ZSTR_LEN(namelist[i]);
  584. if ((namelist_len == 1 && ZSTR_VAL(namelist[i])[0] == '.') ||
  585. (namelist_len == 2 && ZSTR_VAL(namelist[i])[0] == '.' && ZSTR_VAL(namelist[i])[1] == '.')) {
  586. zend_string_release_ex(namelist[i], 0);
  587. continue;
  588. }
  589. if ((path_len + namelist_len + 1) >= MAXPATHLEN) {
  590. php_error_docref(NULL, E_WARNING, "add_path string too long (max: %u, %zu given)",
  591. MAXPATHLEN - 1, (path_len + namelist_len + 1));
  592. zend_string_release_ex(namelist[i], 0);
  593. break;
  594. }
  595. snprintf(fullpath, MAXPATHLEN, "%s%c%s", path, DEFAULT_SLASH, ZSTR_VAL(namelist[i]));
  596. if (0 != VCWD_STAT(fullpath, &s)) {
  597. php_error_docref(NULL, E_WARNING, "Cannot read <%s>", fullpath);
  598. zend_string_release_ex(namelist[i], 0);
  599. continue;
  600. }
  601. if (S_IFDIR == (s.st_mode & S_IFMT)) {
  602. zend_string_release_ex(namelist[i], 0);
  603. continue;
  604. }
  605. match_data = php_pcre_create_match_data(capture_count, re);
  606. if (!match_data) {
  607. /* Allocation failed, but can proceed to the next pattern. */
  608. zend_string_release_ex(namelist[i], 0);
  609. continue;
  610. }
  611. rc = pcre2_match(re, (PCRE2_SPTR)ZSTR_VAL(namelist[i]), ZSTR_LEN(namelist[i]), 0, preg_options, match_data, mctx);
  612. php_pcre_free_match_data(match_data);
  613. /* 0 means that the vector is too small to hold all the captured substring offsets */
  614. if (rc < 0) {
  615. zend_string_release_ex(namelist[i], 0);
  616. continue;
  617. }
  618. add_next_index_string(return_value, fullpath);
  619. zend_string_release_ex(namelist[i], 0);
  620. }
  621. efree(namelist);
  622. }
  623. return files_cnt;
  624. }
  625. /* }}} */
  626. /* {{{ arginfo */
  627. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open, 0, 0, 1)
  628. ZEND_ARG_INFO(0, filename)
  629. ZEND_END_ARG_INFO()
  630. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_close, 0, 0, 1)
  631. ZEND_ARG_INFO(0, zip)
  632. ZEND_END_ARG_INFO()
  633. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_read, 0, 0, 1)
  634. ZEND_ARG_INFO(0, zip)
  635. ZEND_END_ARG_INFO()
  636. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_open, 0, 0, 2)
  637. ZEND_ARG_INFO(0, zip_dp)
  638. ZEND_ARG_INFO(0, zip_entry)
  639. ZEND_ARG_INFO(0, mode)
  640. ZEND_END_ARG_INFO()
  641. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_close, 0, 0, 1)
  642. ZEND_ARG_INFO(0, zip_ent)
  643. ZEND_END_ARG_INFO()
  644. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_read, 0, 0, 1)
  645. ZEND_ARG_INFO(0, zip_entry)
  646. ZEND_ARG_INFO(0, len)
  647. ZEND_END_ARG_INFO()
  648. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_name, 0, 0, 1)
  649. ZEND_ARG_INFO(0, zip_entry)
  650. ZEND_END_ARG_INFO()
  651. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressedsize, 0, 0, 1)
  652. ZEND_ARG_INFO(0, zip_entry)
  653. ZEND_END_ARG_INFO()
  654. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_filesize, 0, 0, 1)
  655. ZEND_ARG_INFO(0, zip_entry)
  656. ZEND_END_ARG_INFO()
  657. ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_entry_compressionmethod, 0, 0, 1)
  658. ZEND_ARG_INFO(0, zip_entry)
  659. ZEND_END_ARG_INFO()
  660. /* }}} */
  661. /* {{{ zend_function_entry */
  662. static const zend_function_entry zip_functions[] = {
  663. ZEND_RAW_FENTRY("zip_open", zif_zip_open, arginfo_zip_open, 0)
  664. ZEND_RAW_FENTRY("zip_close", zif_zip_close, arginfo_zip_close, 0)
  665. ZEND_RAW_FENTRY("zip_read", zif_zip_read, arginfo_zip_read, 0)
  666. PHP_FE(zip_entry_open, arginfo_zip_entry_open)
  667. PHP_FE(zip_entry_close, arginfo_zip_entry_close)
  668. PHP_FE(zip_entry_read, arginfo_zip_entry_read)
  669. PHP_FE(zip_entry_filesize, arginfo_zip_entry_filesize)
  670. PHP_FE(zip_entry_name, arginfo_zip_entry_name)
  671. PHP_FE(zip_entry_compressedsize, arginfo_zip_entry_compressedsize)
  672. PHP_FE(zip_entry_compressionmethod, arginfo_zip_entry_compressionmethod)
  673. #ifdef PHP_FE_END
  674. PHP_FE_END
  675. #else
  676. {NULL,NULL,NULL}
  677. #endif
  678. };
  679. /* }}} */
  680. /* {{{ ZE2 OO definitions */
  681. static zend_class_entry *zip_class_entry;
  682. static zend_object_handlers zip_object_handlers;
  683. static HashTable zip_prop_handlers;
  684. typedef int (*zip_read_int_t)(struct zip *za);
  685. typedef char *(*zip_read_const_char_t)(struct zip *za, int *len);
  686. typedef char *(*zip_read_const_char_from_ze_t)(ze_zip_object *obj);
  687. typedef struct _zip_prop_handler {
  688. zip_read_int_t read_int_func;
  689. zip_read_const_char_t read_const_char_func;
  690. zip_read_const_char_from_ze_t read_const_char_from_obj_func;
  691. int type;
  692. } zip_prop_handler;
  693. /* }}} */
  694. static void php_zip_register_prop_handler(HashTable *prop_handler, char *name, zip_read_int_t read_int_func, zip_read_const_char_t read_char_func, zip_read_const_char_from_ze_t read_char_from_obj_func, int rettype) /* {{{ */
  695. {
  696. zip_prop_handler hnd;
  697. zend_string *str;
  698. zval tmp;
  699. hnd.read_const_char_func = read_char_func;
  700. hnd.read_int_func = read_int_func;
  701. hnd.read_const_char_from_obj_func = read_char_from_obj_func;
  702. hnd.type = rettype;
  703. str = zend_string_init_interned(name, strlen(name), 1);
  704. zend_hash_add_mem(prop_handler, str, &hnd, sizeof(zip_prop_handler));
  705. /* Register for reflection */
  706. ZVAL_NULL(&tmp);
  707. zend_declare_property_ex(zip_class_entry, str, &tmp, ZEND_ACC_PUBLIC, NULL);
  708. zend_string_release_ex(str, 1);
  709. }
  710. /* }}} */
  711. static zval *php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zval *rv) /* {{{ */
  712. {
  713. const char *retchar = NULL;
  714. int retint = 0;
  715. int len = 0;
  716. if (obj && obj->za != NULL) {
  717. if (hnd->read_const_char_func) {
  718. retchar = hnd->read_const_char_func(obj->za, &len);
  719. } else {
  720. if (hnd->read_int_func) {
  721. retint = hnd->read_int_func(obj->za);
  722. if (retint == -1) {
  723. php_error_docref(NULL, E_WARNING, "Internal zip error returned");
  724. return NULL;
  725. }
  726. } else {
  727. if (hnd->read_const_char_from_obj_func) {
  728. retchar = hnd->read_const_char_from_obj_func(obj);
  729. len = strlen(retchar);
  730. }
  731. }
  732. }
  733. }
  734. switch (hnd->type) {
  735. case IS_STRING:
  736. if (retchar) {
  737. ZVAL_STRINGL(rv, (char *) retchar, len);
  738. } else {
  739. ZVAL_EMPTY_STRING(rv);
  740. }
  741. break;
  742. /* case IS_TRUE */
  743. case IS_FALSE:
  744. ZVAL_BOOL(rv, (long)retint);
  745. break;
  746. case IS_LONG:
  747. ZVAL_LONG(rv, (long)retint);
  748. break;
  749. default:
  750. ZVAL_NULL(rv);
  751. }
  752. return rv;
  753. }
  754. /* }}} */
  755. static zval *php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, void **cache_slot) /* {{{ */
  756. {
  757. ze_zip_object *obj;
  758. zval tmp_member;
  759. zval *retval = NULL;
  760. zip_prop_handler *hnd = NULL;
  761. if (Z_TYPE_P(member) != IS_STRING) {
  762. ZVAL_STR(&tmp_member, zval_get_string_func(member));
  763. member = &tmp_member;
  764. cache_slot = NULL;
  765. }
  766. obj = Z_ZIP_P(object);
  767. if (obj->prop_handler != NULL) {
  768. hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member));
  769. }
  770. if (hnd == NULL) {
  771. retval = zend_std_get_property_ptr_ptr(object, member, type, cache_slot);
  772. }
  773. if (member == &tmp_member) {
  774. zval_ptr_dtor_str(&tmp_member);
  775. }
  776. return retval;
  777. }
  778. /* }}} */
  779. static zval *php_zip_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv) /* {{{ */
  780. {
  781. ze_zip_object *obj;
  782. zval tmp_member;
  783. zval *retval = NULL;
  784. zip_prop_handler *hnd = NULL;
  785. if (Z_TYPE_P(member) != IS_STRING) {
  786. ZVAL_STR(&tmp_member, zval_get_string_func(member));
  787. member = &tmp_member;
  788. cache_slot = NULL;
  789. }
  790. obj = Z_ZIP_P(object);
  791. if (obj->prop_handler != NULL) {
  792. hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member));
  793. }
  794. if (hnd != NULL) {
  795. retval = php_zip_property_reader(obj, hnd, rv);
  796. if (retval == NULL) {
  797. retval = &EG(uninitialized_zval);
  798. }
  799. } else {
  800. retval = zend_std_read_property(object, member, type, cache_slot, rv);
  801. }
  802. if (member == &tmp_member) {
  803. zval_ptr_dtor_str(&tmp_member);
  804. }
  805. return retval;
  806. }
  807. /* }}} */
  808. static int php_zip_has_property(zval *object, zval *member, int type, void **cache_slot) /* {{{ */
  809. {
  810. ze_zip_object *obj;
  811. zval tmp_member;
  812. zip_prop_handler *hnd = NULL;
  813. int retval = 0;
  814. if (Z_TYPE_P(member) != IS_STRING) {
  815. ZVAL_STR(&tmp_member, zval_get_string_func(member));
  816. member = &tmp_member;
  817. cache_slot = NULL;
  818. }
  819. obj = Z_ZIP_P(object);
  820. if (obj->prop_handler != NULL) {
  821. hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member));
  822. }
  823. if (hnd != NULL) {
  824. zval tmp, *prop;
  825. if (type == 2) {
  826. retval = 1;
  827. } else if ((prop = php_zip_property_reader(obj, hnd, &tmp)) != NULL) {
  828. if (type == 1) {
  829. retval = zend_is_true(&tmp);
  830. } else if (type == 0) {
  831. retval = (Z_TYPE(tmp) != IS_NULL);
  832. }
  833. }
  834. zval_ptr_dtor(&tmp);
  835. } else {
  836. retval = zend_std_has_property(object, member, type, cache_slot);
  837. }
  838. if (member == &tmp_member) {
  839. zval_ptr_dtor_str(&tmp_member);
  840. }
  841. return retval;
  842. }
  843. /* }}} */
  844. static HashTable *php_zip_get_gc(zval *object, zval **gc_data, int *gc_data_count) /* {{{ */
  845. {
  846. *gc_data = NULL;
  847. *gc_data_count = 0;
  848. return zend_std_get_properties(object);
  849. }
  850. /* }}} */
  851. static HashTable *php_zip_get_properties(zval *object)/* {{{ */
  852. {
  853. ze_zip_object *obj;
  854. HashTable *props;
  855. zip_prop_handler *hnd;
  856. zend_string *key;
  857. obj = Z_ZIP_P(object);
  858. props = zend_std_get_properties(object);
  859. if (obj->prop_handler == NULL) {
  860. return NULL;
  861. }
  862. ZEND_HASH_FOREACH_STR_KEY_PTR(obj->prop_handler, key, hnd) {
  863. zval *ret, val;
  864. ret = php_zip_property_reader(obj, hnd, &val);
  865. if (ret == NULL) {
  866. ret = &EG(uninitialized_zval);
  867. }
  868. zend_hash_update(props, key, ret);
  869. } ZEND_HASH_FOREACH_END();
  870. return props;
  871. }
  872. /* }}} */
  873. static void php_zip_object_free_storage(zend_object *object) /* {{{ */
  874. {
  875. ze_zip_object * intern = php_zip_fetch_object(object);
  876. int i;
  877. if (!intern) {
  878. return;
  879. }
  880. if (intern->za) {
  881. if (zip_close(intern->za) != 0) {
  882. #if LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR == 3 && LIBZIP_VERSION_MICRO == 1
  883. php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context: %s", "zip_close have failed");
  884. #else
  885. php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context: %s", zip_strerror(intern->za));
  886. zip_discard(intern->za);
  887. #endif
  888. }
  889. }
  890. if (intern->buffers_cnt>0) {
  891. for (i=0; i<intern->buffers_cnt; i++) {
  892. efree(intern->buffers[i]);
  893. }
  894. efree(intern->buffers);
  895. }
  896. intern->za = NULL;
  897. zend_object_std_dtor(&intern->zo);
  898. if (intern->filename) {
  899. efree(intern->filename);
  900. }
  901. }
  902. /* }}} */
  903. static zend_object *php_zip_object_new(zend_class_entry *class_type) /* {{{ */
  904. {
  905. ze_zip_object *intern;
  906. intern = zend_object_alloc(sizeof(ze_zip_object), class_type);
  907. intern->prop_handler = &zip_prop_handlers;
  908. zend_object_std_init(&intern->zo, class_type);
  909. object_properties_init(&intern->zo, class_type);
  910. intern->zo.handlers = &zip_object_handlers;
  911. return &intern->zo;
  912. }
  913. /* }}} */
  914. /* {{{ Resource dtors */
  915. /* {{{ php_zip_free_dir */
  916. static void php_zip_free_dir(zend_resource *rsrc)
  917. {
  918. zip_rsrc * zip_int = (zip_rsrc *) rsrc->ptr;
  919. if (zip_int) {
  920. if (zip_int->za) {
  921. if (zip_close(zip_int->za) != 0) {
  922. php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context");
  923. }
  924. zip_int->za = NULL;
  925. }
  926. efree(rsrc->ptr);
  927. rsrc->ptr = NULL;
  928. }
  929. }
  930. /* }}} */
  931. /* {{{ php_zip_free_entry */
  932. static void php_zip_free_entry(zend_resource *rsrc)
  933. {
  934. zip_read_rsrc *zr_rsrc = (zip_read_rsrc *) rsrc->ptr;
  935. if (zr_rsrc) {
  936. if (zr_rsrc->zf) {
  937. zip_fclose(zr_rsrc->zf);
  938. zr_rsrc->zf = NULL;
  939. }
  940. efree(zr_rsrc);
  941. rsrc->ptr = NULL;
  942. }
  943. }
  944. /* }}} */
  945. /* }}}*/
  946. /* reset macro */
  947. /* {{{ function prototypes */
  948. static PHP_MINIT_FUNCTION(zip);
  949. static PHP_MSHUTDOWN_FUNCTION(zip);
  950. static PHP_MINFO_FUNCTION(zip);
  951. /* }}} */
  952. /* {{{ zip_module_entry
  953. */
  954. zend_module_entry zip_module_entry = {
  955. STANDARD_MODULE_HEADER,
  956. "zip",
  957. zip_functions,
  958. PHP_MINIT(zip),
  959. PHP_MSHUTDOWN(zip),
  960. NULL,
  961. NULL,
  962. PHP_MINFO(zip),
  963. PHP_ZIP_VERSION,
  964. STANDARD_MODULE_PROPERTIES
  965. };
  966. /* }}} */
  967. #ifdef COMPILE_DL_ZIP
  968. ZEND_GET_MODULE(zip)
  969. #endif
  970. /* set macro */
  971. /* {{{ proto resource zip_open(string filename)
  972. Create new zip using source uri for output */
  973. static PHP_NAMED_FUNCTION(zif_zip_open)
  974. {
  975. char resolved_path[MAXPATHLEN + 1];
  976. zip_rsrc *rsrc_int;
  977. int err = 0;
  978. zend_string *filename;
  979. if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &filename) == FAILURE) {
  980. return;
  981. }
  982. if (ZSTR_LEN(filename) == 0) {
  983. php_error_docref(NULL, E_WARNING, "Empty string as source");
  984. RETURN_FALSE;
  985. }
  986. if (ZIP_OPENBASEDIR_CHECKPATH(ZSTR_VAL(filename))) {
  987. RETURN_FALSE;
  988. }
  989. if(!expand_filepath(ZSTR_VAL(filename), resolved_path)) {
  990. RETURN_FALSE;
  991. }
  992. rsrc_int = (zip_rsrc *)emalloc(sizeof(zip_rsrc));
  993. rsrc_int->za = zip_open(resolved_path, 0, &err);
  994. if (rsrc_int->za == NULL) {
  995. efree(rsrc_int);
  996. RETURN_LONG((zend_long)err);
  997. }
  998. rsrc_int->index_current = 0;
  999. rsrc_int->num_files = zip_get_num_files(rsrc_int->za);
  1000. RETURN_RES(zend_register_resource(rsrc_int, le_zip_dir));
  1001. }
  1002. /* }}} */
  1003. /* {{{ proto void zip_close(resource zip)
  1004. Close a Zip archive */
  1005. static PHP_NAMED_FUNCTION(zif_zip_close)
  1006. {
  1007. zval * zip;
  1008. zip_rsrc *z_rsrc = NULL;
  1009. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip) == FAILURE) {
  1010. return;
  1011. }
  1012. if ((z_rsrc = (zip_rsrc *)zend_fetch_resource(Z_RES_P(zip), le_zip_dir_name, le_zip_dir)) == NULL) {
  1013. RETURN_FALSE;
  1014. }
  1015. /* really close the zip will break BC :-D */
  1016. zend_list_close(Z_RES_P(zip));
  1017. }
  1018. /* }}} */
  1019. /* {{{ proto resource zip_read(resource zip)
  1020. Returns the next file in the archive */
  1021. static PHP_NAMED_FUNCTION(zif_zip_read)
  1022. {
  1023. zval *zip_dp;
  1024. zip_read_rsrc *zr_rsrc;
  1025. int ret;
  1026. zip_rsrc *rsrc_int;
  1027. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip_dp) == FAILURE) {
  1028. return;
  1029. }
  1030. if ((rsrc_int = (zip_rsrc *)zend_fetch_resource(Z_RES_P(zip_dp), le_zip_dir_name, le_zip_dir)) == NULL) {
  1031. RETURN_FALSE;
  1032. }
  1033. if (rsrc_int && rsrc_int->za) {
  1034. if (rsrc_int->index_current >= rsrc_int->num_files) {
  1035. RETURN_FALSE;
  1036. }
  1037. zr_rsrc = emalloc(sizeof(zip_read_rsrc));
  1038. ret = zip_stat_index(rsrc_int->za, rsrc_int->index_current, 0, &zr_rsrc->sb);
  1039. if (ret != 0) {
  1040. efree(zr_rsrc);
  1041. RETURN_FALSE;
  1042. }
  1043. zr_rsrc->zf = zip_fopen_index(rsrc_int->za, rsrc_int->index_current, 0);
  1044. if (zr_rsrc->zf) {
  1045. rsrc_int->index_current++;
  1046. RETURN_RES(zend_register_resource(zr_rsrc, le_zip_entry));
  1047. } else {
  1048. efree(zr_rsrc);
  1049. RETURN_FALSE;
  1050. }
  1051. } else {
  1052. RETURN_FALSE;
  1053. }
  1054. }
  1055. /* }}} */
  1056. /* {{{ proto bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode])
  1057. Open a Zip File, pointed by the resource entry */
  1058. /* Dummy function to follow the old API */
  1059. static PHP_NAMED_FUNCTION(zif_zip_entry_open)
  1060. {
  1061. zval * zip;
  1062. zval * zip_entry;
  1063. char *mode = NULL;
  1064. size_t mode_len = 0;
  1065. zip_read_rsrc * zr_rsrc;
  1066. zip_rsrc *z_rsrc;
  1067. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|s", &zip, &zip_entry, &mode, &mode_len) == FAILURE) {
  1068. return;
  1069. }
  1070. if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) {
  1071. RETURN_FALSE;
  1072. }
  1073. if ((z_rsrc = (zip_rsrc *)zend_fetch_resource(Z_RES_P(zip), le_zip_dir_name, le_zip_dir)) == NULL) {
  1074. RETURN_FALSE;
  1075. }
  1076. if (zr_rsrc->zf != NULL) {
  1077. RETURN_TRUE;
  1078. } else {
  1079. RETURN_FALSE;
  1080. }
  1081. }
  1082. /* }}} */
  1083. /* {{{ proto bool zip_entry_close(resource zip_ent)
  1084. Close a zip entry */
  1085. static PHP_NAMED_FUNCTION(zif_zip_entry_close)
  1086. {
  1087. zval * zip_entry;
  1088. zip_read_rsrc * zr_rsrc;
  1089. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip_entry) == FAILURE) {
  1090. return;
  1091. }
  1092. if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) {
  1093. RETURN_FALSE;
  1094. }
  1095. RETURN_BOOL(SUCCESS == zend_list_close(Z_RES_P(zip_entry)));
  1096. }
  1097. /* }}} */
  1098. /* {{{ proto mixed zip_entry_read(resource zip_entry [, int len])
  1099. Read from an open directory entry */
  1100. static PHP_NAMED_FUNCTION(zif_zip_entry_read)
  1101. {
  1102. zval * zip_entry;
  1103. zend_long len = 0;
  1104. zip_read_rsrc * zr_rsrc;
  1105. zend_string *buffer;
  1106. int n = 0;
  1107. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &zip_entry, &len) == FAILURE) {
  1108. return;
  1109. }
  1110. if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) {
  1111. RETURN_FALSE;
  1112. }
  1113. if (len <= 0) {
  1114. len = 1024;
  1115. }
  1116. if (zr_rsrc->zf) {
  1117. buffer = zend_string_safe_alloc(1, len, 0, 0);
  1118. n = zip_fread(zr_rsrc->zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer));
  1119. if (n > 0) {
  1120. ZSTR_VAL(buffer)[n] = '\0';
  1121. ZSTR_LEN(buffer) = n;
  1122. RETURN_NEW_STR(buffer);
  1123. } else {
  1124. zend_string_efree(buffer);
  1125. RETURN_EMPTY_STRING()
  1126. }
  1127. } else {
  1128. RETURN_FALSE;
  1129. }
  1130. }
  1131. /* }}} */
  1132. static void php_zip_entry_get_info(INTERNAL_FUNCTION_PARAMETERS, int opt) /* {{{ */
  1133. {
  1134. zval * zip_entry;
  1135. zip_read_rsrc * zr_rsrc;
  1136. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zip_entry) == FAILURE) {
  1137. return;
  1138. }
  1139. if ((zr_rsrc = (zip_read_rsrc *)zend_fetch_resource(Z_RES_P(zip_entry), le_zip_entry_name, le_zip_entry)) == NULL) {
  1140. RETURN_FALSE;
  1141. }
  1142. if (!zr_rsrc->zf) {
  1143. RETURN_FALSE;
  1144. }
  1145. switch (opt) {
  1146. case 0:
  1147. RETURN_STRING((char *)zr_rsrc->sb.name);
  1148. break;
  1149. case 1:
  1150. RETURN_LONG((zend_long) (zr_rsrc->sb.comp_size));
  1151. break;
  1152. case 2:
  1153. RETURN_LONG((zend_long) (zr_rsrc->sb.size));
  1154. break;
  1155. case 3:
  1156. switch (zr_rsrc->sb.comp_method) {
  1157. case 0:
  1158. RETURN_STRING("stored");
  1159. break;
  1160. case 1:
  1161. RETURN_STRING("shrunk");
  1162. break;
  1163. case 2:
  1164. case 3:
  1165. case 4:
  1166. case 5:
  1167. RETURN_STRING("reduced");
  1168. break;
  1169. case 6:
  1170. RETURN_STRING("imploded");
  1171. break;
  1172. case 7:
  1173. RETURN_STRING("tokenized");
  1174. break;
  1175. case 8:
  1176. RETURN_STRING("deflated");
  1177. break;
  1178. case 9:
  1179. RETURN_STRING("deflatedX");
  1180. break;
  1181. case 10:
  1182. RETURN_STRING("implodedX");
  1183. break;
  1184. default:
  1185. RETURN_FALSE;
  1186. }
  1187. RETURN_LONG((zend_long) (zr_rsrc->sb.comp_method));
  1188. break;
  1189. }
  1190. }
  1191. /* }}} */
  1192. /* {{{ proto string zip_entry_name(resource zip_entry)
  1193. Return the name given a ZZip entry */
  1194. static PHP_NAMED_FUNCTION(zif_zip_entry_name)
  1195. {
  1196. php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  1197. }
  1198. /* }}} */
  1199. /* {{{ proto int zip_entry_compressedsize(resource zip_entry)
  1200. Return the compressed size of a ZZip entry */
  1201. static PHP_NAMED_FUNCTION(zif_zip_entry_compressedsize)
  1202. {
  1203. php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
  1204. }
  1205. /* }}} */
  1206. /* {{{ proto int zip_entry_filesize(resource zip_entry)
  1207. Return the actual filesize of a ZZip entry */
  1208. static PHP_NAMED_FUNCTION(zif_zip_entry_filesize)
  1209. {
  1210. php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
  1211. }
  1212. /* }}} */
  1213. /* {{{ proto string zip_entry_compressionmethod(resource zip_entry)
  1214. Return a string containing the compression method used on a particular entry */
  1215. static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod)
  1216. {
  1217. php_zip_entry_get_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3);
  1218. }
  1219. /* }}} */
  1220. /* {{{ proto mixed ZipArchive::open(string source [, int flags])
  1221. Create new zip using source uri for output, return TRUE on success or the error code */
  1222. static ZIPARCHIVE_METHOD(open)
  1223. {
  1224. struct zip *intern;
  1225. int err = 0;
  1226. zend_long flags = 0;
  1227. char *resolved_path;
  1228. zend_string *filename;
  1229. zval *self = getThis();
  1230. ze_zip_object *ze_obj = NULL;
  1231. if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &filename, &flags) == FAILURE) {
  1232. return;
  1233. }
  1234. if (self) {
  1235. /* We do not use ZIP_FROM_OBJECT, zip init function here */
  1236. ze_obj = Z_ZIP_P(self);
  1237. }
  1238. if (ZSTR_LEN(filename) == 0) {
  1239. php_error_docref(NULL, E_WARNING, "Empty string as source");
  1240. RETURN_FALSE;
  1241. }
  1242. if (ZIP_OPENBASEDIR_CHECKPATH(ZSTR_VAL(filename))) {
  1243. RETURN_FALSE;
  1244. }
  1245. if (!(resolved_path = expand_filepath(ZSTR_VAL(filename), NULL))) {
  1246. RETURN_FALSE;
  1247. }
  1248. if (ze_obj->za) {
  1249. /* we already have an opened zip, free it */
  1250. if (zip_close(ze_obj->za) != 0) {
  1251. php_error_docref(NULL, E_WARNING, "Empty string as source");
  1252. efree(resolved_path);
  1253. RETURN_FALSE;
  1254. }
  1255. ze_obj->za = NULL;
  1256. }
  1257. if (ze_obj->filename) {
  1258. efree(ze_obj->filename);
  1259. ze_obj->filename = NULL;
  1260. }
  1261. #if LIBZIP_VERSION_MAJOR > 1 || LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR >= 6
  1262. /* reduce BC break introduce in libzip 1.6.0
  1263. "Do not accept empty files as valid zip archives any longer" */
  1264. /* open for write without option to empty the archive */
  1265. if ((flags & (ZIP_TRUNCATE | ZIP_RDONLY)) == 0) {
  1266. zend_stat_t st;
  1267. /* exists and is empty */
  1268. if (VCWD_STAT(resolved_path, &st) == 0 && st.st_size == 0) {
  1269. flags |= ZIP_TRUNCATE;
  1270. }
  1271. }
  1272. #endif
  1273. intern = zip_open(resolved_path, flags, &err);
  1274. if (!intern || err) {
  1275. efree(resolved_path);
  1276. RETURN_LONG((zend_long)err);
  1277. }
  1278. ze_obj->filename = resolved_path;
  1279. ze_obj->filename_len = strlen(resolved_path);
  1280. ze_obj->za = intern;
  1281. RETURN_TRUE;
  1282. }
  1283. /* }}} */
  1284. /* {{{ proto resource ZipArchive::setPassword(string password)
  1285. Set the password for the active archive */
  1286. static ZIPARCHIVE_METHOD(setPassword)
  1287. {
  1288. struct zip *intern;
  1289. zval *self = getThis();
  1290. char *password;
  1291. size_t password_len;
  1292. if (!self) {
  1293. RETURN_FALSE;
  1294. }
  1295. ZIP_FROM_OBJECT(intern, self);
  1296. if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &password, &password_len) == FAILURE) {
  1297. return;
  1298. }
  1299. if (password_len < 1) {
  1300. RETURN_FALSE;
  1301. } else {
  1302. int res = zip_set_default_password(intern, (const char *)password);
  1303. if (res == 0) {
  1304. RETURN_TRUE;
  1305. } else {
  1306. RETURN_FALSE;
  1307. }
  1308. }
  1309. }
  1310. /* }}} */
  1311. /* {{{ proto bool ZipArchive::close()
  1312. close the zip archive */
  1313. static ZIPARCHIVE_METHOD(close)
  1314. {
  1315. struct zip *intern;
  1316. zval *self = getThis();
  1317. ze_zip_object *ze_obj;
  1318. int err;
  1319. if (!self) {
  1320. RETURN_FALSE;
  1321. }
  1322. ZIP_FROM_OBJECT(intern, self);
  1323. ze_obj = Z_ZIP_P(self);
  1324. if ((err = zip_close(intern))) {
  1325. #if LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR == 3 && LIBZIP_VERSION_MICRO == 1
  1326. php_error_docref(NULL, E_WARNING, "%s", "zip_close have failed");
  1327. #else
  1328. php_error_docref(NULL, E_WARNING, "%s", zip_strerror(intern));
  1329. zip_discard(intern);
  1330. #endif
  1331. }
  1332. efree(ze_obj->filename);
  1333. ze_obj->filename = NULL;
  1334. ze_obj->filename_len = 0;
  1335. ze_obj->za = NULL;
  1336. if (!err) {
  1337. RETURN_TRUE;
  1338. } else {
  1339. RETURN_FALSE;
  1340. }
  1341. }
  1342. /* }}} */
  1343. /* {{{ proto bool ZipArchive::count()
  1344. close the zip archive */
  1345. static ZIPARCHIVE_METHOD(count)
  1346. {
  1347. struct zip *intern;
  1348. zval *self = getThis();
  1349. if (!self) {
  1350. RETURN_FALSE;
  1351. }
  1352. ZIP_FROM_OBJECT(intern, self);
  1353. RETVAL_LONG(zip_get_num_files(intern));
  1354. }
  1355. /* }}} */
  1356. /* {{{ proto string ZipArchive::getStatusString()
  1357. * Returns the status error message, system and/or zip messages */
  1358. static ZIPARCHIVE_METHOD(getStatusString)
  1359. {
  1360. struct zip *intern;
  1361. zval *self = getThis();
  1362. #if LIBZIP_VERSION_MAJOR < 1
  1363. int zep, syp, len;
  1364. char error_string[128];
  1365. #else
  1366. zip_error_t *err;
  1367. #endif
  1368. if (!self) {
  1369. RETURN_FALSE;
  1370. }
  1371. ZIP_FROM_OBJECT(intern, self);
  1372. #if LIBZIP_VERSION_MAJOR < 1
  1373. zip_error_get(intern, &zep, &syp);
  1374. len = zip_error_to_str(error_string, 128, zep, syp);
  1375. RETVAL_STRINGL(error_string, len);
  1376. #else
  1377. err = zip_get_error(intern);
  1378. RETVAL_STRING(zip_error_strerror(err));
  1379. zip_error_fini(err);
  1380. #endif
  1381. }
  1382. /* }}} */
  1383. /* {{{ proto bool ZipArchive::createEmptyDir(string dirname)
  1384. Returns the index of the entry named filename in the archive */
  1385. static ZIPARCHIVE_METHOD(addEmptyDir)
  1386. {
  1387. struct zip *intern;
  1388. zval *self = getThis();
  1389. char *dirname;
  1390. size_t dirname_len;
  1391. int idx;
  1392. struct zip_stat sb;
  1393. char *s;
  1394. if (!self) {
  1395. RETURN_FALSE;
  1396. }
  1397. ZIP_FROM_OBJECT(intern, self);
  1398. if (zend_parse_parameters(ZEND_NUM_ARGS(), "s",
  1399. &dirname, &dirname_len) == FAILURE) {
  1400. return;
  1401. }
  1402. if (dirname_len<1) {
  1403. RETURN_FALSE;
  1404. }
  1405. if (dirname[dirname_len-1] != '/') {
  1406. s=(char *)safe_emalloc(dirname_len, 1, 2);
  1407. strcpy(s, dirname);
  1408. s[dirname_len] = '/';
  1409. s[dirname_len+1] = '\0';
  1410. } else {
  1411. s = dirname;
  1412. }
  1413. idx = zip_stat(intern, s, 0, &sb);
  1414. if (idx >= 0) {
  1415. RETVAL_FALSE;
  1416. } else {
  1417. if (zip_add_dir(intern, (const char *)s) == -1) {
  1418. RETVAL_FALSE;
  1419. }
  1420. zip_error_clear(intern);
  1421. RETVAL_TRUE;
  1422. }
  1423. if (s != dirname) {
  1424. efree(s);
  1425. }
  1426. }
  1427. /* }}} */
  1428. static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
  1429. {
  1430. struct zip *intern;
  1431. zval *self = getThis();
  1432. char *path = ".";
  1433. char *remove_path = NULL, *save_remove_path;
  1434. char *add_path = NULL;
  1435. size_t add_path_len, remove_path_len = 0, path_len = 1;
  1436. zend_long remove_all_path = 0;
  1437. zend_long flags = 0;
  1438. zval *options = NULL;
  1439. int found;
  1440. zend_string *pattern;
  1441. if (!self) {
  1442. RETURN_FALSE;
  1443. }
  1444. ZIP_FROM_OBJECT(intern, self);
  1445. /* 1 == glob, 2 == pcre */
  1446. if (type == 1) {
  1447. if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|la",
  1448. &pattern, &flags, &options) == FAILURE) {
  1449. return;
  1450. }
  1451. } else {
  1452. if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|sa",
  1453. &pattern, &path, &path_len, &options) == FAILURE) {
  1454. return;
  1455. }
  1456. }
  1457. if (ZSTR_LEN(pattern) == 0) {
  1458. php_error_docref(NULL, E_NOTICE, "Empty string as pattern");
  1459. RETURN_FALSE;
  1460. }
  1461. if (options && (php_zip_parse_options(options, &remove_all_path, &remove_path, &remove_path_len,
  1462. &add_path, &add_path_len) < 0)) {
  1463. RETURN_FALSE;
  1464. }
  1465. save_remove_path = remove_path;
  1466. if (remove_path && remove_path_len > 1) {
  1467. size_t real_len = strlen(remove_path);
  1468. if ((real_len > 1) && ((remove_path[real_len - 1] == '/') || (remove_path[real_len - 1] == '\\'))) {
  1469. remove_path = estrndup(remove_path, real_len - 1);
  1470. }
  1471. }
  1472. if (type == 1) {
  1473. found = php_zip_glob(ZSTR_VAL(pattern), ZSTR_LEN(pattern), flags, return_value);
  1474. } else {
  1475. found = php_zip_pcre(pattern, path, path_len, return_value);
  1476. }
  1477. if (found > 0) {
  1478. int i;
  1479. zval *zval_file;
  1480. for (i = 0; i < found; i++) {
  1481. char *file_stripped, *entry_name;
  1482. size_t entry_name_len, file_stripped_len;
  1483. char entry_name_buf[MAXPATHLEN];
  1484. zend_string *basename = NULL;
  1485. if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(return_value), i)) != NULL) {
  1486. if (remove_all_path) {
  1487. basename = php_basename(Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), NULL, 0);
  1488. file_stripped = ZSTR_VAL(basename);
  1489. file_stripped_len = ZSTR_LEN(basename);
  1490. } else if (remove_path && strstr(Z_STRVAL_P(zval_file), remove_path) != NULL) {
  1491. file_stripped = Z_STRVAL_P(zval_file) + remove_path_len + 1;
  1492. file_stripped_len = Z_STRLEN_P(zval_file) - remove_path_len - 1;
  1493. } else {
  1494. file_stripped = Z_STRVAL_P(zval_file);
  1495. file_stripped_len = Z_STRLEN_P(zval_file);
  1496. }
  1497. if (add_path) {
  1498. if ((add_path_len + file_stripped_len) > MAXPATHLEN) {
  1499. php_error_docref(NULL, E_WARNING, "Entry name too long (max: %d, %zd given)",
  1500. MAXPATHLEN - 1, (add_path_len + file_stripped_len));
  1501. zend_array_destroy(Z_ARR_P(return_value));
  1502. RETURN_FALSE;
  1503. }
  1504. snprintf(entry_name_buf, MAXPATHLEN, "%s%s", add_path, file_stripped);
  1505. } else {
  1506. snprintf(entry_name_buf, MAXPATHLEN, "%s", file_stripped);
  1507. }
  1508. entry_name = entry_name_buf;
  1509. entry_name_len = strlen(entry_name);
  1510. if (basename) {
  1511. zend_string_release_ex(basename, 0);
  1512. basename = NULL;
  1513. }
  1514. if (php_zip_add_file(intern, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file),
  1515. entry_name, entry_name_len, 0, 0) < 0) {
  1516. zend_array_destroy(Z_ARR_P(return_value));
  1517. RETURN_FALSE;
  1518. }
  1519. }
  1520. }
  1521. }
  1522. if (remove_path != save_remove_path) {
  1523. efree(remove_path);
  1524. }
  1525. }
  1526. /* }}} */
  1527. /* {{{ proto bool ZipArchive::addGlob(string pattern[,int flags [, array options]])
  1528. Add files matching the glob pattern. See php's glob for the pattern syntax. */
  1529. static ZIPARCHIVE_METHOD(addGlob)
  1530. {
  1531. php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
  1532. }
  1533. /* }}} */
  1534. /* {{{ proto bool ZipArchive::addPattern(string pattern[, string path [, array options]])
  1535. Add files matching the pcre pattern. See php's pcre for the pattern syntax. */
  1536. static ZIPARCHIVE_METHOD(addPattern)
  1537. {
  1538. php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
  1539. }
  1540. /* }}} */
  1541. /* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length]]])
  1542. Add a file in a Zip archive using its path and the name to use. */
  1543. static ZIPARCHIVE_METHOD(addFile)
  1544. {
  1545. struct zip *intern;
  1546. zval *self = getThis();
  1547. char *entry_name = NULL;
  1548. size_t entry_name_len = 0;
  1549. zend_long offset_start = 0, offset_len = 0;
  1550. zend_string *filename;
  1551. if (!self) {
  1552. RETURN_FALSE;
  1553. }
  1554. ZIP_FROM_OBJECT(intern, self);
  1555. if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|sll",
  1556. &filename, &entry_name, &entry_name_len, &offset_start, &offset_len) == FAILURE) {
  1557. return;
  1558. }
  1559. if (ZSTR_LEN(filename) == 0) {
  1560. php_error_docref(NULL, E_NOTICE, "Empty string as filename");
  1561. RETURN_FALSE;
  1562. }
  1563. if (entry_name_len == 0) {
  1564. entry_name = ZSTR_VAL(filename);
  1565. entry_name_len = ZSTR_LEN(filename);
  1566. }
  1567. if (php_zip_add_file(intern, ZSTR_VAL(filename), ZSTR_LEN(filename),
  1568. entry_name, entry_name_len, offset_start, offset_len) < 0) {
  1569. RETURN_FALSE;
  1570. } else {
  1571. RETURN_TRUE;
  1572. }
  1573. }
  1574. /* }}} */
  1575. /* {{{ proto bool ZipArchive::addFromString(string name, string content)
  1576. Add a file using content and the entry name */
  1577. static ZIPARCHIVE_METHOD(addFromString)
  1578. {
  1579. struct zip *intern;
  1580. zval *self = getThis();
  1581. zend_string *buffer;
  1582. char *name;
  1583. size_t name_len;
  1584. ze_zip_object *ze_obj;
  1585. struct zip_source *zs;
  1586. int pos = 0;
  1587. int cur_idx;
  1588. if (!self) {
  1589. RETURN_FALSE;
  1590. }
  1591. ZIP_FROM_OBJECT(intern, self);
  1592. if (zend_parse_parameters(ZEND_NUM_ARGS(), "sS",
  1593. &name, &name_len, &buffer) == FAILURE) {
  1594. return;
  1595. }
  1596. ze_obj = Z_ZIP_P(self);
  1597. if (ze_obj->buffers_cnt) {
  1598. ze_obj->buffers = (char **)safe_erealloc(ze_obj->buffers, sizeof(char *), (ze_obj->buffers_cnt+1), 0);
  1599. pos = ze_obj->buffers_cnt++;
  1600. } else {
  1601. ze_obj->buffers = (char **)emalloc(sizeof(char *));
  1602. ze_obj->buffers_cnt++;
  1603. pos = 0;
  1604. }
  1605. ze_obj->buffers[pos] = (char *)safe_emalloc(ZSTR_LEN(buffer), 1, 1);
  1606. memcpy(ze_obj->buffers[pos], ZSTR_VAL(buffer), ZSTR_LEN(buffer) + 1);
  1607. zs = zip_source_buffer(intern, ze_obj->buffers[pos], ZSTR_LEN(buffer), 0);
  1608. if (zs == NULL) {
  1609. RETURN_FALSE;
  1610. }
  1611. cur_idx = zip_name_locate(intern, (const char *)name, 0);
  1612. /* TODO: fix _zip_replace */
  1613. if (cur_idx >= 0) {
  1614. if (zip_delete(intern, cur_idx) == -1) {
  1615. zip_source_free(zs);
  1616. RETURN_FALSE;
  1617. }
  1618. }
  1619. if (zip_add(intern, name, zs) == -1) {
  1620. zip_source_free(zs);
  1621. RETURN_FALSE;
  1622. } else {
  1623. zip_error_clear(intern);
  1624. RETURN_TRUE;
  1625. }
  1626. }
  1627. /* }}} */
  1628. /* {{{ proto array ZipArchive::statName(string filename[, int flags])
  1629. Returns the information about a the zip entry filename */
  1630. static ZIPARCHIVE_METHOD(statName)
  1631. {
  1632. struct zip *intern;
  1633. zval *self = getThis();
  1634. zend_long flags = 0;
  1635. struct zip_stat sb;
  1636. zend_string *name;
  1637. if (!self) {
  1638. RETURN_FALSE;
  1639. }
  1640. ZIP_FROM_OBJECT(intern, self);
  1641. if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &name, &flags) == FAILURE) {
  1642. return;
  1643. }
  1644. PHP_ZIP_STAT_PATH(intern, ZSTR_VAL(name), ZSTR_LEN(name), flags, sb);
  1645. RETURN_SB(&sb);
  1646. }
  1647. /* }}} */
  1648. /* {{{ proto resource ZipArchive::statIndex(int index[, int flags])
  1649. Returns the zip entry informations using its index */
  1650. static ZIPARCHIVE_METHOD(statIndex)
  1651. {
  1652. struct zip *intern;
  1653. zval *self = getThis();
  1654. zend_long index, flags = 0;
  1655. struct zip_stat sb;
  1656. if (!self) {
  1657. RETURN_FALSE;
  1658. }
  1659. ZIP_FROM_OBJECT(intern, self);
  1660. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l",
  1661. &index, &flags) == FAILURE) {
  1662. return;
  1663. }
  1664. if (zip_stat_index(intern, index, flags, &sb) != 0) {
  1665. RETURN_FALSE;
  1666. }
  1667. RETURN_SB(&sb);
  1668. }
  1669. /* }}} */
  1670. /* {{{ proto int ZipArchive::locateName(string filename[, int flags])
  1671. Returns the index of the entry named filename in the archive */
  1672. static ZIPARCHIVE_METHOD(locateName)
  1673. {
  1674. struct zip *intern;
  1675. zval *self = getThis();
  1676. zend_long flags = 0;
  1677. zend_long idx = -1;
  1678. zend_string *name;
  1679. if (!self) {
  1680. RETURN_FALSE;
  1681. }
  1682. ZIP_FROM_OBJECT(intern, self);
  1683. if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &name, &flags) == FAILURE) {
  1684. return;
  1685. }
  1686. if (ZSTR_LEN(name) < 1) {
  1687. RETURN_FALSE;
  1688. }
  1689. idx = (zend_long)zip_name_locate(intern, (const char *)ZSTR_VAL(name), flags);
  1690. if (idx >= 0) {
  1691. RETURN_LONG(idx);
  1692. } else {
  1693. RETURN_FALSE;
  1694. }
  1695. }
  1696. /* }}} */
  1697. /* {{{ proto string ZipArchive::getNameIndex(int index [, int flags])
  1698. Returns the name of the file at position index */
  1699. static ZIPARCHIVE_METHOD(getNameIndex)
  1700. {
  1701. struct zip *intern;
  1702. zval *self = getThis();
  1703. const char *name;
  1704. zend_long flags = 0, index = 0;
  1705. if (!self) {
  1706. RETURN_FALSE;
  1707. }
  1708. ZIP_FROM_OBJECT(intern, self);
  1709. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l",
  1710. &index, &flags) == FAILURE) {
  1711. return;
  1712. }
  1713. name = zip_get_name(intern, (int) index, flags);
  1714. if (name) {
  1715. RETVAL_STRING((char *)name);
  1716. } else {
  1717. RETURN_FALSE;
  1718. }
  1719. }
  1720. /* }}} */
  1721. /* {{{ proto bool ZipArchive::setArchiveComment(string comment)
  1722. Set or remove (NULL/'') the comment of the archive */
  1723. static ZIPARCHIVE_METHOD(setArchiveComment)
  1724. {
  1725. struct zip *intern;
  1726. zval *self = getThis();
  1727. size_t comment_len;
  1728. char * comment;
  1729. if (!self) {
  1730. RETURN_FALSE;
  1731. }
  1732. ZIP_FROM_OBJECT(intern, self);
  1733. if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &comment, &comment_len) == FAILURE) {
  1734. return;
  1735. }
  1736. if (zip_set_archive_comment(intern, (const char *)comment, (int)comment_len)) {
  1737. RETURN_FALSE;
  1738. } else {
  1739. RETURN_TRUE;
  1740. }
  1741. }
  1742. /* }}} */
  1743. /* {{{ proto string ZipArchive::getArchiveComment([int flags])
  1744. Returns the comment of an entry using its index */
  1745. static ZIPARCHIVE_METHOD(getArchiveComment)
  1746. {
  1747. struct zip *intern;
  1748. zval *self = getThis();
  1749. zend_long flags = 0;
  1750. const char * comment;
  1751. int comment_len = 0;
  1752. if (!self) {
  1753. RETURN_FALSE;
  1754. }
  1755. ZIP_FROM_OBJECT(intern, self);
  1756. if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &flags) == FAILURE) {
  1757. return;
  1758. }
  1759. comment = zip_get_archive_comment(intern, &comment_len, (int)flags);
  1760. if(comment==NULL) {
  1761. RETURN_FALSE;
  1762. }
  1763. RETURN_STRINGL((char *)comment, (zend_long)comment_len);
  1764. }
  1765. /* }}} */
  1766. /* {{{ proto bool ZipArchive::setCommentName(string name, string comment)
  1767. Set or remove (NULL/'') the comment of an entry using its Name */
  1768. static ZIPARCHIVE_METHOD(setCommentName)
  1769. {
  1770. struct zip *intern;
  1771. zval *self = getThis();
  1772. size_t comment_len, name_len;
  1773. char * comment, *name;
  1774. int idx;
  1775. if (!self) {
  1776. RETURN_FALSE;
  1777. }
  1778. ZIP_FROM_OBJECT(intern, self);
  1779. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
  1780. &name, &name_len, &comment, &comment_len) == FAILURE) {
  1781. return;
  1782. }
  1783. if (name_len < 1) {
  1784. php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
  1785. }
  1786. idx = zip_name_locate(intern, name, 0);
  1787. if (idx < 0) {
  1788. RETURN_FALSE;
  1789. }
  1790. PHP_ZIP_SET_FILE_COMMENT(intern, idx, comment, comment_len);
  1791. }
  1792. /* }}} */
  1793. /* {{{ proto bool ZipArchive::setCommentIndex(int index, string comment)
  1794. Set or remove (NULL/'') the comment of an entry using its index */
  1795. static ZIPARCHIVE_METHOD(setCommentIndex)
  1796. {
  1797. struct zip *intern;
  1798. zval *self = getThis();
  1799. zend_long index;
  1800. size_t comment_len;
  1801. char * comment;
  1802. struct zip_stat sb;
  1803. if (!self) {
  1804. RETURN_FALSE;
  1805. }
  1806. ZIP_FROM_OBJECT(intern, self);
  1807. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls",
  1808. &index, &comment, &comment_len) == FAILURE) {
  1809. return;
  1810. }
  1811. PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
  1812. PHP_ZIP_SET_FILE_COMMENT(intern, index, comment, comment_len);
  1813. }
  1814. /* }}} */
  1815. /* those constants/functions are only available in libzip since 0.11.2 */
  1816. #ifdef ZIP_OPSYS_DEFAULT
  1817. /* {{{ proto bool ZipArchive::setExternalAttributesName(string name, int opsys, int attr [, int flags])
  1818. Set external attributes for file in zip, using its name */
  1819. static ZIPARCHIVE_METHOD(setExternalAttributesName)
  1820. {
  1821. struct zip *intern;
  1822. zval *self = getThis();
  1823. size_t name_len;
  1824. char *name;
  1825. zend_long flags=0, opsys, attr;
  1826. zip_int64_t idx;
  1827. if (!self) {
  1828. RETURN_FALSE;
  1829. }
  1830. ZIP_FROM_OBJECT(intern, self);
  1831. if (zend_parse_parameters(ZEND_NUM_ARGS(), "sll|l",
  1832. &name, &name_len, &opsys, &attr, &flags) == FAILURE) {
  1833. return;
  1834. }
  1835. if (name_len < 1) {
  1836. php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
  1837. }
  1838. idx = zip_name_locate(intern, name, 0);
  1839. if (idx < 0) {
  1840. RETURN_FALSE;
  1841. }
  1842. if (zip_file_set_external_attributes(intern, idx, (zip_flags_t)flags,
  1843. (zip_uint8_t)(opsys&0xff), (zip_uint32_t)attr) < 0) {
  1844. RETURN_FALSE;
  1845. }
  1846. RETURN_TRUE;
  1847. }
  1848. /* }}} */
  1849. /* {{{ proto bool ZipArchive::setExternalAttributesIndex(int index, int opsys, int attr [, int flags])
  1850. Set external attributes for file in zip, using its index */
  1851. static ZIPARCHIVE_METHOD(setExternalAttributesIndex)
  1852. {
  1853. struct zip *intern;
  1854. zval *self = getThis();
  1855. zend_long index, flags=0, opsys, attr;
  1856. struct zip_stat sb;
  1857. if (!self) {
  1858. RETURN_FALSE;
  1859. }
  1860. ZIP_FROM_OBJECT(intern, self);
  1861. if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll|l",
  1862. &index, &opsys, &attr, &flags) == FAILURE) {
  1863. return;
  1864. }
  1865. PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
  1866. if (zip_file_set_external_attributes(intern, (zip_uint64_t)index,
  1867. (zip_flags_t)flags, (zip_uint8_t)(opsys&0xff), (zip_uint32_t)attr) < 0) {
  1868. RETURN_FALSE;
  1869. }
  1870. RETURN_TRUE;
  1871. }
  1872. /* }}} */
  1873. /* {{{ proto bool ZipArchive::getExternalAttributesName(string name, int &opsys, int &attr [, int flags])
  1874. Get external attributes for file in zip, using its name */
  1875. static ZIPARCHIVE_METHOD(getExternalAttributesName)
  1876. {
  1877. struct zip *intern;
  1878. zval *self = getThis(), *z_opsys, *z_attr;
  1879. size_t name_len;
  1880. char *name;
  1881. zend_long flags=0;
  1882. zip_uint8_t opsys;
  1883. zip_uint32_t attr;
  1884. zip_int64_t idx;
  1885. if (!self) {
  1886. RETURN_FALSE;
  1887. }
  1888. ZIP_FROM_OBJECT(intern, self);
  1889. if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz/z/|l",
  1890. &name, &name_len, &z_opsys, &z_attr, &flags) == FAILURE) {
  1891. return;
  1892. }
  1893. if (name_len < 1) {
  1894. php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
  1895. }
  1896. idx = zip_name_locate(intern, name, 0);
  1897. if (idx < 0) {
  1898. RETURN_FALSE;
  1899. }
  1900. if (zip_file_get_external_attributes(intern, idx,
  1901. (zip_flags_t)flags, &opsys, &attr) < 0) {
  1902. RETURN_FALSE;
  1903. }
  1904. zval_ptr_dtor(z_opsys);
  1905. ZVAL_LONG(z_opsys, opsys);
  1906. zval_ptr_dtor(z_attr);
  1907. ZVAL_LONG(z_attr, attr);
  1908. RETURN_TRUE;
  1909. }
  1910. /* }}} */
  1911. /* {{{ proto bool ZipArchive::getExternalAttributesIndex(int index, int &opsys, int &attr [, int flags])
  1912. Get external attributes for file in zip, using its index */
  1913. static ZIPARCHIVE_METHOD(getExternalAttributesIndex)
  1914. {
  1915. struct zip *intern;
  1916. zval *self = getThis(), *z_opsys, *z_attr;
  1917. zend_long index, flags=0;
  1918. zip_uint8_t opsys;
  1919. zip_uint32_t attr;
  1920. struct zip_stat sb;
  1921. if (!self) {
  1922. RETURN_FALSE;
  1923. }
  1924. ZIP_FROM_OBJECT(intern, self);
  1925. if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz/z/|l",
  1926. &index, &z_opsys, &z_attr, &flags) == FAILURE) {
  1927. return;
  1928. }
  1929. PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
  1930. if (zip_file_get_external_attributes(intern, (zip_uint64_t)index,
  1931. (zip_flags_t)flags, &opsys, &attr) < 0) {
  1932. RETURN_FALSE;
  1933. }
  1934. zval_ptr_dtor(z_opsys);
  1935. ZVAL_LONG(z_opsys, opsys);
  1936. zval_ptr_dtor(z_attr);
  1937. ZVAL_LONG(z_attr, attr);
  1938. RETURN_TRUE;
  1939. }
  1940. /* }}} */
  1941. #endif /* ifdef ZIP_OPSYS_DEFAULT */
  1942. #ifdef HAVE_ENCRYPTION
  1943. /* {{{ proto bool ZipArchive::setEncryptionName(string name, int method, [string password])
  1944. Set encryption method for file in zip, using its name */
  1945. static ZIPARCHIVE_METHOD(setEncryptionName)
  1946. {
  1947. struct zip *intern;
  1948. zval *self = getThis();
  1949. zend_long method;
  1950. zip_int64_t idx;
  1951. char *name, *password = NULL;
  1952. size_t name_len, password_len;
  1953. if (!self) {
  1954. RETURN_FALSE;
  1955. }
  1956. ZIP_FROM_OBJECT(intern, self);
  1957. if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|s",
  1958. &name, &name_len, &method, &password, &password_len) == FAILURE) {
  1959. return;
  1960. }
  1961. if (name_len < 1) {
  1962. php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
  1963. }
  1964. idx = zip_name_locate(intern, name, 0);
  1965. if (idx < 0) {
  1966. RETURN_FALSE;
  1967. }
  1968. if (zip_file_set_encryption(intern, idx, (zip_uint16_t)method, password)) {
  1969. RETURN_FALSE;
  1970. }
  1971. RETURN_TRUE;
  1972. }
  1973. /* }}} */
  1974. /* {{{ proto bool ZipArchive::setEncryptionIndex(int index, int method, [string password])
  1975. Set encryption method for file in zip, using its index */
  1976. static ZIPARCHIVE_METHOD(setEncryptionIndex)
  1977. {
  1978. struct zip *intern;
  1979. zval *self = getThis();
  1980. zend_long index, method;
  1981. char *password = NULL;
  1982. size_t password_len;
  1983. if (!self) {
  1984. RETURN_FALSE;
  1985. }
  1986. ZIP_FROM_OBJECT(intern, self);
  1987. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|s",
  1988. &index, &method, &password, &password_len) == FAILURE) {
  1989. return;
  1990. }
  1991. if (zip_file_set_encryption(intern, index, (zip_uint16_t)method, password)) {
  1992. RETURN_FALSE;
  1993. }
  1994. RETURN_TRUE;
  1995. }
  1996. /* }}} */
  1997. #endif
  1998. /* {{{ proto string ZipArchive::getCommentName(string name[, int flags])
  1999. Returns the comment of an entry using its name */
  2000. static ZIPARCHIVE_METHOD(getCommentName)
  2001. {
  2002. struct zip *intern;
  2003. zval *self = getThis();
  2004. size_t name_len;
  2005. int idx;
  2006. zend_long flags = 0;
  2007. int comment_len = 0;
  2008. const char * comment;
  2009. char *name;
  2010. if (!self) {
  2011. RETURN_FALSE;
  2012. }
  2013. ZIP_FROM_OBJECT(intern, self);
  2014. if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l",
  2015. &name, &name_len, &flags) == FAILURE) {
  2016. return;
  2017. }
  2018. if (name_len < 1) {
  2019. php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
  2020. RETURN_FALSE;
  2021. }
  2022. idx = zip_name_locate(intern, name, 0);
  2023. if (idx < 0) {
  2024. RETURN_FALSE;
  2025. }
  2026. comment = zip_get_file_comment(intern, idx, &comment_len, (int)flags);
  2027. RETURN_STRINGL((char *)comment, (zend_long)comment_len);
  2028. }
  2029. /* }}} */
  2030. /* {{{ proto string ZipArchive::getCommentIndex(int index[, int flags])
  2031. Returns the comment of an entry using its index */
  2032. static ZIPARCHIVE_METHOD(getCommentIndex)
  2033. {
  2034. struct zip *intern;
  2035. zval *self = getThis();
  2036. zend_long index, flags = 0;
  2037. const char * comment;
  2038. int comment_len = 0;
  2039. struct zip_stat sb;
  2040. if (!self) {
  2041. RETURN_FALSE;
  2042. }
  2043. ZIP_FROM_OBJECT(intern, self);
  2044. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l",
  2045. &index, &flags) == FAILURE) {
  2046. return;
  2047. }
  2048. PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
  2049. comment = zip_get_file_comment(intern, index, &comment_len, (int)flags);
  2050. RETURN_STRINGL((char *)comment, (zend_long)comment_len);
  2051. }
  2052. /* }}} */
  2053. /* {{{ proto bool ZipArchive::setCompressionName(string name, int comp_method[, int comp_flags])
  2054. Set the compression of a file in zip, using its name */
  2055. static ZIPARCHIVE_METHOD(setCompressionName)
  2056. {
  2057. struct zip *intern;
  2058. zval *this = getThis();
  2059. size_t name_len;
  2060. char *name;
  2061. zip_int64_t idx;
  2062. zend_long comp_method, comp_flags = 0;
  2063. if (!this) {
  2064. RETURN_FALSE;
  2065. }
  2066. ZIP_FROM_OBJECT(intern, this);
  2067. if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|l",
  2068. &name, &name_len, &comp_method, &comp_flags) == FAILURE) {
  2069. return;
  2070. }
  2071. if (name_len < 1) {
  2072. php_error_docref(NULL, E_NOTICE, "Empty string as entry name");
  2073. }
  2074. idx = zip_name_locate(intern, name, 0);
  2075. if (idx < 0) {
  2076. RETURN_FALSE;
  2077. }
  2078. if (zip_set_file_compression(intern, (zip_uint64_t)idx,
  2079. (zip_int32_t)comp_method, (zip_uint32_t)comp_flags) != 0) {
  2080. RETURN_FALSE;
  2081. }
  2082. RETURN_TRUE;
  2083. }
  2084. /* }}} */
  2085. /* {{{ proto bool ZipArchive::setCompressionIndex(int index, int comp_method[, int comp_flags])
  2086. Set the compression of a file in zip, using its index */
  2087. static ZIPARCHIVE_METHOD(setCompressionIndex)
  2088. {
  2089. struct zip *intern;
  2090. zval *this = getThis();
  2091. zend_long index;
  2092. zend_long comp_method, comp_flags = 0;
  2093. if (!this) {
  2094. RETURN_FALSE;
  2095. }
  2096. ZIP_FROM_OBJECT(intern, this);
  2097. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|l",
  2098. &index, &comp_method, &comp_flags) == FAILURE) {
  2099. return;
  2100. }
  2101. if (zip_set_file_compression(intern, (zip_uint64_t)index,
  2102. (zip_int32_t)comp_method, (zip_uint32_t)comp_flags) != 0) {
  2103. RETURN_FALSE;
  2104. }
  2105. RETURN_TRUE;
  2106. }
  2107. /* }}} */
  2108. /* {{{ proto bool ZipArchive::deleteIndex(int index)
  2109. Delete a file using its index */
  2110. static ZIPARCHIVE_METHOD(deleteIndex)
  2111. {
  2112. struct zip *intern;
  2113. zval *self = getThis();
  2114. zend_long index;
  2115. if (!self) {
  2116. RETURN_FALSE;
  2117. }
  2118. ZIP_FROM_OBJECT(intern, self);
  2119. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
  2120. return;
  2121. }
  2122. if (index < 0) {
  2123. RETURN_FALSE;
  2124. }
  2125. if (zip_delete(intern, index) < 0) {
  2126. RETURN_FALSE;
  2127. }
  2128. RETURN_TRUE;
  2129. }
  2130. /* }}} */
  2131. /* {{{ proto bool ZipArchive::deleteName(string name)
  2132. Delete a file using its index */
  2133. static ZIPARCHIVE_METHOD(deleteName)
  2134. {
  2135. struct zip *intern;
  2136. zval *self = getThis();
  2137. size_t name_len;
  2138. char *name;
  2139. struct zip_stat sb;
  2140. if (!self) {
  2141. RETURN_FALSE;
  2142. }
  2143. ZIP_FROM_OBJECT(intern, self);
  2144. if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
  2145. return;
  2146. }
  2147. if (name_len < 1) {
  2148. RETURN_FALSE;
  2149. }
  2150. PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
  2151. if (zip_delete(intern, sb.index)) {
  2152. RETURN_FALSE;
  2153. }
  2154. RETURN_TRUE;
  2155. }
  2156. /* }}} */
  2157. /* {{{ proto bool ZipArchive::renameIndex(int index, string new_name)
  2158. Rename an entry selected by its index to new_name */
  2159. static ZIPARCHIVE_METHOD(renameIndex)
  2160. {
  2161. struct zip *intern;
  2162. zval *self = getThis();
  2163. char *new_name;
  2164. size_t new_name_len;
  2165. zend_long index;
  2166. if (!self) {
  2167. RETURN_FALSE;
  2168. }
  2169. ZIP_FROM_OBJECT(intern, self);
  2170. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &index, &new_name, &new_name_len) == FAILURE) {
  2171. return;
  2172. }
  2173. if (index < 0) {
  2174. RETURN_FALSE;
  2175. }
  2176. if (new_name_len < 1) {
  2177. php_error_docref(NULL, E_NOTICE, "Empty string as new entry name");
  2178. RETURN_FALSE;
  2179. }
  2180. if (zip_rename(intern, index, (const char *)new_name) != 0) {
  2181. RETURN_FALSE;
  2182. }
  2183. RETURN_TRUE;
  2184. }
  2185. /* }}} */
  2186. /* {{{ proto bool ZipArchive::renameName(string name, string new_name)
  2187. Rename an entry selected by its name to new_name */
  2188. static ZIPARCHIVE_METHOD(renameName)
  2189. {
  2190. struct zip *intern;
  2191. zval *self = getThis();
  2192. struct zip_stat sb;
  2193. char *name, *new_name;
  2194. size_t name_len, new_name_len;
  2195. if (!self) {
  2196. RETURN_FALSE;
  2197. }
  2198. ZIP_FROM_OBJECT(intern, self);
  2199. if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &name, &name_len, &new_name, &new_name_len) == FAILURE) {
  2200. return;
  2201. }
  2202. if (new_name_len < 1) {
  2203. php_error_docref(NULL, E_NOTICE, "Empty string as new entry name");
  2204. RETURN_FALSE;
  2205. }
  2206. PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
  2207. if (zip_rename(intern, sb.index, (const char *)new_name)) {
  2208. RETURN_FALSE;
  2209. }
  2210. RETURN_TRUE;
  2211. }
  2212. /* }}} */
  2213. /* {{{ proto bool ZipArchive::unchangeIndex(int index)
  2214. Changes to the file at position index are reverted */
  2215. static ZIPARCHIVE_METHOD(unchangeIndex)
  2216. {
  2217. struct zip *intern;
  2218. zval *self = getThis();
  2219. zend_long index;
  2220. if (!self) {
  2221. RETURN_FALSE;
  2222. }
  2223. ZIP_FROM_OBJECT(intern, self);
  2224. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
  2225. return;
  2226. }
  2227. if (index < 0) {
  2228. RETURN_FALSE;
  2229. }
  2230. if (zip_unchange(intern, index) != 0) {
  2231. RETURN_FALSE;
  2232. } else {
  2233. RETURN_TRUE;
  2234. }
  2235. }
  2236. /* }}} */
  2237. /* {{{ proto bool ZipArchive::unchangeName(string name)
  2238. Changes to the file named 'name' are reverted */
  2239. static ZIPARCHIVE_METHOD(unchangeName)
  2240. {
  2241. struct zip *intern;
  2242. zval *self = getThis();
  2243. struct zip_stat sb;
  2244. char *name;
  2245. size_t name_len;
  2246. if (!self) {
  2247. RETURN_FALSE;
  2248. }
  2249. ZIP_FROM_OBJECT(intern, self);
  2250. if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
  2251. return;
  2252. }
  2253. if (name_len < 1) {
  2254. RETURN_FALSE;
  2255. }
  2256. PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb);
  2257. if (zip_unchange(intern, sb.index) != 0) {
  2258. RETURN_FALSE;
  2259. } else {
  2260. RETURN_TRUE;
  2261. }
  2262. }
  2263. /* }}} */
  2264. /* {{{ proto bool ZipArchive::unchangeAll()
  2265. All changes to files and global information in archive are reverted */
  2266. static ZIPARCHIVE_METHOD(unchangeAll)
  2267. {
  2268. struct zip *intern;
  2269. zval *self = getThis();
  2270. if (!self) {
  2271. RETURN_FALSE;
  2272. }
  2273. ZIP_FROM_OBJECT(intern, self);
  2274. if (zip_unchange_all(intern) != 0) {
  2275. RETURN_FALSE;
  2276. } else {
  2277. RETURN_TRUE;
  2278. }
  2279. }
  2280. /* }}} */
  2281. /* {{{ proto bool ZipArchive::unchangeArchive()
  2282. Revert all global changes to the archive archive. For now, this only reverts archive comment changes. */
  2283. static ZIPARCHIVE_METHOD(unchangeArchive)
  2284. {
  2285. struct zip *intern;
  2286. zval *self = getThis();
  2287. if (!self) {
  2288. RETURN_FALSE;
  2289. }
  2290. ZIP_FROM_OBJECT(intern, self);
  2291. if (zip_unchange_archive(intern) != 0) {
  2292. RETURN_FALSE;
  2293. } else {
  2294. RETURN_TRUE;
  2295. }
  2296. }
  2297. /* }}} */
  2298. /* {{{ proto bool ZipArchive::extractTo(string pathto[, mixed files])
  2299. Extract one or more file from a zip archive */
  2300. /* TODO:
  2301. * - allow index or array of indeces
  2302. * - replace path
  2303. * - patterns
  2304. */
  2305. static ZIPARCHIVE_METHOD(extractTo)
  2306. {
  2307. struct zip *intern;
  2308. zval *self = getThis();
  2309. zval *zval_files = NULL;
  2310. zval *zval_file = NULL;
  2311. php_stream_statbuf ssb;
  2312. char *pathto;
  2313. size_t pathto_len;
  2314. int ret, i;
  2315. int nelems;
  2316. if (!self) {
  2317. RETURN_FALSE;
  2318. }
  2319. if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|z", &pathto, &pathto_len, &zval_files) == FAILURE) {
  2320. return;
  2321. }
  2322. if (pathto_len < 1) {
  2323. RETURN_FALSE;
  2324. }
  2325. if (php_stream_stat_path_ex(pathto, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL) < 0) {
  2326. ret = php_stream_mkdir(pathto, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL);
  2327. if (!ret) {
  2328. RETURN_FALSE;
  2329. }
  2330. }
  2331. ZIP_FROM_OBJECT(intern, self);
  2332. if (zval_files && (Z_TYPE_P(zval_files) != IS_NULL)) {
  2333. switch (Z_TYPE_P(zval_files)) {
  2334. case IS_STRING:
  2335. if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_files), Z_STRLEN_P(zval_files))) {
  2336. RETURN_FALSE;
  2337. }
  2338. break;
  2339. case IS_ARRAY:
  2340. nelems = zend_hash_num_elements(Z_ARRVAL_P(zval_files));
  2341. if (nelems == 0 ) {
  2342. RETURN_FALSE;
  2343. }
  2344. for (i = 0; i < nelems; i++) {
  2345. if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(zval_files), i)) != NULL) {
  2346. switch (Z_TYPE_P(zval_file)) {
  2347. case IS_LONG:
  2348. break;
  2349. case IS_STRING:
  2350. if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file))) {
  2351. RETURN_FALSE;
  2352. }
  2353. break;
  2354. }
  2355. }
  2356. }
  2357. break;
  2358. case IS_LONG:
  2359. default:
  2360. php_error_docref(NULL, E_WARNING, "Invalid argument, expect string or array of strings");
  2361. break;
  2362. }
  2363. } else {
  2364. /* Extract all files */
  2365. int filecount = zip_get_num_files(intern);
  2366. if (filecount == -1) {
  2367. php_error_docref(NULL, E_WARNING, "Illegal archive");
  2368. RETURN_FALSE;
  2369. }
  2370. for (i = 0; i < filecount; i++) {
  2371. char *file = (char*)zip_get_name(intern, i, ZIP_FL_UNCHANGED);
  2372. if (!file || !php_zip_extract_file(intern, pathto, file, strlen(file))) {
  2373. RETURN_FALSE;
  2374. }
  2375. }
  2376. }
  2377. RETURN_TRUE;
  2378. }
  2379. /* }}} */
  2380. static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
  2381. {
  2382. struct zip *intern;
  2383. zval *self = getThis();
  2384. struct zip_stat sb;
  2385. struct zip_file *zf;
  2386. zend_long index = -1;
  2387. zend_long flags = 0;
  2388. zend_long len = 0;
  2389. zend_string *filename;
  2390. zend_string *buffer;
  2391. int n = 0;
  2392. if (!self) {
  2393. RETURN_FALSE;
  2394. }
  2395. ZIP_FROM_OBJECT(intern, self);
  2396. if (type == 1) {
  2397. if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|ll", &filename, &len, &flags) == FAILURE) {
  2398. return;
  2399. }
  2400. PHP_ZIP_STAT_PATH(intern, ZSTR_VAL(filename), ZSTR_LEN(filename), flags, sb);
  2401. } else {
  2402. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|ll", &index, &len, &flags) == FAILURE) {
  2403. return;
  2404. }
  2405. PHP_ZIP_STAT_INDEX(intern, index, 0, sb);
  2406. }
  2407. if (sb.size < 1) {
  2408. RETURN_EMPTY_STRING();
  2409. }
  2410. if (len < 1) {
  2411. len = sb.size;
  2412. }
  2413. if (index >= 0) {
  2414. zf = zip_fopen_index(intern, index, flags);
  2415. } else {
  2416. zf = zip_fopen(intern, ZSTR_VAL(filename), flags);
  2417. }
  2418. if (zf == NULL) {
  2419. RETURN_FALSE;
  2420. }
  2421. buffer = zend_string_safe_alloc(1, len, 0, 0);
  2422. n = zip_fread(zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer));
  2423. if (n < 1) {
  2424. zend_string_efree(buffer);
  2425. RETURN_EMPTY_STRING();
  2426. }
  2427. zip_fclose(zf);
  2428. ZSTR_VAL(buffer)[n] = '\0';
  2429. ZSTR_LEN(buffer) = n;
  2430. RETURN_NEW_STR(buffer);
  2431. }
  2432. /* }}} */
  2433. /* {{{ proto string ZipArchive::getFromName(string entryname[, int len [, int flags]])
  2434. get the contents of an entry using its name */
  2435. static ZIPARCHIVE_METHOD(getFromName)
  2436. {
  2437. php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
  2438. }
  2439. /* }}} */
  2440. /* {{{ proto string ZipArchive::getFromIndex(int index[, int len [, int flags]])
  2441. get the contents of an entry using its index */
  2442. static ZIPARCHIVE_METHOD(getFromIndex)
  2443. {
  2444. php_zip_get_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  2445. }
  2446. /* }}} */
  2447. /* {{{ proto resource ZipArchive::getStream(string entryname)
  2448. get a stream for an entry using its name */
  2449. static ZIPARCHIVE_METHOD(getStream)
  2450. {
  2451. struct zip *intern;
  2452. zval *self = getThis();
  2453. struct zip_stat sb;
  2454. char *mode = "rb";
  2455. zend_string *filename;
  2456. php_stream *stream;
  2457. ze_zip_object *obj;
  2458. if (!self) {
  2459. RETURN_FALSE;
  2460. }
  2461. ZIP_FROM_OBJECT(intern, self);
  2462. if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &filename) == FAILURE) {
  2463. return;
  2464. }
  2465. if (zip_stat(intern, ZSTR_VAL(filename), 0, &sb) != 0) {
  2466. RETURN_FALSE;
  2467. }
  2468. obj = Z_ZIP_P(self);
  2469. stream = php_stream_zip_open(obj->filename, ZSTR_VAL(filename), mode STREAMS_CC);
  2470. if (stream) {
  2471. php_stream_to_zval(stream, return_value);
  2472. } else {
  2473. RETURN_FALSE;
  2474. }
  2475. }
  2476. /* }}} */
  2477. /* {{{ arginfo */
  2478. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open, 0, 0, 1)
  2479. ZEND_ARG_INFO(0, filename)
  2480. ZEND_ARG_INFO(0, flags)
  2481. ZEND_END_ARG_INFO()
  2482. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setpassword, 0, 0, 1)
  2483. ZEND_ARG_INFO(0, password)
  2484. ZEND_END_ARG_INFO()
  2485. ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void, 0)
  2486. ZEND_END_ARG_INFO()
  2487. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addemptydir, 0, 0, 1)
  2488. ZEND_ARG_INFO(0, dirname)
  2489. ZEND_END_ARG_INFO()
  2490. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addglob, 0, 0, 1)
  2491. ZEND_ARG_INFO(0, pattern)
  2492. ZEND_ARG_INFO(0, flags)
  2493. ZEND_ARG_INFO(0, options)
  2494. ZEND_END_ARG_INFO()
  2495. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addpattern, 0, 0, 1)
  2496. ZEND_ARG_INFO(0, pattern)
  2497. ZEND_ARG_INFO(0, path)
  2498. ZEND_ARG_INFO(0, options)
  2499. ZEND_END_ARG_INFO()
  2500. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfile, 0, 0, 1)
  2501. ZEND_ARG_INFO(0, filepath)
  2502. ZEND_ARG_INFO(0, entryname)
  2503. ZEND_ARG_INFO(0, start)
  2504. ZEND_ARG_INFO(0, length)
  2505. ZEND_END_ARG_INFO()
  2506. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_addfromstring, 0, 0, 2)
  2507. ZEND_ARG_INFO(0, name)
  2508. ZEND_ARG_INFO(0, content)
  2509. ZEND_END_ARG_INFO()
  2510. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statname, 0, 0, 1)
  2511. ZEND_ARG_INFO(0, filename)
  2512. ZEND_ARG_INFO(0, flags)
  2513. ZEND_END_ARG_INFO()
  2514. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_statindex, 0, 0, 1)
  2515. ZEND_ARG_INFO(0, index)
  2516. ZEND_ARG_INFO(0, flags)
  2517. ZEND_END_ARG_INFO()
  2518. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setarchivecomment, 0, 0, 1)
  2519. ZEND_ARG_INFO(0, comment)
  2520. ZEND_END_ARG_INFO()
  2521. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentindex, 0, 0, 2)
  2522. ZEND_ARG_INFO(0, index)
  2523. ZEND_ARG_INFO(0, comment)
  2524. ZEND_END_ARG_INFO()
  2525. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentname, 0, 0, 1)
  2526. ZEND_ARG_INFO(0, name)
  2527. ZEND_ARG_INFO(0, flags)
  2528. ZEND_END_ARG_INFO()
  2529. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getcommentindex, 0, 0, 1)
  2530. ZEND_ARG_INFO(0, index)
  2531. ZEND_ARG_INFO(0, flags)
  2532. ZEND_END_ARG_INFO()
  2533. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renameindex, 0, 0, 2)
  2534. ZEND_ARG_INFO(0, index)
  2535. ZEND_ARG_INFO(0, new_name)
  2536. ZEND_END_ARG_INFO()
  2537. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_renamename, 0, 0, 2)
  2538. ZEND_ARG_INFO(0, name)
  2539. ZEND_ARG_INFO(0, new_name)
  2540. ZEND_END_ARG_INFO()
  2541. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangeindex, 0, 0, 1)
  2542. ZEND_ARG_INFO(0, index)
  2543. ZEND_END_ARG_INFO()
  2544. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_unchangename, 0, 0, 1)
  2545. ZEND_ARG_INFO(0, name)
  2546. ZEND_END_ARG_INFO()
  2547. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_extractto, 0, 0, 1)
  2548. ZEND_ARG_INFO(0, pathto)
  2549. ZEND_ARG_INFO(0, files)
  2550. ZEND_END_ARG_INFO()
  2551. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromname, 0, 0, 1)
  2552. ZEND_ARG_INFO(0, entryname)
  2553. ZEND_ARG_INFO(0, len)
  2554. ZEND_ARG_INFO(0, flags)
  2555. ZEND_END_ARG_INFO()
  2556. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getfromindex, 0, 0, 1)
  2557. ZEND_ARG_INFO(0, index)
  2558. ZEND_ARG_INFO(0, len)
  2559. ZEND_ARG_INFO(0, flags)
  2560. ZEND_END_ARG_INFO()
  2561. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getarchivecomment, 0, 0, 0)
  2562. ZEND_ARG_INFO(0, flags)
  2563. ZEND_END_ARG_INFO()
  2564. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcommentname, 0, 0, 2)
  2565. ZEND_ARG_INFO(0, name)
  2566. ZEND_ARG_INFO(0, comment)
  2567. ZEND_END_ARG_INFO()
  2568. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getstream, 0, 0, 1)
  2569. ZEND_ARG_INFO(0, entryname)
  2570. ZEND_END_ARG_INFO()
  2571. #ifdef ZIP_OPSYS_DEFAULT
  2572. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setextattrname, 0, 0, 3)
  2573. ZEND_ARG_INFO(0, name)
  2574. ZEND_ARG_INFO(0, opsys)
  2575. ZEND_ARG_INFO(0, attr)
  2576. ZEND_ARG_INFO(0, flags)
  2577. ZEND_END_ARG_INFO()
  2578. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setextattrindex, 0, 0, 3)
  2579. ZEND_ARG_INFO(0, index)
  2580. ZEND_ARG_INFO(0, opsys)
  2581. ZEND_ARG_INFO(0, attr)
  2582. ZEND_ARG_INFO(0, flags)
  2583. ZEND_END_ARG_INFO()
  2584. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getextattrname, 0, 0, 3)
  2585. ZEND_ARG_INFO(0, name)
  2586. ZEND_ARG_INFO(1, opsys)
  2587. ZEND_ARG_INFO(1, attr)
  2588. ZEND_ARG_INFO(0, flags)
  2589. ZEND_END_ARG_INFO()
  2590. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_getextattrindex, 0, 0, 3)
  2591. ZEND_ARG_INFO(0, index)
  2592. ZEND_ARG_INFO(1, opsys)
  2593. ZEND_ARG_INFO(1, attr)
  2594. ZEND_ARG_INFO(0, flags)
  2595. ZEND_END_ARG_INFO()
  2596. #endif /* ifdef ZIP_OPSYS_DEFAULT */
  2597. /* }}} */
  2598. #ifdef HAVE_ENCRYPTION
  2599. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setencryption_name, 0, 0, 2)
  2600. ZEND_ARG_INFO(0, name)
  2601. ZEND_ARG_INFO(0, method)
  2602. ZEND_ARG_INFO(0, password)
  2603. ZEND_END_ARG_INFO()
  2604. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setencryption_index, 0, 0, 2)
  2605. ZEND_ARG_INFO(0, index)
  2606. ZEND_ARG_INFO(0, method)
  2607. ZEND_ARG_INFO(0, password)
  2608. ZEND_END_ARG_INFO()
  2609. #endif
  2610. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcompname, 0, 0, 2)
  2611. ZEND_ARG_INFO(0, name)
  2612. ZEND_ARG_INFO(0, method)
  2613. ZEND_ARG_INFO(0, compflags)
  2614. ZEND_END_ARG_INFO()
  2615. ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setcompindex, 0, 0, 2)
  2616. ZEND_ARG_INFO(0, index)
  2617. ZEND_ARG_INFO(0, method)
  2618. ZEND_ARG_INFO(0, compflags)
  2619. ZEND_END_ARG_INFO()
  2620. /* {{{ ze_zip_object_class_functions */
  2621. static const zend_function_entry zip_class_functions[] = {
  2622. ZIPARCHIVE_ME(open, arginfo_ziparchive_open, ZEND_ACC_PUBLIC)
  2623. ZIPARCHIVE_ME(setPassword, arginfo_ziparchive_setpassword, ZEND_ACC_PUBLIC)
  2624. ZIPARCHIVE_ME(close, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
  2625. ZIPARCHIVE_ME(count, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
  2626. ZIPARCHIVE_ME(getStatusString, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
  2627. ZIPARCHIVE_ME(addEmptyDir, arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC)
  2628. ZIPARCHIVE_ME(addFromString, arginfo_ziparchive_addfromstring, ZEND_ACC_PUBLIC)
  2629. ZIPARCHIVE_ME(addFile, arginfo_ziparchive_addfile, ZEND_ACC_PUBLIC)
  2630. ZIPARCHIVE_ME(addGlob, arginfo_ziparchive_addglob, ZEND_ACC_PUBLIC)
  2631. ZIPARCHIVE_ME(addPattern, arginfo_ziparchive_addpattern, ZEND_ACC_PUBLIC)
  2632. ZIPARCHIVE_ME(renameIndex, arginfo_ziparchive_renameindex, ZEND_ACC_PUBLIC)
  2633. ZIPARCHIVE_ME(renameName, arginfo_ziparchive_renamename, ZEND_ACC_PUBLIC)
  2634. ZIPARCHIVE_ME(setArchiveComment, arginfo_ziparchive_setarchivecomment, ZEND_ACC_PUBLIC)
  2635. ZIPARCHIVE_ME(getArchiveComment, arginfo_ziparchive_getarchivecomment, ZEND_ACC_PUBLIC)
  2636. ZIPARCHIVE_ME(setCommentIndex, arginfo_ziparchive_setcommentindex, ZEND_ACC_PUBLIC)
  2637. ZIPARCHIVE_ME(setCommentName, arginfo_ziparchive_setcommentname, ZEND_ACC_PUBLIC)
  2638. ZIPARCHIVE_ME(getCommentIndex, arginfo_ziparchive_getcommentindex, ZEND_ACC_PUBLIC)
  2639. ZIPARCHIVE_ME(getCommentName, arginfo_ziparchive_getcommentname, ZEND_ACC_PUBLIC)
  2640. ZIPARCHIVE_ME(deleteIndex, arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
  2641. ZIPARCHIVE_ME(deleteName, arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
  2642. ZIPARCHIVE_ME(statName, arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
  2643. ZIPARCHIVE_ME(statIndex, arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
  2644. ZIPARCHIVE_ME(locateName, arginfo_ziparchive_statname, ZEND_ACC_PUBLIC)
  2645. ZIPARCHIVE_ME(getNameIndex, arginfo_ziparchive_statindex, ZEND_ACC_PUBLIC)
  2646. ZIPARCHIVE_ME(unchangeArchive, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
  2647. ZIPARCHIVE_ME(unchangeAll, arginfo_ziparchive__void, ZEND_ACC_PUBLIC)
  2648. ZIPARCHIVE_ME(unchangeIndex, arginfo_ziparchive_unchangeindex, ZEND_ACC_PUBLIC)
  2649. ZIPARCHIVE_ME(unchangeName, arginfo_ziparchive_unchangename, ZEND_ACC_PUBLIC)
  2650. ZIPARCHIVE_ME(extractTo, arginfo_ziparchive_extractto, ZEND_ACC_PUBLIC)
  2651. ZIPARCHIVE_ME(getFromName, arginfo_ziparchive_getfromname, ZEND_ACC_PUBLIC)
  2652. ZIPARCHIVE_ME(getFromIndex, arginfo_ziparchive_getfromindex, ZEND_ACC_PUBLIC)
  2653. ZIPARCHIVE_ME(getStream, arginfo_ziparchive_getstream, ZEND_ACC_PUBLIC)
  2654. #ifdef ZIP_OPSYS_DEFAULT
  2655. ZIPARCHIVE_ME(setExternalAttributesName, arginfo_ziparchive_setextattrname, ZEND_ACC_PUBLIC)
  2656. ZIPARCHIVE_ME(setExternalAttributesIndex, arginfo_ziparchive_setextattrindex, ZEND_ACC_PUBLIC)
  2657. ZIPARCHIVE_ME(getExternalAttributesName, arginfo_ziparchive_getextattrname, ZEND_ACC_PUBLIC)
  2658. ZIPARCHIVE_ME(getExternalAttributesIndex, arginfo_ziparchive_getextattrindex, ZEND_ACC_PUBLIC)
  2659. #endif
  2660. ZIPARCHIVE_ME(setCompressionName, arginfo_ziparchive_setcompname, ZEND_ACC_PUBLIC)
  2661. ZIPARCHIVE_ME(setCompressionIndex, arginfo_ziparchive_setcompindex, ZEND_ACC_PUBLIC)
  2662. #ifdef HAVE_ENCRYPTION
  2663. ZIPARCHIVE_ME(setEncryptionName, arginfo_ziparchive_setencryption_name, ZEND_ACC_PUBLIC)
  2664. ZIPARCHIVE_ME(setEncryptionIndex, arginfo_ziparchive_setencryption_index, ZEND_ACC_PUBLIC)
  2665. #endif
  2666. PHP_FE_END
  2667. };
  2668. /* }}} */
  2669. static void php_zip_free_prop_handler(zval *el) /* {{{ */ {
  2670. pefree(Z_PTR_P(el), 1);
  2671. } /* }}} */
  2672. /* {{{ PHP_MINIT_FUNCTION */
  2673. static PHP_MINIT_FUNCTION(zip)
  2674. {
  2675. zend_class_entry ce;
  2676. memcpy(&zip_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
  2677. zip_object_handlers.offset = XtOffsetOf(ze_zip_object, zo);
  2678. zip_object_handlers.free_obj = php_zip_object_free_storage;
  2679. zip_object_handlers.clone_obj = NULL;
  2680. zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr;
  2681. zip_object_handlers.get_gc = php_zip_get_gc;
  2682. zip_object_handlers.get_properties = php_zip_get_properties;
  2683. zip_object_handlers.read_property = php_zip_read_property;
  2684. zip_object_handlers.has_property = php_zip_has_property;
  2685. INIT_CLASS_ENTRY(ce, "ZipArchive", zip_class_functions);
  2686. ce.create_object = php_zip_object_new;
  2687. zip_class_entry = zend_register_internal_class(&ce);
  2688. zend_hash_init(&zip_prop_handlers, 0, NULL, php_zip_free_prop_handler, 1);
  2689. php_zip_register_prop_handler(&zip_prop_handlers, "status", php_zip_status, NULL, NULL, IS_LONG);
  2690. php_zip_register_prop_handler(&zip_prop_handlers, "statusSys", php_zip_status_sys, NULL, NULL, IS_LONG);
  2691. php_zip_register_prop_handler(&zip_prop_handlers, "numFiles", php_zip_get_num_files, NULL, NULL, IS_LONG);
  2692. php_zip_register_prop_handler(&zip_prop_handlers, "filename", NULL, NULL, php_zipobj_get_filename, IS_STRING);
  2693. php_zip_register_prop_handler(&zip_prop_handlers, "comment", NULL, php_zipobj_get_zip_comment, NULL, IS_STRING);
  2694. #if PHP_VERSION_ID >= 70200
  2695. zend_class_implements(zip_class_entry, 1, zend_ce_countable);
  2696. #elif defined(HAVE_SPL)
  2697. zend_class_implements(zip_class_entry, 1, spl_ce_Countable);
  2698. #endif
  2699. REGISTER_ZIP_CLASS_CONST_LONG("CREATE", ZIP_CREATE);
  2700. REGISTER_ZIP_CLASS_CONST_LONG("EXCL", ZIP_EXCL);
  2701. REGISTER_ZIP_CLASS_CONST_LONG("CHECKCONS", ZIP_CHECKCONS);
  2702. REGISTER_ZIP_CLASS_CONST_LONG("OVERWRITE", ZIP_OVERWRITE);
  2703. REGISTER_ZIP_CLASS_CONST_LONG("FL_NOCASE", ZIP_FL_NOCASE);
  2704. REGISTER_ZIP_CLASS_CONST_LONG("FL_NODIR", ZIP_FL_NODIR);
  2705. REGISTER_ZIP_CLASS_CONST_LONG("FL_COMPRESSED", ZIP_FL_COMPRESSED);
  2706. REGISTER_ZIP_CLASS_CONST_LONG("FL_UNCHANGED", ZIP_FL_UNCHANGED);
  2707. #ifdef ZIP_FL_ENC_GUESS
  2708. /* Default filename encoding policy. */
  2709. REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_GUESS", ZIP_FL_ENC_GUESS);
  2710. #endif
  2711. #ifdef ZIP_FL_ENC_RAW
  2712. REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_RAW", ZIP_FL_ENC_RAW);
  2713. #endif
  2714. #ifdef ZIP_FL_ENC_STRICT
  2715. REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_STRICT", ZIP_FL_ENC_STRICT);
  2716. #endif
  2717. #ifdef ZIP_FL_ENC_UTF_8
  2718. REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_UTF_8", ZIP_FL_ENC_UTF_8);
  2719. #endif
  2720. #ifdef ZIP_FL_ENC_CP437
  2721. REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_CP437", ZIP_FL_ENC_CP437);
  2722. #endif
  2723. REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFAULT", ZIP_CM_DEFAULT);
  2724. REGISTER_ZIP_CLASS_CONST_LONG("CM_STORE", ZIP_CM_STORE);
  2725. REGISTER_ZIP_CLASS_CONST_LONG("CM_SHRINK", ZIP_CM_SHRINK);
  2726. REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_1", ZIP_CM_REDUCE_1);
  2727. REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_2", ZIP_CM_REDUCE_2);
  2728. REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_3", ZIP_CM_REDUCE_3);
  2729. REGISTER_ZIP_CLASS_CONST_LONG("CM_REDUCE_4", ZIP_CM_REDUCE_4);
  2730. REGISTER_ZIP_CLASS_CONST_LONG("CM_IMPLODE", ZIP_CM_IMPLODE);
  2731. REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE", ZIP_CM_DEFLATE);
  2732. REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFLATE64", ZIP_CM_DEFLATE64);
  2733. REGISTER_ZIP_CLASS_CONST_LONG("CM_PKWARE_IMPLODE", ZIP_CM_PKWARE_IMPLODE);
  2734. REGISTER_ZIP_CLASS_CONST_LONG("CM_BZIP2", ZIP_CM_BZIP2);
  2735. REGISTER_ZIP_CLASS_CONST_LONG("CM_LZMA", ZIP_CM_LZMA);
  2736. REGISTER_ZIP_CLASS_CONST_LONG("CM_TERSE", ZIP_CM_TERSE);
  2737. REGISTER_ZIP_CLASS_CONST_LONG("CM_LZ77", ZIP_CM_LZ77);
  2738. REGISTER_ZIP_CLASS_CONST_LONG("CM_WAVPACK", ZIP_CM_WAVPACK);
  2739. REGISTER_ZIP_CLASS_CONST_LONG("CM_PPMD", ZIP_CM_PPMD);
  2740. /* Error code */
  2741. REGISTER_ZIP_CLASS_CONST_LONG("ER_OK", ZIP_ER_OK); /* N No error */
  2742. REGISTER_ZIP_CLASS_CONST_LONG("ER_MULTIDISK", ZIP_ER_MULTIDISK); /* N Multi-disk zip archives not supported */
  2743. REGISTER_ZIP_CLASS_CONST_LONG("ER_RENAME", ZIP_ER_RENAME); /* S Renaming temporary file failed */
  2744. REGISTER_ZIP_CLASS_CONST_LONG("ER_CLOSE", ZIP_ER_CLOSE); /* S Closing zip archive failed */
  2745. REGISTER_ZIP_CLASS_CONST_LONG("ER_SEEK", ZIP_ER_SEEK); /* S Seek error */
  2746. REGISTER_ZIP_CLASS_CONST_LONG("ER_READ", ZIP_ER_READ); /* S Read error */
  2747. REGISTER_ZIP_CLASS_CONST_LONG("ER_WRITE", ZIP_ER_WRITE); /* S Write error */
  2748. REGISTER_ZIP_CLASS_CONST_LONG("ER_CRC", ZIP_ER_CRC); /* N CRC error */
  2749. REGISTER_ZIP_CLASS_CONST_LONG("ER_ZIPCLOSED", ZIP_ER_ZIPCLOSED); /* N Containing zip archive was closed */
  2750. REGISTER_ZIP_CLASS_CONST_LONG("ER_NOENT", ZIP_ER_NOENT); /* N No such file */
  2751. REGISTER_ZIP_CLASS_CONST_LONG("ER_EXISTS", ZIP_ER_EXISTS); /* N File already exists */
  2752. REGISTER_ZIP_CLASS_CONST_LONG("ER_OPEN", ZIP_ER_OPEN); /* S Can't open file */
  2753. REGISTER_ZIP_CLASS_CONST_LONG("ER_TMPOPEN", ZIP_ER_TMPOPEN); /* S Failure to create temporary file */
  2754. REGISTER_ZIP_CLASS_CONST_LONG("ER_ZLIB", ZIP_ER_ZLIB); /* Z Zlib error */
  2755. REGISTER_ZIP_CLASS_CONST_LONG("ER_MEMORY", ZIP_ER_MEMORY); /* N Malloc failure */
  2756. REGISTER_ZIP_CLASS_CONST_LONG("ER_CHANGED", ZIP_ER_CHANGED); /* N Entry has been changed */
  2757. REGISTER_ZIP_CLASS_CONST_LONG("ER_COMPNOTSUPP", ZIP_ER_COMPNOTSUPP);/* N Compression method not supported */
  2758. REGISTER_ZIP_CLASS_CONST_LONG("ER_EOF", ZIP_ER_EOF); /* N Premature EOF */
  2759. REGISTER_ZIP_CLASS_CONST_LONG("ER_INVAL", ZIP_ER_INVAL); /* N Invalid argument */
  2760. REGISTER_ZIP_CLASS_CONST_LONG("ER_NOZIP", ZIP_ER_NOZIP); /* N Not a zip archive */
  2761. REGISTER_ZIP_CLASS_CONST_LONG("ER_INTERNAL", ZIP_ER_INTERNAL); /* N Internal error */
  2762. REGISTER_ZIP_CLASS_CONST_LONG("ER_INCONS", ZIP_ER_INCONS); /* N Zip archive inconsistent */
  2763. REGISTER_ZIP_CLASS_CONST_LONG("ER_REMOVE", ZIP_ER_REMOVE); /* S Can't remove file */
  2764. REGISTER_ZIP_CLASS_CONST_LONG("ER_DELETED", ZIP_ER_DELETED); /* N Entry has been deleted */
  2765. #ifdef ZIP_OPSYS_DEFAULT
  2766. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_DOS", ZIP_OPSYS_DOS);
  2767. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_AMIGA", ZIP_OPSYS_AMIGA);
  2768. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OPENVMS", ZIP_OPSYS_OPENVMS);
  2769. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_UNIX", ZIP_OPSYS_UNIX);
  2770. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_VM_CMS", ZIP_OPSYS_VM_CMS);
  2771. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_ATARI_ST", ZIP_OPSYS_ATARI_ST);
  2772. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OS_2", ZIP_OPSYS_OS_2);
  2773. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MACINTOSH", ZIP_OPSYS_MACINTOSH);
  2774. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_SYSTEM", ZIP_OPSYS_Z_SYSTEM);
  2775. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_Z_CPM", ZIP_OPSYS_CPM); // typo kept for BC
  2776. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_CPM", ZIP_OPSYS_CPM);
  2777. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_WINDOWS_NTFS", ZIP_OPSYS_WINDOWS_NTFS);
  2778. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_MVS", ZIP_OPSYS_MVS);
  2779. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_VSE", ZIP_OPSYS_VSE);
  2780. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_ACORN_RISC", ZIP_OPSYS_ACORN_RISC);
  2781. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_VFAT", ZIP_OPSYS_VFAT);
  2782. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_ALTERNATE_MVS", ZIP_OPSYS_ALTERNATE_MVS);
  2783. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_BEOS", ZIP_OPSYS_BEOS);
  2784. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_TANDEM", ZIP_OPSYS_TANDEM);
  2785. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OS_400", ZIP_OPSYS_OS_400);
  2786. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_OS_X", ZIP_OPSYS_OS_X);
  2787. REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_DEFAULT", ZIP_OPSYS_DEFAULT);
  2788. #endif /* ifdef ZIP_OPSYS_DEFAULT */
  2789. #ifdef HAVE_ENCRYPTION
  2790. REGISTER_ZIP_CLASS_CONST_LONG("EM_NONE", ZIP_EM_NONE);
  2791. REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_128", ZIP_EM_AES_128);
  2792. REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_192", ZIP_EM_AES_192);
  2793. REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_256", ZIP_EM_AES_256);
  2794. #endif
  2795. php_register_url_stream_wrapper("zip", &php_stream_zip_wrapper);
  2796. le_zip_dir = zend_register_list_destructors_ex(php_zip_free_dir, NULL, le_zip_dir_name, module_number);
  2797. le_zip_entry = zend_register_list_destructors_ex(php_zip_free_entry, NULL, le_zip_entry_name, module_number);
  2798. return SUCCESS;
  2799. }
  2800. /* }}} */
  2801. /* {{{ PHP_MSHUTDOWN_FUNCTION
  2802. */
  2803. static PHP_MSHUTDOWN_FUNCTION(zip)
  2804. {
  2805. zend_hash_destroy(&zip_prop_handlers);
  2806. php_unregister_url_stream_wrapper("zip");
  2807. return SUCCESS;
  2808. }
  2809. /* }}} */
  2810. /* {{{ PHP_MINFO_FUNCTION
  2811. */
  2812. static PHP_MINFO_FUNCTION(zip)
  2813. {
  2814. php_info_print_table_start();
  2815. php_info_print_table_row(2, "Zip", "enabled");
  2816. php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION);
  2817. #if HAVE_LIBZIP_VERSION
  2818. php_info_print_table_row(2, "Libzip headers version", LIBZIP_VERSION);
  2819. php_info_print_table_row(2, "Libzip library version", zip_libzip_version());
  2820. #else
  2821. php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION);
  2822. #endif
  2823. php_info_print_table_end();
  2824. }
  2825. /* }}} */
  2826. /*
  2827. * Local variables:
  2828. * tab-width: 4
  2829. * c-basic-offset: 4
  2830. * End:
  2831. * vim600: noet sw=4 ts=4 fdm=marker
  2832. * vim<600: noet sw=4 ts=4
  2833. */