php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
util.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | phar php single-file executable PHP extension |
4 | utility functions |
5 +----------------------------------------------------------------------+
6 | Copyright (c) The PHP Group |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | https://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
16 | Authors: Gregory Beaver <cellog@php.net> |
17 | Marcus Boerger <helly@php.net> |
18 +----------------------------------------------------------------------+
19*/
20
21#include "phar_internal.h"
22#include "php_phar.h"
23#include "ext/hash/php_hash.h" /* Needed for PHP_HASH_API in ext/hash/php_hash_sha.h */
25#include "ext/standard/md5.h"
26
27#ifdef PHAR_HAVE_OPENSSL
28/* OpenSSL includes */
29#include <openssl/evp.h>
30#include <openssl/x509.h>
31#include <openssl/x509v3.h>
32#include <openssl/crypto.h>
33#include <openssl/pem.h>
34#include <openssl/err.h>
35#include <openssl/conf.h>
36#include <openssl/rand.h>
37#include <openssl/ssl.h>
38#include <openssl/pkcs12.h>
39#else
40static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type);
41#endif
42
43/* for links to relative location, prepend cwd of the entry */
44static char *phar_get_link_location(phar_entry_info *entry) /* {{{ */
45{
46 char *p, *ret = NULL;
47 if (!entry->link) {
48 return NULL;
49 }
50 if (entry->link[0] == '/') {
51 return estrdup(entry->link + 1);
52 }
53 p = strrchr(entry->filename, '/');
54 if (p) {
55 *p = '\0';
56 spprintf(&ret, 0, "%s/%s", entry->filename, entry->link);
57 return ret;
58 }
59 return entry->link;
60}
61/* }}} */
62
64{
65 phar_entry_info *link_entry;
66 char *link;
67
68 if (!entry->link) {
69 return entry;
70 }
71
72 link = phar_get_link_location(entry);
73 if (NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), entry->link, strlen(entry->link))) ||
74 NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), link, strlen(link)))) {
75 if (link != entry->link) {
76 efree(link);
77 }
78 return phar_get_link_source(link_entry);
79 } else {
80 if (link != entry->link) {
81 efree(link);
82 }
83 return NULL;
84 }
85}
86/* }}} */
87
88static php_stream *phar_get_entrypufp(const phar_entry_info *entry)
89{
90 if (!entry->is_persistent) {
91 return entry->phar->ufp;
92 }
93 return PHAR_G(cached_fp)[entry->phar->phar_pos].ufp;
94}
95
96/* retrieve a phar_entry_info's current file pointer for reading contents */
97php_stream *phar_get_efp(phar_entry_info *entry, int follow_links) /* {{{ */
98{
99 if (follow_links && entry->link) {
100 phar_entry_info *link_entry = phar_get_link_source(entry);
101
102 if (link_entry && link_entry != entry) {
103 return phar_get_efp(link_entry, 1);
104 }
105 }
106
107 if (phar_get_fp_type(entry) == PHAR_FP) {
108 if (!phar_get_entrypfp(entry)) {
109 /* re-open just in time for cases where our refcount reached 0 on the phar archive */
111 }
112 return phar_get_entrypfp(entry);
113 } else if (phar_get_fp_type(entry) == PHAR_UFP) {
114 return phar_get_entrypufp(entry);
115 } else if (entry->fp_type == PHAR_MOD) {
116 return entry->fp;
117 } else {
118 /* temporary manifest entry */
119 if (!entry->fp) {
120 entry->fp = php_stream_open_wrapper(entry->tmp, "rb", STREAM_MUST_SEEK|0, NULL);
121 }
122 return entry->fp;
123 }
124}
125/* }}} */
126
127static zend_off_t phar_get_fp_offset(const phar_entry_info *entry)
128{
129 if (!entry->is_persistent) {
130 return entry->offset;
131 }
132 if (PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type == PHAR_FP) {
133 if (!PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset) {
134 PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset = entry->offset;
135 }
136 }
137 return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset;
138}
139
140int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links) /* {{{ */
141{
142 php_stream *fp = phar_get_efp(entry, follow_links);
143 zend_off_t temp, eoffset;
144
145 if (!fp) {
146 return -1;
147 }
148
149 if (follow_links) {
151 t = phar_get_link_source(entry);
152 if (t) {
153 entry = t;
154 }
155 }
156
157 if (entry->is_dir) {
158 return 0;
159 }
160
161 eoffset = phar_get_fp_offset(entry);
162
163 switch (whence) {
164 case SEEK_END:
165 temp = eoffset + entry->uncompressed_filesize + offset;
166 break;
167 case SEEK_CUR:
168 temp = eoffset + position + offset;
169 break;
170 case SEEK_SET:
171 temp = eoffset + offset;
172 break;
173 default:
174 temp = 0;
175 }
176
177 if (temp > eoffset + (zend_off_t) entry->uncompressed_filesize) {
178 return -1;
179 }
180
181 if (temp < eoffset) {
182 return -1;
183 }
184
185 return php_stream_seek(fp, temp, SEEK_SET);
186}
187/* }}} */
188
189/* mount an absolute path or uri to a path internal to the phar archive */
190zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */
191{
192 phar_entry_info entry = {0};
194 int is_phar;
195 const char *err;
196
197 if (phar_path_check(&path, &path_len, &err) > pcr_is_ok) {
198 return FAILURE;
199 }
200
201 if (path_len >= sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) {
202 /* no creating magic phar files by mounting them */
203 return FAILURE;
204 }
205
206 is_phar = (filename_len > 7 && !memcmp(filename, "phar://", 7));
207
208 entry.phar = phar;
209 entry.filename = estrndup(path, path_len);
210#ifdef PHP_WIN32
211 phar_unixify_path_separators(entry.filename, path_len);
212#endif
213 entry.filename_len = path_len;
214 if (is_phar) {
215 entry.tmp = estrndup(filename, filename_len);
216 } else {
217 entry.tmp = expand_filepath(filename, NULL);
218 if (!entry.tmp) {
219 entry.tmp = estrndup(filename, filename_len);
220 }
221 }
222 filename = entry.tmp;
223
224 /* only check openbasedir for files, not for phar streams */
225 if (!is_phar && php_check_open_basedir(filename)) {
226 efree(entry.tmp);
227 efree(entry.filename);
228 return FAILURE;
229 }
230
231 entry.is_mounted = 1;
232 entry.is_crc_checked = 1;
233 entry.fp_type = PHAR_TMP;
234
235 if (SUCCESS != php_stream_stat_path(filename, &ssb)) {
236 efree(entry.tmp);
237 efree(entry.filename);
238 return FAILURE;
239 }
240
241 if (ssb.sb.st_mode & S_IFDIR) {
242 entry.is_dir = 1;
243 if (NULL == zend_hash_str_add_ptr(&phar->mounted_dirs, entry.filename, path_len, entry.filename)) {
244 /* directory already mounted */
245 efree(entry.tmp);
246 efree(entry.filename);
247 return FAILURE;
248 }
249 } else {
250 entry.is_dir = 0;
251 entry.uncompressed_filesize = entry.compressed_filesize = ssb.sb.st_size;
252 }
253
254 entry.flags = ssb.sb.st_mode;
255
256 if (NULL != zend_hash_str_add_mem(&phar->manifest, entry.filename, path_len, (void*)&entry, sizeof(phar_entry_info))) {
257 return SUCCESS;
258 }
259
260 efree(entry.tmp);
261 efree(entry.filename);
262 return FAILURE;
263}
264/* }}} */
265
267{
269 char *path, *arch, *entry, *test;
270 size_t arch_len, entry_len;
271 phar_archive_data *phar;
272
273 if (pphar) {
274 *pphar = NULL;
275 } else {
276 pphar = &phar;
277 }
278
279 if (!zend_is_executing() || !PHAR_G(cwd)) {
280 return NULL;
281 }
282
284 if (!fname) {
285 return NULL;
286 }
287
288 bool is_file_a_phar_wrapper = zend_string_starts_with_literal_ci(fname, "phar://");
289 size_t length_phar_protocol = strlen("phar://");
290
291 if (
293 && is_file_a_phar_wrapper
294 && ZSTR_LEN(fname) - length_phar_protocol >= PHAR_G(last_phar_name_len)
295 && !memcmp(ZSTR_VAL(fname) + length_phar_protocol, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))
296 ) {
298 arch_len = PHAR_G(last_phar_name_len);
299 phar = PHAR_G(last_phar);
300 goto splitted;
301 }
302
303 if (!is_file_a_phar_wrapper || SUCCESS != phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
304 return NULL;
305 }
306
307 efree(entry);
308
309 if (*ZSTR_VAL(filename) == '.') {
310 size_t try_len;
311
312 if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) {
313 efree(arch);
314 return NULL;
315 }
316splitted:
317 if (pphar) {
318 *pphar = phar;
319 }
320
321 try_len = ZSTR_LEN(filename);
322 test = phar_fix_filepath(estrndup(ZSTR_VAL(filename), ZSTR_LEN(filename)), &try_len, 1);
323
324 if (*test == '/') {
325 if (zend_hash_str_exists(&(phar->manifest), test + 1, try_len - 1)) {
326 ret = strpprintf(0, "phar://%s%s", arch, test);
327 efree(arch);
328 efree(test);
329 return ret;
330 }
331 } else {
332 if (zend_hash_str_exists(&(phar->manifest), test, try_len)) {
333 ret = strpprintf(0, "phar://%s/%s", arch, test);
334 efree(arch);
335 efree(test);
336 return ret;
337 }
338 }
339 efree(test);
340 }
341
342 spprintf(&path, MAXPATHLEN + 1 + strlen(PG(include_path)), "phar://%s/%s%c%s", arch, PHAR_G(cwd), DEFAULT_DIR_SEPARATOR, PG(include_path));
343 efree(arch);
344 ret = php_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename), path);
345 efree(path);
346
347 if (ret && zend_string_starts_with_literal_ci(ret, "phar://")) {
348 /* found phar:// */
349 if (SUCCESS != phar_split_fname(ZSTR_VAL(ret), ZSTR_LEN(ret), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
350 return ret;
351 }
352
353 *pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), arch, arch_len);
354
355 if (!*pphar && PHAR_G(manifest_cached)) {
356 *pphar = zend_hash_str_find_ptr(&cached_phars, arch, arch_len);
357 }
358
359 efree(arch);
360 efree(entry);
361 }
362
363 return ret;
364}
365/* }}} */
366
367static zend_result phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */
368{
369 if (entry->fp_type == PHAR_MOD) {
370 /* already newly created, truncate */
372
373 entry->old_flags = entry->flags;
374 entry->is_modified = 1;
375 phar->is_modified = 1;
376 /* reset file size */
377 entry->uncompressed_filesize = 0;
378 entry->compressed_filesize = 0;
379 entry->crc32 = 0;
381 entry->fp_type = PHAR_MOD;
382 entry->offset = 0;
383 return SUCCESS;
384 }
385
386 if (error) {
387 *error = NULL;
388 }
389
390 /* open a new temp file for writing */
391 if (entry->link) {
392 efree(entry->link);
393 entry->link = NULL;
394 entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
395 }
396
397 entry->fp = php_stream_fopen_tmpfile();
398
399 if (!entry->fp) {
400 if (error) {
401 spprintf(error, 0, "phar error: unable to create temporary file");
402 }
403 return FAILURE;
404 }
405
406 entry->old_flags = entry->flags;
407 entry->is_modified = 1;
408 phar->is_modified = 1;
409 /* reset file size */
410 entry->uncompressed_filesize = 0;
411 entry->compressed_filesize = 0;
412 entry->crc32 = 0;
414 entry->fp_type = PHAR_MOD;
415 entry->offset = 0;
416 return SUCCESS;
417}
418/* }}} */
419
420static zend_result phar_separate_entry_fp(phar_entry_info *entry, char **error) /* {{{ */
421{
422 php_stream *fp;
424
425 if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
426 return FAILURE;
427 }
428
429 if (entry->fp_type == PHAR_MOD) {
430 return SUCCESS;
431 }
432
434 if (fp == NULL) {
435 spprintf(error, 0, "phar error: unable to create temporary file");
436 return FAILURE;
437 }
438 phar_seek_efp(entry, 0, SEEK_SET, 0, 1);
439 link = phar_get_link_source(entry);
440
441 if (!link) {
442 link = entry;
443 }
444
445 if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), fp, link->uncompressed_filesize, NULL)) {
446 if (error) {
447 spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", entry->filename, entry->phar->fname);
448 }
449 return FAILURE;
450 }
451
452 if (entry->link) {
453 efree(entry->link);
454 entry->link = NULL;
455 entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
456 }
457
458 entry->offset = 0;
459 entry->fp = fp;
460 entry->fp_type = PHAR_MOD;
461 entry->is_modified = 1;
462 return SUCCESS;
463}
464/* }}} */
465
474zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */
475{
476 phar_archive_data *phar;
477 phar_entry_info *entry;
478 bool for_write = mode[0] != 'r' || mode[1] == '+';
479 bool for_append = mode[0] == 'a';
480 bool for_create = mode[0] != 'r';
481 bool for_trunc = mode[0] == 'w';
482
483 if (!ret) {
484 return FAILURE;
485 }
486
487 *ret = NULL;
488
489 if (error) {
490 *error = NULL;
491 }
492
493 if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) {
494 return FAILURE;
495 }
496
497 if (for_write && PHAR_G(readonly) && !phar->is_data) {
498 if (error) {
499 spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, disabled by ini setting", path, fname);
500 }
501 return FAILURE;
502 }
503
504 if (!path_len) {
505 if (error) {
506 spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" must not be empty", fname);
507 }
508 return FAILURE;
509 }
510really_get_entry:
511 if (allow_dir) {
512 if ((entry = phar_get_entry_info_dir(phar, path, path_len, allow_dir, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) {
513 if (for_create && (!PHAR_G(readonly) || phar->is_data)) {
514 return SUCCESS;
515 }
516 return FAILURE;
517 }
518 } else {
519 if ((entry = phar_get_entry_info(phar, path, path_len, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) {
520 if (for_create && (!PHAR_G(readonly) || phar->is_data)) {
521 return SUCCESS;
522 }
523 return FAILURE;
524 }
525 }
526
527 if (for_write && phar->is_persistent) {
528 if (FAILURE == phar_copy_on_write(&phar)) {
529 if (error) {
530 spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, could not make cached phar writeable", path, fname);
531 }
532 return FAILURE;
533 } else {
534 goto really_get_entry;
535 }
536 }
537
538 if (entry->is_modified && !for_write) {
539 if (error) {
540 spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for reading, writable file pointers are open", path, fname);
541 }
542 return FAILURE;
543 }
544
545 if (entry->fp_refcount && for_write) {
546 if (error) {
547 spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, readable file pointers are open", path, fname);
548 }
549 return FAILURE;
550 }
551
552 if (entry->is_deleted) {
553 if (!for_create) {
554 return FAILURE;
555 }
556 entry->is_deleted = 0;
557 }
558
559 if (entry->is_dir) {
561 (*ret)->position = 0;
562 (*ret)->fp = NULL;
563 (*ret)->phar = phar;
564 (*ret)->internal_file = entry;
565
566 if (!phar->is_persistent) {
567 ++(entry->phar->refcount);
568 ++(entry->fp_refcount);
569 }
570
571 return SUCCESS;
572 }
573
574 if (entry->fp_type == PHAR_MOD) {
575 if (for_trunc) {
576 if (FAILURE == phar_create_writeable_entry(phar, entry, error)) {
577 return FAILURE;
578 }
579 } else if (for_append) {
580 phar_seek_efp(entry, 0, SEEK_END, 0, 0);
581 }
582 } else {
583 if (for_write) {
584 if (entry->link) {
585 efree(entry->link);
586 entry->link = NULL;
587 entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
588 }
589
590 if (for_trunc) {
591 if (FAILURE == phar_create_writeable_entry(phar, entry, error)) {
592 return FAILURE;
593 }
594 } else {
595 if (FAILURE == phar_separate_entry_fp(entry, error)) {
596 return FAILURE;
597 }
598 }
599 } else {
600 if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
601 return FAILURE;
602 }
603 }
604 }
605
607 (*ret)->position = 0;
608 (*ret)->phar = phar;
609 (*ret)->internal_file = entry;
610 (*ret)->fp = phar_get_efp(entry, 1);
611 if (entry->link) {
613 if(!link) {
614 efree(*ret);
615 return FAILURE;
616 }
617 (*ret)->zero = phar_get_fp_offset(link);
618 } else {
619 (*ret)->zero = phar_get_fp_offset(entry);
620 }
621
622 if (!phar->is_persistent) {
623 ++(entry->fp_refcount);
624 ++(entry->phar->refcount);
625 }
626
627 return SUCCESS;
628}
629/* }}} */
630
634phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */
635{
636 phar_archive_data *phar;
637 phar_entry_info *entry, etemp;
639 const char *pcr_error;
640 char is_dir;
641
642#ifdef PHP_WIN32
643 phar_unixify_path_separators(path, path_len);
644#endif
645
646 is_dir = (path_len && path[path_len - 1] == '/') ? 1 : 0;
647
648 if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) {
649 return NULL;
650 }
651
652 if (FAILURE == phar_get_entry_data(&ret, fname, fname_len, path, path_len, mode, allow_dir, error, security)) {
653 return NULL;
654 } else if (ret) {
655 return ret;
656 }
657
658 if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) {
659 if (error) {
660 spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
661 }
662 return NULL;
663 }
664
665 if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar)) {
666 if (error) {
667 spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be created, could not make cached phar writeable", path, fname);
668 }
669 return NULL;
670 }
671
672 /* create a new phar data holder */
674
675 /* create an entry, this is a new file */
676 memset(&etemp, 0, sizeof(phar_entry_info));
677 etemp.filename_len = path_len;
678 etemp.fp_type = PHAR_MOD;
680
681 if (!etemp.fp) {
682 if (error) {
683 spprintf(error, 0, "phar error: unable to create temporary file");
684 }
685 efree(ret);
686 return NULL;
687 }
688
689 etemp.fp_refcount = 1;
690
691 if (allow_dir == 2) {
692 etemp.is_dir = 1;
693 etemp.flags = etemp.old_flags = PHAR_ENT_PERM_DEF_DIR;
694 } else {
695 etemp.flags = etemp.old_flags = PHAR_ENT_PERM_DEF_FILE;
696 }
697 if (is_dir && path_len) {
698 etemp.filename_len--; /* strip trailing / */
699 path_len--;
700 }
701
702 phar_add_virtual_dirs(phar, path, path_len);
703 etemp.is_modified = 1;
704 etemp.timestamp = time(0);
705 etemp.is_crc_checked = 1;
706 etemp.phar = phar;
707 etemp.filename = estrndup(path, path_len);
708 etemp.is_zip = phar->is_zip;
709
710 if (phar->is_tar) {
711 etemp.is_tar = phar->is_tar;
712 etemp.tar_type = etemp.is_dir ? TAR_DIR : TAR_FILE;
713 }
714
715 if (NULL == (entry = zend_hash_str_add_mem(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info)))) {
716 php_stream_close(etemp.fp);
717 if (error) {
718 spprintf(error, 0, "phar error: unable to add new entry \"%s\" to phar \"%s\"", etemp.filename, phar->fname);
719 }
720 efree(ret);
721 efree(etemp.filename);
722 return NULL;
723 }
724
725 if (!entry) {
726 php_stream_close(etemp.fp);
727 efree(etemp.filename);
728 efree(ret);
729 return NULL;
730 }
731
732 ++(phar->refcount);
733 ret->phar = phar;
734 ret->fp = entry->fp;
735 ret->position = ret->zero = 0;
736 ret->internal_file = entry;
737
738 return ret;
739}
740/* }}} */
741
742static inline void phar_set_pharfp(phar_archive_data *phar, php_stream *fp)
743{
744 if (!phar->is_persistent) {
745 phar->fp = fp;
746 return;
747 }
748
749 PHAR_G(cached_fp)[phar->phar_pos].fp = fp;
750}
751
752/* initialize a phar_archive_data's read-only fp for existing phar data */
754{
755 if (phar_get_pharfp(phar)) {
756 return SUCCESS;
757 }
758
759 if (php_check_open_basedir(phar->fname)) {
760 return FAILURE;
761 }
762
763 phar_set_pharfp(phar, php_stream_open_wrapper(phar->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|0, NULL));
764
765 if (!phar_get_pharfp(phar)) {
766 return FAILURE;
767 }
768
769 return SUCCESS;
770}
771/* }}} */
772
773/* copy file data from an existing to a new phar_entry_info that is not in the manifest */
775{
777
778 if (FAILURE == phar_open_entry_fp(source, error, 1)) {
779 return FAILURE;
780 }
781
782 if (dest->link) {
783 efree(dest->link);
784 dest->link = NULL;
785 dest->tar_type = (dest->is_tar ? TAR_FILE : '\0');
786 }
787
788 dest->fp_type = PHAR_MOD;
789 dest->offset = 0;
790 dest->is_modified = 1;
792 if (dest->fp == NULL) {
793 spprintf(error, 0, "phar error: unable to create temporary file");
794 return EOF;
795 }
796 phar_seek_efp(source, 0, SEEK_SET, 0, 1);
797 link = phar_get_link_source(source);
798
799 if (!link) {
800 link = source;
801 }
802
803 if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), dest->fp, link->uncompressed_filesize, NULL)) {
804 php_stream_close(dest->fp);
805 dest->fp_type = PHAR_FP;
806 if (error) {
807 spprintf(error, 4096, "phar error: unable to copy contents of file \"%s\" to \"%s\" in phar archive \"%s\"", source->filename, dest->filename, source->phar->fname);
808 }
809 return FAILURE;
810 }
811
812 return SUCCESS;
813}
814/* }}} */
815
816static void phar_set_entrypufp(const phar_entry_info *entry, php_stream *fp)
817{
818 if (!entry->phar->is_persistent) {
819 entry->phar->ufp = fp;
820 return;
821 }
822
823 PHAR_G(cached_fp)[entry->phar->phar_pos].ufp = fp;
824}
825
826static void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, zend_off_t offset)
827{
829
830 if (!entry->is_persistent) {
831 entry->fp_type = type;
832 entry->offset = offset;
833 return;
834 }
835 data = &(PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos]);
836 data->fp_type = type;
837 data->offset = offset;
838}
839
840/* open and decompress a compressed phar entry
841 */
842zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) /* {{{ */
843{
844 php_stream_filter *filter;
845 phar_archive_data *phar = entry->phar;
846 char *filtername;
847 zend_off_t loc;
848 php_stream *ufp;
849 phar_entry_data dummy;
850
851 if (follow_links && entry->link) {
852 phar_entry_info *link_entry = phar_get_link_source(entry);
853 if (link_entry && link_entry != entry) {
854 return phar_open_entry_fp(link_entry, error, 1);
855 }
856 }
857
858 if (entry->is_modified) {
859 return SUCCESS;
860 }
861
862 if (entry->fp_type == PHAR_TMP) {
863 if (!entry->fp) {
864 entry->fp = php_stream_open_wrapper(entry->tmp, "rb", STREAM_MUST_SEEK|0, NULL);
865 }
866 return SUCCESS;
867 }
868
869 if (entry->fp_type != PHAR_FP) {
870 /* either newly created or already modified */
871 return SUCCESS;
872 }
873
874 if (!phar_get_pharfp(phar)) {
875 if (FAILURE == phar_open_archive_fp(phar)) {
876 spprintf(error, 4096, "phar error: Cannot open phar archive \"%s\" for reading", phar->fname);
877 return FAILURE;
878 }
879 }
880
881 if ((entry->old_flags && !(entry->old_flags & PHAR_ENT_COMPRESSION_MASK)) || !(entry->flags & PHAR_ENT_COMPRESSION_MASK)) {
882 dummy.internal_file = entry;
883 dummy.phar = phar;
884 dummy.zero = entry->offset;
885 dummy.fp = phar_get_pharfp(phar);
886 if (FAILURE == phar_postprocess_file(&dummy, entry->crc32, error, 1)) {
887 return FAILURE;
888 }
889 return SUCCESS;
890 }
891
892 if (!phar_get_entrypufp(entry)) {
893 phar_set_entrypufp(entry, php_stream_fopen_tmpfile());
894 if (!phar_get_entrypufp(entry)) {
895 spprintf(error, 4096, "phar error: Cannot open temporary file for decompressing phar archive \"%s\" file \"%s\"", phar->fname, entry->filename);
896 return FAILURE;
897 }
898 }
899
900 dummy.internal_file = entry;
901 dummy.phar = phar;
902 dummy.zero = entry->offset;
903 dummy.fp = phar_get_pharfp(phar);
904 if (FAILURE == phar_postprocess_file(&dummy, entry->crc32, error, 1)) {
905 return FAILURE;
906 }
907
908 ufp = phar_get_entrypufp(entry);
909
910 if ((filtername = phar_decompress_filter(entry, 0)) != NULL) {
911 filter = php_stream_filter_create(filtername, NULL, 0);
912 } else {
913 filter = NULL;
914 }
915
916 if (!filter) {
917 spprintf(error, 4096, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->fname, phar_decompress_filter(entry, 1), entry->filename);
918 return FAILURE;
919 }
920
921 /* now we can safely use proper decompression */
922 /* save the new offset location within ufp */
923 php_stream_seek(ufp, 0, SEEK_END);
924 loc = php_stream_tell(ufp);
926 php_stream_seek(phar_get_entrypfp(entry), phar_get_fp_offset(entry), SEEK_SET);
927
928 if (entry->uncompressed_filesize) {
929 if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_entrypfp(entry), ufp, entry->compressed_filesize, NULL)) {
930 spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, entry->filename);
931 php_stream_filter_remove(filter, 1);
932 return FAILURE;
933 }
934 }
935
936 php_stream_filter_flush(filter, 1);
937 php_stream_flush(ufp);
938 php_stream_filter_remove(filter, 1);
939
940 if (php_stream_tell(ufp) - loc != (zend_off_t) entry->uncompressed_filesize) {
941 spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, entry->filename);
942 return FAILURE;
943 }
944
945 entry->old_flags = entry->flags;
946
947 /* this is now the new location of the file contents within this fp */
948 phar_set_fp_type(entry, PHAR_UFP, loc);
949 dummy.zero = entry->offset;
950 dummy.fp = ufp;
951 if (FAILURE == phar_postprocess_file(&dummy, entry->crc32, error, 0)) {
952 return FAILURE;
953 }
954 return SUCCESS;
955}
956/* }}} */
957
962{
963 if (error) {
964 *error = NULL;
965 }
966 /* seek to start of internal file and read it */
967 if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
968 return NULL;
969 }
970 if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 1)) {
971 spprintf(error, 4096, "phar error: cannot seek to start of file \"%s\" in phar \"%s\"", entry->filename, phar->fname);
972 return NULL;
973 }
974 return entry;
975}
976/* }}} */
977
978PHP_PHAR_API zend_result phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len) /* {{{ */ {
979 phar_archive_data *fd_ptr;
981 && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) {
982 *filename = fd_ptr->fname;
983 *filename_len = fd_ptr->fname_len;
984 return SUCCESS;
985 }
986 return FAILURE;
987}
988/* }}} */
989
990zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* {{{ */
991{
992 if (phar->refcount || phar->is_persistent) {
993 return FAILURE;
994 }
995
996 /* this archive has no open references, so emit a notice and remove it */
997 if (zend_hash_str_del(&(PHAR_G(phar_fname_map)), phar->fname, phar->fname_len) != SUCCESS) {
998 return FAILURE;
999 }
1000
1001 /* invalidate phar cache */
1004
1005 return SUCCESS;
1006}
1007/* }}} */
1008
1013zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error) /* {{{ */
1014{
1015 phar_archive_data *fd, *fd_ptr;
1016 char *my_realpath, *save;
1017 size_t save_len;
1018
1020
1021 if (error) {
1022 *error = NULL;
1023 }
1024
1025 *archive = NULL;
1026
1027 if (PHAR_G(last_phar) && fname_len == PHAR_G(last_phar_name_len) && !memcmp(fname, PHAR_G(last_phar_name), fname_len)) {
1028 *archive = PHAR_G(last_phar);
1029 if (alias && alias_len) {
1030
1031 if (!PHAR_G(last_phar)->is_temporary_alias && (alias_len != PHAR_G(last_phar)->alias_len || memcmp(PHAR_G(last_phar)->alias, alias, alias_len))) {
1032 if (error) {
1033 spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, PHAR_G(last_phar)->fname, fname);
1034 }
1035 *archive = NULL;
1036 return FAILURE;
1037 }
1038
1039 if (PHAR_G(last_phar)->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len))) {
1041 }
1042
1043 zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, *archive);
1044 PHAR_G(last_alias) = alias;
1045 PHAR_G(last_alias_len) = alias_len;
1046 }
1047
1048 return SUCCESS;
1049 }
1050
1051 if (alias && alias_len && PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) {
1052 fd = PHAR_G(last_phar);
1053 fd_ptr = fd;
1054 goto alias_success;
1055 }
1056
1057 if (alias && alias_len) {
1058 if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) {
1059alias_success:
1060 if (fname && (fname_len != fd_ptr->fname_len || strncmp(fname, fd_ptr->fname, fname_len))) {
1061 if (error) {
1062 spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
1063 }
1064 if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len)) {
1065 if (error) {
1066 efree(*error);
1067 *error = NULL;
1068 }
1069 }
1070 return FAILURE;
1071 }
1072
1073 *archive = fd_ptr;
1074 fd = fd_ptr;
1075 PHAR_G(last_phar) = fd;
1076 PHAR_G(last_phar_name) = fd->fname;
1077 PHAR_G(last_phar_name_len) = fd->fname_len;
1078 PHAR_G(last_alias) = alias;
1079 PHAR_G(last_alias_len) = alias_len;
1080
1081 return SUCCESS;
1082 }
1083
1084 if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, alias, alias_len))) {
1085 goto alias_success;
1086 }
1087 }
1088
1089 my_realpath = NULL;
1090 save = fname;
1091 save_len = fname_len;
1092
1093 if (fname && fname_len) {
1094 if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) {
1095 *archive = fd_ptr;
1096 fd = fd_ptr;
1097
1098 if (alias && alias_len) {
1099 if (!fd->is_temporary_alias && (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len))) {
1100 if (error) {
1101 spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
1102 }
1103 return FAILURE;
1104 }
1105
1106 if (fd->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len))) {
1107 zend_hash_str_del(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len);
1108 }
1109
1110 zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd);
1111 }
1112
1113 PHAR_G(last_phar) = fd;
1114 PHAR_G(last_phar_name) = fd->fname;
1115 PHAR_G(last_phar_name_len) = fd->fname_len;
1116 PHAR_G(last_alias) = fd->alias;
1117 PHAR_G(last_alias_len) = fd->alias_len;
1118
1119 return SUCCESS;
1120 }
1121
1122 if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) {
1123 *archive = fd_ptr;
1124 fd = fd_ptr;
1125
1126 /* this could be problematic - alias should never be different from manifest alias
1127 for cached phars */
1128 if (!fd->is_temporary_alias && alias && alias_len) {
1129 if (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len)) {
1130 if (error) {
1131 spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
1132 }
1133 return FAILURE;
1134 }
1135 }
1136
1137 PHAR_G(last_phar) = fd;
1138 PHAR_G(last_phar_name) = fd->fname;
1139 PHAR_G(last_phar_name_len) = fd->fname_len;
1140 PHAR_G(last_alias) = fd->alias;
1141 PHAR_G(last_alias_len) = fd->alias_len;
1142
1143 return SUCCESS;
1144 }
1145
1146 if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), save, save_len))) {
1147 fd = *archive = fd_ptr;
1148
1149 PHAR_G(last_phar) = fd;
1150 PHAR_G(last_phar_name) = fd->fname;
1151 PHAR_G(last_phar_name_len) = fd->fname_len;
1152 PHAR_G(last_alias) = fd->alias;
1153 PHAR_G(last_alias_len) = fd->alias_len;
1154
1155 return SUCCESS;
1156 }
1157
1158 if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, save, save_len))) {
1159 fd = *archive = fd_ptr;
1160
1161 PHAR_G(last_phar) = fd;
1162 PHAR_G(last_phar_name) = fd->fname;
1163 PHAR_G(last_phar_name_len) = fd->fname_len;
1164 PHAR_G(last_alias) = fd->alias;
1165 PHAR_G(last_alias_len) = fd->alias_len;
1166
1167 return SUCCESS;
1168 }
1169
1170 /* not found, try converting \ to / */
1171 my_realpath = expand_filepath(fname, my_realpath);
1172
1173 if (my_realpath) {
1174 fname_len = strlen(my_realpath);
1175 fname = my_realpath;
1176 } else {
1177 return FAILURE;
1178 }
1179#ifdef PHP_WIN32
1180 phar_unixify_path_separators(fname, fname_len);
1181#endif
1182
1183 if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) {
1184realpath_success:
1185 *archive = fd_ptr;
1186 fd = fd_ptr;
1187
1188 if (alias && alias_len) {
1189 zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd);
1190 }
1191
1192 efree(my_realpath);
1193
1194 PHAR_G(last_phar) = fd;
1195 PHAR_G(last_phar_name) = fd->fname;
1196 PHAR_G(last_phar_name_len) = fd->fname_len;
1197 PHAR_G(last_alias) = fd->alias;
1198 PHAR_G(last_alias_len) = fd->alias_len;
1199
1200 return SUCCESS;
1201 }
1202
1203 if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) {
1204 goto realpath_success;
1205 }
1206
1207 efree(my_realpath);
1208 }
1209
1210 return FAILURE;
1211}
1212/* }}} */
1213
1217char * phar_compress_filter(phar_entry_info * entry, int return_unknown) /* {{{ */
1218{
1219 switch (entry->flags & PHAR_ENT_COMPRESSION_MASK) {
1221 return "zlib.deflate";
1223 return "bzip2.compress";
1224 default:
1225 return return_unknown ? "unknown" : NULL;
1226 }
1227}
1228/* }}} */
1229
1233char * phar_decompress_filter(phar_entry_info * entry, int return_unknown) /* {{{ */
1234{
1235 uint32_t flags;
1236
1237 if (entry->is_modified) {
1238 flags = entry->old_flags;
1239 } else {
1240 flags = entry->flags;
1241 }
1242
1243 switch (flags & PHAR_ENT_COMPRESSION_MASK) {
1245 return "zlib.inflate";
1247 return "bzip2.decompress";
1248 default:
1249 return return_unknown ? "unknown" : NULL;
1250 }
1251}
1252/* }}} */
1253
1257phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, int security) /* {{{ */
1258{
1259 return phar_get_entry_info_dir(phar, path, path_len, 0, error, security);
1260}
1261/* }}} */
1267phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, int security) /* {{{ */
1268{
1269 const char *pcr_error;
1270 phar_entry_info *entry;
1271 int is_dir;
1272
1273#ifdef PHP_WIN32
1274 phar_unixify_path_separators(path, path_len);
1275#endif
1276
1277 is_dir = (path_len && (path[path_len - 1] == '/')) ? 1 : 0;
1278
1279 if (error) {
1280 *error = NULL;
1281 }
1282
1283 if (security && path_len >= sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) {
1284 if (error) {
1285 spprintf(error, 4096, "phar error: cannot directly access magic \".phar\" directory or files within it");
1286 }
1287 return NULL;
1288 }
1289
1290 if (!path_len && !dir) {
1291 if (error) {
1292 spprintf(error, 4096, "phar error: invalid path \"%s\" must not be empty", path);
1293 }
1294 return NULL;
1295 }
1296
1297 if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) {
1298 if (error) {
1299 spprintf(error, 4096, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
1300 }
1301 return NULL;
1302 }
1303
1304 if (!HT_IS_INITIALIZED(&phar->manifest)) {
1305 return NULL;
1306 }
1307
1308 if (is_dir) {
1309 if (path_len <= 1) {
1310 return NULL;
1311 }
1312 path_len--;
1313 }
1314
1315 if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) {
1316 if (entry->is_deleted) {
1317 /* entry is deleted, but has not been flushed to disk yet */
1318 return NULL;
1319 }
1320 if (entry->is_dir && !dir) {
1321 if (error) {
1322 spprintf(error, 4096, "phar error: path \"%s\" is a directory", path);
1323 }
1324 return NULL;
1325 }
1326 if (!entry->is_dir && dir == 2) {
1327 /* user requested a directory, we must return one */
1328 if (error) {
1329 spprintf(error, 4096, "phar error: path \"%s\" exists and is a not a directory", path);
1330 }
1331 return NULL;
1332 }
1333 return entry;
1334 }
1335
1336 if (dir) {
1337 if (zend_hash_str_exists(&phar->virtual_dirs, path, path_len)) {
1338 /* a file or directory exists in a sub-directory of this path */
1339 entry = (phar_entry_info *) ecalloc(1, sizeof(phar_entry_info));
1340 /* this next line tells PharFileInfo->__destruct() to efree the filename */
1341 entry->is_temp_dir = entry->is_dir = 1;
1342 entry->filename = (char *) estrndup(path, path_len + 1);
1343 entry->filename_len = path_len;
1344 entry->phar = phar;
1345 return entry;
1346 }
1347 }
1348
1349 if (HT_IS_INITIALIZED(&phar->mounted_dirs) && zend_hash_num_elements(&phar->mounted_dirs)) {
1350 zend_string *str_key;
1351
1353 if (ZSTR_LEN(str_key) >= path_len || strncmp(ZSTR_VAL(str_key), path, ZSTR_LEN(str_key))) {
1354 continue;
1355 } else {
1356 char *test;
1357 size_t test_len;
1359
1360 if (NULL == (entry = zend_hash_find_ptr(&phar->manifest, str_key))) {
1361 if (error) {
1362 spprintf(error, 4096, "phar internal error: mounted path \"%s\" could not be retrieved from manifest", ZSTR_VAL(str_key));
1363 }
1364 return NULL;
1365 }
1366
1367 if (!entry->tmp || !entry->is_mounted) {
1368 if (error) {
1369 spprintf(error, 4096, "phar internal error: mounted path \"%s\" is not properly initialized as a mounted path", ZSTR_VAL(str_key));
1370 }
1371 return NULL;
1372 }
1373
1374 test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, path + ZSTR_LEN(str_key));
1375
1376 if (SUCCESS != php_stream_stat_path(test, &ssb)) {
1377 efree(test);
1378 return NULL;
1379 }
1380
1381 if ((ssb.sb.st_mode & S_IFDIR) && !dir) {
1382 efree(test);
1383 if (error) {
1384 spprintf(error, 4096, "phar error: path \"%s\" is a directory", path);
1385 }
1386 return NULL;
1387 }
1388
1389 if ((ssb.sb.st_mode & S_IFDIR) == 0 && dir) {
1390 efree(test);
1391 /* user requested a directory, we must return one */
1392 if (error) {
1393 spprintf(error, 4096, "phar error: path \"%s\" exists and is a not a directory", path);
1394 }
1395 return NULL;
1396 }
1397
1398 /* mount the file just in time */
1399 if (SUCCESS != phar_mount_entry(phar, test, test_len, path, path_len)) {
1400 efree(test);
1401 if (error) {
1402 spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be mounted", path, test);
1403 }
1404 return NULL;
1405 }
1406
1407 efree(test);
1408
1409 if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) {
1410 if (error) {
1411 spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be retrieved after being mounted", path, test);
1412 }
1413 return NULL;
1414 }
1415 return entry;
1416 }
1418 }
1419
1420 return NULL;
1421}
1422/* }}} */
1423
1424static const char hexChars[] = "0123456789ABCDEF";
1425
1426static int phar_hex_str(const char *digest, size_t digest_len, char **signature) /* {{{ */
1427{
1428 int pos = -1;
1429 size_t len = 0;
1430
1431 *signature = (char*)safe_pemalloc(digest_len, 2, 1, PHAR_G(persist));
1432
1433 for (; len < digest_len; ++len) {
1434 (*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] >> 4];
1435 (*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] & 0x0F];
1436 }
1437 (*signature)[++pos] = '\0';
1438 return pos;
1439}
1440/* }}} */
1441
1442#ifndef PHAR_HAVE_OPENSSL
1443static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type) /* {{{ */
1444{
1445 zend_fcall_info fci;
1447 zval retval, zp[4], openssl;
1448 zend_string *str;
1449
1450 ZVAL_STRINGL(&openssl, is_sign ? "openssl_sign" : "openssl_verify", is_sign ? sizeof("openssl_sign")-1 : sizeof("openssl_verify")-1);
1451 if (*signature_len) {
1452 ZVAL_STRINGL(&zp[1], *signature, *signature_len);
1453 } else {
1454 ZVAL_EMPTY_STRING(&zp[1]);
1455 }
1456 ZVAL_STRINGL(&zp[2], key, key_len);
1458 str = php_stream_copy_to_mem(fp, (size_t) end, 0);
1459 if (str) {
1460 ZVAL_STR(&zp[0], str);
1461 } else {
1462 ZVAL_EMPTY_STRING(&zp[0]);
1463 }
1464 if (sig_type == PHAR_SIG_OPENSSL_SHA512) {
1465 ZVAL_LONG(&zp[3], 9); /* value from openssl.c #define OPENSSL_ALGO_SHA512 9 */
1466 } else if (sig_type == PHAR_SIG_OPENSSL_SHA256) {
1467 ZVAL_LONG(&zp[3], 7); /* value from openssl.c #define OPENSSL_ALGO_SHA256 7 */
1468 } else {
1469 /* don't rely on default value which may change in the future */
1470 ZVAL_LONG(&zp[3], 1); /* value from openssl.c #define OPENSSL_ALGO_SHA1 1 */
1471 }
1472
1473 if ((size_t)end != Z_STRLEN(zp[0])) {
1474 zval_ptr_dtor_str(&zp[0]);
1475 zval_ptr_dtor_str(&zp[1]);
1476 zval_ptr_dtor_str(&zp[2]);
1477 zval_ptr_dtor_str(&openssl);
1478 return FAILURE;
1479 }
1480
1481 if (FAILURE == zend_fcall_info_init(&openssl, 0, &fci, &fcc, NULL, NULL)) {
1482 zval_ptr_dtor_str(&zp[0]);
1483 zval_ptr_dtor_str(&zp[1]);
1484 zval_ptr_dtor_str(&zp[2]);
1485 zval_ptr_dtor_str(&openssl);
1486 return FAILURE;
1487 }
1488
1489 fci.param_count = 4;
1490 fci.params = zp;
1491 Z_ADDREF(zp[0]);
1492 if (is_sign) {
1493 ZVAL_NEW_REF(&zp[1], &zp[1]);
1494 } else {
1495 Z_ADDREF(zp[1]);
1496 }
1497 Z_ADDREF(zp[2]);
1498
1499 fci.retval = &retval;
1500
1501 if (FAILURE == zend_call_function(&fci, &fcc)) {
1502 zval_ptr_dtor_str(&zp[0]);
1503 zval_ptr_dtor(&zp[1]);
1504 zval_ptr_dtor_str(&zp[2]);
1505 zval_ptr_dtor_str(&openssl);
1506 return FAILURE;
1507 }
1508
1509 zval_ptr_dtor_str(&openssl);
1510 Z_DELREF(zp[0]);
1511
1512 if (is_sign) {
1513 ZVAL_UNREF(&zp[1]);
1514 } else {
1515 Z_DELREF(zp[1]);
1516 }
1517 Z_DELREF(zp[2]);
1518
1519 zval_ptr_dtor_str(&zp[0]);
1520 zval_ptr_dtor_str(&zp[2]);
1521
1522 switch (Z_TYPE(retval)) {
1523 default:
1524 case IS_LONG:
1525 zval_ptr_dtor(&zp[1]);
1526 if (1 == Z_LVAL(retval)) {
1527 return SUCCESS;
1528 }
1529 return FAILURE;
1530 case IS_TRUE:
1531 *signature = estrndup(Z_STRVAL(zp[1]), Z_STRLEN(zp[1]));
1532 *signature_len = Z_STRLEN(zp[1]);
1533 zval_ptr_dtor(&zp[1]);
1534 return SUCCESS;
1535 case IS_FALSE:
1536 zval_ptr_dtor(&zp[1]);
1537 return FAILURE;
1538 }
1539}
1540/* }}} */
1541#endif /* #ifndef PHAR_HAVE_OPENSSL */
1542
1543zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */
1544{
1545 size_t read_size, len;
1546 zend_off_t read_len;
1547 unsigned char buf[1024];
1548
1550
1551 switch (sig_type) {
1554 case PHAR_SIG_OPENSSL: {
1555#ifdef PHAR_HAVE_OPENSSL
1556 BIO *in;
1557 EVP_PKEY *key;
1558 const EVP_MD *mdtype;
1559 EVP_MD_CTX *md_ctx;
1560
1561 if (sig_type == PHAR_SIG_OPENSSL_SHA512) {
1562 mdtype = EVP_sha512();
1563 } else if (sig_type == PHAR_SIG_OPENSSL_SHA256) {
1564 mdtype = EVP_sha256();
1565 } else {
1566 mdtype = EVP_sha1();
1567 }
1568#else
1569 size_t tempsig;
1570#endif
1571 zend_string *pubkey = NULL;
1572 char *pfile;
1573 php_stream *pfp;
1574#ifndef PHAR_HAVE_OPENSSL
1575 if (!zend_hash_str_exists(&module_registry, "openssl", sizeof("openssl")-1)) {
1576 if (error) {
1577 spprintf(error, 0, "openssl not loaded");
1578 }
1579 return FAILURE;
1580 }
1581#endif
1582 /* use __FILE__ . '.pubkey' for public key file */
1583 spprintf(&pfile, 0, "%s.pubkey", fname);
1584 pfp = php_stream_open_wrapper(pfile, "rb", 0, NULL);
1585 efree(pfile);
1586
1587 if (!pfp || !(pubkey = php_stream_copy_to_mem(pfp, PHP_STREAM_COPY_ALL, 0)) || !ZSTR_LEN(pubkey)) {
1588 if (pfp) {
1589 php_stream_close(pfp);
1590 }
1591 if (error) {
1592 spprintf(error, 0, "openssl public key could not be read");
1593 }
1594 return FAILURE;
1595 }
1596
1597 php_stream_close(pfp);
1598#ifndef PHAR_HAVE_OPENSSL
1599 tempsig = sig_len;
1600
1601 if (FAILURE == phar_call_openssl_signverify(0, fp, end_of_phar, ZSTR_VAL(pubkey), ZSTR_LEN(pubkey), &sig, &tempsig, sig_type)) {
1602 zend_string_release_ex(pubkey, 0);
1603
1604 if (error) {
1605 spprintf(error, 0, "openssl signature could not be verified");
1606 }
1607
1608 return FAILURE;
1609 }
1610
1611 zend_string_release_ex(pubkey, 0);
1612
1613 sig_len = tempsig;
1614#else
1615 in = BIO_new_mem_buf(ZSTR_VAL(pubkey), ZSTR_LEN(pubkey));
1616
1617 if (NULL == in) {
1618 zend_string_release_ex(pubkey, 0);
1619 if (error) {
1620 spprintf(error, 0, "openssl signature could not be processed");
1621 }
1622 return FAILURE;
1623 }
1624
1625 key = PEM_read_bio_PUBKEY(in, NULL, NULL, NULL);
1626 BIO_free(in);
1627 zend_string_release_ex(pubkey, 0);
1628
1629 if (NULL == key) {
1630 if (error) {
1631 spprintf(error, 0, "openssl signature could not be processed");
1632 }
1633 return FAILURE;
1634 }
1635
1636 md_ctx = EVP_MD_CTX_create();
1637 if (!md_ctx || !EVP_VerifyInit(md_ctx, mdtype)) {
1638 if (md_ctx) {
1639 EVP_MD_CTX_destroy(md_ctx);
1640 }
1641 if (error) {
1642 spprintf(error, 0, "openssl signature could not be verified");
1643 }
1644 return FAILURE;
1645 }
1646 read_len = end_of_phar;
1647
1648 if ((size_t)read_len > sizeof(buf)) {
1649 read_size = sizeof(buf);
1650 } else {
1651 read_size = (size_t)read_len;
1652 }
1653
1654 php_stream_seek(fp, 0, SEEK_SET);
1655
1656 while (read_size && (len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1657 if (UNEXPECTED(EVP_VerifyUpdate (md_ctx, buf, len) == 0)) {
1658 goto failure;
1659 }
1660 read_len -= (zend_off_t)len;
1661
1662 if (read_len < read_size) {
1663 read_size = (size_t)read_len;
1664 }
1665 }
1666
1667 if (EVP_VerifyFinal(md_ctx, (unsigned char *)sig, sig_len, key) != 1) {
1668 failure:
1669 /* 1: signature verified, 0: signature does not match, -1: failed signature operation */
1670 EVP_PKEY_free(key);
1671 EVP_MD_CTX_destroy(md_ctx);
1672
1673 if (error) {
1674 spprintf(error, 0, "broken openssl signature");
1675 }
1676
1677 return FAILURE;
1678 }
1679
1680 EVP_PKEY_free(key);
1681 EVP_MD_CTX_destroy(md_ctx);
1682#endif
1683
1684 *signature_len = phar_hex_str((const char*)sig, sig_len, signature);
1685 }
1686 break;
1687 case PHAR_SIG_SHA512: {
1688 unsigned char digest[64];
1690
1691 if (sig_len < sizeof(digest)) {
1692 if (error) {
1693 spprintf(error, 0, "broken signature");
1694 }
1695 return FAILURE;
1696 }
1697
1699 read_len = end_of_phar;
1700
1701 if ((size_t)read_len > sizeof(buf)) {
1702 read_size = sizeof(buf);
1703 } else {
1704 read_size = (size_t)read_len;
1705 }
1706
1707 while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1709 read_len -= (zend_off_t)len;
1710 if ((size_t)read_len < read_size) {
1711 read_size = (size_t)read_len;
1712 }
1713 }
1714
1715 PHP_SHA512Final(digest, &context);
1716
1717 if (memcmp(digest, sig, sizeof(digest))) {
1718 if (error) {
1719 spprintf(error, 0, "broken signature");
1720 }
1721 return FAILURE;
1722 }
1723
1724 *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
1725 break;
1726 }
1727 case PHAR_SIG_SHA256: {
1728 unsigned char digest[32];
1730
1731 if (sig_len < sizeof(digest)) {
1732 if (error) {
1733 spprintf(error, 0, "broken signature");
1734 }
1735 return FAILURE;
1736 }
1737
1739 read_len = end_of_phar;
1740
1741 if ((size_t)read_len > sizeof(buf)) {
1742 read_size = sizeof(buf);
1743 } else {
1744 read_size = (size_t)read_len;
1745 }
1746
1747 while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1749 read_len -= (zend_off_t)len;
1750 if ((size_t)read_len < read_size) {
1751 read_size = (size_t)read_len;
1752 }
1753 }
1754
1755 PHP_SHA256Final(digest, &context);
1756
1757 if (memcmp(digest, sig, sizeof(digest))) {
1758 if (error) {
1759 spprintf(error, 0, "broken signature");
1760 }
1761 return FAILURE;
1762 }
1763
1764 *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
1765 break;
1766 }
1767 case PHAR_SIG_SHA1: {
1768 unsigned char digest[20];
1770
1771 if (sig_len < sizeof(digest)) {
1772 if (error) {
1773 spprintf(error, 0, "broken signature");
1774 }
1775 return FAILURE;
1776 }
1777
1779 read_len = end_of_phar;
1780
1781 if ((size_t)read_len > sizeof(buf)) {
1782 read_size = sizeof(buf);
1783 } else {
1784 read_size = (size_t)read_len;
1785 }
1786
1787 while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1789 read_len -= (zend_off_t)len;
1790 if ((size_t)read_len < read_size) {
1791 read_size = (size_t)read_len;
1792 }
1793 }
1794
1795 PHP_SHA1Final(digest, &context);
1796
1797 if (memcmp(digest, sig, sizeof(digest))) {
1798 if (error) {
1799 spprintf(error, 0, "broken signature");
1800 }
1801 return FAILURE;
1802 }
1803
1804 *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
1805 break;
1806 }
1807 case PHAR_SIG_MD5: {
1808 unsigned char digest[16];
1810
1811 if (sig_len < sizeof(digest)) {
1812 if (error) {
1813 spprintf(error, 0, "broken signature");
1814 }
1815 return FAILURE;
1816 }
1817
1819 read_len = end_of_phar;
1820
1821 if ((size_t)read_len > sizeof(buf)) {
1822 read_size = sizeof(buf);
1823 } else {
1824 read_size = (size_t)read_len;
1825 }
1826
1827 while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1829 read_len -= (zend_off_t)len;
1830 if ((size_t)read_len < read_size) {
1831 read_size = (size_t)read_len;
1832 }
1833 }
1834
1835 PHP_MD5Final(digest, &context);
1836
1837 if (memcmp(digest, sig, sizeof(digest))) {
1838 if (error) {
1839 spprintf(error, 0, "broken signature");
1840 }
1841 return FAILURE;
1842 }
1843
1844 *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
1845 break;
1846 }
1847 default:
1848 if (error) {
1849 spprintf(error, 0, "broken or unsupported signature");
1850 }
1851 return FAILURE;
1852 }
1853 return SUCCESS;
1854}
1855/* }}} */
1856
1857zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error) /* {{{ */
1858{
1859 unsigned char buf[1024];
1860 size_t sig_len;
1861
1863
1864 if (phar->signature) {
1865 efree(phar->signature);
1866 phar->signature = NULL;
1867 }
1868
1869 switch(phar->sig_flags) {
1870 case PHAR_SIG_SHA512: {
1871 unsigned char digest[64];
1873
1875
1876 while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
1877 PHP_SHA512Update(&context, buf, sig_len);
1878 }
1879
1880 PHP_SHA512Final(digest, &context);
1881 *signature = estrndup((char *) digest, 64);
1882 *signature_length = 64;
1883 break;
1884 }
1885 default:
1886 phar->sig_flags = PHAR_SIG_SHA256;
1888 case PHAR_SIG_SHA256: {
1889 unsigned char digest[32];
1891
1893
1894 while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
1895 PHP_SHA256Update(&context, buf, sig_len);
1896 }
1897
1898 PHP_SHA256Final(digest, &context);
1899 *signature = estrndup((char *) digest, 32);
1900 *signature_length = 32;
1901 break;
1902 }
1905 case PHAR_SIG_OPENSSL: {
1906 unsigned char *sigbuf;
1907#ifdef PHAR_HAVE_OPENSSL
1908 unsigned int siglen;
1909 BIO *in;
1910 EVP_PKEY *key;
1911 EVP_MD_CTX *md_ctx;
1912 const EVP_MD *mdtype;
1913
1914 if (phar->sig_flags == PHAR_SIG_OPENSSL_SHA512) {
1915 mdtype = EVP_sha512();
1916 } else if (phar->sig_flags == PHAR_SIG_OPENSSL_SHA256) {
1917 mdtype = EVP_sha256();
1918 } else {
1919 mdtype = EVP_sha1();
1920 }
1921
1922 in = BIO_new_mem_buf(PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len));
1923
1924 if (in == NULL) {
1925 if (error) {
1926 spprintf(error, 0, "unable to write to phar \"%s\" with requested openssl signature", phar->fname);
1927 }
1928 return FAILURE;
1929 }
1930
1931 key = PEM_read_bio_PrivateKey(in, NULL,NULL, "");
1932 BIO_free(in);
1933
1934 if (!key) {
1935 if (error) {
1936 spprintf(error, 0, "unable to process private key");
1937 }
1938 return FAILURE;
1939 }
1940
1941 md_ctx = EVP_MD_CTX_create();
1942 if (md_ctx == NULL) {
1943 EVP_PKEY_free(key);
1944 if (error) {
1945 spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", phar->fname);
1946 }
1947 return FAILURE;
1948 }
1949
1950 siglen = EVP_PKEY_size(key);
1951 sigbuf = emalloc(siglen + 1);
1952
1953 if (!EVP_SignInit(md_ctx, mdtype)) {
1954 EVP_PKEY_free(key);
1955 efree(sigbuf);
1956 if (error) {
1957 spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", phar->fname);
1958 }
1959 return FAILURE;
1960 }
1961
1962 while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
1963 if (!EVP_SignUpdate(md_ctx, buf, sig_len)) {
1964 EVP_PKEY_free(key);
1965 efree(sigbuf);
1966 if (error) {
1967 spprintf(error, 0, "unable to update the openssl signature for phar \"%s\"", phar->fname);
1968 }
1969 return FAILURE;
1970 }
1971 }
1972
1973 if (!EVP_SignFinal (md_ctx, sigbuf, &siglen, key)) {
1974 EVP_PKEY_free(key);
1975 efree(sigbuf);
1976 if (error) {
1977 spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname);
1978 }
1979 return FAILURE;
1980 }
1981
1982 sigbuf[siglen] = '\0';
1983 EVP_PKEY_free(key);
1984 EVP_MD_CTX_destroy(md_ctx);
1985#else
1986 size_t siglen;
1987 sigbuf = NULL;
1988 siglen = 0;
1989 php_stream_seek(fp, 0, SEEK_END);
1990
1991 if (FAILURE == phar_call_openssl_signverify(1, fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen, phar->sig_flags)) {
1992 if (error) {
1993 spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname);
1994 }
1995 return FAILURE;
1996 }
1997#endif
1998 *signature = (char *) sigbuf;
1999 *signature_length = siglen;
2000 }
2001 break;
2002 case PHAR_SIG_SHA1: {
2003 unsigned char digest[20];
2005
2007
2008 while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
2009 PHP_SHA1Update(&context, buf, sig_len);
2010 }
2011
2012 PHP_SHA1Final(digest, &context);
2013 *signature = estrndup((char *) digest, 20);
2014 *signature_length = 20;
2015 break;
2016 }
2017 case PHAR_SIG_MD5: {
2018 unsigned char digest[16];
2020
2022
2023 while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
2024 PHP_MD5Update(&context, buf, sig_len);
2025 }
2026
2027 PHP_MD5Final(digest, &context);
2028 *signature = estrndup((char *) digest, 16);
2029 *signature_length = 16;
2030 break;
2031 }
2032 }
2033
2034 phar->sig_len = phar_hex_str((const char *)*signature, *signature_length, &phar->signature);
2035 return SUCCESS;
2036}
2037/* }}} */
2038
2039void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len) /* {{{ */
2040{
2041 const char *s;
2042 zend_string *str;
2043 zval *ret;
2044
2045 while ((s = zend_memrchr(filename, '/', filename_len))) {
2046 filename_len = s - filename;
2047 if (!filename_len) {
2048 break;
2049 }
2050 if (GC_FLAGS(&phar->virtual_dirs) & GC_PERSISTENT) {
2051 str = zend_string_init_interned(filename, filename_len, 1);
2052 } else {
2053 str = zend_string_init(filename, filename_len, 0);
2054 }
2056 zend_string_release(str);
2057 if (ret == NULL) {
2058 break;
2059 }
2060 }
2061}
2062/* }}} */
2063
2064static int phar_update_cached_entry(zval *data, void *argument) /* {{{ */
2065{
2067
2068 entry->phar = (phar_archive_data *)argument;
2069
2070 if (entry->link) {
2071 entry->link = estrdup(entry->link);
2072 }
2073
2074 if (entry->tmp) {
2075 entry->tmp = estrdup(entry->tmp);
2076 }
2077
2078 entry->filename = estrndup(entry->filename, entry->filename_len);
2079 entry->is_persistent = 0;
2080
2081 /* Replace metadata with non-persistent clones of the metadata. */
2083 return ZEND_HASH_APPLY_KEEP;
2084}
2085/* }}} */
2086
2087static void phar_manifest_copy_ctor(zval *zv) /* {{{ */
2088{
2089 phar_entry_info *info = emalloc(sizeof(phar_entry_info));
2090 memcpy(info, Z_PTR_P(zv), sizeof(phar_entry_info));
2091 Z_PTR_P(zv) = info;
2092}
2093/* }}} */
2094
2095static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */
2096{
2097 phar_archive_data *phar;
2098 HashTable newmanifest;
2099 char *fname;
2100 phar_archive_object *objphar;
2101
2102 phar = (phar_archive_data *) emalloc(sizeof(phar_archive_data));
2103 *phar = **pphar;
2104 phar->is_persistent = 0;
2105 fname = phar->fname;
2106 phar->fname = estrndup(phar->fname, phar->fname_len);
2107 phar->ext = phar->fname + (phar->ext - fname);
2108
2109 if (phar->alias) {
2110 phar->alias = estrndup(phar->alias, phar->alias_len);
2111 }
2112
2113 if (phar->signature) {
2114 phar->signature = estrdup(phar->signature);
2115 }
2116
2118
2119 zend_hash_init(&newmanifest, sizeof(phar_entry_info),
2120 zend_get_hash_value, destroy_phar_manifest_entry, 0);
2121 zend_hash_copy(&newmanifest, &(*pphar)->manifest, phar_manifest_copy_ctor);
2122 zend_hash_apply_with_argument(&newmanifest, phar_update_cached_entry, (void *)phar);
2123 phar->manifest = newmanifest;
2124 zend_hash_init(&phar->mounted_dirs, sizeof(char *),
2125 zend_get_hash_value, NULL, 0);
2126 zend_hash_init(&phar->virtual_dirs, sizeof(char *),
2127 zend_get_hash_value, NULL, 0);
2128 zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL);
2129 *pphar = phar;
2130
2131 /* now, scan the list of persistent Phar objects referencing this phar and update the pointers */
2133 if (objphar->archive->fname_len == phar->fname_len && !memcmp(objphar->archive->fname, phar->fname, phar->fname_len)) {
2134 objphar->archive = phar;
2135 }
2137}
2138/* }}} */
2139
2141{
2142 zval zv, *pzv;
2143 phar_archive_data *newpphar;
2144
2145 ZVAL_PTR(&zv, *pphar);
2146 if (NULL == (pzv = zend_hash_str_add(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len, &zv))) {
2147 return FAILURE;
2148 }
2149
2150 phar_copy_cached_phar((phar_archive_data **)&Z_PTR_P(pzv));
2151 newpphar = Z_PTR_P(pzv);
2152 /* invalidate phar cache */
2155
2156 if (newpphar->alias_len && NULL == zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), newpphar->alias, newpphar->alias_len, newpphar)) {
2157 zend_hash_str_del(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len);
2158 return FAILURE;
2159 }
2160
2161 *pphar = newpphar;
2162 return SUCCESS;
2163}
2164/* }}} */
size_t len
Definition apprentice.c:174
is_dir(string $filename)
strrchr(string $haystack, string $needle, bool $before_needle=false)
dir(string $directory, $context=null)
link(string $target, string $link)
char s[4]
Definition cdf.c:77
error($message)
Definition ext_skel.php:22
zend_ffi_type * type
Definition ffi.c:3812
zval * zv
Definition ffi.c:3975
memcpy(ptr1, ptr2, size)
char * err
Definition ffi.c:3029
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
const SEEK_CUR
Definition file.stub.php:16
const SEEK_END
Definition file.stub.php:21
PHPAPI zend_string * php_resolve_path(const char *filename, size_t filename_length, const char *path)
PHPAPI int php_check_open_basedir(const char *path)
PHPAPI char * expand_filepath(const char *filepath, char *real_path)
zend_long offset
char * mode
size_t filename_len
#define SEEK_SET
Definition gd_io_file.c:20
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
PHP_HASH_API void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX *context)
Definition hash_sha.c:360
PHP_HASH_API void PHP_SHA256Update(PHP_SHA256_CTX *context, const unsigned char *input, size_t inputLen)
Definition hash_sha.c:320
PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX *context, const unsigned char *input, size_t inputLen)
Definition hash_sha.c:690
PHP_HASH_API void PHP_SHA512Final(unsigned char digest[64], PHP_SHA512_CTX *context)
Definition hash_sha.c:731
PHPAPI php_stream_filter * php_stream_filter_create(const char *filtername, zval *filterparams, uint8_t persistent)
Definition filter.c:220
PHPAPI php_stream_filter * php_stream_filter_remove(php_stream_filter *filter, int call_dtor)
Definition filter.c:483
PHPAPI void PHP_MD5Final(unsigned char *result, PHP_MD5_CTX *ctx)
Definition md5.c:339
PHPAPI void PHP_MD5Update(PHP_MD5_CTX *ctx, const void *data, size_t size)
Definition md5.c:304
#define PHP_MD5Init(ctx)
Definition md5.h:43
HashTable cached_phars
Definition phar.c:90
char * phar_fix_filepath(char *path, size_t *new_len, int use_cwd)
Definition phar.c:2128
phar_globals readonly
Definition phar.c:3346
zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip)
Definition phar.c:2378
void phar_metadata_tracker_clone(phar_metadata_tracker *tracker)
Definition phar.c:684
zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create)
Definition phar.c:2240
void phar_request_initialize(void)
Definition phar.c:3446
void destroy_phar_manifest_entry(zval *zv)
Definition phar.c:384
HashTable cached_alias
Definition phar.c:91
char * last_alias
#define PHAR_SIG_OPENSSL_SHA512
phar_fp_type
@ PHAR_MOD
@ PHAR_TMP
@ PHAR_FP
@ PHAR_UFP
phar_path_check_result phar_path_check(char **p, size_t *len, const char **error)
#define PHAR_ENT_COMPRESSED_GZ
#define PHAR_SIG_OPENSSL_SHA256
HashTable phar_alias_map
phar_archive_data * last_phar
struct _phar_entry_fp_info phar_entry_fp_info
#define PHAR_ENT_PERM_DEF_DIR
HashTable phar_fname_map
uint32_t last_phar_name_len
char * cwd
#define PHAR_SIG_SHA1
#define PHAR_ENT_PERM_DEF_FILE
#define PHAR_G(v)
char * phar_decompress_filter(phar_entry_info *entry, int return_unknown)
Definition util.c:1233
HashTable phar_persist_map
uint32_t last_alias_len
struct _phar_archive_data phar_archive_data
bool manifest_cached
#define PHAR_ENT_COMPRESSION_MASK
#define PHAR_SIG_OPENSSL
uint32_t openssl_privatekey_len
#define TAR_FILE
#define PHAR_ENT_COMPRESSED_BZ2
#define PHAR_SIG_SHA512
struct _phar_entry_info phar_entry_info
#define PHAR_SIG_SHA256
bool persist
struct _phar_entry_data phar_entry_data
union _phar_archive_object phar_archive_object
phar_entry_fp * cached_fp
char * last_phar_name
#define PHAR_SIG_MD5
zend_result phar_copy_on_write(phar_archive_data **pphar)
Definition util.c:2140
char * openssl_privatekey
@ pcr_is_ok
#define TAR_DIR
time()
unsigned const char * end
Definition php_ffi.h:51
unsigned const char * pos
Definition php_ffi.h:52
#define PG(v)
Definition php_globals.h:31
#define PHP_SHA256Init(ctx)
#define PHP_SHA512Init(ctx)
#define PHP_PHAR_API
Definition php_phar.h:32
unsigned char key[REFLECTION_KEY_LEN]
#define php_stream_filter_append(chain, filter)
#define php_stream_filter_flush(filter, finish)
#define php_stream_fopen_tmpfile()
#define php_stream_stat_path(path, ssb)
struct _php_stream php_stream
Definition php_streams.h:96
#define php_stream_read(stream, buf, count)
struct _php_stream_filter php_stream_filter
Definition php_streams.h:99
#define php_stream_rewind(stream)
#define PHP_STREAM_COPY_ALL
#define php_stream_seek(stream, offset, whence)
#define php_stream_flush(stream)
#define php_stream_truncate_set_size(stream, size)
#define php_stream_close(stream)
#define php_stream_tell(stream)
#define php_stream_copy_to_mem(src, maxlen, persistent)
#define php_stream_open_wrapper(path, mode, options, opened)
#define php_stream_copy_to_stream_ex(src, dest, maxlen, len)
#define STREAM_MUST_SEEK
#define IGNORE_URL
struct _php_stream_statbuf php_stream_statbuf
int fd
Definition phpdbg.h:282
#define zend_hash_str_add(...)
Definition phpdbg.h:77
zend_constant * data
p
Definition session.c:1105
PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX *context)
Definition sha1.c:215
PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX *context, const unsigned char *input, size_t inputLen)
Definition sha1.c:173
#define PHP_SHA1Init(ctx)
Definition sha1.h:28
#define strpprintf
Definition spprintf.h:30
#define spprintf
Definition spprintf.h:29
phar_metadata_tracker metadata_tracker
phar_archive_data * phar
phar_entry_info * internal_file
zend_off_t zero
php_stream * fp
uint32_t timestamp
uint32_t is_modified
uint32_t is_crc_checked
uint32_t is_tar
uint32_t flags
uint32_t is_deleted
uint32_t is_dir
char * filename
uint32_t manifest_pos
uint32_t compressed_filesize
php_stream * fp
int fp_refcount
uint32_t is_temp_dir
uint32_t old_flags
uint32_t is_zip
phar_metadata_tracker metadata_tracker
uint32_t is_mounted
enum phar_fp_type fp_type
uint32_t crc32
char tar_type
char * tmp
uint32_t uncompressed_filesize
phar_archive_data * phar
uint32_t is_persistent
uint32_t filename_len
char * link
zend_long offset
php_stream_filter_chain writefilters
uint32_t param_count
Definition zend_API.h:51
Definition dce.c:49
test($x, $y=0)
Definition test.php:21
phar_archive_data * archive
void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len)
Definition util.c:2039
char * phar_compress_filter(phar_entry_info *entry, int return_unknown)
Definition util.c:1217
phar_entry_info * phar_get_link_source(phar_entry_info *entry)
Definition util.c:63
int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links)
Definition util.c:140
PHP_PHAR_API zend_result phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len)
Definition util.c:978
zend_string * phar_find_in_include_path(zend_string *filename, phar_archive_data **pphar)
Definition util.c:266
zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error)
Definition util.c:774
phar_entry_data * phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security)
Definition util.c:634
phar_entry_info * phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, int security)
Definition util.c:1267
php_stream * phar_get_efp(phar_entry_info *entry, int follow_links)
Definition util.c:97
char * phar_decompress_filter(phar_entry_info *entry, int return_unknown)
Definition util.c:1233
zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error)
Definition util.c:1857
zend_result phar_open_archive_fp(phar_archive_data *phar)
Definition util.c:753
phar_entry_info * phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, int security)
Definition util.c:1257
zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len)
Definition util.c:190
zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len)
Definition util.c:990
zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security)
Definition util.c:474
zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error)
Definition util.c:1543
zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links)
Definition util.c:842
zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error)
Definition util.c:1013
zend_result phar_copy_on_write(phar_archive_data **pphar)
Definition util.c:2140
phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error)
Definition util.c:961
ZEND_API HashTable module_registry
Definition zend_API.c:41
ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error)
Definition zend_API.c:4310
struct _zend_fcall_info_cache zend_fcall_info_cache
struct _zend_fcall_info zend_fcall_info
#define ZVAL_STRINGL(z, s, l)
Definition zend_API.h:952
ZEND_API zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
#define ZVAL_EMPTY_STRING(z)
Definition zend_API.h:961
#define estrndup(s, length)
Definition zend_alloc.h:165
#define ecalloc(nmemb, size)
Definition zend_alloc.h:158
#define efree(ptr)
Definition zend_alloc.h:155
#define estrdup(s)
Definition zend_alloc.h:164
#define safe_pemalloc(nmemb, size, offset, persistent)
Definition zend_alloc.h:190
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
strlen(string $string)
strncmp(string $string1, string $string2, int $length)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API zend_string * zend_get_executed_filename_ex(void)
ZEND_API bool zend_is_executing(void)
ZEND_API void ZEND_FASTCALL zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *argument)
Definition zend_hash.c:2099
ZEND_API void ZEND_FASTCALL zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor)
Definition zend_hash.c:2240
ZEND_API zval *ZEND_FASTCALL zend_hash_add_empty_element(HashTable *ht, zend_string *key)
Definition zend_hash.c:1067
ZEND_API zend_result ZEND_FASTCALL zend_hash_str_del(HashTable *ht, const char *str, size_t len)
Definition zend_hash.c:1661
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
Definition zend_hash.h:108
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
Definition zend_hash.h:1326
#define HT_IS_INITIALIZED(ht)
Definition zend_hash.h:56
#define ZEND_HASH_APPLY_KEEP
Definition zend_hash.h:146
#define ZEND_HASH_MAP_FOREACH_STR_KEY(ht, _key)
Definition zend_hash.h:1346
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
int32_t zend_off_t
Definition zend_long.h:44
struct _zend_string zend_string
#define ZEND_FALLTHROUGH
#define UNEXPECTED(condition)
ZEND_API zend_string_init_interned_func_t zend_string_init_interned
Definition zend_string.c:31
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define zend_string_starts_with_literal_ci(str, prefix)
#define IS_TRUE
Definition zend_types.h:603
#define ZVAL_STR(z, s)
#define IS_FALSE
Definition zend_types.h:602
#define ZVAL_LONG(z, l)
struct _zend_array HashTable
Definition zend_types.h:386
#define Z_PTR_P(zval_p)
#define ZVAL_NEW_REF(z, r)
#define GC_FLAGS(p)
Definition zend_types.h:756
#define ZVAL_UNREF(z)
#define Z_STRVAL(zval)
Definition zend_types.h:974
@ FAILURE
Definition zend_types.h:61
#define Z_STRLEN(zval)
Definition zend_types.h:977
#define Z_ADDREF(z)
#define IS_LONG
Definition zend_types.h:604
#define ZVAL_PTR(z, p)
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
#define GC_PERSISTENT
Definition zend_types.h:781
#define Z_TYPE(zval)
Definition zend_types.h:659
#define Z_LVAL(zval)
Definition zend_types.h:965
#define Z_DELREF(z)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
#define DEFAULT_DIR_SEPARATOR
#define MAXPATHLEN
zval retval
zval * ret