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