Annotation of embedaddon/php/ext/phar/phar_internal.h, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | phar php single-file executable PHP extension |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 2006-2012 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: | Authors: Gregory Beaver <cellog@php.net> |
! 16: | Marcus Boerger <helly@php.net> |
! 17: +----------------------------------------------------------------------+
! 18: */
! 19:
! 20: /* $Id: phar_internal.h 321634 2012-01-01 13:15:04Z felipe $ */
! 21:
! 22: #ifdef HAVE_CONFIG_H
! 23: #include "config.h"
! 24: #endif
! 25:
! 26: #include <time.h>
! 27: #include "php.h"
! 28: #include "tar.h"
! 29: #include "php_ini.h"
! 30: #include "zend_constants.h"
! 31: #include "zend_execute.h"
! 32: #include "zend_exceptions.h"
! 33: #include "zend_hash.h"
! 34: #include "zend_interfaces.h"
! 35: #include "zend_operators.h"
! 36: #include "zend_qsort.h"
! 37: #include "zend_vm.h"
! 38: #include "main/php_streams.h"
! 39: #include "main/streams/php_stream_plain_wrapper.h"
! 40: #include "main/SAPI.h"
! 41: #include "main/php_main.h"
! 42: #include "main/php_open_temporary_file.h"
! 43: #include "ext/standard/info.h"
! 44: #include "ext/standard/basic_functions.h"
! 45: #include "ext/standard/file.h"
! 46: #include "ext/standard/php_string.h"
! 47: #include "ext/standard/url.h"
! 48: #include "ext/standard/crc32.h"
! 49: #include "ext/standard/md5.h"
! 50: #include "ext/standard/sha1.h"
! 51: #include "ext/standard/php_var.h"
! 52: #include "ext/standard/php_smart_str.h"
! 53: #include "ext/standard/php_versioning.h"
! 54: #ifndef PHP_WIN32
! 55: #include "TSRM/tsrm_strtok_r.h"
! 56: #endif
! 57: #include "TSRM/tsrm_virtual_cwd.h"
! 58: #if HAVE_SPL
! 59: #include "ext/spl/spl_array.h"
! 60: #include "ext/spl/spl_directory.h"
! 61: #include "ext/spl/spl_engine.h"
! 62: #include "ext/spl/spl_exceptions.h"
! 63: #include "ext/spl/spl_iterators.h"
! 64: #endif
! 65: #include "php_phar.h"
! 66: #ifdef HAVE_STDINT_H
! 67: #include <stdint.h>
! 68: #endif
! 69: #ifdef PHAR_HASH_OK
! 70: #include "ext/hash/php_hash.h"
! 71: #include "ext/hash/php_hash_sha.h"
! 72: #endif
! 73:
! 74: #ifndef E_RECOVERABLE_ERROR
! 75: # define E_RECOVERABLE_ERROR E_ERROR
! 76: #endif
! 77:
! 78: #ifndef pestrndup
! 79: # define pestrndup(s, length, persistent) ((persistent)?zend_strndup((s),(length)):estrndup((s),(length)))
! 80: #endif
! 81:
! 82: #ifndef ALLOC_PERMANENT_ZVAL
! 83: # define ALLOC_PERMANENT_ZVAL(z) \
! 84: (z) = (zval*)malloc(sizeof(zval))
! 85: #endif
! 86:
! 87: /* PHP_ because this is public information via MINFO */
! 88: #define PHP_PHAR_API_VERSION "1.1.1"
! 89: /* x.y.z maps to 0xyz0 */
! 90: #define PHAR_API_VERSION 0x1110
! 91: /* if we bump PHAR_API_VERSION, change this from 0x1100 to PHAR_API_VERSION */
! 92: #define PHAR_API_VERSION_NODIR 0x1100
! 93: #define PHAR_API_MIN_DIR 0x1110
! 94: #define PHAR_API_MIN_READ 0x1000
! 95: #define PHAR_API_MAJORVERSION 0x1000
! 96: #define PHAR_API_MAJORVER_MASK 0xF000
! 97: #define PHAR_API_VER_MASK 0xFFF0
! 98:
! 99: #define PHAR_HDR_COMPRESSION_MASK 0x0000F000
! 100: #define PHAR_HDR_COMPRESSED_NONE 0x00000000
! 101: #define PHAR_HDR_COMPRESSED_GZ 0x00001000
! 102: #define PHAR_HDR_COMPRESSED_BZ2 0x00002000
! 103: #define PHAR_HDR_SIGNATURE 0x00010000
! 104:
! 105: /* flags for defining that the entire file should be compressed */
! 106: #define PHAR_FILE_COMPRESSION_MASK 0x00F00000
! 107: #define PHAR_FILE_COMPRESSED_NONE 0x00000000
! 108: #define PHAR_FILE_COMPRESSED_GZ 0x00100000
! 109: #define PHAR_FILE_COMPRESSED_BZ2 0x00200000
! 110:
! 111: #define PHAR_SIG_MD5 0x0001
! 112: #define PHAR_SIG_SHA1 0x0002
! 113: #define PHAR_SIG_SHA256 0x0003
! 114: #define PHAR_SIG_SHA512 0x0004
! 115: #define PHAR_SIG_OPENSSL 0x0010
! 116:
! 117: /* flags byte for each file adheres to these bitmasks.
! 118: All unused values are reserved */
! 119: #define PHAR_ENT_COMPRESSION_MASK 0x0000F000
! 120: #define PHAR_ENT_COMPRESSED_NONE 0x00000000
! 121: #define PHAR_ENT_COMPRESSED_GZ 0x00001000
! 122: #define PHAR_ENT_COMPRESSED_BZ2 0x00002000
! 123:
! 124: #define PHAR_ENT_PERM_MASK 0x000001FF
! 125: #define PHAR_ENT_PERM_MASK_USR 0x000001C0
! 126: #define PHAR_ENT_PERM_SHIFT_USR 6
! 127: #define PHAR_ENT_PERM_MASK_GRP 0x00000038
! 128: #define PHAR_ENT_PERM_SHIFT_GRP 3
! 129: #define PHAR_ENT_PERM_MASK_OTH 0x00000007
! 130: #define PHAR_ENT_PERM_DEF_FILE 0x000001B6
! 131: #define PHAR_ENT_PERM_DEF_DIR 0x000001FF
! 132:
! 133: #define PHAR_FORMAT_SAME 0
! 134: #define PHAR_FORMAT_PHAR 1
! 135: #define PHAR_FORMAT_TAR 2
! 136: #define PHAR_FORMAT_ZIP 3
! 137:
! 138: #define TAR_FILE '0'
! 139: #define TAR_LINK '1'
! 140: #define TAR_SYMLINK '2'
! 141: #define TAR_DIR '5'
! 142: #define TAR_NEW '8'
! 143:
! 144: #define PHAR_MUNG_PHP_SELF (1<<0)
! 145: #define PHAR_MUNG_REQUEST_URI (1<<1)
! 146: #define PHAR_MUNG_SCRIPT_NAME (1<<2)
! 147: #define PHAR_MUNG_SCRIPT_FILENAME (1<<3)
! 148:
! 149: typedef struct _phar_entry_fp phar_entry_fp;
! 150: typedef struct _phar_archive_data phar_archive_data;
! 151:
! 152: ZEND_BEGIN_MODULE_GLOBALS(phar)
! 153: /* a list of phar_archive_data objects that reference a cached phar, so
! 154: that if copy-on-write is performed, we can swap them out for the new value */
! 155: HashTable phar_persist_map;
! 156: HashTable phar_fname_map;
! 157: /* for cached phars, this is a per-process store of fp/ufp */
! 158: phar_entry_fp *cached_fp;
! 159: HashTable phar_alias_map;
! 160: int phar_SERVER_mung_list;
! 161: int readonly;
! 162: char* cache_list;
! 163: int manifest_cached;
! 164: int persist;
! 165: int has_zlib;
! 166: int has_bz2;
! 167: zend_bool readonly_orig;
! 168: zend_bool require_hash_orig;
! 169: zend_bool intercepted;
! 170: int request_init;
! 171: int require_hash;
! 172: int request_done;
! 173: int request_ends;
! 174: void (*orig_fopen)(INTERNAL_FUNCTION_PARAMETERS);
! 175: void (*orig_file_get_contents)(INTERNAL_FUNCTION_PARAMETERS);
! 176: void (*orig_is_file)(INTERNAL_FUNCTION_PARAMETERS);
! 177: void (*orig_is_link)(INTERNAL_FUNCTION_PARAMETERS);
! 178: void (*orig_is_dir)(INTERNAL_FUNCTION_PARAMETERS);
! 179: void (*orig_opendir)(INTERNAL_FUNCTION_PARAMETERS);
! 180: void (*orig_file_exists)(INTERNAL_FUNCTION_PARAMETERS);
! 181: void (*orig_fileperms)(INTERNAL_FUNCTION_PARAMETERS);
! 182: void (*orig_fileinode)(INTERNAL_FUNCTION_PARAMETERS);
! 183: void (*orig_filesize)(INTERNAL_FUNCTION_PARAMETERS);
! 184: void (*orig_fileowner)(INTERNAL_FUNCTION_PARAMETERS);
! 185: void (*orig_filegroup)(INTERNAL_FUNCTION_PARAMETERS);
! 186: void (*orig_fileatime)(INTERNAL_FUNCTION_PARAMETERS);
! 187: void (*orig_filemtime)(INTERNAL_FUNCTION_PARAMETERS);
! 188: void (*orig_filectime)(INTERNAL_FUNCTION_PARAMETERS);
! 189: void (*orig_filetype)(INTERNAL_FUNCTION_PARAMETERS);
! 190: void (*orig_is_writable)(INTERNAL_FUNCTION_PARAMETERS);
! 191: void (*orig_is_readable)(INTERNAL_FUNCTION_PARAMETERS);
! 192: void (*orig_is_executable)(INTERNAL_FUNCTION_PARAMETERS);
! 193: void (*orig_lstat)(INTERNAL_FUNCTION_PARAMETERS);
! 194: void (*orig_readfile)(INTERNAL_FUNCTION_PARAMETERS);
! 195: void (*orig_stat)(INTERNAL_FUNCTION_PARAMETERS);
! 196: /* used for includes with . in them inside front controller */
! 197: char* cwd;
! 198: int cwd_len;
! 199: int cwd_init;
! 200: char *openssl_privatekey;
! 201: int openssl_privatekey_len;
! 202: /* phar_get_archive cache */
! 203: char* last_phar_name;
! 204: int last_phar_name_len;
! 205: char* last_alias;
! 206: int last_alias_len;
! 207: phar_archive_data* last_phar;
! 208: HashTable mime_types;
! 209: ZEND_END_MODULE_GLOBALS(phar)
! 210:
! 211: ZEND_EXTERN_MODULE_GLOBALS(phar)
! 212:
! 213: #ifdef ZTS
! 214: # include "TSRM.h"
! 215: # define PHAR_G(v) TSRMG(phar_globals_id, zend_phar_globals *, v)
! 216: # define PHAR_GLOBALS ((zend_phar_globals *) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(phar_globals_id)])
! 217: #else
! 218: # define PHAR_G(v) (phar_globals.v)
! 219: # define PHAR_GLOBALS (&phar_globals)
! 220: #endif
! 221:
! 222: #ifndef php_uint16
! 223: # if SIZEOF_SHORT == 2
! 224: # define php_uint16 unsigned short
! 225: # else
! 226: # define php_uint16 uint16_t
! 227: # endif
! 228: #endif
! 229: #include "pharzip.h"
! 230:
! 231: #if HAVE_SPL
! 232: typedef union _phar_archive_object phar_archive_object;
! 233: typedef union _phar_entry_object phar_entry_object;
! 234: #endif
! 235:
! 236: /*
! 237: * used in phar_entry_info->fp_type to
! 238: */
! 239: enum phar_fp_type {
! 240: /* regular file pointer phar_archive_data->fp */
! 241: PHAR_FP,
! 242: /* uncompressed file pointer phar_archive_data->uncompressed_fp */
! 243: PHAR_UFP,
! 244: /* modified file pointer phar_entry_info->fp */
! 245: PHAR_MOD,
! 246: /* temporary manifest entry (file outside of the phar mapped to a location inside the phar)
! 247: this entry stores the stream to open in link (normally used for tars, but we steal it here) */
! 248: PHAR_TMP
! 249: };
! 250:
! 251: /* entry for one file in a phar file */
! 252: typedef struct _phar_entry_info {
! 253: /* first bytes are exactly as in file */
! 254: php_uint32 uncompressed_filesize;
! 255: php_uint32 timestamp;
! 256: php_uint32 compressed_filesize;
! 257: php_uint32 crc32;
! 258: php_uint32 flags;
! 259: /* remainder */
! 260: /* when changing compression, save old flags in case fp is NULL */
! 261: php_uint32 old_flags;
! 262: zval *metadata;
! 263: int metadata_len; /* only used for cached manifests */
! 264: php_uint32 filename_len;
! 265: char *filename;
! 266: enum phar_fp_type fp_type;
! 267: /* offset within original phar file of the file contents */
! 268: long offset_abs;
! 269: /* offset within fp of the file contents */
! 270: long offset;
! 271: /* offset within original phar file of the file header (for zip-based/tar-based) */
! 272: long header_offset;
! 273: php_stream *fp;
! 274: php_stream *cfp;
! 275: int fp_refcount;
! 276: char *tmp;
! 277: phar_archive_data *phar;
! 278: smart_str metadata_str;
! 279: char *link; /* symbolic link to another file */
! 280: char tar_type;
! 281: /* position in the manifest */
! 282: uint manifest_pos;
! 283: /* for stat */
! 284: unsigned short inode;
! 285:
! 286: unsigned int is_crc_checked:1;
! 287: unsigned int is_modified:1;
! 288: unsigned int is_deleted:1;
! 289: unsigned int is_dir:1;
! 290: /* this flag is used for mounted entries (external files mapped to location
! 291: inside a phar */
! 292: unsigned int is_mounted:1;
! 293: /* used when iterating */
! 294: unsigned int is_temp_dir:1;
! 295: /* tar-based phar file stuff */
! 296: unsigned int is_tar:1;
! 297: /* zip-based phar file stuff */
! 298: unsigned int is_zip:1;
! 299: /* for cached phar entries */
! 300: unsigned int is_persistent:1;
! 301: } phar_entry_info;
! 302:
! 303: /* information about a phar file (the archive itself) */
! 304: struct _phar_archive_data {
! 305: char *fname;
! 306: int fname_len;
! 307: /* for phar_detect_fname_ext, this stores the location of the file extension within fname */
! 308: char *ext;
! 309: int ext_len;
! 310: char *alias;
! 311: int alias_len;
! 312: char version[12];
! 313: size_t internal_file_start;
! 314: size_t halt_offset;
! 315: HashTable manifest;
! 316: /* hash of virtual directories, as in path/to/file.txt has path/to and path as virtual directories */
! 317: HashTable virtual_dirs;
! 318: /* hash of mounted directory paths */
! 319: HashTable mounted_dirs;
! 320: php_uint32 flags;
! 321: php_uint32 min_timestamp;
! 322: php_uint32 max_timestamp;
! 323: php_stream *fp;
! 324: /* decompressed file contents are stored here */
! 325: php_stream *ufp;
! 326: int refcount;
! 327: php_uint32 sig_flags;
! 328: int sig_len;
! 329: char *signature;
! 330: zval *metadata;
! 331: int metadata_len; /* only used for cached manifests */
! 332: uint phar_pos;
! 333: /* if 1, then this alias was manually specified by the user and is not a permanent alias */
! 334: unsigned int is_temporary_alias:1;
! 335: unsigned int is_modified:1;
! 336: unsigned int is_writeable:1;
! 337: unsigned int is_brandnew:1;
! 338: /* defer phar creation */
! 339: unsigned int donotflush:1;
! 340: /* zip-based phar variables */
! 341: unsigned int is_zip:1;
! 342: /* tar-based phar variables */
! 343: unsigned int is_tar:1;
! 344: /* PharData variables */
! 345: unsigned int is_data:1;
! 346: /* for cached phar manifests */
! 347: unsigned int is_persistent:1;
! 348: };
! 349:
! 350: typedef struct _phar_entry_fp_info {
! 351: enum phar_fp_type fp_type;
! 352: /* offset within fp of the file contents */
! 353: long offset;
! 354: } phar_entry_fp_info;
! 355:
! 356: struct _phar_entry_fp {
! 357: php_stream *fp;
! 358: php_stream *ufp;
! 359: phar_entry_fp_info *manifest;
! 360: };
! 361:
! 362: static inline php_stream *phar_get_entrypfp(phar_entry_info *entry TSRMLS_DC)
! 363: {
! 364: if (!entry->is_persistent) {
! 365: return entry->phar->fp;
! 366: }
! 367: return PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].fp;
! 368: }
! 369:
! 370: static inline php_stream *phar_get_entrypufp(phar_entry_info *entry TSRMLS_DC)
! 371: {
! 372: if (!entry->is_persistent) {
! 373: return entry->phar->ufp;
! 374: }
! 375: return PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].ufp;
! 376: }
! 377:
! 378: static inline void phar_set_entrypfp(phar_entry_info *entry, php_stream *fp TSRMLS_DC)
! 379: {
! 380: if (!entry->phar->is_persistent) {
! 381: entry->phar->fp = fp;
! 382: return;
! 383: }
! 384:
! 385: PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].fp = fp;
! 386: }
! 387:
! 388: static inline void phar_set_entrypufp(phar_entry_info *entry, php_stream *fp TSRMLS_DC)
! 389: {
! 390: if (!entry->phar->is_persistent) {
! 391: entry->phar->ufp = fp;
! 392: return;
! 393: }
! 394:
! 395: PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].ufp = fp;
! 396: }
! 397:
! 398: static inline php_stream *phar_get_pharfp(phar_archive_data *phar TSRMLS_DC)
! 399: {
! 400: if (!phar->is_persistent) {
! 401: return phar->fp;
! 402: }
! 403: return PHAR_GLOBALS->cached_fp[phar->phar_pos].fp;
! 404: }
! 405:
! 406: static inline php_stream *phar_get_pharufp(phar_archive_data *phar TSRMLS_DC)
! 407: {
! 408: if (!phar->is_persistent) {
! 409: return phar->ufp;
! 410: }
! 411: return PHAR_GLOBALS->cached_fp[phar->phar_pos].ufp;
! 412: }
! 413:
! 414: static inline void phar_set_pharfp(phar_archive_data *phar, php_stream *fp TSRMLS_DC)
! 415: {
! 416: if (!phar->is_persistent) {
! 417: phar->fp = fp;
! 418: return;
! 419: }
! 420:
! 421: PHAR_GLOBALS->cached_fp[phar->phar_pos].fp = fp;
! 422: }
! 423:
! 424: static inline void phar_set_pharufp(phar_archive_data *phar, php_stream *fp TSRMLS_DC)
! 425: {
! 426: if (!phar->is_persistent) {
! 427: phar->ufp = fp;
! 428: return;
! 429: }
! 430:
! 431: PHAR_GLOBALS->cached_fp[phar->phar_pos].ufp = fp;
! 432: }
! 433:
! 434: static inline void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, off_t offset TSRMLS_DC)
! 435: {
! 436: phar_entry_fp_info *data;
! 437:
! 438: if (!entry->is_persistent) {
! 439: entry->fp_type = type;
! 440: entry->offset = offset;
! 441: return;
! 442: }
! 443: data = &(PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].manifest[entry->manifest_pos]);
! 444: data->fp_type = type;
! 445: data->offset = offset;
! 446: }
! 447:
! 448: static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry TSRMLS_DC)
! 449: {
! 450: if (!entry->is_persistent) {
! 451: return entry->fp_type;
! 452: }
! 453: return PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type;
! 454: }
! 455:
! 456: static inline off_t phar_get_fp_offset(phar_entry_info *entry TSRMLS_DC)
! 457: {
! 458: if (!entry->is_persistent) {
! 459: return entry->offset;
! 460: }
! 461: if (PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type == PHAR_FP) {
! 462: if (!PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].manifest[entry->manifest_pos].offset) {
! 463: PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].manifest[entry->manifest_pos].offset = entry->offset;
! 464: }
! 465: }
! 466: return PHAR_GLOBALS->cached_fp[entry->phar->phar_pos].manifest[entry->manifest_pos].offset;
! 467: }
! 468:
! 469: #define PHAR_MIME_PHP '\0'
! 470: #define PHAR_MIME_PHPS '\1'
! 471: #define PHAR_MIME_OTHER '\2'
! 472:
! 473: typedef struct _phar_mime_type {
! 474: char *mime;
! 475: int len;
! 476: /* one of PHAR_MIME_* */
! 477: char type;
! 478: } phar_mime_type;
! 479:
! 480: /* stream access data for one file entry in a phar file */
! 481: typedef struct _phar_entry_data {
! 482: phar_archive_data *phar;
! 483: php_stream *fp;
! 484: /* stream position proxy, allows multiple open streams referring to the same fp */
! 485: off_t position;
! 486: /* for copies of the phar fp, defines where 0 is */
! 487: off_t zero;
! 488: int for_write:1;
! 489: int is_zip:1;
! 490: int is_tar:1;
! 491: phar_entry_info *internal_file;
! 492: } phar_entry_data;
! 493:
! 494: #if HAVE_SPL
! 495: /* archive php object */
! 496: union _phar_archive_object {
! 497: zend_object std;
! 498: spl_filesystem_object spl;
! 499: struct {
! 500: zend_object std;
! 501: phar_archive_data *archive;
! 502: } arc;
! 503: };
! 504: #endif
! 505:
! 506: #if HAVE_SPL
! 507: /* entry php object */
! 508: union _phar_entry_object {
! 509: zend_object std;
! 510: spl_filesystem_object spl;
! 511: struct {
! 512: zend_object std;
! 513: phar_entry_info *entry;
! 514: } ent;
! 515: };
! 516: #endif
! 517:
! 518: #ifndef PHAR_MAIN
! 519: # if PHP_VERSION_ID >= 50300
! 520: extern char *(*phar_save_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
! 521: # endif
! 522: #endif
! 523:
! 524: #if PHP_VERSION_ID < 50209
! 525: static inline size_t phar_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC)
! 526: {
! 527: size_t ret = php_stream_copy_to_stream(src, dest, maxlen);
! 528: if (len) {
! 529: *len = ret;
! 530: }
! 531: if (ret) {
! 532: return SUCCESS;
! 533: }
! 534: return FAILURE;
! 535: }
! 536: #else
! 537: # define phar_stream_copy_to_stream(src, dest, maxlen, len) _php_stream_copy_to_stream_ex((src), (dest), (maxlen), (len) STREAMS_CC TSRMLS_CC)
! 538:
! 539: #endif
! 540:
! 541: #if PHP_VERSION_ID >= 60000
! 542: typedef zstr phar_zstr;
! 543: #define PHAR_STR(a, b) \
! 544: spprintf(&b, 0, "%s", a.s);
! 545: #define PHAR_ZSTR(a, b) \
! 546: b = ZSTR(a);
! 547: #define PHAR_STR_FREE(a) \
! 548: efree(a);
! 549: static inline int phar_make_unicode(zstr *c_var, char *arKey, uint nKeyLength TSRMLS_DC)
! 550: {
! 551: int c_var_len;
! 552: UConverter *conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv));
! 553:
! 554: c_var->u = NULL;
! 555: if (zend_string_to_unicode(conv, &c_var->u, &c_var_len, arKey, nKeyLength TSRMLS_CC) == FAILURE) {
! 556:
! 557: if (c_var->u) {
! 558: efree(c_var->u);
! 559: }
! 560: return 0;
! 561:
! 562: }
! 563: return c_var_len;
! 564: }
! 565: static inline int phar_find_key(HashTable *_SERVER, char *key, int len, void **stuff TSRMLS_DC)
! 566: {
! 567: if (SUCCESS == zend_hash_find(_SERVER, key, len, stuff)) {
! 568: return 1;
! 569: } else {
! 570: int s = len;
! 571: zstr var;
! 572: s = phar_make_unicode(&var, key, len TSRMLS_CC);
! 573: if (SUCCESS == zend_u_hash_find(_SERVER, IS_UNICODE, var, s, stuff)) {
! 574: efree(var.u);
! 575: return 1;
! 576: }
! 577: efree(var.u);
! 578: return 0;
! 579: }
! 580: }
! 581: #else
! 582: typedef char *phar_zstr;
! 583: #define PHAR_STR(a, b) \
! 584: b = a;
! 585: #define PHAR_ZSTR(a, b) \
! 586: b = a;
! 587: #define PHAR_STR_FREE(a)
! 588: #endif
! 589:
! 590: BEGIN_EXTERN_C()
! 591:
! 592: #ifdef PHP_WIN32
! 593: char *tsrm_strtok_r(char *s, const char *delim, char **last);
! 594:
! 595: static inline void phar_unixify_path_separators(char *path, int path_len)
! 596: {
! 597: char *s;
! 598:
! 599: /* unixify win paths */
! 600: for (s = path; s - path < path_len; ++s) {
! 601: if (*s == '\\') {
! 602: *s = '/';
! 603: }
! 604: }
! 605: }
! 606: #endif
! 607: /**
! 608: * validate an alias, returns 1 for success, 0 for failure
! 609: */
! 610: static inline int phar_validate_alias(const char *alias, int alias_len) /* {{{ */
! 611: {
! 612: return !(memchr(alias, '/', alias_len) || memchr(alias, '\\', alias_len) || memchr(alias, ':', alias_len) ||
! 613: memchr(alias, ';', alias_len) || memchr(alias, '\n', alias_len) || memchr(alias, '\r', alias_len));
! 614: }
! 615: /* }}} */
! 616:
! 617: static inline void phar_set_inode(phar_entry_info *entry TSRMLS_DC) /* {{{ */
! 618: {
! 619: char tmp[MAXPATHLEN];
! 620: int tmp_len;
! 621:
! 622: tmp_len = entry->filename_len + entry->phar->fname_len;
! 623: memcpy(tmp, entry->phar->fname, entry->phar->fname_len);
! 624: memcpy(tmp + entry->phar->fname_len, entry->filename, entry->filename_len);
! 625: entry->inode = (unsigned short)zend_get_hash_value(tmp, tmp_len);
! 626: }
! 627: /* }}} */
! 628:
! 629: void phar_request_initialize(TSRMLS_D);
! 630:
! 631: void phar_object_init(TSRMLS_D);
! 632: void phar_destroy_phar_data(phar_archive_data *phar TSRMLS_DC);
! 633:
! 634: int phar_open_entry_file(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC);
! 635: int phar_postprocess_file(phar_entry_data *idata, php_uint32 crc32, char **error, int process_zip TSRMLS_DC);
! 636: int phar_open_from_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
! 637: int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
! 638: int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
! 639: int phar_open_executed_filename(char *alias, int alias_len, char **error TSRMLS_DC);
! 640: int phar_free_alias(phar_archive_data *phar, char *alias, int alias_len TSRMLS_DC);
! 641: int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, char *alias, int alias_len, char **error TSRMLS_DC);
! 642: int phar_open_parsed_phar(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
! 643: int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_type, char *sig, int sig_len, char *fname, char **signature, int *signature_len, char **error TSRMLS_DC);
! 644: int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, int *signature_length, char **error TSRMLS_DC);
! 645:
! 646: /* utility functions */
! 647: char *phar_create_default_stub(const char *index_php, const char *web_index, size_t *len, char **error TSRMLS_DC);
! 648: char *phar_decompress_filter(phar_entry_info * entry, int return_unknown);
! 649: char *phar_compress_filter(phar_entry_info * entry, int return_unknown);
! 650:
! 651: void phar_remove_virtual_dirs(phar_archive_data *phar, char *filename, int filename_len TSRMLS_DC);
! 652: void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, int filename_len TSRMLS_DC);
! 653: int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len TSRMLS_DC);
! 654: char *phar_find_in_include_path(char *file, int file_len, phar_archive_data **pphar TSRMLS_DC);
! 655: char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC);
! 656: phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC);
! 657: int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSRMLS_DC);
! 658: void destroy_phar_manifest_entry(void *pDest);
! 659: int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t position, int follow_links TSRMLS_DC);
! 660: php_stream *phar_get_efp(phar_entry_info *entry, int follow_links TSRMLS_DC);
! 661: int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error TSRMLS_DC);
! 662: int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links TSRMLS_DC);
! 663: phar_entry_info *phar_get_link_source(phar_entry_info *entry TSRMLS_DC);
! 664: int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC);
! 665: int phar_separate_entry_fp(phar_entry_info *entry, char **error TSRMLS_DC);
! 666: int phar_open_archive_fp(phar_archive_data *phar TSRMLS_DC);
! 667: int phar_copy_on_write(phar_archive_data **pphar TSRMLS_DC);
! 668:
! 669: /* tar functions in tar.c */
! 670: int phar_is_tar(char *buf, char *fname);
! 671: int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, int is_data, php_uint32 compression, char **error TSRMLS_DC);
! 672: int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
! 673: int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC);
! 674:
! 675: /* zip functions in zip.c */
! 676: int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, char **error TSRMLS_DC);
! 677: int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
! 678: int phar_zip_flush(phar_archive_data *archive, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC);
! 679:
! 680: #ifdef PHAR_MAIN
! 681: static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, int is_data, char **error TSRMLS_DC);
! 682: extern php_stream_wrapper php_stream_phar_wrapper;
! 683: #else
! 684: extern HashTable cached_phars;
! 685: extern HashTable cached_alias;
! 686: #endif
! 687:
! 688: int phar_archive_delref(phar_archive_data *phar TSRMLS_DC);
! 689: int phar_entry_delref(phar_entry_data *idata TSRMLS_DC);
! 690:
! 691: phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int path_len, char **error, int security TSRMLS_DC);
! 692: phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, int path_len, char dir, char **error, int security TSRMLS_DC);
! 693: phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error, int security TSRMLS_DC);
! 694: int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error, int security TSRMLS_DC);
! 695: int phar_flush(phar_archive_data *archive, char *user_stub, long len, int convert, char **error TSRMLS_DC);
! 696: int phar_detect_phar_fname_ext(const char *filename, int filename_len, const char **ext_str, int *ext_len, int executable, int for_create, int is_complete TSRMLS_DC);
! 697: int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len, int executable, int for_create TSRMLS_DC);
! 698:
! 699: typedef enum {
! 700: pcr_use_query,
! 701: pcr_is_ok,
! 702: pcr_err_double_slash,
! 703: pcr_err_up_dir,
! 704: pcr_err_curr_dir,
! 705: pcr_err_back_slash,
! 706: pcr_err_star,
! 707: pcr_err_illegal_char,
! 708: pcr_err_empty_entry
! 709: } phar_path_check_result;
! 710:
! 711: phar_path_check_result phar_path_check(char **p, int *len, const char **error);
! 712:
! 713: END_EXTERN_C()
! 714:
! 715: /*
! 716: * Local variables:
! 717: * tab-width: 4
! 718: * c-basic-offset: 4
! 719: * End:
! 720: * vim600: noet sw=4 ts=4 fdm=marker
! 721: * vim<600: noet sw=4 ts=4
! 722: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>