Moriyoshi Koizumi
moriy****@users*****
2002年 10月 7日 (月) 06:54:35 JST
moriyoshi 02/10/07 06:54:35 Modified: ext/standard Makefile.frag aggregation.c array.c assert.c base64.c basic_functions.c basic_functions.h browscap.c config.m4 credits.c credits_ext.h credits_sapi.h cyr_convert.c datetime.c dir.c dl.c dns.c exec.c exec.h file.c file.h filestat.c flock_compat.c formatted_print.c fsock.c fsock.h ftok.c ftp_fopen_wrapper.c head.c html.c html.h http_fopen_wrapper.c image.c incomplete_class.c info.c info.h iptc.c lcg.c levenshtein.c link.c mail.c math.c md5.c microtime.c pack.c pageinfo.c parsedate.y php_array.h php_filestat.h php_fopen_wrapper.c php_image.h php_incomplete_class.h php_mail.h php_rand.h php_smart_str.h php_standard.h php_string.h php_var.h rand.c reg.c reg.h scanf.c string.c syslog.c type.c url.c url_scanner.c url_scanner_ex.c url_scanner_ex.re var.c var_unserializer.c var_unserializer.re versioning.c main SAPI.c SAPI.h build-defs.h.in config.w32.h.in fopen_wrappers.c fopen_wrappers.h internal_functions_win32.c main.c memory_streams.c mergesort.c network.c output.c php.h php_compat.h php_content_types.c php_globals.h php_ini.c php_main.h php_network.h php_open_temporary_file.c php_output.h php_streams.h php_syslog.h php_variables.c php_version.h reentrancy.c rfc1867.c rfc1867.h safe_mode.c snprintf.c snprintf.h spprintf.c spprintf.h streams.c user_streams.c win95nt.h sapi/cgi cgi_main.c sapi/cli config.m4 php_cli.c Log: merged the recent cvs.php.net changes Revision Changes Path 1.3 +1 -0 php4/ext/standard/Makefile.frag Index: Makefile.frag =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/Makefile.frag,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Makefile.frag 29 Apr 2002 02:31:01 -0000 1.2 +++ Makefile.frag 6 Oct 2002 21:54:32 -0000 1.3 @@ -7,3 +7,4 @@ $(srcdir)/url_scanner_ex.c: $(srcdir)/url_scanner_ex.re re2c -b $(srcdir)/url_scanner_ex.re > $@ +$(srcdir)/info.c: $(builddir)/../../main/build-defs.h 1.4 +3 -3 php4/ext/standard/aggregation.c Index: aggregation.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/aggregation.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- aggregation.c 3 May 2002 00:14:52 -0000 1.3 +++ aggregation.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: aggregation.c,v 1.9 2002/04/30 14:45:50 stas Exp $ */ +/* $Id: aggregation.c,v 1.11 2002/08/24 01:19:27 helly Exp $ */ #include "php.h" #include "basic_functions.h" @@ -339,7 +339,7 @@ zend_str_tolower(class_name_lc, class_name_len); if (zend_hash_find(EG(class_table), class_name_lc, class_name_len+1, (void **)&ce) == FAILURE) { - php_error(E_WARNING, "%s() expects parameter 2 to be a valid class name, '%s' given\n", get_active_function_name(TSRMLS_C), class_name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects the second parameter to be a valid class name, '%s' given", class_name); efree(class_name_lc); return; } @@ -614,7 +614,7 @@ if (zend_hash_find(EG(class_table), Z_OBJCE_P(obj)->name, Z_OBJCE_P(obj)->name_length+1, (void **)&orig_ce) == FAILURE) { - php_error(E_WARNING, "internal deaggregation error"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal deaggregation error"); return; } 1.4 +436 -249 php4/ext/standard/array.c Index: array.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/array.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- array.c 2 Aug 2002 22:05:24 -0000 1.3 +++ array.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: array.c,v 1.162 2002/05/13 17:28:38 andrei Exp $ */ +/* $Id: array.c,v 1.194 2002/09/21 16:10:33 andrey Exp $ */ #include "php.h" #include "php_ini.h" @@ -60,18 +60,26 @@ #define EXTR_PREFIX_IF_EXISTS 5 #define EXTR_IF_EXISTS 6 -#define SORT_REGULAR 0 -#define SORT_NUMERIC 1 -#define SORT_STRING 2 +#define EXTR_REFS 0x100 -#define SORT_DESC 3 -#define SORT_ASC 4 +#define SORT_REGULAR 0 +#define SORT_NUMERIC 1 +#define SORT_STRING 2 -#define CASE_LOWER 0 -#define CASE_UPPER 1 +#define SORT_DESC 3 +#define SORT_ASC 4 -#define COUNT_NORMAL 0 -#define COUNT_RECURSIVE 1 +#define CASE_LOWER 0 +#define CASE_UPPER 1 + +#define COUNT_NORMAL 0 +#define COUNT_RECURSIVE 1 + +#define DIFF_NORMAL 0 +#define DIFF_ASSOC 1 + +#define INTERSECT_NORMAL 0 +#define INTERSECT_ASSOC 1 PHP_MINIT_FUNCTION(array) { @@ -86,6 +94,7 @@ REGISTER_LONG_CONSTANT("EXTR_PREFIX_INVALID", EXTR_PREFIX_INVALID, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("EXTR_PREFIX_IF_EXISTS", EXTR_PREFIX_IF_EXISTS, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("EXTR_IF_EXISTS", EXTR_IF_EXISTS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("EXTR_REFS", EXTR_REFS, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SORT_ASC", SORT_ASC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SORT_DESC", SORT_DESC, CONST_CS | CONST_PERSISTENT); @@ -105,10 +114,10 @@ PHP_MSHUTDOWN_FUNCTION(array) { #ifdef ZTS - ts_free_id(array_globals_id); + ts_free_id(array_globals_id); #endif - return SUCCESS; + return SUCCESS; } static void set_compare_func(int sort_type TSRMLS_DC) @@ -158,19 +167,19 @@ Z_STRLEN(second) = s->nKeyLength-1; } - if (ARRAYG(compare_func)(&result, &first, &second TSRMLS_CC) == FAILURE) { - return 0; - } + if (ARRAYG(compare_func)(&result, &first, &second TSRMLS_CC) == FAILURE) { + return 0; + } - if (Z_TYPE(result) == IS_DOUBLE) { - if (Z_DVAL(result) < 0) { + if (Z_TYPE(result) == IS_DOUBLE) { + if (Z_DVAL(result) < 0) { return -1; - } else if (Z_DVAL(result) > 0) { + } else if (Z_DVAL(result) > 0) { return 1; - } else { + } else { return 0; } - } + } convert_to_long(&result); @@ -241,8 +250,7 @@ target_hash = HASH_OF(array); - if (Z_TYPE_P(array) == IS_ARRAY) - { + if (Z_TYPE_P(array) == IS_ARRAY) { cnt += zend_hash_num_elements(target_hash); if (mode == COUNT_RECURSIVE) { HashPosition pos; @@ -302,19 +310,19 @@ first = *((pval **) f->pData); second = *((pval **) s->pData); - if (ARRAYG(compare_func)(&result, first, second TSRMLS_CC) == FAILURE) { - return 0; - } + if (ARRAYG(compare_func)(&result, first, second TSRMLS_CC) == FAILURE) { + return 0; + } - if (Z_TYPE(result) == IS_DOUBLE) { - if (Z_DVAL(result) < 0) { + if (Z_TYPE(result) == IS_DOUBLE) { + if (Z_DVAL(result) < 0) { return -1; - } else if (Z_DVAL(result) > 0) { + } else if (Z_DVAL(result) > 0) { return 1; - } else { + } else { return 0; } - } + } convert_to_long(&result); @@ -351,7 +359,7 @@ convert_to_string(&first); } if (Z_TYPE_P(sval) != IS_STRING) { - zval_copy_ctor(&first); + zval_copy_ctor(&second); convert_to_string(&second); } @@ -387,8 +395,7 @@ target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Wrong datatype in %s() call", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); return; } @@ -553,7 +560,7 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Wrong datatype in usort() call"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); BG(user_compare_func_name) = old_compare_func; RETURN_FALSE; } @@ -581,7 +588,7 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Wrong datatype in uasort() call"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); BG(user_compare_func_name) = old_compare_func; RETURN_FALSE; } @@ -633,7 +640,7 @@ zval_dtor(&key1); zval_dtor(&key2); - if (status==SUCCESS) { + if (status == SUCCESS) { convert_to_long(&retval); return Z_LVAL(retval); } else { @@ -656,7 +663,7 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Wrong datatype in uksort() call"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); BG(user_compare_func_name) = old_compare_func; RETURN_FALSE; } @@ -681,7 +688,7 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Variable passed to end() is not an array or object"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed variable is not an array or object"); RETURN_FALSE; } zend_hash_internal_pointer_end(target_hash); @@ -709,7 +716,7 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Variable passed to prev() is not an array or object"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed variable is not an array or object"); RETURN_FALSE; } zend_hash_move_backwards(target_hash); @@ -737,7 +744,7 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Variable passed to next() is not an array or object"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed variable is not an array or object"); RETURN_FALSE; } zend_hash_move_forward(target_hash); @@ -765,7 +772,7 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Variable passed to reset() is not an array or object"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed variable is not an array or object"); RETURN_FALSE; } zend_hash_internal_pointer_reset(target_hash); @@ -793,7 +800,7 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Variable passed to current() is not an array or object"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed variable is not an array or object"); RETURN_FALSE; } if (zend_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) { @@ -810,6 +817,7 @@ { pval **array; char *string_key; + uint string_length; ulong num_key; HashTable *target_hash; @@ -818,12 +826,12 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Variable passed to key() is not an array or object"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed variable is not an array or object"); RETURN_FALSE; } - switch (zend_hash_get_current_key(target_hash, &string_key, &num_key, 1)) { + switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_length, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: - RETVAL_STRING(string_key, 0); + RETVAL_STRINGL(string_key, string_length - 1, 1); break; case HASH_KEY_IS_LONG: RETVAL_LONG(num_key); @@ -842,7 +850,7 @@ pval **result; if (argc<=0) { - php_error(E_WARNING, "min: must be passed at least 1 value"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Atleast one value should be passed"); RETURN_NULL(); } set_compare_func(SORT_REGULAR TSRMLS_CC); @@ -852,11 +860,11 @@ if (zend_get_parameters_ex(1, &arr) == FAILURE || Z_TYPE_PP(arr) != IS_ARRAY) { WRONG_PARAM_COUNT; } - if (zend_hash_minmax(Z_ARRVAL_PP(arr), array_data_compare, 0, (void **) &result TSRMLS_CC)==SUCCESS) { + if (zend_hash_minmax(Z_ARRVAL_PP(arr), array_data_compare, 0, (void **) &result TSRMLS_CC) == SUCCESS) { *return_value = **result; zval_copy_ctor(return_value); } else { - php_error(E_WARNING, "min: array must contain at least 1 element"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array must contain atleast one element"); RETURN_FALSE; } } else { @@ -894,7 +902,7 @@ pval **result; if (argc<=0) { - php_error(E_WARNING, "max: must be passed at least 1 value"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Atleast one value should be passed"); RETURN_NULL(); } set_compare_func(SORT_REGULAR TSRMLS_CC); @@ -904,11 +912,11 @@ if (zend_get_parameters_ex(1, &arr) == FAILURE || Z_TYPE_PP(arr) != IS_ARRAY) { WRONG_PARAM_COUNT; } - if (zend_hash_minmax(Z_ARRVAL_PP(arr), array_data_compare, 1, (void **) &result TSRMLS_CC)==SUCCESS) { + if (zend_hash_minmax(Z_ARRVAL_PP(arr), array_data_compare, 1, (void **) &result TSRMLS_CC) == SUCCESS) { *return_value = **result; zval_copy_ctor(return_value); } else { - php_error(E_WARNING, "max: array must contain at least 1 element"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array must contain atleast one element"); RETURN_FALSE; } } else { @@ -916,7 +924,7 @@ pval **max, result; int i; - if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args)==FAILURE) { + if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { efree(args); WRONG_PARAM_COUNT; } @@ -958,7 +966,7 @@ zend_hash_internal_pointer_reset_ex(target_hash, &pos); /* Iterate through hash */ - while(zend_hash_get_current_data_ex(target_hash, (void **)&args[0], &pos) == SUCCESS) { + while (zend_hash_get_current_data_ex(target_hash, (void **)&args[0], &pos) == SUCCESS) { /* Set up the key */ if (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, &pos) == HASH_KEY_IS_LONG) { Z_TYPE_P(key) = IS_LONG; @@ -974,12 +982,13 @@ &retval_ptr, userdata ? 3 : 2, args, 0, NULL TSRMLS_CC) == SUCCESS) { zval_ptr_dtor(&retval_ptr); - } else - php_error(E_WARNING, "Unable to call %s() - function does not exist", + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", (*BG(array_walk_func_name))->value.str.val); + } zend_hash_move_forward_ex(target_hash, &pos); - } + } efree(key); return 0; @@ -989,7 +998,7 @@ Apply a user function to every member of an array */ PHP_FUNCTION(array_walk) { - int argc; + int argc; zval **array, **userdata = NULL, **old_walk_func_name; @@ -1004,15 +1013,13 @@ } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Wrong datatype in %s() call", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); BG(array_walk_func_name) = old_walk_func_name; RETURN_FALSE; } if (Z_TYPE_PP(BG(array_walk_func_name)) != IS_ARRAY && Z_TYPE_PP(BG(array_walk_func_name)) != IS_STRING) { - php_error(E_WARNING, "Wrong syntax for function name in %s() call", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong syntax for function name"); BG(array_walk_func_name) = old_walk_func_name; RETURN_FALSE; } @@ -1023,8 +1030,8 @@ /* }}} */ /* void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) - * 0 = return boolean - * 1 = return key + * 0 = return boolean + * 1 = return key */ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) { @@ -1039,19 +1046,19 @@ uint str_key_len; char *string_key; int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function; - + if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict) == FAILURE) { WRONG_PARAM_COUNT; } if (Z_TYPE_PP(value) == IS_OBJECT) { - php_error(E_WARNING, "Wrong datatype for first argument in call to %s", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong datatype for first argument"); RETURN_FALSE; } if (Z_TYPE_PP(array) != IS_ARRAY) { - php_error(E_WARNING, "Wrong datatype for second argument in call to %s", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong datatype for second argument"); RETURN_FALSE; } @@ -1059,15 +1066,15 @@ convert_to_boolean_ex(strict); if (Z_LVAL_PP(strict)) { is_equal_func = is_identical_function; - } + } } target_hash = HASH_OF(*array); zend_hash_internal_pointer_reset_ex(target_hash, &pos); - while(zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) { - is_equal_func(&res, *value, *entry TSRMLS_CC); + while (zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) { + is_equal_func(&res, *value, *entry TSRMLS_CC); if (Z_LVAL(res)) { - if (behavior==0) { + if (behavior == 0) { RETURN_TRUE; } else { /* Return current key */ @@ -1119,7 +1126,7 @@ return 0; if (len > 1) { - for(i=1; i<len; i++) { + for (i=1; i<len; i++) { if (!isalnum((int)var_name[i]) && var_name[i] != '_') { return 0; } @@ -1141,6 +1148,7 @@ ulong num_key; uint var_name_len; int var_exists, extract_type, key_type, count = 0; + zend_bool extract_refs = 0; HashPosition pos; switch (ZEND_NUM_ARGS()) { @@ -1157,9 +1165,10 @@ } convert_to_long_ex(z_extract_type); extract_type = Z_LVAL_PP(z_extract_type); + extract_refs = (extract_type & EXTR_REFS)>>8; + extract_type &= 0xff; if (extract_type > EXTR_SKIP && extract_type <= EXTR_PREFIX_IF_EXISTS) { - php_error(E_WARNING, "%s() expects a prefix to be specified", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Prefix expected to be specified"); return; } break; @@ -1170,6 +1179,8 @@ } convert_to_long_ex(z_extract_type); extract_type = Z_LVAL_PP(z_extract_type); + extract_refs = (extract_type & EXTR_REFS)>>8; + extract_type &= 0xff; convert_to_string_ex(prefix); break; @@ -1179,19 +1190,17 @@ } if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) { - php_error(E_WARNING, "Unknown extract type in call to %s()", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown extract type"); return; } if (Z_TYPE_PP(var_array) != IS_ARRAY) { - php_error(E_WARNING, "%s() expects first argument to be an array", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument should be an array"); return; } zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(var_array), &pos); - while(zend_hash_get_current_data_ex(Z_ARRVAL_PP(var_array), (void **)&entry, &pos) == SUCCESS) { + while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(var_array), (void **)&entry, &pos) == SUCCESS) { key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(var_array), &var_name, &var_name_len, &num_key, 0, &pos); var_exists = 0; @@ -1257,11 +1266,28 @@ if (final_name.len) { smart_str_0(&final_name); if (php_valid_var_name(final_name.c)) { - MAKE_STD_ZVAL(data); - *data = **entry; - zval_copy_ctor(data); + if (extract_refs) { + zval **orig_var; - ZEND_SET_SYMBOL(EG(active_symbol_table), final_name.c, data); + (*entry)->is_ref = 1; + (*entry)->refcount++; + if (zend_hash_find(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) &orig_var) == SUCCESS + && PZVAL_IS_REF(*orig_var)) { + + (*entry)->refcount += (*orig_var)->refcount-2; + zval_dtor(*orig_var); + FREE_ZVAL(*orig_var); + *orig_var = *entry; + } else { + zend_hash_update(EG(active_symbol_table), final_name.c, final_name.len+1, entry, sizeof(zval *), NULL); + } + } else { + MAKE_STD_ZVAL(data); + *data = **entry; + zval_copy_ctor(data); + + ZEND_SET_SYMBOL(EG(active_symbol_table), final_name.c, data); + } count++; } @@ -1344,16 +1370,16 @@ WRONG_PARAM_COUNT; } - /* allocate an array for return */ - if (array_init(return_value) == FAILURE) { + /* allocate an array for return */ + if (array_init(return_value) == FAILURE) { RETURN_FALSE; - } + } - switch(Z_TYPE_PP(start_key)) { + switch (Z_TYPE_PP(start_key)) { case IS_STRING: case IS_LONG: case IS_DOUBLE: - if(PZVAL_IS_REF(*val)) { + if (PZVAL_IS_REF(*val)) { SEPARATE_ZVAL(val); } convert_to_long_ex(start_key); @@ -1361,20 +1387,20 @@ zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(start_key), val, sizeof(val), NULL); break; default: - php_error(E_WARNING, "Wrong datatype for start key in array_init()"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong data type for start key"); RETURN_FALSE; break; } convert_to_long_ex(num); i = Z_LVAL_PP(num) - 1; - if(i<0) { - php_error(E_WARNING, "Number of elements must be positive in array_init()"); + if (i < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements must be positive"); RETURN_FALSE; } newval = *val; - while(i--) { - if(!(i%62000)) { + while (i--) { + if (!(i%62000)) { MAKE_STD_ZVAL(newval); *newval = **val; zval_copy_ctor(newval); @@ -1395,18 +1421,18 @@ WRONG_PARAM_COUNT; } - /* allocate an array for return */ - if (array_init(return_value) == FAILURE) { + /* allocate an array for return */ + if (array_init(return_value) == FAILURE) { RETURN_FALSE; - } + } - if(Z_TYPE_PP(zlow)==IS_STRING && Z_TYPE_PP(zhigh)==IS_STRING) { + if (Z_TYPE_PP(zlow)==IS_STRING && Z_TYPE_PP(zhigh)==IS_STRING) { char *low, *high; convert_to_string_ex(zlow); convert_to_string_ex(zhigh); low = Z_STRVAL_PP(zlow); high = Z_STRVAL_PP(zhigh); - if(*low>*high) { + if (*low>*high) { for (; *low >= *high; (*low)--) { add_next_index_stringl(return_value, low, 1, 1); } @@ -1421,7 +1447,7 @@ convert_to_long_ex(zhigh); low = Z_LVAL_PP(zlow); high = Z_LVAL_PP(zhigh); - if(low>high) { + if (low > high) { for (; low >= high; low--) { add_next_index_long(return_value, low); } @@ -1435,11 +1461,60 @@ /* }}} */ -static int array_data_shuffle(const void *a, const void *b TSRMLS_DC) +static void array_data_shuffle(zval *array TSRMLS_DC) { - return (php_rand(TSRMLS_C) % 2) ? 1 : -1; -} + Bucket **elems, *temp; + HashTable *hash; + int j, n_elems, rnd_idx, n_left; + + n_elems = zend_hash_num_elements(Z_ARRVAL_P(array)); + + if (n_elems <= 1) { + return; + } + + elems = (Bucket **)emalloc(n_elems * sizeof(Bucket *)); + hash = Z_ARRVAL_P(array); + n_left = n_elems; + + for (j = 0, temp = hash->pListHead; temp; temp = temp->pListNext) + elems[j++] = temp; + while (--n_left) { + rnd_idx = php_rand(TSRMLS_C); + RAND_RANGE(rnd_idx, 0, n_left, PHP_RAND_MAX); + if (rnd_idx != n_left) { + temp = elems[n_left]; + elems[n_left] = elems[rnd_idx]; + elems[rnd_idx] = temp; + } + } + HANDLE_BLOCK_INTERRUPTIONS(); + hash->pListHead = elems[0]; + hash->pListTail = NULL; + hash->pInternalPointer = hash->pListHead; + + for (j = 0; j < n_elems; j++) { + if (hash->pListTail) { + hash->pListTail->pListNext = elems[j]; + } + elems[j]->pListLast = hash->pListTail; + elems[j]->pListNext = NULL; + hash->pListTail = elems[j]; + } + temp = hash->pListHead; + j = 0; + while (temp != NULL) { + temp->nKeyLength = 0; + temp->h = j++; + temp = temp->pListNext; + } + hash->nNextFreeElement = n_elems; + zend_hash_rehash(hash); + HANDLE_UNBLOCK_INTERRUPTIONS(); + + efree(elems); +} /* {{{ proto bool shuffle(array array_arg) Randomly shuffle the contents of an array */ @@ -1450,9 +1525,9 @@ if (zend_parse_parameters(1 TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } - if (zend_hash_sort(Z_ARRVAL_PP(&array), (sort_func_t)php_mergesort, array_data_shuffle, 1 TSRMLS_CC) == FAILURE) { - RETURN_FALSE; - } + + array_data_shuffle(array TSRMLS_CC); + RETURN_TRUE; } /* }}} */ @@ -1484,10 +1559,11 @@ offset = 0; /* ..and the length */ - if (length < 0) + if (length < 0) { length = num_in-offset+length; - else if(offset+length > num_in) + } else if (offset+length > num_in) { length = num_in-offset; + } /* Create and initialize output hash */ ALLOC_HASHTABLE(out_hash); @@ -1510,7 +1586,7 @@ /* If hash for removed entries exists, go until offset+length and copy the entries to it */ if (removed != NULL) { - for( ; pos<offset+length && p; pos++, p=p->pListNext) { + for ( ; pos<offset+length && p; pos++, p=p->pListNext) { entry = *((zval **)p->pData); entry->refcount++; if (p->nKeyLength) @@ -1519,7 +1595,7 @@ zend_hash_next_index_insert(*removed, &entry, sizeof(zval *), NULL); } } else /* otherwise just skip those entries */ - for( ; pos<offset+length && p; pos++, p=p->pListNext); + for ( ; pos<offset+length && p; pos++, p=p->pListNext); /* If there are entries to insert.. */ if (list != NULL) { @@ -1563,8 +1639,8 @@ PHP_FUNCTION(array_push) { zval ***args, /* Function arguments array */ - *stack, /* Input array */ - *new_var; /* Variable to be pushed */ + *stack, /* Input array */ + *new_var; /* Variable to be pushed */ int i, /* Loop counter */ argc; /* Number of function arguments */ @@ -1584,7 +1660,7 @@ /* Get first argument and check that it's an array */ stack = *args[0]; if (Z_TYPE_P(stack) != IS_ARRAY) { - php_error(E_WARNING, "First argument to array_push() needs to be an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument should be an array"); efree(args); RETURN_FALSE; } @@ -1610,7 +1686,9 @@ { zval **stack, /* Input stack */ **val; /* Value to be popped */ - HashTable *new_hash; /* New stack */ + char *key = NULL; + int key_len = 0; + ulong index; /* Get the arguments and do error-checking */ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &stack) == FAILURE) { @@ -1618,7 +1696,7 @@ } if (Z_TYPE_PP(stack) != IS_ARRAY) { - php_error(E_WARNING, "The argument needs to be an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); return; } @@ -1637,14 +1715,26 @@ INIT_PZVAL(return_value); /* Delete the first or last value */ - new_hash = php_splice(Z_ARRVAL_PP(stack), (off_the_end) ? -1 : 0, 1, NULL, 0, NULL); - zend_hash_destroy(Z_ARRVAL_PP(stack)); - efree(Z_ARRVAL_PP(stack)); - Z_ARRVAL_PP(stack) = new_hash; + zend_hash_get_current_key_ex(Z_ARRVAL_PP(stack), &key, &key_len, &index, 0, NULL); + zend_hash_del_key_or_index(Z_ARRVAL_PP(stack), key, key_len, index, (key) ? HASH_DEL_KEY : HASH_DEL_INDEX); + + /* If we did a shift... re-index like it did before */ + if (!off_the_end) { + int k = 0; + Bucket *p = Z_ARRVAL_PP(stack)->pListHead; + while (p != NULL) { + if (p->nKeyLength == 0) + p->h = k++; + p = p->pListNext; + } + Z_ARRVAL_PP(stack)->nNextFreeElement = k+1; + zend_hash_rehash(Z_ARRVAL_PP(stack)); + } else if (!key_len) { + Z_ARRVAL_PP(stack)->nNextFreeElement = Z_ARRVAL_PP(stack)->nNextFreeElement - 1; + } } /* }}} */ - /* {{{ proto mixed array_pop(array stack) Pops an element off the end of the array */ PHP_FUNCTION(array_pop) @@ -1689,7 +1779,7 @@ /* Get first argument and check that it's an array */ stack = *args[0]; if (Z_TYPE_P(stack) != IS_ARRAY) { - php_error(E_WARNING, "First argument to array_unshift() needs to be an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array"); efree(args); RETURN_FALSE; } @@ -1739,7 +1829,7 @@ /* Get first argument and check that it's an array */ array = *args[0]; if (Z_TYPE_P(array) != IS_ARRAY) { - php_error(E_WARNING, "First argument to array_splice() should be an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array"); efree(args); return; } @@ -1814,7 +1904,7 @@ } if (Z_TYPE_PP(input) != IS_ARRAY) { - php_error(E_WARNING, "First argument to array_slice() should be an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array"); return; } @@ -1826,8 +1916,9 @@ if (argc == 3) { convert_to_long_ex(length); length_val = Z_LVAL_PP(length); - } else + } else { length_val = zend_hash_num_elements(Z_ARRVAL_PP(input)); + } /* Initialize returned array */ array_init(return_value); @@ -1842,10 +1933,11 @@ offset_val = 0; /* ..and the length */ - if (length_val < 0) + if (length_val < 0) { length_val = num_in-offset_val+length_val; - else if(offset_val+length_val > num_in) + } else if (offset_val+length_val > num_in) { length_val = num_in-offset_val; + } if (length_val == 0) return; @@ -1853,14 +1945,14 @@ /* Start at the beginning and go until we hit offset */ pos = 0; zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &hpos); - while(pos < offset_val && + while (pos < offset_val && zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &hpos) == SUCCESS) { pos++; zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &hpos); } /* Copy elements from input array to the one that's returned */ - while(pos < offset_val+length_val && + while (pos < offset_val+length_val && zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &hpos) == SUCCESS) { (*entry)->refcount++; @@ -1883,7 +1975,7 @@ /* }}} */ -PHPAPI void php_array_merge(HashTable *dest, HashTable *src, int recursive) +PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC) { zval **src_entry, **dest_entry; @@ -1893,16 +1985,22 @@ HashPosition pos; zend_hash_internal_pointer_reset_ex(src, &pos); - while(zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS) { + while (zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS) { switch (zend_hash_get_current_key_ex(src, &string_key, &string_key_len, &num_key, 0, &pos)) { case HASH_KEY_IS_STRING: if (recursive && zend_hash_find(dest, string_key, string_key_len, (void **)&dest_entry) == SUCCESS) { + if (*src_entry == *dest_entry) { + zend_error(E_WARNING, "%s(): recursion detected", + get_active_function_name(TSRMLS_C)); + return 0; + } convert_to_array_ex(dest_entry); convert_to_array_ex(src_entry); - php_array_merge(Z_ARRVAL_PP(dest_entry), - Z_ARRVAL_PP(src_entry), recursive); + if (!php_array_merge(Z_ARRVAL_PP(dest_entry), + Z_ARRVAL_PP(src_entry), recursive TSRMLS_CC)) + return 0; } else { (*src_entry)->refcount++; @@ -1919,6 +2017,8 @@ zend_hash_move_forward_ex(src, &pos); } + + return 1; } static void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMETERS, int recursive) @@ -1929,7 +2029,7 @@ /* Get the argument count and check it */ argc = ZEND_NUM_ARGS(); - if (argc < 2) { + if (argc < 1) { WRONG_PARAM_COUNT; } @@ -1945,7 +2045,7 @@ for (i=0; i<argc; i++) { SEPARATE_ZVAL(args[i]); convert_to_array_ex(args[i]); - php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), recursive); + php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), recursive TSRMLS_CC); } efree(args); @@ -1994,7 +2094,7 @@ } if (Z_TYPE_PP(input) != IS_ARRAY) { - php_error(E_WARNING, "First argument to array_keys() should be an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array"); return; } @@ -2004,9 +2104,9 @@ /* Go through input array and add keys to the return array */ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos); - while(zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS) { + while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS) { if (search_value != NULL) { - is_equal_function(&res, *search_value, *entry TSRMLS_CC); + is_equal_function(&res, *search_value, *entry TSRMLS_CC); add_key = zval_is_true(&res); } @@ -2051,7 +2151,7 @@ } if (Z_TYPE_PP(input) != IS_ARRAY) { - php_error(E_WARNING, "Argument to array_values() should be an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); return; } @@ -2060,7 +2160,7 @@ /* Go through input array and add values to the return array */ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos); - while(zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS) { + while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS) { (*entry)->refcount++; zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry, @@ -2078,7 +2178,7 @@ { zval **input, /* Input array */ **entry; /* An entry in the input array */ - zval **tmp; + zval **tmp; HashTable *myht; HashPosition pos; @@ -2088,7 +2188,7 @@ } if (Z_TYPE_PP(input) != IS_ARRAY) { - php_error(E_WARNING, "Argument to array_count_values() should be an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); return; } @@ -2125,7 +2225,7 @@ Z_LVAL_PP(tmp)++; } } else { - php_error(E_WARNING, "Can only count STRING and INTEGER values!"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only count STRING and INTEGER values!"); } zend_hash_move_forward_ex(myht, &pos); @@ -2154,7 +2254,7 @@ } if (Z_TYPE_PP(input) != IS_ARRAY) { - php_error(E_WARNING, "Argument to array_reverse() should be an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); return; } @@ -2167,7 +2267,7 @@ array_init(return_value); zend_hash_internal_pointer_end_ex(Z_ARRVAL_PP(input), &pos); - while(zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS) { + while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS) { (*entry)->refcount++; switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, &string_key_len, &num_key, 0, &pos)) { @@ -2214,8 +2314,7 @@ /* Make sure arguments are of the proper type */ if (Z_TYPE_PP(input) != IS_ARRAY) { - php_error(E_WARNING, "Argument to %s() should be an array", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); return; } convert_to_long_ex(pad_size); @@ -2273,7 +2372,7 @@ target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Wrong datatype in array_flip() call"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); RETURN_FALSE; } @@ -2300,7 +2399,7 @@ zend_hash_update(Z_ARRVAL_P(return_value), Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &data, sizeof(data), NULL); } else { zval_ptr_dtor(&data); /* will free also zval structure */ - php_error(E_WARNING, "Can only flip STRING and INTEGER values!"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only flip STRING and INTEGER values!"); } zend_hash_move_forward_ex(target_hash, &pos); @@ -2332,7 +2431,7 @@ } if (Z_TYPE_PP(array) != IS_ARRAY) { - php_error(E_WARNING, "Wrong datatype in array_change_key_case() call"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); RETURN_FALSE; } @@ -2343,10 +2442,10 @@ (*entry)->refcount++; switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(array), &string_key, &str_key_len, &num_key, 0, &pos)) { - case HASH_KEY_IS_LONG: + case HASH_KEY_IS_LONG: zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry, sizeof(entry), NULL); break; - case HASH_KEY_IS_STRING: + case HASH_KEY_IS_STRING: new_key=estrndup(string_key,str_key_len); if (change_to_upper) php_strtoupper(new_key, str_key_len - 1); @@ -2368,16 +2467,20 @@ { zval **array; HashTable *target_hash; - Bucket **arTmp, **cmpdata, **lastkept; Bucket *p; - int i; + struct bucketindex { + Bucket *b; + unsigned int i; + }; + struct bucketindex *arTmp, *cmpdata, *lastkept; + unsigned int i; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &array) == FAILURE) { WRONG_PARAM_COUNT; } target_hash = HASH_OF(*array); if (!target_hash) { - php_error(E_WARNING, "Wrong datatype in array_unique() call"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); RETURN_FALSE; } @@ -2386,38 +2489,43 @@ zval_copy_ctor(return_value); if (target_hash->nNumOfElements <= 1) /* nothing to do */ - return; + return; /* create and sort array with pointers to the target_hash buckets */ - arTmp = (Bucket **) pemalloc((target_hash->nNumOfElements + 1) * sizeof(Bucket *), target_hash->persistent); + arTmp = (struct bucketindex *) pemalloc((target_hash->nNumOfElements + 1) * sizeof(struct bucketindex), target_hash->persistent); if (!arTmp) RETURN_FALSE; - for (i = 0, p = target_hash->pListHead; p; i++, p = p->pListNext) - arTmp[i] = p; - arTmp[i] = NULL; - set_compare_func(SORT_STRING TSRMLS_CC); - zend_qsort((void *) arTmp, i, sizeof(Bucket *), array_data_compare TSRMLS_CC); + for (i = 0, p = target_hash->pListHead; p; i++, p = p->pListNext) { + arTmp[i].b = p; + arTmp[i].i = i; + } + arTmp[i].b = NULL; + set_compare_func(SORT_STRING TSRMLS_CC); + zend_qsort((void *) arTmp, i, sizeof(struct bucketindex), array_data_compare TSRMLS_CC); /* go through the sorted array and delete duplicates from the copy */ lastkept = arTmp; - for (cmpdata = arTmp + 1; *cmpdata; cmpdata++) { + for (cmpdata = arTmp + 1; cmpdata->b; cmpdata++) { if (array_data_compare(lastkept, cmpdata TSRMLS_CC)) { - lastkept = cmpdata; + lastkept = cmpdata; } else { - p = *cmpdata; + if (lastkept->i > cmpdata->i) { + p = lastkept->b; + lastkept = cmpdata; + } else { + p = cmpdata->b; + } if (p->nKeyLength) - zend_hash_del(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength); + zend_hash_del(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength); else - zend_hash_index_del(Z_ARRVAL_P(return_value), p->h); + zend_hash_index_del(Z_ARRVAL_P(return_value), p->h); } } pefree(arTmp, target_hash->persistent); } /* }}} */ -/* {{{ proto array array_intersect(array arr1, array arr2 [, array ...]) - Returns the entries of arr1 that have values which are present in all the other arguments */ -PHP_FUNCTION(array_intersect) +static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior) { zval ***args = NULL; HashTable *hash; @@ -2438,10 +2546,10 @@ /* for each argument, create and sort list with pointers to the hash buckets */ lists = (Bucket ***)emalloc(argc * sizeof(Bucket **)); ptrs = (Bucket ***)emalloc(argc * sizeof(Bucket **)); - set_compare_func(SORT_STRING TSRMLS_CC); + set_compare_func(SORT_STRING TSRMLS_CC); for (i=0; i<argc; i++) { if (Z_TYPE_PP(args[i]) != IS_ARRAY) { - php_error(E_WARNING, "Argument #%d to array_intersect() is not an array", i+1); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i+1); argc = i; /* only free up to i-1 */ goto out; } @@ -2454,7 +2562,11 @@ for (p = hash->pListHead; p; p = p->pListNext) *list++ = p; *list = NULL; - zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_data_compare TSRMLS_CC); + if (behavior == INTERSECT_NORMAL) { + zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_data_compare TSRMLS_CC); + } else if (behavior == INTERSECT_ASSOC) { + zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_key_compare TSRMLS_CC); + } } /* copy the argument array */ @@ -2464,11 +2576,26 @@ /* go through the lists and look for common values */ while (*ptrs[0]) { for (i=1; i<argc; i++) { - while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC)))) - ptrs[i]++; + if (behavior == INTERSECT_NORMAL) { + while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC)))) + ptrs[i]++; + } else if (behavior == INTERSECT_ASSOC) { + while (*ptrs[i] && (0 < (c = array_key_compare(ptrs[0], ptrs[i] TSRMLS_CC)))) + ptrs[i]++; + if (!c && *ptrs[i]) { /* this means that ptrs[i] is not NULL so we can compare */ + /* and "c==0" is from last operation */ + if (array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC) != 0) { + c = 1; + /* we are going to the break */ + } else { + /* continue looping */ + } + } + } if (!*ptrs[i]) { /* delete any values corresponding to remains of ptrs[0] */ - /* and exit */ + /* and exit because they do not present in at least one of */ + /* the other arguments */ for (;;) { p = *ptrs[0]++; if (!p) @@ -2479,13 +2606,13 @@ zend_hash_index_del(Z_ARRVAL_P(return_value), p->h); } } - if (c) + if (c) /* here we get if not all are equal */ break; ptrs[i]++; } if (c) { /* Value of ptrs[0] not in all arguments, delete all entries */ - /* with value < value of ptrs[i] */ + /* with value < value of ptrs[i] */ for (;;) { p = *ptrs[0]; if (p->nKeyLength) @@ -2494,8 +2621,13 @@ zend_hash_index_del(Z_ARRVAL_P(return_value), p->h); if (!*++ptrs[0]) goto out; - if (0 <= array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC)) + if (behavior == INTERSECT_NORMAL) { + if (0 <= array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC)) + break; + } else if (behavior == INTERSECT_ASSOC) { + /* no need of looping because indexes are unique */ break; + } } } else { /* ptrs[0] is present in all the arguments */ @@ -2503,8 +2635,13 @@ for (;;) { if (!*++ptrs[0]) goto out; - if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC)) + if (behavior == INTERSECT_NORMAL) { + if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC)) + break; + } else if (behavior == INTERSECT_ASSOC) { + /* no need of looping because indexes are unique */ break; + } } } } @@ -2518,18 +2655,32 @@ efree(lists); efree(args); } + +/* {{{ proto array array_intersect(array arr1, array arr2 [, array ...]) + Returns the entries of arr1 that have values which are present in all the other arguments */ +PHP_FUNCTION(array_intersect) +{ + php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_NORMAL); +} /* }}} */ -/* {{{ proto array array_diff(array arr1, array arr2 [, array ...]) - Returns the entries of arr1 that have values which are not present in any of the others arguments */ -PHP_FUNCTION(array_diff) +/* {{{ proto array array_intersect_assoc(array arr1, array arr2 [, array ...]) + Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrctive check */ +PHP_FUNCTION(array_intersect_assoc) +{ + php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_ASSOC); +} +/* }}} */ + + +static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior) { zval ***args = NULL; HashTable *hash; int argc, i, c; Bucket ***lists, **list, ***ptrs, *p; - /* Get the argument count and check it */ + /* Get the argument count and check it */ argc = ARG_COUNT(ht); if (argc < 2) { WRONG_PARAM_COUNT; @@ -2543,23 +2694,29 @@ /* for each argument, create and sort list with pointers to the hash buckets */ lists = (Bucket ***)emalloc(argc * sizeof(Bucket **)); ptrs = (Bucket ***)emalloc(argc * sizeof(Bucket **)); - set_compare_func(SORT_STRING TSRMLS_CC); - for (i=0; i<argc; i++) { + set_compare_func(SORT_STRING TSRMLS_CC); + for (i = 0; i < argc; i++) { if (Z_TYPE_PP(args[i]) != IS_ARRAY) { - php_error(E_WARNING, "Argument #%d to array_diff() is not an array", i+1); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1); argc = i; /* only free up to i-1 */ goto out; } hash = HASH_OF(*args[i]); list = (Bucket **) pemalloc((hash->nNumOfElements + 1) * sizeof(Bucket *), hash->persistent); - if (!list) - RETURN_FALSE; + if (!list) { + RETURN_FALSE; + } lists[i] = list; ptrs[i] = list; - for (p = hash->pListHead; p; p = p->pListNext) - *list++ = p; + for (p = hash->pListHead; p; p = p->pListNext) { + *list++ = p; + } *list = NULL; - zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_data_compare TSRMLS_CC); + if (behavior == DIFF_NORMAL) { + zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_data_compare TSRMLS_CC); + } else if (behavior == DIFF_ASSOC) { + zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_key_compare TSRMLS_CC); + } } /* copy the argument array */ @@ -2567,16 +2724,34 @@ zval_copy_ctor(return_value); /* go through the lists and look for values of ptr[0] - that are not in the others */ + that are not in the others */ while (*ptrs[0]) { c = 1; - for (i=1; i<argc; i++) { - while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC)))) - ptrs[i]++; - if (!c) { - if (*ptrs[i]) + for (i = 1; i < argc; i++) { + if (behavior == DIFF_NORMAL) { + while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC)))) { ptrs[i]++; - break; + } + } else if (behavior == DIFF_ASSOC) { + while (*ptrs[i] && (0 < (c = array_key_compare(ptrs[0], ptrs[i] TSRMLS_CC)))) { + ptrs[i]++; + } + } + if (!c) { + if (behavior == DIFF_NORMAL) { + if (*ptrs[i]) { + ptrs[i]++; + } + break; + } else if (behavior == DIFF_ASSOC) { + if (*ptrs[i]) { + if (array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC) != 0) { + c = -1; + } else { + break; + } + } + } } } if (!c) { @@ -2584,37 +2759,69 @@ /* delete all entries with value as ptrs[0] */ for (;;) { p = *ptrs[0]; - if (p->nKeyLength) + if (p->nKeyLength) { zend_hash_del(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength); - else - zend_hash_index_del(Z_ARRVAL_P(return_value), p->h); - if (!*++ptrs[0]) + } else { + zend_hash_index_del(Z_ARRVAL_P(return_value), p->h); + } + if (!*++ptrs[0]) { goto out; - if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC)) + } + if (behavior == DIFF_NORMAL) { + if (array_data_compare(ptrs[0] - 1, ptrs[0] TSRMLS_CC)) { + break; + } + } else if (behavior == DIFF_ASSOC) { + /* in this case no array_key_compare is needed */ break; + } } } else { /* ptrs[0] in none of the other arguments */ /* skip all entries with value as ptrs[0] */ for (;;) { - if (!*++ptrs[0]) + if (!*++ptrs[0]) { goto out; - if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC)) + } + if (behavior == DIFF_NORMAL) { + if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC)) { + break; + } + } else if (behavior == DIFF_ASSOC) { + /* in this case no array_key_compare is needed */ break; + } } } } out: - for (i=0; i<argc; i++) { - hash = HASH_OF(*args[i]); + for (i = 0; i < argc; i++) { + hash = HASH_OF(*args[i]); pefree(lists[i], hash->persistent); } efree(ptrs); efree(lists); efree(args); } + +/* {{{ proto array array_diff(array arr1, array arr2 [, array ...]) + Returns the entries of arr1 that have values which are not present in any of the others arguments */ +PHP_FUNCTION(array_diff) +{ + php_array_diff(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIFF_NORMAL); +} /* }}} */ +/* {{{ proto array array_diff_assoc(array arr1, array arr2 [, array ...]) + Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal */ +PHP_FUNCTION(array_diff_assoc) +{ + php_array_diff(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIFF_ASSOC); +} +/* }}} */ + + + #define MULTISORT_ORDER 0 #define MULTISORT_TYPE 1 #define MULTISORT_LAST 2 @@ -2660,7 +2867,7 @@ int array_size; int num_arrays = 0; int parse_state[MULTISORT_LAST]; /* 0 - flag not allowed - 1 - flag allowed */ + 1 - flag allowed */ int sort_order = SORT_ASC; int sort_type = SORT_REGULAR; int i, k; @@ -2716,7 +2923,7 @@ sort_order = Z_LVAL_PP(args[i]) == SORT_DESC ? -1 : 1; parse_state[MULTISORT_ORDER] = 0; } else { - php_error(E_WARNING, "Argument %i to %s() is expected to be an array or sorting flag that has not already been specified", i+1, get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is expected to be an array or sorting flag that has not already been specified", i+1); MULTISORT_ABORT; } break; @@ -2730,20 +2937,19 @@ sort_type = Z_LVAL_PP(args[i]); parse_state[MULTISORT_TYPE] = 0; } else { - php_error(E_WARNING, "Argument %i to %s() is expected to be an array or sorting flag that has not already been specified", i+1, get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1); MULTISORT_ABORT; } break; default: - php_error(E_WARNING, "Argument %i to %s() is an unknown sort flag", i+1, - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is an unknown sort flag", i + 1); MULTISORT_ABORT; break; } } else { - php_error(E_WARNING, "Argument %i to %s() is expected to be an array or a sort flag", i+1, get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is expected to be an array or a sort flag", i + 1); MULTISORT_ABORT; } } @@ -2755,7 +2961,7 @@ array_size = zend_hash_num_elements(Z_ARRVAL_PP(arrays[0])); for (i = 0; i < num_arrays; i++) { if (zend_hash_num_elements(Z_ARRVAL_PP(arrays[i])) != array_size) { - php_error(E_WARNING, "Array sizes are inconsistent"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array sizes are inconsistent"); MULTISORT_ABORT; } } @@ -2852,8 +3058,7 @@ } if (Z_TYPE_PP(input) != IS_ARRAY) { - zend_error(E_WARNING, "Argument to %s() has to be an array", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument has to be an array"); return; } @@ -2863,7 +3068,7 @@ convert_to_long_ex(num_req); num_req_val = Z_LVAL_PP(num_req); if (num_req_val <= 0 || num_req_val > num_avail) { - zend_error(E_WARNING, "Second argument to %s() has to be between 1 and the number of elements in the array", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument has to be between 1 and the number of elements in the array"); return; } } else @@ -2878,15 +3083,7 @@ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos); while (num_req_val && (key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, &string_key_len, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTANT) { -#ifdef HAVE_RANDOM - randval = random(); -#else -#ifdef HAVE_LRAND48 - randval = lrand48(); -#else - randval = rand(); -#endif -#endif + randval = php_rand(TSRMLS_C); if ((double)(randval/(PHP_RAND_MAX+1.0)) < (double)num_req_val/(double)num_avail) { /* If we are returning a single result, just do it. */ @@ -2910,10 +3107,7 @@ } if (num_req_val == num_avail) { - if (zend_hash_sort(Z_ARRVAL_P(return_value), (sort_func_t)php_mergesort, array_data_shuffle, 1 TSRMLS_CC) == FAILURE) { - zval_dtor(return_value); - RETURN_FALSE; - } + array_data_shuffle(return_value TSRMLS_CC); } } /* }}} */ @@ -2935,8 +3129,7 @@ } if (Z_TYPE_PP(input) != IS_ARRAY) { - php_error(E_WARNING, "The argument to %s() should be an array", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); return; } @@ -2986,14 +3179,12 @@ } if (Z_TYPE_PP(input) != IS_ARRAY) { - php_error(E_WARNING, "%s() expects argument 1 to be an array", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array"); return; } if (!zend_is_callable(*callback, 0, &callback_name)) { - php_error(E_WARNING, "%s() expects argument 2, '%s', to be a valid callback", - get_active_function_name(TSRMLS_C), callback_name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument, '%s', should be a valid callback", callback_name); efree(callback_name); return; } @@ -3021,7 +3212,7 @@ zval_ptr_dtor(&result); result = retval; } else { - php_error(E_WARNING, "%s() had an error invoking the reduction callback", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the reduction callback"); return; } } else { @@ -3059,15 +3250,13 @@ } if (Z_TYPE_PP(input) != IS_ARRAY) { - php_error(E_WARNING, "%s() expects argument 1 to be an array", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument shouldbe an array"); return; } if (ZEND_NUM_ARGS() > 1) { if (!zend_is_callable(*callback, 0, &callback_name)) { - php_error(E_WARNING, "%s() expects argument 2, '%s', to be a valid callback", - get_active_function_name(TSRMLS_C), callback_name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument, '%s', should be a valid callback", callback_name); efree(callback_name); return; } @@ -3091,7 +3280,7 @@ } else zval_ptr_dtor(&retval); } else { - php_error(E_WARNING, "%s() had an error invoking the filter callback", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the filter callback"); return; } } else if (!zend_is_true(*operand)) @@ -3140,7 +3329,7 @@ callback = *args[0]; if (Z_TYPE_P(callback) != IS_NULL) { if (!zend_is_callable(callback, 0, &callback_name)) { - php_error(E_WARNING, "%s() expects argument 1, '%s', to be either NULL or a valid callback", get_active_function_name(TSRMLS_C), callback_name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument, '%s', should be either NULL or a valid callback", callback_name); efree(callback_name); efree(args); return; @@ -3155,8 +3344,7 @@ /* Check that arrays are indeed arrays and calculate maximum size. */ for (i = 0; i < ZEND_NUM_ARGS()-1; i++) { if (Z_TYPE_PP(args[i+1]) != IS_ARRAY) { - php_error(E_WARNING, "%s() expects argument %d to be an array", - get_active_function_name(TSRMLS_C), i + 2); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d should be an array", i + 2); efree(array_len); efree(args); return; @@ -3187,7 +3375,7 @@ uint str_key_len; ulong num_key; char *str_key; - int key_type; + int key_type = 0; /* * If no callback, the result will be an array, consisting of current @@ -3227,7 +3415,7 @@ if (Z_TYPE_P(callback) != IS_NULL) { if (!call_user_function_ex(EG(function_table), NULL, callback, &result, ZEND_NUM_ARGS()-1, params, 0, NULL TSRMLS_CC) == SUCCESS && result) { - php_error(E_WARNING, "%s() had an error invoking the map callback", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the map callback"); efree(array_len); efree(args); efree(array_pos); @@ -3268,7 +3456,7 @@ } if (Z_TYPE_PP(array) != IS_ARRAY && Z_TYPE_PP(array) != IS_OBJECT) { - php_error(E_WARNING, "Wrong datatype for second argument in call to %s", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument should be either an array or an object"); RETURN_FALSE; } @@ -3286,7 +3474,7 @@ RETURN_FALSE; default: - php_error(E_WARNING, "Wrong datatype for first argument in call to %s", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be either a string or an integer"); RETURN_FALSE; } @@ -3315,8 +3503,7 @@ /* Do bounds checking for size parameter. */ if (size < 1) { - php_error(E_WARNING, "%s() expects the size parameter to be > 0", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size parameter expected to be greater than 0"); return; } 1.3 +4 -4 php4/ext/standard/assert.c Index: assert.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/assert.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- assert.c 29 Apr 2002 02:31:01 -0000 1.2 +++ assert.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: assert.c,v 1.47 2002/02/28 08:26:44 sebastian Exp $ */ +/* $Id: assert.c,v 1.49 2002/08/24 01:19:27 helly Exp $ */ /* {{{ includes/startup/misc */ @@ -206,9 +206,9 @@ if (ASSERTG(warning)) { if (myeval) { - php_error(E_WARNING, "Assertion \"%s\" failed", myeval); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Assertion \"%s\" failed", myeval); } else { - php_error(E_WARNING, "Assertion failed"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Assertion failed"); } } @@ -282,7 +282,7 @@ break; default: - php_error(E_WARNING, "Unknown value %d.", Z_LVAL_PP(what)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown value %d", Z_LVAL_PP(what)); break; } 1.4 +8 -5 php4/ext/standard/base64.c Index: base64.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/base64.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- base64.c 3 May 2002 00:14:52 -0000 1.3 +++ base64.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -15,7 +15,7 @@ | Author: Jim Winstead <jimw****@php*****> | +----------------------------------------------------------------------+ */ -/* $Id: base64.c,v 1.31 2002/05/01 20:11:09 derick Exp $ */ +/* $Id: base64.c,v 1.33 2002/08/22 01:20:50 sniper Exp $ */ #include <string.h> @@ -53,7 +53,8 @@ /* }}} */ /* {{{ */ -unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length) { +unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length) +{ const unsigned char *current = str; int i = 0; unsigned char *result = (unsigned char *)emalloc(((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char)); @@ -94,7 +95,8 @@ /* generate reverse table (do not set index 0 to 64) static unsigned short base64_reverse_table[256]; #define rt base64_reverse_table -void php_base64_init() { +void php_base64_init() +{ char *s = emalloc(10240), *sp; char *chp; short idx; @@ -125,7 +127,8 @@ /* {{{ */ /* as above, but backwards. :) */ -unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length) { +unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length) +{ const unsigned char *current = str; int ch, i = 0, j = 0, k; /* this sucks for threaded environments */ @@ -241,5 +244,5 @@ * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker - * vimo<600: sw=4 ts=4 + * vim<600: sw=4 ts=4 */ 1.6 +318 -95 php4/ext/standard/basic_functions.c Index: basic_functions.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/basic_functions.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- basic_functions.c 2 Aug 2002 22:05:24 -0000 1.5 +++ basic_functions.c 6 Oct 2002 21:54:32 -0000 1.6 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.478 2002/05/11 19:19:49 rasmus Exp $ */ +/* $Id: basic_functions.c,v 1.526 2002/10/06 16:33:14 sander Exp $ */ #include "php.h" #include "php_streams.h" @@ -37,7 +37,19 @@ #include <math.h> #include <time.h> #include <stdio.h> + +#ifndef NETWARE +#include <netdb.h> +#else +/*#include "netware/env.h"*/ /* Temporary */ +#ifdef NEW_LIBC /* Same headers hold good for Winsock and Berkeley sockets */ +#include <netinet/in.h> +/*#include <arpa/inet.h>*/ #include <netdb.h> +#else +#include <sys/socket.h> +#endif +#endif #if HAVE_ARPA_INET_H # include <arpa/inet.h> @@ -82,10 +94,14 @@ #include "php_fopen_wrappers.h" +static unsigned char first_and_second__args_force_ref[] = { 2, BYREF_FORCE, BYREF_FORCE }; static unsigned char second_and_third_args_force_ref[] = { 3, BYREF_NONE, BYREF_FORCE, BYREF_FORCE }; static unsigned char second_args_force_ref[] = { 2, BYREF_NONE, BYREF_FORCE }; static unsigned char third_and_fourth_args_force_ref[] = { 4, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE }; static unsigned char third_and_rest_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE_REST }; +static unsigned char first_through_third_args_force_ref[] = +{3, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE}; + typedef struct _php_shutdown_function_entry { zval **arguments; @@ -95,6 +111,7 @@ typedef struct _user_tick_function_entry { zval **arguments; int arg_count; + int calling; } user_tick_function_entry; /* some prototypes for local functions */ @@ -274,6 +291,8 @@ PHP_FE(htmlentities, NULL) PHP_FE(html_entity_decode, NULL) PHP_FE(get_html_translation_table, NULL) + PHP_FE(sha1, NULL) + PHP_FE(sha1_file, NULL) PHP_NAMED_FE(md5,php_if_md5, NULL) PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) PHP_NAMED_FE(crc32,php_if_crc32, NULL) @@ -281,6 +300,7 @@ PHP_FE(iptcparse, NULL) PHP_FE(iptcembed, NULL) PHP_FE(getimagesize, second_args_force_ref) + PHP_FE(image_type_to_mime_type, NULL) PHP_FE(phpinfo, NULL) PHP_FE(phpversion, NULL) @@ -312,11 +332,16 @@ PHP_FE(strstr, NULL) PHP_FE(stristr, NULL) PHP_FE(strrchr, NULL) + PHP_FE(str_shuffle, NULL) #ifdef HAVE_STRCOLL PHP_FE(strcoll, NULL) #endif +#ifdef HAVE_STRFMON + PHP_FE(money_format, NULL) +#endif + PHP_FE(substr, NULL) PHP_FE(substr_replace, NULL) PHP_FE(quotemeta, NULL) @@ -407,7 +432,7 @@ PHP_FE(gethostbyname, NULL) PHP_FE(gethostbynamel, NULL) -#if HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(PHP_WIN32)) +#if HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(PHP_WIN32) || defined(NETWARE)) PHP_FE(checkdnsrr, NULL) PHP_FE(getmxrr,second_and_third_args_force_ref) #endif @@ -436,7 +461,7 @@ PHP_FE(cosh, NULL) PHP_FE(tanh, NULL) -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(NETWARE) PHP_FE(asinh, NULL) PHP_FE(acosh, NULL) PHP_FE(atanh, NULL) @@ -473,6 +498,10 @@ PHP_FE(putenv, NULL) #endif +#ifdef HAVE_GETOPT + PHP_FE(getopt, NULL) +#endif + PHP_FE(microtime, NULL) PHP_FE(gettimeofday, NULL) @@ -521,7 +550,7 @@ PHP_FE(setcookie, NULL) PHP_FE(header, NULL) - PHP_FE(headers_sent, NULL) + PHP_FE(headers_sent, first_and_second__args_force_ref) PHP_FE(connection_aborted, NULL) PHP_FE(connection_status, NULL) @@ -595,31 +624,34 @@ PHP_STATIC_FE("tmpfile", php_if_tmpfile, NULL) PHP_FE(file, NULL) PHP_FE(file_get_contents, NULL) + PHP_FE(stream_select, first_through_third_args_force_ref) PHP_FE(stream_context_create, NULL) PHP_FE(stream_context_set_params, NULL) PHP_FE(stream_context_set_option, NULL) PHP_FE(stream_context_get_options, NULL) + PHP_FE(stream_filter_prepend, NULL) + PHP_FE(stream_filter_append, NULL) PHP_FE(fgetcsv, NULL) PHP_FE(flock, NULL) PHP_FE(get_meta_tags, NULL) - PHP_FE(set_file_buffer, NULL) + PHP_FE(stream_set_write_buffer, NULL) + PHP_FALIAS(set_file_buffer, stream_set_write_buffer, NULL) - /* set_socket_blocking() is deprecated, - use socket_set_blocking() instead - */ PHP_FE(set_socket_blocking, NULL) - PHP_FE(socket_set_blocking, NULL) + PHP_FE(stream_set_blocking, NULL) + PHP_FALIAS(socket_set_blocking, stream_set_blocking, NULL) - PHP_FE(file_get_wrapper_data, NULL) - PHP_FE(file_register_wrapper, NULL) + PHP_FE(stream_get_meta_data, NULL) + PHP_FE(stream_register_wrapper, NULL) -#if HAVE_SYS_TIME_H - PHP_FE(socket_set_timeout, NULL) +#if HAVE_SYS_TIME_H || defined(PHP_WIN32) + PHP_FE(stream_set_timeout, NULL) + PHP_FALIAS(socket_set_timeout, stream_set_timeout, NULL) #endif - PHP_FE(socket_get_status, NULL) + PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) -#if (!defined(PHP_WIN32) && !defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS) +#if (!defined(PHP_WIN32) && !defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) PHP_FE(realpath, NULL) #endif @@ -673,7 +705,9 @@ PHP_FE(is_writable, NULL) PHP_FALIAS(is_writeable, is_writable, NULL) PHP_FE(is_readable, NULL) +#ifndef PHP_WIN32 PHP_FE(is_executable, NULL) +#endif PHP_FE(is_file, NULL) PHP_FE(is_dir, NULL) PHP_FE(is_link, NULL) @@ -716,11 +750,14 @@ PHP_FE(ob_clean, NULL) PHP_FE(ob_end_flush, NULL) PHP_FE(ob_end_clean, NULL) + PHP_FE(ob_get_flush, NULL) + PHP_FE(ob_get_clean, NULL) PHP_FE(ob_get_length, NULL) PHP_FE(ob_get_level, NULL) PHP_FE(ob_get_status, NULL) PHP_FE(ob_get_contents, NULL) PHP_FE(ob_implicit_flush, NULL) + PHP_FE(ob_list_handlers, NULL) /* functions from array.c */ PHP_FE(ksort, first_arg_force_ref) @@ -771,7 +808,9 @@ PHP_FE(array_rand, NULL) PHP_FE(array_unique, NULL) PHP_FE(array_intersect, NULL) + PHP_FE(array_intersect_assoc, NULL) PHP_FE(array_diff, NULL) + PHP_FE(array_diff_assoc, NULL) PHP_FE(array_sum, NULL) PHP_FE(array_filter, NULL) PHP_FE(array_map, NULL) @@ -969,6 +1008,7 @@ PHP_MINIT(file) (INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(pack) (INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(browscap) (INIT_FUNC_ARGS_PASSTHRU); + PHP_MINIT(string_filters) (INIT_FUNC_ARGS_PASSTHRU); #if defined(HAVE_LOCALECONV) && defined(ZTS) PHP_MINIT(localeconv) (INIT_FUNC_ARGS_PASSTHRU); @@ -992,13 +1032,17 @@ PHP_MINIT(proc_open) (INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(user_streams) (INIT_FUNC_ARGS_PASSTHRU); + PHP_MINIT(imagetypes) (INIT_FUNC_ARGS_PASSTHRU); - php_register_url_stream_wrapper("http", &php_stream_http_wrapper TSRMLS_CC); php_register_url_stream_wrapper("php", &php_stream_php_wrapper TSRMLS_CC); +#ifndef PHP_CURL_URL_WRAPPERS + php_register_url_stream_wrapper("http", &php_stream_http_wrapper TSRMLS_CC); php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper TSRMLS_CC); # if HAVE_OPENSSL_EXT php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC); + php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC); # endif +#endif return SUCCESS; } @@ -1012,12 +1056,15 @@ basic_globals_dtor(&basic_globals TSRMLS_CC); #endif + php_unregister_url_stream_wrapper("php" TSRMLS_CC); +#ifndef PHP_CURL_URL_WRAPPERS php_unregister_url_stream_wrapper("http" TSRMLS_CC); php_unregister_url_stream_wrapper("ftp" TSRMLS_CC); - php_unregister_url_stream_wrapper("php" TSRMLS_CC); # if HAVE_OPENSSL_EXT php_unregister_url_stream_wrapper("https" TSRMLS_CC); + php_unregister_url_stream_wrapper("ftps" TSRMLS_CC); # endif +#endif UNREGISTER_INI_ENTRIES(); @@ -1027,6 +1074,7 @@ PHP_MSHUTDOWN(assert) (SHUTDOWN_FUNC_ARGS_PASSTHRU); PHP_MSHUTDOWN(url_scanner_ex) (SHUTDOWN_FUNC_ARGS_PASSTHRU); PHP_MSHUTDOWN(file) (SHUTDOWN_FUNC_ARGS_PASSTHRU); + PHP_MSHUTDOWN(string_filters) (SHUTDOWN_FUNC_ARGS_PASSTHRU); #if defined(HAVE_LOCALECONV) && defined(ZTS) PHP_MSHUTDOWN(localeconv) (SHUTDOWN_FUNC_ARGS_PASSTHRU); #endif @@ -1068,6 +1116,9 @@ PHP_RINIT(dir) (INIT_FUNC_ARGS_PASSTHRU); PHP_RINIT(url_scanner_ex) (INIT_FUNC_ARGS_PASSTHRU); + /* Reset magic_quotes_runtime */ + PG(magic_quotes_runtime) = INI_BOOL("magic_quotes_runtime"); + return SUCCESS; } @@ -1096,6 +1147,7 @@ PHP_RSHUTDOWN(syslog) (SHUTDOWN_FUNC_ARGS_PASSTHRU); PHP_RSHUTDOWN(assert) (SHUTDOWN_FUNC_ARGS_PASSTHRU); PHP_RSHUTDOWN(url_scanner_ex) (SHUTDOWN_FUNC_ARGS_PASSTHRU); + PHP_RSHUTDOWN(streams) (SHUTDOWN_FUNC_ARGS_PASSTHRU); if (BG(user_tick_functions)) { zend_llist_destroy(BG(user_tick_functions)); @@ -1108,7 +1160,7 @@ efree(BG(aggregation_table)); BG(aggregation_table) = NULL; } - + #ifdef HAVE_MMAP if (BG(mmap_file)) { munmap(BG(mmap_file), BG(mmap_len)); @@ -1143,7 +1195,7 @@ convert_to_string_ex(const_name); if (!zend_get_constant(Z_STRVAL_PP(const_name), Z_STRLEN_PP(const_name), return_value TSRMLS_CC)) { - php_error(E_WARNING, "Couldn't find constant %s", Z_STRVAL_PP(const_name)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find constant %s", Z_STRVAL_PP(const_name)); RETURN_NULL(); } } @@ -1237,7 +1289,7 @@ if (PG(safe_mode)) { /* Check the protected list */ if (zend_hash_exists(&BG(sm_protected_env_vars), pe.key, pe.key_len)) { - php_error(E_WARNING, "Safe Mode: Cannot override protected environment variable '%s'", pe.key); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Safe Mode warning: Cannot override protected environment variable '%s'", pe.key); efree(pe.putenv_string); efree(pe.key); RETURN_FALSE; @@ -1258,7 +1310,7 @@ } efree(allowed_env_vars); if (!allowed) { - php_error(E_WARNING, "Safe Mode: Cannot set environment variable '%s' - it's not in the allowed list", pe.key); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Safe Mode warning: Cannot set environment variable '%s' - it's not in the allowed list", pe.key); efree(pe.putenv_string); efree(pe.key); RETURN_FALSE; @@ -1295,6 +1347,117 @@ /* }}} */ #endif +#ifdef HAVE_GETOPT +/* {{{ free_argv + Free the memory allocated to an argv array. */ +static void free_argv(char **argv, int argc) +{ + int i; + + if (argv) { + for (i = 0; i < argc; i++) { + if (argv[i]) { + efree(argv[i]); + } + } + efree(argv); + } +} +/* }}} */ + +/* {{{ proto array getopt(string options) + Get options from the command line argument list */ +PHP_FUNCTION(getopt) +{ + char *options = NULL, **argv = NULL; + char opt[2] = { '\0' }; + int argc = 0, options_len = 0, o; + zval *val, **args = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", + &options, &options_len) == FAILURE) { + RETURN_FALSE; + } + + /* + * Get argv from the global symbol table. We calculate argc ourselves + * in order to be on the safe side, even though it is also available + * from the symbol table. + */ + if (zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), + (void **) &args) != FAILURE) { + int pos = 0; + zval **arg; + + argc = zend_hash_num_elements(Z_ARRVAL_PP(args)); + + /* + * Attempt to allocate enough memory to hold all of the arguments + * and a trailing NULL + */ + if ((argv = (char **) emalloc((argc + 1) * sizeof(char *))) == NULL) { + RETURN_FALSE; + } + + /* Reset the array indexes. */ + zend_hash_internal_pointer_reset(Z_ARRVAL_PP(args)); + + /* Iterate over the hash to construct the argv array. */ + while (zend_hash_get_current_data(Z_ARRVAL_PP(args), + (void **)&arg) == SUCCESS) { + argv[pos++] = estrdup(Z_STRVAL_PP(arg)); + zend_hash_move_forward(Z_ARRVAL_PP(args)); + } + + /* + * The C Standard requires argv[argc] to be NULL - this might + * keep some getopt implementations happy. + */ + argv[argc] = NULL; + } else { + /* Return false if we can't find argv. */ + RETURN_FALSE; + } + + /* Initialize the return value as an array. */ + if (array_init(return_value)) { + RETURN_FALSE; + } + + /* Disable getopt()'s error messages. */ + opterr = 0; + + /* Invoke getopt(3) on the argument array. */ + while ((o = getopt(argc, argv, options)) != -1) { + + /* Skip unknown arguments. */ + if (o == '?') { + continue; + } + + /* Prepare the option character and the argument string. */ + opt[0] = o; + + MAKE_STD_ZVAL(val); + if (optarg != NULL) { + ZVAL_STRING(val, optarg, 1); + } else { + ZVAL_NULL(val); + } + + /* Add this option / argument pair to the result hash. */ + if (zend_hash_add(HASH_OF(return_value), opt, sizeof(opt), (void *)&val, + sizeof(zval *), NULL) == FAILURE) { + free_argv(argv, argc); + RETURN_FALSE; + } + } + + free_argv(argv, argc); +} +/* }}} */ +#endif + /* {{{ proto void flush(void) Flush the output buffer */ PHP_FUNCTION(flush) @@ -1412,7 +1575,7 @@ 3 = save to file in 3rd parameter */ -/* {{{ proto bool error_log(string message, int message_type [, string destination] [, string extra_headers]) +/* {{{ proto bool error_log(string message [, int message_type [, string destination [, string extra_headers]]]) Send an error message somewhere */ PHP_FUNCTION(error_log) { @@ -1423,14 +1586,14 @@ switch (ZEND_NUM_ARGS()) { case 1: if (zend_get_parameters_ex(1, &string) == FAILURE) { - php_error(E_WARNING, "Invalid argument 1 in error_log"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument 1 invalid"); RETURN_FALSE; } break; case 2: if (zend_get_parameters_ex(2, &string, &erropt) == FAILURE) { - php_error(E_WARNING, "Invalid arguments in error_log"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments"); RETURN_FALSE; } convert_to_long_ex(erropt); @@ -1438,9 +1601,8 @@ break; case 3: - if (zend_get_parameters_ex(3, &string, &erropt, &option) == - FAILURE) { - php_error(E_WARNING, "Invalid arguments in error_log"); + if (zend_get_parameters_ex(3, &string, &erropt, &option) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments"); RETURN_FALSE; } convert_to_long_ex(erropt); @@ -1450,9 +1612,8 @@ break; case 4: - if (zend_get_parameters_ex - (4, &string, &erropt, &option, &emailhead) == FAILURE) { - php_error(E_WARNING, "Invalid arguments in error_log"); + if (zend_get_parameters_ex (4, &string, &erropt, &option, &emailhead) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments"); RETURN_FALSE; } break; @@ -1501,14 +1662,14 @@ return FAILURE; } #else - php_error(E_WARNING, "Mail option not available!"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Mail option not available!"); return FAILURE; #endif } break; case 2: /*send to an address */ - php_error(E_WARNING, "TCP/IP option not available!"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TCP/IP option not available!"); return FAILURE; break; @@ -1553,7 +1714,7 @@ } if (!zend_is_callable(*params[0], 0, &name)) { - php_error(E_WARNING, "%s() expects first argument, '%s', to be a valid callback", get_active_function_name(TSRMLS_C), name); + php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "First argumented is expected to be a valid callback"); efree(name); efree(params); RETURN_NULL(); @@ -1562,7 +1723,19 @@ if (call_user_function_ex(EG(function_table), NULL, *params[0], &retval_ptr, argc-1, params+1, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } else { - php_error(E_WARNING, "Unable to call %s()", name); + if (argc > 1) { + SEPARATE_ZVAL(params[1]); + convert_to_string_ex(params[1]); + if (argc > 2) { + SEPARATE_ZVAL(params[2]); + convert_to_string_ex(params[2]); + php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "Unable to call %s(%s,%s)", name, Z_STRVAL_PP(params[1]), Z_STRVAL_PP(params[2])); + } else { + php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "Unable to call %s(%s)", name, Z_STRVAL_PP(params[1])); + } + } else { + php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "Unable to call %s()", name); + } } efree(name); @@ -1594,7 +1767,7 @@ } if (!zend_is_callable(*func, 0, &name)) { - php_error(E_WARNING, "%s() expects first argument, '%s', to be a valid callback", get_active_function_name(TSRMLS_C), name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argumented is expected to be a valid callback, '%s' was given", name); efree(name); RETURN_NULL(); } @@ -1614,7 +1787,7 @@ if (call_user_function_ex(EG(function_table), NULL, *func, &retval_ptr, count, func_params, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } else { - php_error(E_WARNING, "Unable to call %s()", name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", name); } efree(name); @@ -1622,7 +1795,7 @@ } /* }}} */ -#define _CUM_DEPREC "The %s() function is deprecated, use the call_user_func variety with the array(&$obj, \"method\") syntax instead" +#define _CUM_DEPREC "This function is deprecated, use the call_user_func variety with the array(&$obj, \"method\") syntax instead" /* {{{ proto mixed call_user_method(string method_name, mixed object [, mixed parameter] [, mixed ...]) Call a user method on a specific object or class */ @@ -1632,7 +1805,7 @@ zval *retval_ptr; int arg_count = ZEND_NUM_ARGS(); - php_error(E_NOTICE, _CUM_DEPREC, "call_user_method"); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, _CUM_DEPREC); if (arg_count < 2) { WRONG_PARAM_COUNT; @@ -1644,7 +1817,7 @@ RETURN_FALSE; } if (Z_TYPE_PP(params[1]) != IS_OBJECT && Z_TYPE_PP(params[1]) != IS_STRING) { - php_error(E_WARNING, "2nd argument is not an object or class name\n"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument is not an object or class name"); efree(params); RETURN_FALSE; } @@ -1655,7 +1828,7 @@ if (call_user_function_ex(EG(function_table), params[1], *params[0], &retval_ptr, arg_count-2, params+2, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } else { - php_error(E_WARNING, "Unable to call %s()", Z_STRVAL_PP(params[0])); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", Z_STRVAL_PP(params[0])); } efree(params); } @@ -1669,14 +1842,14 @@ HashTable *params_ar; int num_elems, element = 0; - php_error(E_NOTICE, _CUM_DEPREC, "call_user_method_array"); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, _CUM_DEPREC); if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &method_name, &obj, ¶ms) == FAILURE) { WRONG_PARAM_COUNT; } if (Z_TYPE_PP(obj) != IS_OBJECT && Z_TYPE_PP(obj) != IS_STRING) { - php_error(E_WARNING, "2nd argument is not an object or class name\n"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument is not an object or class name"); RETURN_FALSE; } @@ -1699,7 +1872,7 @@ if (call_user_function_ex(EG(function_table), obj, *method_name, &retval_ptr, num_elems, method_args, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } else { - php_error(E_WARNING, "Unable to call %s()", Z_STRVAL_PP(method_name)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", Z_STRVAL_PP(method_name)); } efree(method_args); @@ -1740,7 +1913,7 @@ zval_dtor(&retval); } else { - php_error(E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(shutdown_function_entry->arguments[0])); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(shutdown_function_entry->arguments[0])); } return 0; } @@ -1749,29 +1922,36 @@ { zval retval; zval *function = tick_fe->arguments[0]; + + /* Prevent reentrant calls to the same user ticks function */ + if (! tick_fe->calling) { + tick_fe->calling = 1; + + if (call_user_function( EG(function_table), NULL, + function, + &retval, + tick_fe->arg_count - 1, + tick_fe->arguments+1 + TSRMLS_CC) == SUCCESS) { + zval_dtor(&retval); - if (call_user_function( EG(function_table), NULL, - function, - &retval, - tick_fe->arg_count - 1, - tick_fe->arguments+1 - TSRMLS_CC) == SUCCESS) { - zval_dtor(&retval); - - } else { - zval **obj, **method; - - if (Z_TYPE_P(function) == IS_STRING) { - php_error(E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(function)); - } else if ( Z_TYPE_P(function) == IS_ARRAY - && zend_hash_index_find(Z_ARRVAL_P(function), 0, (void **) &obj) == SUCCESS - && zend_hash_index_find(Z_ARRVAL_P(function), 1, (void **) &method) == SUCCESS - && Z_TYPE_PP(obj) == IS_OBJECT - && Z_TYPE_PP(method) == IS_STRING ) { - php_error(E_WARNING, "Unable to call %s::%s() - function does not exist", Z_OBJCE_PP(obj)->name, Z_STRVAL_PP(method)); } else { - php_error(E_WARNING, "Unable to call tick function"); + zval **obj, **method; + + if (Z_TYPE_P(function) == IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(function)); + } else if ( Z_TYPE_P(function) == IS_ARRAY + && zend_hash_index_find(Z_ARRVAL_P(function), 0, (void **) &obj) == SUCCESS + && zend_hash_index_find(Z_ARRVAL_P(function), 1, (void **) &method) == SUCCESS + && Z_TYPE_PP(obj) == IS_OBJECT + && Z_TYPE_PP(method) == IS_STRING ) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s::%s() - function does not exist", Z_OBJCE_PP(obj)->name, Z_STRVAL_PP(method)); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call tick function"); + } } + + tick_fe->calling = 0; } } @@ -1862,7 +2042,7 @@ zend_bool i = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &filename, &i) == FAILURE) { - return; + RETURN_FALSE; } convert_to_string(filename); @@ -1903,7 +2083,7 @@ zend_bool i = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &expr, &i) == FAILURE) { - return; + RETURN_FALSE; } convert_to_string(expr); @@ -1943,7 +2123,7 @@ convert_to_string_ex(varname); - str = php_ini_string(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, 0); + str = zend_ini_string(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, 0); if (!str) { RETURN_FALSE; @@ -1960,7 +2140,7 @@ int module_number = va_arg(args, int); zval *option; - if(module_number != 0 && ini_entry->module_number != module_number) { + if (module_number != 0 && ini_entry->module_number != module_number) { return 0; } @@ -1969,7 +2149,7 @@ MAKE_STD_ZVAL(option); array_init(option); - if(ini_entry->orig_value) { + if (ini_entry->orig_value) { add_assoc_stringl(option, "global_value", ini_entry->orig_value, ini_entry->orig_value_length, 1); } else if (ini_entry->value) { add_assoc_stringl(option, "global_value", ini_entry->value, ini_entry->value_length, 1); @@ -1977,7 +2157,7 @@ add_assoc_null(option, "global_value"); } - if(ini_entry->value) { + if (ini_entry->value) { add_assoc_stringl(option, "local_value", ini_entry->value, ini_entry->value_length, 1); } else { add_assoc_null(option, "local_value"); @@ -1999,24 +2179,33 @@ zend_module_entry *module; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &extname, &extname_len) == FAILURE) { - return; + RETURN_FALSE; } zend_ini_sort_entries(TSRMLS_C); - if(extname) { + if (extname) { if (zend_hash_find(&module_registry, extname, extname_len+1, (void **) &module) == FAILURE) { - php_error(E_WARNING, "Unable to find extension '%s'", extname); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find extension '%s'", extname); RETURN_FALSE; } extnumber = module->module_number; } array_init(return_value); - zend_hash_apply_with_arguments(&EG(ini_directives), (apply_func_args_t) php_ini_get_option, 2, return_value, extnumber TSRMLS_CC); + zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) php_ini_get_option, 2, return_value, extnumber TSRMLS_CC); } /* }}} */ +static int php_ini_check_path(char *option_name, int option_len, char *new_option_name, int new_option_len) +{ + if ( option_len != (new_option_len-1) ) { + return 0; + } + + return strncmp(option_name, new_option_name, option_len); +} + /* {{{ proto string ini_set(string varname, string newvalue) Set a configuration option, returns false on error and the old value of the configuration option on success */ PHP_FUNCTION(ini_set) @@ -2031,7 +2220,7 @@ convert_to_string_ex(varname); convert_to_string_ex(new_value); - old_value = php_ini_string(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, 0); + old_value = zend_ini_string(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, 0); /* copy to return here, because alter might free it! */ if (old_value) { @@ -2040,6 +2229,28 @@ RETVAL_FALSE; } +#define _CHECK_PATH(var, ini) php_ini_check_path(Z_STRVAL_PP(var), Z_STRLEN_PP(var), ini, sizeof(ini)) + + /* safe_mode & basedir check */ + if (PG(safe_mode) || PG(open_basedir)) { + if (_CHECK_PATH(varname, "error_log") || + _CHECK_PATH(varname, "java.class.path") || + _CHECK_PATH(varname, "java.home") || + _CHECK_PATH(varname, "java.library.path") || + _CHECK_PATH(varname, "session.save_path") || + _CHECK_PATH(varname, "vpopmail.directory")) { + if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(new_value), NULL, CHECKUID_CHECK_FILE_AND_DIR))) { + zval_dtor(return_value); + RETURN_FALSE; + } + + if (php_check_open_basedir(Z_STRVAL_PP(new_value) TSRMLS_CC)) { + zval_dtor(return_value); + RETURN_FALSE; + } + } + } + if (zend_alter_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, Z_STRVAL_PP(new_value), Z_STRLEN_PP(new_value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) { zval_dtor(return_value); @@ -2064,19 +2275,29 @@ } /* }}} */ -/* {{{ proto bool print_r(mixed var) - Prints out information about the specified variable */ +/* {{{ proto bool print_r(mixed var [, bool return]) + Prints out or returns information about the specified variable */ PHP_FUNCTION(print_r) { - pval **expr; + zval *var; + zend_bool i = 0; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &expr) == FAILURE) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &i) == FAILURE) { + RETURN_FALSE; + } + + if (i) { + php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); } - zend_print_pval_r(*expr, 0); + zend_print_pval_r(var, 0); - RETURN_TRUE; + if (i) { + php_ob_get_buffer (return_value TSRMLS_CC); + php_end_ob_buffer (0, 0 TSRMLS_CC); + } else { + RETURN_TRUE; + } } /* }}} */ @@ -2098,7 +2319,7 @@ } /* }}} */ -/* {{{ proto int ignore_user_abort(boolean value) +/* {{{ proto int ignore_user_abort(bool value) Set whether we want to ignore a user abort event or not */ PHP_FUNCTION(ignore_user_abort) { @@ -2115,11 +2336,11 @@ if (zend_get_parameters_ex(1, &arg) == FAILURE) { RETURN_FALSE; } - convert_to_boolean_ex(arg); - PG(ignore_user_abort) = (zend_bool) Z_LVAL_PP(arg); + convert_to_string_ex(arg); + zend_alter_ini_entry("ignore_user_abort", sizeof("ignore_user_abort"), Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); break; - default: + default: WRONG_PARAM_COUNT; break; } @@ -2197,7 +2418,7 @@ if (ent == NULL) { Z_LVAL_P(return_value) = -1; Z_TYPE_P(return_value) = IS_LONG; - return; + RETURN_FALSE; } RETURN_LONG(ent->p_proto); @@ -2237,6 +2458,7 @@ user_tick_function_entry tick_fe; int i; + tick_fe.calling = 0; tick_fe.arg_count = ZEND_NUM_ARGS(); if (tick_fe.arg_count < 1) { WRONG_PARAM_COUNT; @@ -2357,7 +2579,7 @@ if (successful) { zend_hash_del(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1); } else { - php_error(E_WARNING, "Unable to move '%s' to '%s'", Z_STRVAL_PP(path), Z_STRVAL_PP(new_path)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to move '%s' to '%s'", Z_STRVAL_PP(path), Z_STRVAL_PP(new_path)); } RETURN_BOOL(successful); } @@ -2371,7 +2593,7 @@ switch (callback_type) { case ZEND_INI_PARSER_ENTRY: - if(!arg2) { + if (!arg2) { /* bare string - nothing to do */ break; } @@ -2398,7 +2620,7 @@ { zval *active_arr; - if(!arg2) { + if (!arg2) { /* bare string - nothing to do */ break; } @@ -2431,7 +2653,7 @@ } -/* {{{ proto array parse_ini_file(string filename [, boolean process_sections]) +/* {{{ proto array parse_ini_file(string filename [, bool process_sections]) Parse configuration file */ PHP_FUNCTION(parse_ini_file) { @@ -2482,8 +2704,8 @@ fh.handle.fp = VCWD_FOPEN(Z_STRVAL_PP(filename), "r"); if (!fh.handle.fp) { - php_error(E_WARNING, "Cannot open '%s' for reading", Z_STRVAL_PP(filename)); - return; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot open '%s' for reading", Z_STRVAL_PP(filename)); + RETURN_FALSE; } Z_TYPE(fh) = ZEND_HANDLE_FP; fh.filename = Z_STRVAL_PP(filename); @@ -2512,7 +2734,8 @@ memcpy(new_key, prefix, prefix_len); memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength); - ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, 0, 1); + zend_hash_del(&EG(symbol_table), new_key, new_key_len); + ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); efree(new_key); return 0; @@ -2551,7 +2774,7 @@ } if (prefix_len == 0) { - zend_error(E_NOTICE, "No prefix specified in %s() - possible security hazard", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "No prefix specified - possible security hazard"); } convert_to_string_ex(z_types); 1.3 +4 -2 php4/ext/standard/basic_functions.h Index: basic_functions.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/basic_functions.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- basic_functions.h 29 Apr 2002 02:31:01 -0000 1.2 +++ basic_functions.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.h,v 1.105 2002/03/23 23:03:04 derick Exp $ */ +/* $Id: basic_functions.h,v 1.108 2002/09/30 03:02:52 jon Exp $ */ #ifndef BASIC_FUNCTIONS_H #define BASIC_FUNCTIONS_H @@ -50,6 +50,8 @@ PHP_FUNCTION(getenv); PHP_FUNCTION(putenv); +PHP_FUNCTION(getopt); + PHP_FUNCTION(get_current_user); PHP_FUNCTION(set_time_limit); @@ -141,7 +143,7 @@ HashTable sm_protected_env_vars; char *sm_allowed_env_vars; - + /* pageinfo.c */ long page_uid; long page_gid; 1.4 +2 -2 php4/ext/standard/browscap.c Index: browscap.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/browscap.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- browscap.c 3 May 2002 00:14:52 -0000 1.3 +++ browscap.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: browscap.c,v 1.57 2002/04/30 11:30:07 stas Exp $ */ +/* $Id: browscap.c,v 1.59 2002/08/24 01:19:27 helly Exp $ */ #include "php.h" #include "php_regex.h" @@ -149,7 +149,7 @@ fh.handle.fp = VCWD_FOPEN(browscap, "r"); if (!fh.handle.fp) { - php_error(E_CORE_WARNING, "Cannot open '%s' for reading", browscap); + php_error_docref(NULL TSRMLS_CC, E_CORE_WARNING, "Cannot open '%s' for reading", browscap); return FAILURE; } fh.filename = browscap; 1.3 +8 -7 php4/ext/standard/config.m4 Index: config.m4 =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/config.m4,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- config.m4 29 Apr 2002 02:31:01 -0000 1.2 +++ config.m4 6 Oct 2002 21:54:32 -0000 1.3 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.37 2002/04/08 18:43:35 sniper Exp $ -*- sh -*- +dnl $Id: config.m4,v 1.42 2002/10/01 01:47:09 sniper Exp $ -*- sh -*- divert(3)dnl @@ -185,8 +185,6 @@ AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) ]) -AC_CHECK_FUNC(dlopen, [AC_DEFINE(HAVE_LIBDL,1,[ ])]) - dnl AC_CHECK_LIB(pam, pam_start, [ dnl EXTRA_LIBS="$EXTRA_LIBS -lpam" dnl AC_DEFINE(HAVE_LIBPAM,1,[ ]) ], []) @@ -224,8 +222,11 @@ ],[ REGEX_TYPE=php ]) - -AC_CHECK_FUNCS(fnmatch glob) + +AC_FUNC_FNMATCH +AC_CHECK_FUNCS(glob) + +AC_CHECK_FUNCS(strfmon) if test "$PHP_SAPI" = "cgi"; then AC_DEFINE(ENABLE_CHROOT_FUNC, 1, [Whether to enable chroot() function]) @@ -238,7 +239,7 @@ parsedate.c quot_print.c rand.c reg.c soundex.c string.c scanf.c \ syslog.c type.c uniqid.c url.c url_scanner.c var.c versioning.c assert.c \ strnatcmp.c levenshtein.c incomplete_class.c url_scanner_ex.c \ - ftp_fopen_wrapper.c http_fopen_wrapper.c php_fopen_wrapper.c credits.c \ - var_unserializer.c ftok.c aggregation.c) + ftp_fopen_wrapper.c http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ + var_unserializer.c ftok.c aggregation.c sha1.c ) PHP_ADD_MAKEFILE_FRAGMENT 1.3 +5 -7 php4/ext/standard/credits.c Index: credits.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/credits.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- credits.c 29 Apr 2002 02:31:01 -0000 1.2 +++ credits.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: credits.c,v 1.17 2002/02/28 08:26:44 sebastian Exp $ */ +/* $Id: credits.c,v 1.20 2002/09/26 19:48:56 sebastian Exp $ */ #include "php.h" #include "info.h" @@ -31,19 +31,17 @@ TSRMLS_FETCH(); if (flag & PHP_CREDITS_FULLPAGE) { - PUTS("<html><head><title>PHP Credits</title></head><body>\n"); + php_print_info_htmlhead(TSRMLS_C); } - php_info_print_style(); - - PUTS("<h1 align=\"center\">PHP 4 Credits</h1>\n"); + PUTS("<h1>PHP Credits</h1>\n"); if (flag & PHP_CREDITS_GROUP) { /* Group */ php_info_print_table_start(); php_info_print_table_header(1, "PHP Group"); - php_info_print_table_row(1, "Thies C. Arntzen, Stig Bakken, Andi Gutmans, Rasmus Lerdorf, Sam Ruby, Sascha Schumann, Zeev Suraski, Jim Winstead, Andrei Zmievski"); + php_info_print_table_row(1, "Thies C. Arntzen, Stig Bakken, Shane Caraveo, Andi Gutmans, Rasmus Lerdorf, Sam Ruby, Sascha Schumann, Zeev Suraski, Jim Winstead, Andrei Zmievski"); php_info_print_table_end(); } @@ -110,7 +108,7 @@ } if (flag & PHP_CREDITS_FULLPAGE) { - PUTS("</body></html>\n"); + PUTS("</center></body></html>\n"); } } /* }}} */ 1.3 +12 -12 php4/ext/standard/credits_ext.h Index: credits_ext.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/credits_ext.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- credits_ext.h 29 Apr 2002 02:31:01 -0000 1.2 +++ credits_ext.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -13,7 +13,7 @@ CREDIT_LINE("aspell", "Rasmus Lerdorf"); CREDIT_LINE("Assert", "Thies C. Arntzen"); CREDIT_LINE("BC Math", "Andi Gutmans"); -CREDIT_LINE("bz2", "Sterling Hughes"); +CREDIT_LINE("Bzip2", "Sterling Hughes"); CREDIT_LINE("Calendar", "Shane Caraveo, Colin Viebrock, Hartmut Holzgraefe, Wez Furlong"); CREDIT_LINE("ccvs", "Brendan W. McAdams, Doug DeJulio"); CREDIT_LINE("cpdf", "Uwe Steinmann"); @@ -25,19 +25,19 @@ CREDIT_LINE("DBA", "Sascha Schumann"); CREDIT_LINE("dBase", "Jim Winstead"); CREDIT_LINE("DBM", "Rasmus Lerdorf, Jim Winstead"); -CREDIT_LINE("dbplus", "Hartmut Holzgraefe"); CREDIT_LINE("dbx (database abstraction)", "Marc Boeren, Rui Hirokawa, Frank M. Kromann"); -CREDIT_LINE("domxml", "Uwe Steinmann"); +CREDIT_LINE("domxml", "Uwe Steinmann, Christian Stocker"); CREDIT_LINE("dotnet", "Sam Ruby"); CREDIT_LINE("EXIF", "Rasmus Lerdorf, Marcus Boerger"); CREDIT_LINE("FBSQL", "Frank M. Kromann"); CREDIT_LINE("FDF", "Uwe Steinmann"); CREDIT_LINE("FilePro", "Chad Robinson"); -CREDIT_LINE("FRIBIDI", "Onn Ben-Zvi"); +CREDIT_LINE("FriBidi", "Onn Ben-Zvi, Tal Peer"); CREDIT_LINE("FTP", "Andrew Skalski"); CREDIT_LINE("GD imaging", "Rasmus Lerdorf, Stig Bakken, Jim Winstead, Jouni Ahto"); CREDIT_LINE("GetText", "Alex Plotnick"); CREDIT_LINE("GNU GMP support", "Stanislav Malyshev"); +CREDIT_LINE("HwAPI", "Uwe Steinmann"); CREDIT_LINE("HyperWave", "Uwe Steinmann"); CREDIT_LINE("icap", "Mark Musone"); CREDIT_LINE("IMAP", "Rex Logan, Mark Musone, Brian Wang, Kaj-Michael Lang, Antoni Pamies Olive, Rasmus Lerdorf, Andrew Skalski, Chuck Hagenbuch, Daniel R Kalowsky"); @@ -47,17 +47,18 @@ CREDIT_LINE("IRCG", "Sascha Schumann"); CREDIT_LINE("Java", "Sam Ruby"); CREDIT_LINE("LDAP", "Amitay Isaacs, Eric Warnke, Rasmus Lerdorf, Gerrit Thomson, Stig Venaas"); -CREDIT_LINE("Mailparse MIME parsing and manipulation functions", "Wez Furlong"); CREDIT_LINE("MCAL", "Mark Musone, Chuck Hagenbuch"); CREDIT_LINE("mcrypt", "Sascha Schumann, Derick Rethans"); +CREDIT_LINE("MCVE", "Brad House, Chris Faulhaber, Steven Schoch"); CREDIT_LINE("mhash", "Sascha Schumann"); +CREDIT_LINE("mime_magic", "Hartmut Holzgraefe"); CREDIT_LINE("MING", "Dave Hayden"); CREDIT_LINE("mnoGoSearch", "Alex Barkov, Ramil Kalimullin, Sergey Kartashoff"); -CREDIT_LINE("MS SQL", "Frank M. Kromann"); CREDIT_LINE("msession", "Mark L. Woodward"); CREDIT_LINE("mSQL", "Zeev Suraski"); -CREDIT_LINE("Multibyte (Japanese) String Functions", "Tsukada Takuya"); -CREDIT_LINE("MySQL", "Zeev Suraski"); +CREDIT_LINE("MS SQL", "Frank M. Kromann"); +CREDIT_LINE("Multibyte (Japanese) String Functions", "Tsukada Takuya, Rui Hirokawa"); +CREDIT_LINE("MySQL", "Zeev Suraski, Zak Greant, Georg Richter"); CREDIT_LINE("ncurses", "Hartmut Holzgraefe"); CREDIT_LINE("OCI8", "Stig Bakken, Thies C. Arntzen, Andy Sautins, David Benson"); CREDIT_LINE("ODBC", "Stig Bakken, Andreas Karajannis, Frank M. Kromann, Daniel R. Kalowsky"); @@ -73,7 +74,6 @@ CREDIT_LINE("qtdom", "Jan Borsodi"); CREDIT_LINE("Readline", "Thies C. Arntzen"); CREDIT_LINE("Recode", "Kristian K〓hntopp"); -CREDIT_LINE("Satellite (CORBA)", "David Eriksson"); CREDIT_LINE("Sessions", "Sascha Schumann, Andrei Zmievski"); CREDIT_LINE("Shared Memory Operations", "Slava Poliakov, Ilia Alshanetsky"); CREDIT_LINE("SNMP", "Rasmus Lerdorf"); @@ -81,17 +81,17 @@ CREDIT_LINE("SWF", "Sterling Hughes"); CREDIT_LINE("Sybase-CT", "Zeev Suraski, Tom May"); CREDIT_LINE("Sybase-DB", "Zeev Suraski"); +CREDIT_LINE("System V Message based IPC", "Wez Furlong"); CREDIT_LINE("System V Semaphores", "Tom May"); CREDIT_LINE("System V Shared Memory", "Christian Cartus"); CREDIT_LINE("tokenizer", "Andrei Zmievski"); CREDIT_LINE("User-space object overloading", "Andrei Zmievski"); CREDIT_LINE("Verisign Payflow Pro", "John Donagher, David Croft"); -CREDIT_LINE("Vpopmail", "David Croft, Boian Bonev"); CREDIT_LINE("W32API", "James Moore"); CREDIT_LINE("WDDX", "Andrei Zmievski"); -CREDIT_LINE("Win32 COM", "Zeev Suraski, Harald Radi, Alan Brown"); -CREDIT_LINE("XML", "Stig Bakken, Thies C. Arntzen"); +CREDIT_LINE("Win32 COM", "Alan Brown, Wez Furlong, Harald Radi, Zeev Suraski"); CREDIT_LINE("xmlrpc", "Dan Libby"); +CREDIT_LINE("XML", "Stig Bakken, Thies C. Arntzen"); CREDIT_LINE("YAZ", "Adam Dickmeiss"); CREDIT_LINE("Yellow Pages", "Stephanie Wehner, Fredrik Ohrn"); CREDIT_LINE("Zip", "Sterling Hughes"); 1.4 +2 -1 php4/ext/standard/credits_sapi.h Index: credits_sapi.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/credits_sapi.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- credits_sapi.h 9 May 2002 05:39:43 -0000 1.3 +++ credits_sapi.h 6 Oct 2002 21:54:32 -0000 1.4 @@ -10,12 +10,13 @@ */ +CREDIT_LINE("ActiveScript", "Wez Furlong"); CREDIT_LINE("AOLserver", "Sascha Schumann"); CREDIT_LINE("Apache 1.3", "Rasmus Lerdorf, Zeev Suraski, Stig Bakken, David Sklar"); CREDIT_LINE("Apache 2.0", "Sascha Schumann, Aaron Bannert"); CREDIT_LINE("Caudium / Roxen", "David Hedbor"); CREDIT_LINE("CGI", "Rasmus Lerdorf, Stig Bakken"); -CREDIT_LINE("CLI", "Rasmus Lerdorf, Stig Bakken, Edin Kadribasic"); +CREDIT_LINE("CLI", "Edin Kadribasic, Marcus Boerger"); CREDIT_LINE("fastcgi", "Ben Mansell"); CREDIT_LINE("fhttpd", "Alex Belits"); CREDIT_LINE("ISAPI", "Andi Gutmans, Zeev Suraski"); 1.3 +5 -5 php4/ext/standard/cyr_convert.c Index: cyr_convert.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/cyr_convert.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- cyr_convert.c 29 Apr 2002 02:31:01 -0000 1.2 +++ cyr_convert.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cyr_convert.c,v 1.19 2002/02/28 08:26:44 sebastian Exp $ */ +/* $Id: cyr_convert.c,v 1.22 2002/08/24 01:19:27 helly Exp $ */ #include <stdlib.h> @@ -201,7 +201,7 @@ * d - x-cp866 * m - x-mac-cyrillic *****************************************************************************/ -static char * php_convert_cyr_string(unsigned char *str, int length, char from, char to) +static char * php_convert_cyr_string(unsigned char *str, int length, char from, char to TSRMLS_DC) { const unsigned char *from_table, *to_table; unsigned char tmp; @@ -228,7 +228,7 @@ case 'K': break; default: - php_error(E_WARNING, "Unknown source charset: %c", from); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown source charset: %c", from); break; } @@ -250,7 +250,7 @@ case 'K': break; default: - php_error(E_WARNING, "Unknown destination charset: %c", to); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown destination charset: %c", to); break; } @@ -284,7 +284,7 @@ str = (unsigned char*) estrndup(Z_STRVAL_PP(str_arg), Z_STRLEN_PP(str_arg)); - php_convert_cyr_string(str, Z_STRLEN_PP(str_arg), Z_STRVAL_PP(fr_cs)[0], Z_STRVAL_PP(to_cs)[0]); + php_convert_cyr_string(str, Z_STRLEN_PP(str_arg), Z_STRVAL_PP(fr_cs)[0], Z_STRVAL_PP(to_cs)[0] TSRMLS_CC); RETVAL_STRING((char *)str, 0) } /* }}} */ 1.4 +111 -48 php4/ext/standard/datetime.c Index: datetime.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/datetime.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- datetime.c 9 May 2002 05:39:43 -0000 1.3 +++ datetime.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -19,7 +19,7 @@ */ -/* $Id: datetime.c,v 1.86 2002/05/06 21:44:43 mfischer Exp $ */ +/* $Id: datetime.c,v 1.96 2002/09/25 12:20:56 iliaa Exp $ */ #include "php.h" @@ -55,6 +55,9 @@ }; #if !defined(HAVE_TM_ZONE) && !defined(_TIMEZONE) && !defined(HAVE_DECLARED_TIMEZONE) +#if defined(NETWARE) && defined(NEW_LIBC) +#define timezone _timezone /* timezone is called '_timezone' in new version of LibC */ +#endif extern time_t timezone; extern int daylight; #endif @@ -66,6 +69,7 @@ }; #define isleap(year) (((year%4) == 0 && (year%100)!=0) || (year%400)==0) +#define YEAR_BASE 1900 /* {{{ proto int time(void) Return current UNIX timestamp */ @@ -81,9 +85,9 @@ { pval **arguments[7]; struct tm *ta, tmbuf; - time_t t; - int i, gmadjust, seconds, arg_count = ZEND_NUM_ARGS(); - int is_dst = -1; + time_t t, seconds; + int i, gmadjust, arg_count = ZEND_NUM_ARGS(); + int is_dst = -1, val, chgsecs = 0; if (arg_count > 7 || zend_get_parameters_array_ex(arg_count, arguments) == FAILURE) { WRONG_PARAM_COUNT; @@ -118,10 +122,10 @@ ** Now change date values with supplied parameters. */ switch(arg_count) { - case 7: + case 7: /* daylight saving time flag */ ta->tm_isdst = is_dst = Z_LVAL_PP(arguments[6]); /* fall-through */ - case 6: + case 6: /* year */ /* special case: a zero in year, month and day is considered illegal as it would be interpreted as 30.11.1999 otherwise @@ -149,29 +153,70 @@ ta->tm_year = Z_LVAL_PP(arguments[5]) - ((Z_LVAL_PP(arguments[5]) > 1000) ? 1900 : 0); /* fall-through */ - case 5: - ta->tm_mday = Z_LVAL_PP(arguments[4]); - /* fall-through */ - case 4: - ta->tm_mon = Z_LVAL_PP(arguments[3]) - 1; - /* fall-through */ - case 3: - ta->tm_sec = Z_LVAL_PP(arguments[2]); - /* fall-through */ - case 2: - ta->tm_min = Z_LVAL_PP(arguments[1]); - /* fall-through */ - case 1: - ta->tm_hour = Z_LVAL_PP(arguments[0]); - /* fall-through */ - case 0: - break; + case 5: /* day in month (1-baesd) */ + val = (*arguments[4])->value.lval; + if (val < 1) { + chgsecs += (1-val) * 60*60*24; + val = 1; + } + ta->tm_mday = val; + /* fall-through */ + case 4: /* month (zero-based) */ + val = (*arguments[3])->value.lval - 1; + while (val < 0) { + val += 12; ta->tm_year--; + } + ta->tm_mon = val; + /* fall-through */ + case 3: /* second */ + val = (*arguments[2])->value.lval; + if (val < 1) { + chgsecs += (1-val); val = 1; + } + ta->tm_sec = val; + /* fall-through */ + case 2: /* minute */ + val = (*arguments[1])->value.lval; + if (val < 1) { + chgsecs += (1-val) * 60; val = 1; + } + ta->tm_min = val; + /* fall-through */ + case 1: /* hour */ + val = (*arguments[0])->value.lval; + if (val < 1) { + chgsecs += (1-val) * 60*60; val = 1; + } + ta->tm_hour = val; + /* fall-through */ + case 0: + break; + } + + t = mktime(ta); + +#ifdef PHP_WIN32 + if (t < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Windows does not support negative values for this function"); + RETURN_LONG(-1); } +#endif + + seconds = t - chgsecs; - seconds = mktime(ta); - if (is_dst == -1) - is_dst = ta->tm_isdst; + if (is_dst == -1) { + struct tm t1, t2; + t1 = *localtime(&t); + t2 = *localtime(&seconds); + if(t1.tm_isdst != t2.tm_isdst) { + seconds += (t1.tm_isdst == 1) ? 3600 : -3600; + ta = localtime(&seconds); + } + + is_dst = ta->tm_isdst; + } + if (gm) { #if HAVE_TM_GMTOFF /* @@ -265,7 +310,7 @@ } if (!ta) { /* that really shouldn't happen... */ - php_error(E_WARNING, "unexpected error in date()"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected error"); RETURN_FALSE; } for (i = 0; i < Z_STRLEN_PP(format); i++) { @@ -360,7 +405,7 @@ strcat(Z_STRVAL_P(return_value), day_full_names[ta->tm_wday]); break; case 'Y': /* year, numeric, 4 digits */ - sprintf(tmp_buff, "%d", ta->tm_year + 1900); /* SAFE */ + sprintf(tmp_buff, "%d", ta->tm_year + YEAR_BASE); /* SAFE */ strcat(Z_STRVAL_P(return_value), tmp_buff); break; case 'M': /* month, textual, 3 letters */ @@ -446,7 +491,7 @@ } break; case 't': /* days in current month */ - sprintf(tmp_buff, "%2d", phpday_tab[isleap((ta->tm_year+1900))][ta->tm_mon] ); + sprintf(tmp_buff, "%2d", phpday_tab[isleap((ta->tm_year+YEAR_BASE))][ta->tm_mon] ); strcat(Z_STRVAL_P(return_value), tmp_buff); break; case 'w': /* day of the week, numeric EXTENSION */ @@ -455,9 +500,9 @@ break; case 'O': /* GMT offset in [+-]HHMM format */ #if HAVE_TM_GMTOFF - sprintf(tmp_buff, "%c%02d%02d", (ta->tm_gmtoff < 0) ? '-' : '+', abs(ta->tm_gmtoff / 3600), abs( ta->tm_gmtoff % 3600)); + sprintf(tmp_buff, "%c%02d%02d", (ta->tm_gmtoff < 0) ? '-' : '+', abs(ta->tm_gmtoff / 3600), abs( (ta->tm_gmtoff % 3600) / 60 )); #else - sprintf(tmp_buff, "%c%02d%02d", ((ta->tm_isdst ? tzone - 3600:tzone)>0)?'-':'+', abs((ta->tm_isdst ? tzone - 3600 : tzone) / 3600), abs((ta->tm_isdst ? tzone - 3600 : tzone) % 3600)); + sprintf(tmp_buff, "%c%02d%02d", ((ta->tm_isdst ? tzone - 3600:tzone)>0)?'-':'+', abs((ta->tm_isdst ? tzone - 3600 : tzone) / 3600), abs(((ta->tm_isdst ? tzone - 3600 : tzone) % 3600) / 60)); #endif strcat(Z_STRVAL_P(return_value), tmp_buff); break; @@ -470,7 +515,7 @@ strcat(Z_STRVAL_P(return_value), tmp_buff); break; case 'L': /* boolean for leapyear */ - sprintf(tmp_buff, "%d", (isleap((ta->tm_year+1900)) ? 1 : 0 ) ); + sprintf(tmp_buff, "%d", (isleap((ta->tm_year+YEAR_BASE)) ? 1 : 0 ) ); strcat(Z_STRVAL_P(return_value), tmp_buff); break; case 'T': /* timezone name */ @@ -500,38 +545,49 @@ day_short_names[ta->tm_wday], ta->tm_mday, mon_short_names[ta->tm_mon], - ta->tm_year + 1900, + ta->tm_year + YEAR_BASE, ta->tm_hour, ta->tm_min, ta->tm_sec, (ta->tm_gmtoff < 0) ? '-' : '+', abs(ta->tm_gmtoff / 3600), - abs( ta->tm_gmtoff % 3600) + abs( (ta->tm_gmtoff % 3600) / 60 ) ); #else sprintf(tmp_buff, "%3s, %2d %3s %04d %02d:%02d:%02d %c%02d%02d", day_short_names[ta->tm_wday], ta->tm_mday, mon_short_names[ta->tm_mon], - ta->tm_year + 1900, + ta->tm_year + YEAR_BASE, ta->tm_hour, ta->tm_min, ta->tm_sec, ((ta->tm_isdst ? tzone - 3600 : tzone) > 0) ? '-' : '+', abs((ta->tm_isdst ? tzone - 3600 : tzone) / 3600), - abs((ta->tm_isdst ? tzone - 3600 : tzone) % 3600) + abs( ((ta->tm_isdst ? tzone - 3600 : tzone) % 3600) / 60 ) ); #endif strcat(Z_STRVAL_P(return_value), tmp_buff); break; case 'W': /* ISO-8601 week number of year, weeks starting on Monday */ - wd = ta->tm_wday==0 ? 7 : ta->tm_wday; - yd = ta->tm_yday + 1; - fd = (7 + (wd - yd) % 7 ) % 7; - wk = ( (yd + fd - 1) / 7 ) + 1; - if (fd>3) { - wk--; + wd = ta->tm_wday==0 ? 6 : ta->tm_wday-1;/* weekday */ + yd = ta->tm_yday + 1; /* days since January 1st */ + + fd = (7 + wd - yd % 7+ 1) % 7; /* weekday (1st January) */ + + /* week is a last year week (52 or 53) */ + if ((yd <= 7 - fd) && fd > 3){ + wk = (fd == 4 || (fd == 5 && isleap((ta->tm_year + YEAR_BASE - 1)))) ? 53 : 52; + } + /* week is a next year week (1) */ + else if (isleap((ta->tm_year+YEAR_BASE)) + 365 - yd < 3 - wd){ + wk = 1; + } + /* normal week */ + else { + wk = (yd + 6 - wd + fd) / 7 - (fd > 3); } + sprintf(tmp_buff, "%d", wk); /* SAFE */ strcat(Z_STRVAL_P(return_value), tmp_buff); break; @@ -594,13 +650,20 @@ assoc_array = Z_LVAL_PP(assoc_array_arg); break; } + +#ifdef PHP_WIN32 + if (timestamp < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Windows does not support negative values for this function"); + RETURN_FALSE + } +#endif + if (NULL == (ta = php_localtime_r(×tamp, &tmbuf))) { - php_error(E_WARNING, "%s(): invalid local time", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid local time"); RETURN_FALSE; } if (array_init(return_value) == FAILURE) { - php_error(E_ERROR, "Cannot prepare return array from localtime"); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot prepare return array from localtime"); RETURN_FALSE; } @@ -647,11 +710,11 @@ ta = php_localtime_r(×tamp, &tmbuf); if (!ta) { - php_error(E_WARNING, "Cannot perform date calculation"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot perform date calculation"); return; } if (array_init(return_value) == FAILURE) { - php_error(E_ERROR, "Unable to initialize array"); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to initialize array"); return; } add_assoc_long(return_value, "seconds", ta->tm_sec); @@ -832,7 +895,7 @@ convert_to_string_ex(z_time); if (Z_STRLEN_PP(z_time) == 0) - php_error (E_NOTICE, "strtotime() called with empty time parameter"); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Called with empty time parameter"); if (argc == 2) { convert_to_long_ex(z_now); now = Z_LVAL_PP(z_now); 1.4 +63 -20 php4/ext/standard/dir.c Index: dir.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/dir.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- dir.c 2 Aug 2002 22:05:24 -0000 1.3 +++ dir.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dir.c,v 1.90 2002/05/18 13:31:31 mfischer Exp $ */ +/* $Id: dir.c,v 1.107 2002/10/04 18:03:29 rasmus Exp $ */ /* {{{ includes/startup/misc */ @@ -40,7 +40,11 @@ #endif #ifdef HAVE_GLOB +#ifndef PHP_WIN32 #include <glob.h> +#else +#include "win32/glob.h" +#endif #endif typedef struct { @@ -71,7 +75,7 @@ myself = getThis(); \ if (myself) { \ if (zend_hash_find(Z_OBJPROP_P(myself), "handle", sizeof("handle"), (void **)&tmp) == FAILURE) { \ - php_error(E_WARNING, "unable to find my handle property"); \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find my handle property"); \ RETURN_FALSE; \ } \ ZEND_FETCH_RESOURCE(dirp, php_stream *, tmp, -1, "Directory", php_file_le_stream()); \ @@ -94,9 +98,9 @@ static void php_set_default_dir(int id TSRMLS_DC) { - if (DIRG(default_dir)!=-1) { - zend_list_delete(DIRG(default_dir)); - } + if (DIRG(default_dir)!=-1) { + zend_list_delete(DIRG(default_dir)); + } if (id != -1) { zend_list_addref(id); @@ -126,6 +130,21 @@ tmpstr[1] = '\0'; REGISTER_STRING_CONSTANT("DIRECTORY_SEPARATOR", tmpstr, CONST_CS|CONST_PERSISTENT); +#ifdef HAVE_GLOB +#ifdef GLOB_MARK + REGISTER_LONG_CONSTANT("GLOB_MARK", GLOB_MARK, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef GLOB_NOSORT + REGISTER_LONG_CONSTANT("GLOB_NOSORT", GLOB_NOSORT, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef GLOB_NOCHECK + REGISTER_LONG_CONSTANT("GLOB_NOCHECK", GLOB_NOCHECK, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef GLOB_NOESCAPE + REGISTER_LONG_CONSTANT("GLOB_NOESCAPE", GLOB_NOESCAPE, CONST_CS | CONST_PERSISTENT); +#endif +#endif + return SUCCESS; } @@ -154,7 +173,6 @@ object_init_ex(return_value, dir_class_entry_ptr); add_property_stringl(return_value, "path", Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), 1); add_property_resource(return_value, "handle", dirp->rsrc_id); - zend_list_addref(dirp->rsrc_id); /* might not be needed */ php_stream_auto_cleanup(dirp); /* so we don't get warnings under debug */ } else { php_stream_to_zval(dirp, return_value); @@ -171,7 +189,7 @@ } /* }}} */ -/* {{{ proto class dir(string directory) +/* {{{ proto object dir(string directory) Directory class with properties, handle and class and methods read, rewind and close */ PHP_FUNCTION(getdir) @@ -211,17 +229,18 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { RETURN_FALSE; } - ret = chroot(str); + + ret = chroot(str); if (ret != 0) { - php_error(E_WARNING, "chroot: %s (errno %d)", strerror(errno), errno); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno); RETURN_FALSE; } ret = chdir("/"); if (ret != 0) { - php_error(E_WARNING, "chdir: %s (errno %d)", strerror(errno), errno); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno); RETURN_FALSE; } @@ -249,7 +268,7 @@ ret = VCWD_CHDIR(str); if (ret != 0) { - php_error(E_WARNING, "ChDir: %s (errno %d)", strerror(errno), errno); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno); RETURN_FALSE; } @@ -323,31 +342,43 @@ #ifdef HAVE_GLOB /* {{{ proto array glob(string pattern [, int flags]) - */ + Find pathnames matching a pattern */ PHP_FUNCTION(glob) { + char cwd[MAXPATHLEN]; + int cwd_skip = 0; +#ifdef ZTS + char work_pattern[MAXPATHLEN]; + char *result; +#endif char *pattern = NULL; int pattern_len; long flags = 0; glob_t globbuf; int n, ret; - if (PG(safe_mode)) { - php_error(E_WARNING, "%s() SAFE MODE Restriction in effect, function is disabled", - get_active_function_name(TSRMLS_C)); - RETURN_FALSE; - } - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &pattern, &pattern_len, &flags) == FAILURE) return; +#ifdef ZTS + if(!IS_ABSOLUTE_PATH(pattern, pattern_len)) { + result = VCWD_GETCWD(cwd, MAXPATHLEN); + if (!result) { + cwd[0] = '\0'; + } + cwd_skip = strlen(cwd)+1; + snprintf(work_pattern, MAXPATHLEN, "%s/%s", cwd, pattern); + pattern = work_pattern; + } +#endif + globbuf.gl_offs = 0; if (0 != (ret = glob(pattern, flags, NULL, &globbuf))) { #ifdef GLOB_NOMATCH if (GLOB_NOMATCH == ret) { /* Linux handles no matches as an error condition, but FreeBSD * doesn't. This ensure that if no match is found, an empty array - * is always returned so it can be used with worrying in e.g. + * is always returned so it can be used without worrying in e.g. * foreach() */ array_init(return_value); return; @@ -356,10 +387,22 @@ RETURN_FALSE; } + /* we assume that any glob pattern will match files from one directory only + so checking the dirname of the first match should be sufficient */ + strncpy(cwd, globbuf.gl_pathv[0], MAXPATHLEN); + if (PG(safe_mode) && (!php_checkuid(cwd, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { + RETURN_FALSE; + } + if(php_check_open_basedir(cwd TSRMLS_CC)) { + RETURN_FALSE; + } + + array_init(return_value); for (n = 0; n < globbuf.gl_pathc; n++) { - add_next_index_string(return_value, globbuf.gl_pathv[n], 1); + add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip, 1); } + globfree(&globbuf); } /* }}} */ 1.3 +38 -14 php4/ext/standard/dl.c Index: dl.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/dl.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- dl.c 29 Apr 2002 02:31:01 -0000 1.2 +++ dl.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dl.c,v 1.68 2002/04/04 00:24:34 sniper Exp $ */ +/* $Id: dl.c,v 1.73 2002/09/05 21:12:55 sniper Exp $ */ #include "php.h" #include "dl.h" @@ -26,7 +26,7 @@ #include "ext/standard/info.h" #include "SAPI.h" -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(NETWARE) #include "build-defs.h" #endif @@ -34,7 +34,7 @@ #include <stdlib.h> #include <stdio.h> -#if HAVE_STRING_H +#ifdef HAVE_STRING_H #include <string.h> #else #include <strings.h> @@ -43,6 +43,13 @@ #include "win32/param.h" #include "win32/winutil.h" #define GET_DL_ERROR() php_win_err() +#elif defined(NETWARE) +#ifdef NEW_LIBC +#include <sys/param.h> +#else +#include "netware/param.h" +#endif +#define GET_DL_ERROR() dlerror() #else #include <sys/param.h> #define GET_DL_ERROR() DL_ERROR() @@ -59,7 +66,7 @@ #ifdef ZTS if ((strcmp(sapi_module.name, "cgi")!=0) && (strcmp(sapi_module.name, "cli")!=0)) { - php_error(E_ERROR, "dl() is not supported in multithreaded Web servers - use extension statements in your php.ini"); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not supported in multithreaded Web servers - use extension statements in your php.ini"); } #endif @@ -71,9 +78,9 @@ convert_to_string_ex(file); if (!PG(enable_dl)) { - php_error(E_ERROR, "Dynamically loaded extentions aren't enabled."); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Dynamically loaded extentions aren't enabled"); } else if (PG(safe_mode)) { - php_error(E_ERROR, "Dynamically loaded extensions aren't allowed when running in SAFE MODE."); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Dynamically loaded extensions aren't allowed when running in Safe Mode"); } else { php_dl(*file, MODULE_TEMPORARY, return_value TSRMLS_CC); EG(full_tables_cleanup) = 1; @@ -134,14 +141,14 @@ /* load dynamic symbol */ handle = DL_LOAD(libpath); if (!handle) { - php_error(error_type, "Unable to load dynamic library '%s' - %s", libpath, GET_DL_ERROR()); + php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, GET_DL_ERROR()); efree(libpath); RETURN_FALSE; } efree(libpath); - +#ifndef NETWARE get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module"); /* @@ -152,10 +159,27 @@ if (!get_module) get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "_get_module"); +#else + /* NetWare doesn't support two NLMs exporting same symbol */ + { + char symbol_name[64] = "\0"; + int module_name_length = Z_STRLEN_P(file) - 4; /* '.nlm' is 4 characters; knock it off */ + + /* Take the module name (e.g.: 'php_ldap') and append '@get_module' to it */ + strncpy(symbol_name, Z_STRVAL_P(file), module_name_length); + symbol_name[module_name_length] = '\0'; + strcat(symbol_name, "@"); + strcat(symbol_name, "get_module"); + + get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, symbol_name); + } + /* NetWare doesn't prepend '_' to symbol names; so the corresponding portion of code is also + not required for NetWare */ +#endif if (!get_module) { DL_UNLOAD(handle); - php_error(error_type, "Invalid library (maybe not a PHP library) '%s' ", Z_STRVAL_P(file)); + php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%s' ", Z_STRVAL_P(file)); RETURN_FALSE; } module_entry = get_module(); @@ -205,7 +229,7 @@ "PHP compiled with module API=%d, debug=%d, thread-safety=%d\n" "These options need to match\n", name, zend_api, zend_debug, zts, - ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); + ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); DL_UNLOAD(handle); RETURN_FALSE; } @@ -213,7 +237,7 @@ module_entry->module_number = zend_next_free_module(); if (module_entry->module_startup_func) { if (module_entry->module_startup_func(type, module_entry->module_number TSRMLS_CC)==FAILURE) { - php_error(error_type, "%s: Unable to initialize module", module_entry->name); + php_error_docref(NULL TSRMLS_CC, error_type, "Unable to initialize module '%s'", module_entry->name); DL_UNLOAD(handle); RETURN_FALSE; } @@ -222,7 +246,7 @@ if ((type == MODULE_TEMPORARY) && module_entry->request_startup_func) { if (module_entry->request_startup_func(type, module_entry->module_number TSRMLS_CC)) { - php_error(error_type, "%s: Unable to initialize module", module_entry->name); + php_error_docref(NULL TSRMLS_CC, error_type, "Unable to initialize module '%s'", module_entry->name); DL_UNLOAD(handle); RETURN_FALSE; } @@ -230,7 +254,7 @@ /* update the .request_started property... */ if (zend_hash_find(&module_registry, module_entry->name, strlen(module_entry->name)+1, (void **) &tmp)==FAILURE) { - php_error(error_type, "%s: Loaded module got lost", module_entry->name); + php_error_docref(NULL TSRMLS_CC, error_type, "Loaded module '%s' got lost", module_entry->name); RETURN_FALSE; } tmp->handle = handle; @@ -248,7 +272,7 @@ void php_dl(pval *file, int type, pval *return_value TSRMLS_DC) { - php_error(E_WARNING, "Cannot dynamically load %s - dynamic modules are not supported", Z_STRVAL_P(file)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot dynamically load %s - dynamic modules are not supported", Z_STRVAL_P(file)); RETURN_FALSE; } 1.3 +12 -7 php4/ext/standard/dns.c Index: dns.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/dns.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- dns.c 29 Apr 2002 02:31:01 -0000 1.2 +++ dns.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dns.c,v 1.38 2002/02/28 08:26:44 sebastian Exp $ */ +/* $Id: dns.c,v 1.43 2002/09/05 14:21:55 hyanantha Exp $ */ /* {{{ includes */ @@ -42,7 +42,7 @@ #endif #endif #include <winsock.h> -#else +#else /* This holds good for NetWare too, both for Winsock and Berkeley sockets */ #include <netinet/in.h> #if HAVE_ARPA_INET_H #include <arpa/inet.h> @@ -60,6 +60,11 @@ #endif #endif +/* Borrowed from SYS/SOCKET.H */ +#if defined(NETWARE) && defined(USE_WINSOCK) +#define AF_INET 2 /* internetwork: UDP, TCP, etc. */ +#endif + #include "dns.h" /* }}} */ @@ -85,9 +90,9 @@ #if HAVE_IPV6 && !defined(__MacOSX__) /* MacOSX at this time has support for IPv6, but not inet_pton() * so disabling IPv6 until further notice. MacOSX 10.1.2 (kalowsky) */ - php_error(E_WARNING, "Address is not a valid IPv4 or IPv6 address"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Address is not a valid IPv4 or IPv6 address"); #else - php_error(E_WARNING, "Address is not in a.b.c.d form"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Address is not in a.b.c.d form"); #endif RETVAL_FALSE; } else { @@ -128,7 +133,7 @@ hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET); #endif - if (!hp) { + if (!hp || hp->h_name == NULL || hp->h_name[0] == '\0') { return estrdup(ip); } @@ -201,7 +206,7 @@ } /* }}} */ -#if HAVE_RES_SEARCH && !(defined(__BEOS__)||defined(PHP_WIN32)) +#if HAVE_RES_SEARCH && !(defined(__BEOS__)||defined(PHP_WIN32) || defined(NETWARE)) /* {{{ proto int checkdnsrr(string host [, string type]) Check DNS records corresponding to a given Internet host name or IP address */ @@ -236,7 +241,7 @@ else if ( !strcasecmp("SOA", Z_STRVAL_PP(arg2)) ) type = T_SOA; else if ( !strcasecmp("CNAME", Z_STRVAL_PP(arg2)) ) type = T_CNAME; else { - php_error(E_WARNING, "Type '%s' not supported", Z_STRVAL_PP(arg2)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%s' not supported", Z_STRVAL_PP(arg2)); RETURN_FALSE; } break; 1.4 +65 -43 php4/ext/standard/exec.c Index: exec.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/exec.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- exec.c 9 May 2002 05:39:43 -0000 1.3 +++ exec.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -15,7 +15,7 @@ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ */ -/* $Id: exec.c,v 1.74 2002/05/05 17:14:12 stas Exp $ */ +/* $Id: exec.c,v 1.82 2002/09/25 15:46:46 wez Exp $ */ #include <stdio.h> #include "php.h" @@ -72,7 +72,7 @@ larg0 = strlen(arg0); if (strstr(arg0, "..")) { - zend_error(E_WARNING, "No '..' components allowed in path"); + php_error(E_WARNING, "No '..' components allowed in path"); efree(arg0); return FAILURE; } @@ -124,7 +124,7 @@ buf = (char *) emalloc(EXEC_INPUT_BUF); if (!buf) { - php_error(E_WARNING, "Unable to emalloc %d bytes for exec buffer", EXEC_INPUT_BUF); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to emalloc %d bytes for exec buffer", EXEC_INPUT_BUF); return -1; } buflen = EXEC_INPUT_BUF; @@ -137,7 +137,7 @@ c = strchr(cmd, ' '); if (c) *c = '\0'; if (strstr(cmd, "..")) { - php_error(E_WARNING, "No '..' components allowed in path"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No '..' components allowed in path"); efree(buf); return -1; } @@ -169,7 +169,7 @@ fp = VCWD_POPEN(d, "r"); #endif if (!fp) { - php_error(E_WARNING, "Unable to fork [%s]", d); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fork [%s]", d); efree(d); efree(buf); #if PHP_SIGCHILD @@ -188,7 +188,7 @@ fp = VCWD_POPEN(cmd, "r"); #endif if (!fp) { - php_error(E_WARNING, "Unable to fork [%s]", cmd); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fork [%s]", cmd); efree(buf); #if PHP_SIGCHILD signal (SIGCHLD, sig_handler); @@ -219,7 +219,7 @@ if ( buflen <= (l+1) ) { buf = erealloc(buf, buflen + EXEC_INPUT_BUF); if ( buf == NULL ) { - php_error(E_WARNING, "Unable to erealloc %d bytes for exec buffer", + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to erealloc %d bytes for exec buffer", buflen + EXEC_INPUT_BUF); #if PHP_SIGCHILD signal (SIGCHLD, sig_handler); @@ -309,9 +309,14 @@ int arg_count = ZEND_NUM_ARGS(); int ret; - if (arg_count > 3 || zend_get_parameters_ex(arg_count, &arg1, &arg2, &arg3) == FAILURE) { + if (arg_count < 1 || arg_count > 3 || zend_get_parameters_ex(arg_count, &arg1, &arg2, &arg3) == FAILURE) { WRONG_PARAM_COUNT; } + + if (!Z_STRLEN_PP(arg1)) { + PHP_EMPTY_EXEC_PARAM; + } + switch (arg_count) { case 1: ret = php_Exec(0, Z_STRVAL_PP(arg1), NULL, return_value TSRMLS_CC); @@ -337,9 +342,14 @@ int arg_count = ZEND_NUM_ARGS(); int ret; - if (arg_count > 2 || zend_get_parameters_ex(arg_count, &arg1, &arg2) == FAILURE) { + if (arg_count < 1 || arg_count > 2 || zend_get_parameters_ex(arg_count, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; } + + if (!Z_STRLEN_PP(arg1)) { + PHP_EMPTY_EXEC_PARAM; + } + switch (arg_count) { case 1: ret = php_Exec(1, Z_STRVAL_PP(arg1), NULL, return_value TSRMLS_CC); @@ -361,9 +371,14 @@ int arg_count = ZEND_NUM_ARGS(); int ret; - if (arg_count > 2 || zend_get_parameters_ex(arg_count, &arg1, &arg2) == FAILURE) { + if (arg_count < 1 || arg_count > 2 || zend_get_parameters_ex(arg_count, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; } + + if (!Z_STRLEN_PP(arg1)) { + PHP_EMPTY_EXEC_PARAM; + } + switch (arg_count) { case 1: ret = php_Exec(3, Z_STRVAL_PP(arg1), NULL, return_value TSRMLS_CC); @@ -514,7 +529,7 @@ } if (PG(safe_mode)) { - php_error(E_WARNING, "Cannot execute using backquotes in safe mode"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute using backquotes in Safe Mode"); RETURN_FALSE; } @@ -524,7 +539,7 @@ #else if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "r"))==NULL) { #endif - php_error(E_WARNING, "Unable to execute '%s'", Z_STRVAL_PP(cmd)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to execute '%s'", Z_STRVAL_PP(cmd)); RETURN_FALSE; } allocated_space = EXEC_INPUT_BUF; @@ -559,7 +574,7 @@ GetExitCodeProcess(child, &wstatus); FG(pclose_ret) = wstatus; #else -# if HAVE_SYS_WAIT +# if HAVE_SYS_WAIT_H int wstatus; pid_t child, wait_pid; @@ -567,7 +582,7 @@ do { wait_pid = waitpid(child, &wstatus, 0); - } while (wait_pid == -1 && errno = EINTR); + } while (wait_pid == -1 && errno == EINTR); if (wait_pid == -1) FG(pclose_ret) = -1; @@ -591,16 +606,16 @@ close a process opened by proc_open */ PHP_FUNCTION(proc_close) { - zval **proc; + zval *proc; void *child; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &proc) == FAILURE) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE(child, void *, proc, -1, "process", le_proc_open); + ZEND_FETCH_RESOURCE(child, void *, &proc, -1, "process", le_proc_open); - zend_list_delete(Z_LVAL_PP(proc)); + zend_list_delete(Z_LVAL_P(proc)); RETURN_LONG(FG(pclose_ret)); } /* }}} */ @@ -706,8 +721,7 @@ zend_hash_get_current_key_ex(Z_ARRVAL_P(descriptorspec), &str_index, NULL, &nindex, 0, &pos); if (str_index) { - zend_error(E_WARNING, "%s(): descriptor spec must be an integer indexed array", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "descriptor spec must be an integer indexed array"); goto exit_fail; } @@ -718,7 +732,7 @@ php_stream *stream; int fd; - ZEND_FETCH_RESOURCE(stream, php_stream *, descitem, -1, "File-Handle", php_file_le_stream()); + php_stream_from_zval(stream, descitem); if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&fd, REPORT_ERRORS)) { goto exit_fail; @@ -727,41 +741,45 @@ #ifdef PHP_WIN32 descriptors[ndesc].childend = dup_fd_as_handle(fd); if (descriptors[ndesc].childend == NULL) { - zend_error(E_WARNING, "%s(): unable to dup File-Handle for descriptor %d", - get_active_function_name(TSRMLS_C), nindex); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to dup File-Handle for descriptor %d", nindex); goto exit_fail; } #else descriptors[ndesc].childend = dup(fd); if (descriptors[ndesc].childend < 0) { - zend_error(E_WARNING, "%s(): unable to dup File-Handle for descriptor %d - %s", - get_active_function_name(TSRMLS_C), nindex, strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to dup File-Handle for descriptor %d - %s", nindex, strerror(errno)); goto exit_fail; } #endif descriptors[ndesc].mode = DESC_FILE; } else if (Z_TYPE_PP(descitem) != IS_ARRAY) { - zend_error(E_WARNING, "%s(): descriptor item must be either an array or a File-Handle", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Descriptor item must be either an array or a File-Handle"); goto exit_fail; } else { - zend_hash_index_find(Z_ARRVAL_PP(descitem), 0, (void **)&ztype); - convert_to_string_ex(ztype); + if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 0, (void **)&ztype) == SUCCESS) { + convert_to_string_ex(ztype); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing handle qualifier in array", Z_STRVAL_PP(ztype)); + goto exit_fail; + } if (strcmp(Z_STRVAL_PP(ztype), "pipe") == 0) { descriptor_t newpipe[2]; zval **zmode; - zend_hash_index_find(Z_ARRVAL_PP(descitem), 1, (void **)&zmode); - convert_to_string_ex(zmode); + if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 1, (void **)&zmode) == SUCCESS) { + convert_to_string_ex(zmode); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing mode parameter for 'pipe'", Z_STRVAL_PP(ztype)); + goto exit_fail; + } descriptors[ndesc].mode = DESC_PIPE; if (0 != pipe(newpipe)) { - zend_error(E_WARNING, "%s(): unable to create pipe %s", - get_active_function_name(TSRMLS_C), strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to create pipe %s", strerror(errno)); goto exit_fail; } @@ -793,11 +811,19 @@ descriptors[ndesc].mode = DESC_FILE; - zend_hash_index_find(Z_ARRVAL_PP(descitem), 1, (void **)&zfile); - convert_to_string_ex(zfile); + if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 1, (void **)&zfile) == SUCCESS) { + convert_to_string_ex(zfile); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing file name parameter for 'file'", Z_STRVAL_PP(ztype)); + goto exit_fail; + } - zend_hash_index_find(Z_ARRVAL_PP(descitem), 2, (void **)&zmode); - convert_to_string_ex(zmode); + if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 2, (void **)&zmode) == SUCCESS) { + convert_to_string_ex(zmode); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing mode parameter for 'file'", Z_STRVAL_PP(ztype)); + goto exit_fail; + } /* try a wrapper */ @@ -820,8 +846,7 @@ #endif } else { - zend_error(E_WARNING, "%s(): %s is not a valid descriptor spec/mode", - get_active_function_name(TSRMLS_C), Z_STRVAL_PP(ztype)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a valid descriptor spec/mode", Z_STRVAL_PP(ztype)); goto exit_fail; } } @@ -864,7 +889,7 @@ efree(command_with_cmd); if (FALSE == newprocok) { - zend_error(E_WARNING, "%s(): CreateProcess failed", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "CreateProcess failed"); goto exit_fail; } @@ -906,10 +931,7 @@ close(descriptors[i].parentend); } - zend_error(E_WARNING, "%s(): fork failed - %s", - get_active_function_name(TSRMLS_C), - strerror(errno) - ); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "fork failed - %s", strerror(errno)); goto exit_fail; 1.3 +3 -1 php4/ext/standard/exec.h Index: exec.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/exec.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- exec.h 29 Apr 2002 02:31:01 -0000 1.2 +++ exec.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: exec.h,v 1.14 2002/04/03 13:39:35 wez Exp $ */ +/* $Id: exec.h,v 1.15 2002/09/19 18:59:32 iliaa Exp $ */ #ifndef EXEC_H #define EXEC_H @@ -34,5 +34,7 @@ char *php_escape_shell_cmd(char *); char *php_escape_shell_arg(char *); int php_Exec(int type, char *cmd, pval *array, pval *return_value TSRMLS_DC); + +#define PHP_EMPTY_EXEC_PARAM { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute a blank command"); RETURN_FALSE; } #endif /* EXEC_H */ 1.6 +439 -300 php4/ext/standard/file.c Index: file.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/file.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- file.c 2 Aug 2002 22:05:24 -0000 1.5 +++ file.c 6 Oct 2002 21:54:32 -0000 1.6 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.c,v 1.229 2002/05/12 15:59:42 rasmus Exp $ */ +/* $Id: file.c,v 1.268 2002/10/05 10:59:35 wez Exp $ */ /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */ @@ -34,6 +34,7 @@ #include "ext/standard/php_filestat.h" #include "php_open_temporary_file.h" #include "ext/standard/basic_functions.h" +#include "php_ini.h" #include <stdio.h> #include <stdlib.h> @@ -47,11 +48,19 @@ #define O_RDONLY _O_RDONLY #include "win32/param.h" #include "win32/winutil.h" +#elif defined(NETWARE) && !defined(NEW_LIBC) +/*#include <ws2nlm.h>*/ +#include <sys/socket.h> +#include "netware/param.h" #else #include <sys/param.h> +#if defined(NETWARE) && defined(USE_WINSOCK) +#include <novsock2.h> +#else #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> +#endif #if HAVE_ARPA_INET_H #include <arpa/inet.h> #endif @@ -63,6 +72,8 @@ #if HAVE_PWD_H #ifdef PHP_WIN32 #include "win32/pwd.h" +#elif defined(NETWARE) +#include "netware/pwd.h" #else #include <pwd.h> #endif @@ -104,11 +115,14 @@ #include <fnmatch.h> #endif +#ifdef __BEOS__ +#define realpath(x,y) strcpy(y,x) +#endif + /* }}} */ /* {{{ ZTS-stuff / Globals / Prototypes */ /* sharing globals is *evil* */ -static int le_stream = FAILURE; static int le_stream_context = FAILURE; /* }}} */ @@ -119,35 +133,26 @@ php_stream_context_free((php_stream_context*)rsrc->ptr); } -static void _file_stream_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - php_stream *stream = (php_stream*)rsrc->ptr; - /* the stream might be a pipe, so set the return value for pclose */ - FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); -} - -PHPAPI int php_file_le_stream(void) -{ - return le_stream; -} - static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC) { - zend_hash_init(&FG(ht_persistent_socks), 0, NULL, NULL, 1); FG(pclose_ret) = 0; + FG(user_stream_current_filename) = NULL; FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE; } - static void file_globals_dtor(php_file_globals *file_globals_p TSRMLS_DC) { - zend_hash_destroy(&FG(ht_persistent_socks)); } +PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("user_agent", NULL, PHP_INI_ALL, OnUpdateString, user_agent, php_file_globals, file_globals) + STD_PHP_INI_ENTRY("default_socket_timeout", "60", PHP_INI_ALL, OnUpdateInt, default_socket_timeout, php_file_globals, file_globals) + STD_PHP_INI_ENTRY("auto_detect_line_endings", "0", PHP_INI_ALL, OnUpdateInt, auto_detect_line_endings, php_file_globals, file_globals) +PHP_INI_END() + PHP_MINIT_FUNCTION(file) { - le_stream = zend_register_list_destructors_ex(_file_stream_dtor, NULL, "stream", module_number); le_stream_context = zend_register_list_destructors_ex(file_context_dtor, NULL, "stream-context", module_number); #ifdef ZTS @@ -156,6 +161,8 @@ file_globals_ctor(&file_globals TSRMLS_CC); #endif + REGISTER_INI_ENTRIES(); + REGISTER_LONG_CONSTANT("SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT); @@ -177,6 +184,15 @@ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_WARN", PHP_STREAM_NOTIFY_SEVERITY_WARN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_ERR", PHP_STREAM_NOTIFY_SEVERITY_ERR, CONST_CS | CONST_PERSISTENT); +#ifdef HAVE_FNMATCH + REGISTER_LONG_CONSTANT("FNM_NOESCAPE", FNM_NOESCAPE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FNM_PATHNAME", FNM_PATHNAME, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FNM_PERIOD", FNM_PERIOD, CONST_CS | CONST_PERSISTENT); +#ifdef FNM_CASEFOLD /* a GNU extension */ /* TODO emulate if not available */ + REGISTER_LONG_CONSTANT("FNM_CASEFOLD", FNM_CASEFOLD, CONST_CS | CONST_PERSISTENT); +#endif +#endif + return SUCCESS; } @@ -192,7 +208,7 @@ -/* {{{ proto bool flock(resource fp, int operation [, int wouldblock]) +/* {{{ proto bool flock(resource fp, int operation [, int &wouldblock]) Portable file locking */ static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN }; @@ -200,17 +216,16 @@ PHP_FUNCTION(flock) { zval **arg1, **arg2, **arg3; - int type, fd, act, ret, arg_count = ZEND_NUM_ARGS(); - void *what; + int fd, act, ret, arg_count = ZEND_NUM_ARGS(); + php_stream *stream; if (arg_count > 3 || zend_get_parameters_ex(arg_count, &arg1, &arg2, &arg3) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); - if (php_stream_cast((php_stream*)what, PHP_STREAM_AS_FD, (void*)&fd, 1) == FAILURE) { + if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fd, 1) == FAILURE) { RETURN_FALSE; } @@ -218,7 +233,7 @@ act = Z_LVAL_PP(arg2) & 3; if (act < 1 || act > 3) { - php_error(E_WARNING, "Illegal operation argument"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal operation argument"); RETURN_FALSE; } @@ -264,8 +279,9 @@ php_stream_open_wrapper(filename, "rb", 0, NULL); + md.stream = php_stream_open_wrapper(filename, "rb", - use_include_path | ENFORCE_SAFE_MODE | REPORT_ERRORS, + (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); @@ -412,7 +428,7 @@ } stream = php_stream_open_wrapper(filename, "rb", - use_include_path | ENFORCE_SAFE_MODE | REPORT_ERRORS, + (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); if (!stream) { RETURN_FALSE; @@ -448,6 +464,7 @@ char *slashed, *target_buf; register int i = 0; int target_len, len; + char eol_marker = '\n'; zend_bool use_include_path = 0; zend_bool reached_eof = 0; php_stream *stream; @@ -459,7 +476,7 @@ } stream = php_stream_open_wrapper(filename, "rb", - use_include_path | ENFORCE_SAFE_MODE | REPORT_ERRORS, + (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); if (!stream) { RETURN_FALSE; @@ -487,9 +504,14 @@ reached_eof = 1; } } + + /* mini-hack because I don't feel like re-writing this whole function */ + if (stream->flags & PHP_STREAM_FLAG_EOL_MAC) + eol_marker = '\r'; + if (!reached_eof) { target_len += strlen(target_buf+target_len); - if (target_buf[target_len-1] != '\n') { + if (target_buf[target_len-1] != eol_marker) { continue; } } @@ -525,6 +547,11 @@ } convert_to_string_ex(arg1); convert_to_string_ex(arg2); + + if (php_check_open_basedir(Z_STRVAL_PP(arg1) TSRMLS_CC)) { + RETURN_FALSE; + } + d = estrndup(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1)); strlcpy(p, Z_STRVAL_PP(arg2), sizeof(p)); @@ -559,26 +586,182 @@ } /* }}} */ -/* {{{ proto resource file_get_wrapper_data(resource fp) - */ -PHP_FUNCTION(file_get_wrapper_data) +/* {{{ proto resource stream_get_meta_data(resource fp) + Retrieves header/meta data from streams/file pointers */ +PHP_FUNCTION(stream_get_meta_data) { zval **arg1; php_stream *stream; + zval *newval; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; } - stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", NULL, 1, le_stream); - ZEND_VERIFY_RESOURCE(stream); + php_stream_from_zval(stream, arg1); - if (stream->wrapperdata) { - *return_value = *(stream->wrapperdata); - zval_copy_ctor(return_value); + array_init(return_value); + + if (stream->wrapperdata) { + MAKE_STD_ZVAL(newval); + *newval = *(stream->wrapperdata); + zval_copy_ctor(newval); + + add_assoc_zval(return_value, "wrapper_data", newval); } - else + if (stream->wrapper) { + add_assoc_string(return_value, "wrapper_type", (char *)stream->wrapper->wops->label, 1); + } + add_assoc_string(return_value, "stream_type", (char *)stream->ops->label, 1); + + if (stream->filterhead) { + php_stream_filter *filter; + + MAKE_STD_ZVAL(newval); + array_init(newval); + + for (filter = stream->filterhead; filter != NULL; filter = filter->next) { + add_next_index_string(newval, (char *)filter->fops->label, 1); + } + + add_assoc_zval(return_value, "filters", newval); + } + + add_assoc_long(return_value, "unread_bytes", stream->writepos - stream->readpos); + + if (php_stream_is(stream, PHP_STREAM_IS_SOCKET)) { + php_netstream_data_t *sock = PHP_NETSTREAM_DATA_FROM_STREAM(stream); + + add_assoc_bool(return_value, "timed_out", sock->timeout_event); + add_assoc_bool(return_value, "blocked", sock->is_blocked); + add_assoc_bool(return_value, "eof", stream->eof); + } else { + add_assoc_bool(return_value, "timed_out", 0); + add_assoc_bool(return_value, "blocked", 1); + add_assoc_bool(return_value, "eof", php_stream_eof(stream)); + } + +} +/* }}} */ + +/* {{{ stream_select related functions */ +static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, int *max_fd TSRMLS_DC) +{ + zval **elem; + php_stream *stream; + int this_fd; + + if (Z_TYPE_P(stream_array) != IS_ARRAY) + return 0; + + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); + zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) == SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { + + php_stream_from_zval_no_verify(stream, elem); + if (stream == NULL) + continue; + + /* get the fd */ + if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&this_fd, 1)) { + FD_SET(this_fd, fds); + if (this_fd > *max_fd) { + *max_fd = this_fd; + } + } + } + return 1; +} + +static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) +{ + zval **elem, **dest_elem; + php_stream *stream; + HashTable *new_hash; + int this_fd; + + if (Z_TYPE_P(stream_array) != IS_ARRAY) + return 0; + + ALLOC_HASHTABLE(new_hash); + zend_hash_init(new_hash, 0, NULL, ZVAL_PTR_DTOR, 0); + + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); + zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) == SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { + + php_stream_from_zval_no_verify(stream, elem); + if (stream == NULL) + continue; + + /* get the fd */ + if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&this_fd, 1)) { + if (FD_ISSET(this_fd, fds)) { + zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem); + if (dest_elem) + zval_add_ref(dest_elem); + } + } + } + + /* destroy old array and add new one */ + zend_hash_destroy(Z_ARRVAL_P(stream_array)); + efree(Z_ARRVAL_P(stream_array)); + + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(stream_array) = new_hash; + + return 1; +} +/* }}} */ + +/* {{{ proto int stream_select(array &read_streams, array &write_streams, array &except_streams, int tv_sec[, int tv_usec]) + Runs the select() system call on the sets of streams with a timeout specified by tv_sec and tv_usec */ +PHP_FUNCTION(stream_select) +{ + zval *r_array, *w_array, *e_array, *sec; + struct timeval tv; + struct timeval *tv_p = NULL; + fd_set rfds, wfds, efds; + int max_fd = 0; + int retval, sets = 0, usec = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!a!z!|l", &r_array, &w_array, &e_array, &sec, &usec) == FAILURE) + return; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + + if (r_array != NULL) sets += stream_array_to_fd_set(r_array, &rfds, &max_fd TSRMLS_CC); + if (w_array != NULL) sets += stream_array_to_fd_set(w_array, &wfds, &max_fd TSRMLS_CC); + if (e_array != NULL) sets += stream_array_to_fd_set(e_array, &efds, &max_fd TSRMLS_CC); + + if (!sets) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stream arrays were passed"); RETURN_FALSE; + } + + /* If seconds is not set to null, build the timeval, else we wait indefinitely */ + if (sec != NULL) { + convert_to_long_ex(&sec); + tv.tv_sec = Z_LVAL_P(sec); + tv.tv_usec = usec; + tv_p = &tv; + } + + retval = select(max_fd+1, &rfds, &wfds, &efds, tv_p); + + if (retval == -1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to select [%d]: %s", + errno, strerror(errno)); + RETURN_FALSE; + } + if (r_array != NULL) stream_array_from_fd_set(r_array, &rfds TSRMLS_CC); + if (w_array != NULL) stream_array_from_fd_set(w_array, &wfds TSRMLS_CC); + if (e_array != NULL) stream_array_from_fd_set(e_array, &efds TSRMLS_CC); + + RETURN_LONG(retval); } /* }}} */ @@ -611,7 +794,7 @@ ZVAL_LONG(ps[5], bytes_max); if (FAILURE == call_user_function_ex(EG(function_table), NULL, callback, &retval, 6, ptps, 0, NULL TSRMLS_CC)) { - zend_error(E_WARNING, "failed to call user notifier"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to call user notifier"); } if (retval) zval_ptr_dtor(&retval); @@ -676,19 +859,23 @@ /* given a zval which is either a stream or a context, return the underlying * stream_context. If it is a stream that does not have a context assigned, it * will create and assign a context and return that. */ -static php_stream_context *decode_context_param(zval *contextresource TSRMLS_DC) { - php_stream_context *context = NULL; void *what; int type; - - what = zend_fetch_resource(&contextresource TSRMLS_CC, -1, "Stream-Context", &type, 2, le_stream_context, le_stream); +static php_stream_context *decode_context_param(zval *contextresource TSRMLS_DC) +{ + php_stream_context *context = NULL; - if (what && type == le_stream) { - php_stream *stream = (php_stream*)what; - context = stream->context; - if (context == NULL) - context = stream->context = php_stream_context_alloc(); - } else if (what && type == le_stream_context) { - context = (php_stream_context*)what; + context = zend_fetch_resource(&contextresource TSRMLS_CC, -1, "Stream-Context", NULL, 1, le_stream_context); + if (context == NULL) { + php_stream *stream; + + php_stream_from_zval_no_verify(stream, &contextresource); + + if (stream) { + context = stream->context; + if (context == NULL) + context = stream->context = php_stream_context_alloc(); + } } + return context; } /* }}} */ @@ -709,6 +896,7 @@ array_init(return_value); *return_value = *context->options; zval_copy_ctor(return_value); + } /* }}} */ @@ -719,15 +907,14 @@ zval *options = NULL, *zcontext = NULL, *zvalue = NULL; php_stream_context *context; char *wrappername, *optionname; - long wrapperlen, optionlen; + int wrapperlen, optionlen; if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "rssz", &zcontext, &wrappername, &wrapperlen, &optionname, &optionlen, &zvalue) == FAILURE) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "ra", &zcontext, &options) == FAILURE) { - zend_error(E_WARNING, "%s() called with wrong number or type of parameters; please RTM", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "called with wrong number or type of parameters; please RTM"); RETURN_FALSE; } } @@ -744,7 +931,6 @@ php_stream_context_set_option(context, wrappername, optionname, zvalue); RETVAL_TRUE; } - } /* }}} */ @@ -786,6 +972,51 @@ } /* }}} */ +/* {{{ streams filter functions */ +static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) +{ + zval *zstream; + php_stream *stream; + char *filtername, *filterparams = NULL; + int filternamelen, filterparamslen = 0; + php_stream_filter *filter; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s", &zstream, + &filtername, &filternamelen, &filterparams, &filterparamslen) == FAILURE) { + RETURN_FALSE; + } + + php_stream_from_zval(stream, &zstream); + + filter = php_stream_filter_create(filtername, filterparams, filterparamslen, php_stream_is_persistent(stream) TSRMLS_CC); + if (filter == NULL) + RETURN_FALSE; + + if (append) + php_stream_filter_append(stream, filter); + else + php_stream_filter_prepend(stream, filter); + + RETURN_TRUE; +} + +/* {{{ proto bool stream_filter_prepend(resource stream, string filtername[, string filterparams]) + Prepend a filter to a stream */ +PHP_FUNCTION(stream_filter_prepend) +{ + apply_filter_to_stream(0, INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto bool stream_filter_append(resource stream, string filtername[, string filterparams]) + Append a filter to a stream */ +PHP_FUNCTION(stream_filter_append) +{ + apply_filter_to_stream(1, INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ +/* }}} */ + /* {{{ proto resource fopen(string filename, string mode [, bool use_include_path [, resource context]]) Open a file or a URL and return a file pointer */ PHP_NAMED_FUNCTION(php_if_fopen) @@ -802,12 +1033,11 @@ RETURN_FALSE; } if (zcontext) { - context = (php_stream_context*)zend_fetch_resource(&zcontext TSRMLS_CC, -1, "Stream-Context", NULL, 1, le_stream_context); - ZEND_VERIFY_RESOURCE(context); + ZEND_FETCH_RESOURCE(context, php_stream_context*, &zcontext, -1, "stream-context", le_stream_context); } stream = php_stream_open_wrapper_ex(filename, mode, - use_include_path | ENFORCE_SAFE_MODE | REPORT_ERRORS, + (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context); if (stream == NULL) { @@ -825,17 +1055,15 @@ PHPAPI PHP_FUNCTION(fclose) { zval **arg1; - int type; - void *what; + php_stream *stream; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); + php_stream_close(stream); - zend_list_delete(Z_LVAL_PP(arg1)); RETURN_TRUE; } @@ -883,13 +1111,13 @@ efree(tmp); if (!fp) { - php_error(E_WARNING, "popen(\"%s\", \"%s\") - %s", buf, p, strerror(errno)); + php_error_docref2(NULL TSRMLS_CC, buf, p, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } } else { fp = VCWD_POPEN(Z_STRVAL_PP(arg1), p); if (!fp) { - php_error(E_WARNING, "popen(\"%s\", \"%s\") - %s", Z_STRVAL_PP(arg1), p, strerror(errno)); + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(arg1), p, E_WARNING, "%s", strerror(errno)); efree(p); RETURN_FALSE; } @@ -897,7 +1125,7 @@ stream = php_stream_fopen_from_pipe(fp, p); if (stream == NULL) { - zend_error(E_WARNING, "popen(\"%s\", \"%s\"): %s", Z_STRVAL_PP(arg1), p, strerror(errno)); + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(arg1), p, E_WARNING, "%s", strerror(errno)); RETVAL_FALSE; } else { php_stream_to_zval(stream, return_value); @@ -912,18 +1140,15 @@ PHP_FUNCTION(pclose) { zval **arg1; - void *what; - int type; + php_stream *stream; if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); - zend_list_delete(Z_LVAL_PP(arg1)); - RETURN_LONG(FG(pclose_ret)); + RETURN_LONG(php_stream_close(stream)); } /* }}} */ @@ -932,89 +1157,42 @@ PHPAPI PHP_FUNCTION(feof) { zval **arg1; - int type; - void *what; + php_stream *stream; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); - if (type == le_stream) { - if (php_stream_eof((php_stream *) what)) { - RETURN_TRUE; - } + php_stream_from_zval(stream, arg1); + + if (php_stream_eof(stream)) { + RETURN_TRUE; + } else { RETURN_FALSE; } - RETURN_FALSE; } /* }}} */ -/* TODO: move to main/network.c */ -PHPAPI int php_set_sock_blocking(int socketd, int block) -{ - int ret = SUCCESS; - int flags; - int myflag = 0; - -#ifdef PHP_WIN32 - /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */ - flags = !block; - if (ioctlsocket(socketd, FIONBIO, &flags)==SOCKET_ERROR){ - php_error(E_WARNING, "%s", WSAGetLastError()); - ret = FALSE; - } -#else - flags = fcntl(socketd, F_GETFL); -#ifdef O_NONBLOCK - myflag = O_NONBLOCK; /* POSIX version */ -#elif defined(O_NDELAY) - myflag = O_NDELAY; /* old non-POSIX version */ -#endif - if (!block) { - flags |= myflag; - } else { - flags &= ~myflag; - } - fcntl(socketd, F_SETFL, flags); -#endif - return ret; -} - -/* {{{ proto bool socket_set_blocking(resource socket, int mode) - Set blocking/non-blocking mode on a socket */ -PHP_FUNCTION(socket_set_blocking) +/* {{{ proto bool stream_set_blocking(resource socket, int mode) + Set blocking/non-blocking mode on a socket or stream */ +PHP_FUNCTION(stream_set_blocking) { zval **arg1, **arg2; - int block, type; - int socketd = 0; - void *what; + int block; + php_stream *stream; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); convert_to_long_ex(arg2); block = Z_LVAL_PP(arg2); - if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) { - /* TODO: check if the blocking mode is changed elsewhere, and see if we - * can integrate these calls into php_stream_sock_set_blocking */ - if (FAILURE == php_stream_cast((php_stream *) what, PHP_STREAM_AS_SOCKETD, (void *) &socketd, REPORT_ERRORS)) { - RETURN_FALSE; - } - - if (php_set_sock_blocking(socketd, block) == FAILURE) - RETURN_FALSE; - - php_stream_sock_set_blocking((php_stream*)what, block == 0 ? 0 : 1 TSRMLS_CC); - RETURN_TRUE; - } - RETURN_FALSE; + if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block == 0 ? 0 : 1, NULL) == -1) + RETURN_FALSE; + RETURN_TRUE; } /* }}} */ @@ -1023,28 +1201,26 @@ Set blocking/non-blocking mode on a socket */ PHP_FUNCTION(set_socket_blocking) { - php_error(E_NOTICE, "set_socket_blocking() is deprecated, use socket_set_blocking() instead"); - PHP_FN(socket_set_blocking)(INTERNAL_FUNCTION_PARAM_PASSTHRU); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "This function is deprecated, use stream_set_blocking() instead"); + PHP_FN(stream_set_blocking)(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ -/* {{{ proto bool socket_set_timeout(int socket_descriptor, int seconds, int microseconds) - Set timeout on socket read to seconds + microseonds */ -PHP_FUNCTION(socket_set_timeout) +/* {{{ proto bool stream_set_timeout(resource stream, int seconds, int microseconds) + Set timeout on stream read to seconds + microseonds */ +#if HAVE_SYS_TIME_H || defined(PHP_WIN32) +PHP_FUNCTION(stream_set_timeout) { -#if HAVE_SYS_TIME_H zval **socket, **seconds, **microseconds; - int type; - void *what; struct timeval t; + php_stream *stream; if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &socket, &seconds, µseconds)==FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(socket TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, socket); convert_to_long_ex(seconds); t.tv_sec = Z_LVAL_PP(seconds); @@ -1057,69 +1233,30 @@ else t.tv_usec = 0; - if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) { - php_stream_sock_set_timeout((php_stream*)what, &t TSRMLS_CC); + if (PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &t)) { RETURN_TRUE; } RETURN_FALSE; -#endif /* HAVE_SYS_TIME_H */ -} - -/* }}} */ - - -/* {{{ proto array socket_get_status(resource socket_descriptor) - Return an array describing socket status */ -PHP_FUNCTION(socket_get_status) -{ - zval **socket; - int type; - void *what; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &socket) == FAILURE) { - WRONG_PARAM_COUNT; - } - - what = zend_fetch_resource(socket TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); - - array_init(return_value); - - if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) { - - php_netstream_data_t *sock = PHP_NETSTREAM_DATA_FROM_STREAM((php_stream*)what); - - add_assoc_bool(return_value, "timed_out", sock->timeout_event); - add_assoc_bool(return_value, "blocked", sock->is_blocked); - add_assoc_bool(return_value, "eof", sock->eof); - add_assoc_long(return_value, "unread_bytes", sock->writepos - sock->readpos); - - } - else { - RETURN_FALSE; - } - } +#endif /* HAVE_SYS_TIME_H || defined(PHP_WIN32) */ /* }}} */ - /* {{{ proto string fgets(resource fp[, int length]) Get a line from file pointer */ PHPAPI PHP_FUNCTION(fgets) { zval **arg1, **arg2; - int len = 1024, type; + int len = 1024; char *buf; - void *what; int argc = ZEND_NUM_ARGS(); + php_stream *stream; if (argc<1 || argc>2 || zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); if (argc>1) { convert_to_long_ex(arg2); @@ -1127,7 +1264,7 @@ } if (len < 0) { - php_error(E_WARNING, "length parameter to fgets() may not be negative"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative"); RETURN_FALSE; } @@ -1135,7 +1272,7 @@ /* needed because recv doesnt put a null at the end*/ memset(buf, 0, len+1); - if (php_stream_gets((php_stream *) what, buf, len) == NULL) + if (php_stream_gets(stream, buf, len) == NULL) goto exit_failed; if (PG(magic_quotes_runtime)) { @@ -1161,21 +1298,19 @@ PHPAPI PHP_FUNCTION(fgetc) { zval **arg1; - int type; char *buf; - void *what; int result; + php_stream *stream; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); buf = emalloc(2 * sizeof(char)); - result = php_stream_getc((php_stream*)what); + result = php_stream_getc(stream); if (result == EOF) { efree(buf); @@ -1194,7 +1329,7 @@ PHPAPI PHP_FUNCTION(fgetss) { zval **fd, **bytes, **allow=NULL; - int len, type; + int len; char *buf; php_stream *stream; char *allowed_tags=NULL; @@ -1220,13 +1355,12 @@ break; } - stream = zend_fetch_resource(fd TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(stream); + php_stream_from_zval(stream, fd); convert_to_long_ex(bytes); len = Z_LVAL_PP(bytes); if (len < 0) { - php_error(E_WARNING, "length parameter to fgetss() may not be negative"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative"); RETURN_FALSE; } @@ -1246,7 +1380,7 @@ } /* }}} */ -/* {{{ proto mixed fscanf(string str, string format [, string ...]) +/* {{{ proto mixed fscanf(resource stream, string format [, string ...]) Implements a mostly ANSI compatible fscanf() */ PHP_FUNCTION(fscanf) { @@ -1272,7 +1406,8 @@ file_handle = args[0]; format_string = args[1]; - what = zend_fetch_resource(file_handle TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); + what = zend_fetch_resource(file_handle TSRMLS_CC, -1, "File-Handle", &type, 2, + php_file_le_stream(), php_file_le_pstream()); /* * we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up @@ -1313,9 +1448,10 @@ PHPAPI PHP_FUNCTION(fwrite) { zval **arg1, **arg2, **arg3=NULL; - int ret, type; + int ret; int num_bytes; - void *what; + char *buffer = NULL; + php_stream *stream; switch (ZEND_NUM_ARGS()) { case 2: @@ -1339,15 +1475,17 @@ break; } - what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); if (!arg3 && PG(magic_quotes_runtime)) { - zval_copy_ctor(*arg2); - php_stripslashes(Z_STRVAL_PP(arg2), &num_bytes TSRMLS_CC); + buffer = estrndup(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2)); + php_stripslashes(buffer, &num_bytes TSRMLS_CC); } - ret = php_stream_write((php_stream *) what, Z_STRVAL_PP(arg2), num_bytes); + ret = php_stream_write(stream, buffer ? buffer : Z_STRVAL_PP(arg2), num_bytes); + if (buffer) { + efree(buffer); + } RETURN_LONG(ret); } @@ -1358,17 +1496,16 @@ PHPAPI PHP_FUNCTION(fflush) { zval **arg1; - int ret, type; - void *what; + int ret; + php_stream *stream; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); - ret = php_stream_flush((php_stream *) what); + ret = php_stream_flush(stream); if (ret) { RETURN_FALSE; } @@ -1376,14 +1513,14 @@ } /* }}} */ -/* {{{ proto int set_file_buffer(resource fp, int buffer) +/* {{{ proto int stream_set_write_buffer(resource fp, int buffer) Set file write buffer */ -PHP_FUNCTION(set_file_buffer) +PHP_FUNCTION(stream_set_write_buffer) { zval **arg1, **arg2; - int ret, type, buff; + int ret; + size_t buff; php_stream *stream; - FILE * fp; switch (ZEND_NUM_ARGS()) { case 2: @@ -1396,24 +1533,20 @@ /* NOTREACHED */ break; } - - stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(stream); - if (!php_stream_is(stream, PHP_STREAM_IS_STDIO) || FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) { - RETURN_FALSE; - } + + php_stream_from_zval(stream, arg1); convert_to_long_ex(arg2); buff = Z_LVAL_PP(arg2); /* if buff is 0 then set to non-buffered */ - if (buff == 0){ - ret = setvbuf(fp, NULL, _IONBF, 0); + if (buff == 0) { + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_WRITE_BUFFER, PHP_STREAM_BUFFER_NONE, NULL); } else { - ret = setvbuf(fp, NULL, _IOFBF, buff); + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_WRITE_BUFFER, PHP_STREAM_BUFFER_FULL, &buff); } - RETURN_LONG(ret); + RETURN_LONG(ret == 0 ? 0 : EOF); } /* }}} */ @@ -1422,17 +1555,15 @@ PHPAPI PHP_FUNCTION(rewind) { zval **arg1; - void *what; - int type; + php_stream *stream; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); - if (-1 == php_stream_rewind((php_stream*)what)) { + if (-1 == php_stream_rewind(stream)) { RETURN_FALSE; } RETURN_TRUE; @@ -1444,18 +1575,16 @@ PHPAPI PHP_FUNCTION(ftell) { zval **arg1; - void *what; long ret; - int type; + php_stream *stream; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); - ret = php_stream_tell((php_stream*)what); + ret = php_stream_tell(stream); if (ret == -1) { RETURN_FALSE; } @@ -1469,16 +1598,14 @@ { zval **arg1, **arg2, **arg3; int argcount = ZEND_NUM_ARGS(), whence = SEEK_SET; - void *what; - int type; + php_stream *stream; if (argcount < 2 || argcount > 3 || zend_get_parameters_ex(argcount, &arg1, &arg2, &arg3) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); convert_to_long_ex(arg2); if (argcount > 2) { @@ -1486,13 +1613,12 @@ whence = Z_LVAL_PP(arg3); } - RETURN_LONG(php_stream_seek((php_stream*)what, Z_LVAL_PP(arg2), whence)); + RETURN_LONG(php_stream_seek(stream, Z_LVAL_PP(arg2), whence)); } /* }}} */ /* {{{ proto bool mkdir(string pathname[, int mode]) Create a directory */ - PHP_FUNCTION(mkdir) { int dir_len, ret; @@ -1503,7 +1629,7 @@ return; } - if (PG(safe_mode) &&(!php_checkuid(dir, NULL, CHECKUID_ALLOW_ONLY_DIR))) { + if (PG(safe_mode) && (!php_checkuid(dir, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { RETURN_FALSE; } @@ -1513,7 +1639,7 @@ ret = VCWD_MKDIR(dir, (mode_t)mode); if (ret < 0) { - php_error(E_WARNING, "mkdir() failed (%s)", strerror(errno)); + php_error_docref1(NULL TSRMLS_CC, dir, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } RETURN_TRUE; @@ -1543,7 +1669,7 @@ ret = VCWD_RMDIR(Z_STRVAL_PP(arg1)); if (ret < 0) { - php_error(E_WARNING, "rmdir() failed (%s)", strerror(errno)); + php_error_docref1(NULL TSRMLS_CC, Z_STRVAL_PP(arg1), E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } @@ -1580,7 +1706,7 @@ convert_to_string_ex(arg1); stream = php_stream_open_wrapper(Z_STRVAL_PP(arg1), "rb", - use_include_path | ENFORCE_SAFE_MODE | REPORT_ERRORS, + (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); if (stream) { size = php_stream_passthru(stream); @@ -1591,7 +1717,6 @@ } /* }}} */ - /* {{{ proto int umask([int mask]) Return or change the umask */ PHP_FUNCTION(umask) @@ -1619,24 +1744,22 @@ /* }}} */ - /* {{{ proto int fpassthru(resource fp) Output all remaining data from a file pointer */ PHPAPI PHP_FUNCTION(fpassthru) { zval **arg1; - int size, type; - void *what; + int size; + php_stream *stream; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, arg1); - size = php_stream_passthru((php_stream*)what); + size = php_stream_passthru(stream); RETURN_LONG(size); } /* }}} */ @@ -1670,7 +1793,7 @@ ret = VCWD_RENAME(old_name, new_name); if (ret == -1) { - php_error(E_WARNING, "rename() failed (%s)", strerror(errno)); + php_error_docref2(NULL TSRMLS_CC, old_name, new_name, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } @@ -1700,7 +1823,7 @@ ret = VCWD_UNLINK(Z_STRVAL_PP(filename)); if (ret == -1) { - php_error(E_WARNING, "unlink() failed (%s)", strerror(errno)); + php_error_docref1(NULL TSRMLS_CC, Z_STRVAL_PP(filename), E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } /* Clear stat cache */ @@ -1715,24 +1838,22 @@ { zval **fp , **size; short int ret; - int type; - void *what; int fd; + php_stream *stream; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fp, &size) == FAILURE) { WRONG_PARAM_COUNT; } - what = zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + php_stream_from_zval(stream, fp); convert_to_long_ex(size); - if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) { - php_error(E_WARNING, "can't truncate sockets!"); + if (php_stream_is(stream, PHP_STREAM_IS_SOCKET)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate sockets!"); RETURN_FALSE; } - if (SUCCESS == php_stream_cast((php_stream*)what, PHP_STREAM_AS_FD, (void*)&fd, 1)) { + if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fd, 1)) { ret = ftruncate(fd, Z_LVAL_PP(size)); RETURN_LONG(ret + 1); } @@ -1747,7 +1868,6 @@ zval **fp; zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev, *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks; - int type; php_stream *stream; php_stream_statbuf stat_ssb; @@ -1758,8 +1878,7 @@ WRONG_PARAM_COUNT; } - stream = (php_stream *) zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(stream); + php_stream_from_zval(stream, fp); if (php_stream_stat(stream, &stat_ssb)) { RETURN_FALSE; @@ -1845,14 +1964,6 @@ RETURN_FALSE; } - if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(target), NULL, CHECKUID_CHECK_FILE_AND_DIR))) { - RETURN_FALSE; - } - - if (php_check_open_basedir(Z_STRVAL_PP(target) TSRMLS_CC)) { - RETURN_FALSE; - } - if (php_copy_file(Z_STRVAL_PP(source), Z_STRVAL_PP(target) TSRMLS_CC)==SUCCESS) { RETURN_TRUE; } else { @@ -1871,6 +1982,9 @@ srcstream = php_stream_open_wrapper(src, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); + + if (!srcstream) + return ret; deststream = php_stream_open_wrapper(dest, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, @@ -1893,20 +2007,19 @@ PHPAPI PHP_FUNCTION(fread) { zval **arg1, **arg2; - int len, type; + int len; php_stream *stream; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; } - stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(stream); + php_stream_from_zval(stream, arg1); convert_to_long_ex(arg2); len = Z_LVAL_PP(arg2); if (len < 0) { - php_error(E_WARNING, "length parameter to fread() may not be negative"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative"); RETURN_FALSE; } @@ -1924,17 +2037,18 @@ } /* }}} */ -/* {{{ proto array fgetcsv(resource fp, int length [, string delimiter]) +/* {{{ proto array fgetcsv(resource fp, int length [, string delimiter [, string enclosure]]) Get line from file pointer and parse for CSV fields */ PHP_FUNCTION(fgetcsv) { char *temp, *tptr, *bptr, *lineEnd; char delimiter = ','; /* allow this to be set as parameter */ + char enclosure = '"'; /* allow this to be set as parameter */ /* first section exactly as php_fgetss */ - zval **fd, **bytes, **p_delim; - int len, type; + zval **fd, **bytes, **p_delim, **p_enclosure; + int len; char *buf; php_stream *stream; @@ -1952,10 +2066,30 @@ convert_to_string_ex(p_delim); /* Make sure that there is at least one character in string */ if (Z_STRLEN_PP(p_delim) < 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Third parameter must be a character"); + return; + } + /* use first character from string */ + delimiter = Z_STRVAL_PP(p_delim)[0]; + break; + + case 4: + if (zend_get_parameters_ex(4, &fd, &bytes, &p_delim, &p_enclosure) == FAILURE) { WRONG_PARAM_COUNT; } - /* use first character from string */ + convert_to_string_ex(p_delim); + /* Make sure that there is at least one character in string */ + if (Z_STRLEN_PP(p_delim) < 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Third parameter must be a character"); + return; + } + /* use first character from string */ delimiter = Z_STRVAL_PP(p_delim)[0]; + + convert_to_string_ex(p_enclosure); + /* use first character from string */ + enclosure = Z_STRVAL_PP(p_enclosure)[0]; + break; default: @@ -1964,28 +2098,27 @@ break; } - stream = (php_stream*)zend_fetch_resource(fd TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(stream); + php_stream_from_zval(stream, fd); convert_to_long_ex(bytes); len = Z_LVAL_PP(bytes); if (len < 0) { - php_error(E_WARNING, "length parameter to fgetcsv() may not be negative"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative"); RETURN_FALSE; } buf = emalloc(len + 1); - /*needed because recv/read/gzread doesnt set null char at end*/ + /* needed because recv/read/gzread doesnt set null char at end */ memset(buf, 0, len + 1); - if (php_stream_gets(stream, buf, len) == NULL) { + if (php_stream_gets(stream, buf, len) == NULL) { efree(buf); RETURN_FALSE; } - /* Now into new section that parses buf for comma/quote delimited fields */ + /* Now into new section that parses buf for delimiter/enclosure fields */ - /* Strip trailing space from buf, saving end of line in case required for quoted field */ + /* Strip trailing space from buf, saving end of line in case required for enclosure field */ lineEnd = emalloc(len + 1); bptr = buf; @@ -2000,7 +2133,7 @@ /* reserve workspace for building each individual field */ - temp = emalloc(len); /* unlikely but possible! */ + temp = emalloc(len); /* unlikely but possible! */ tptr = temp; /* Initialize return array */ @@ -2009,18 +2142,24 @@ /* Main loop to read CSV fields */ /* NB this routine will return a single null entry for a blank line */ - do { + do { /* 1. Strip any leading space */ while(isspace((int) *bptr) && (*bptr!=delimiter)) bptr++; /* 2. Read field, leaving bptr pointing at start of next field */ - if (*bptr == '"') { - /* 2A. handle quote delimited field */ - bptr++; /* move on to first character in field */ + if (enclosure && *bptr == enclosure) { + bptr++; /* move on to first character in field */ + + /* Check if there is an end to the enclosure */ + if (!strchr(bptr, enclosure)) { + continue; + } + + /* 2A. handle enclosure delimited field */ while (*bptr) { - if (*bptr == '"') { - /* handle the double-quote */ - if ( *(bptr+1) == '"') { - /* embedded double quotes */ + if (*bptr == enclosure) { + /* handle the enclosure */ + if ( *(bptr+1) == enclosure) { + /* embedded enclosure */ *tptr++ = *bptr; bptr +=2; } else { /* must be end of string - skip to start of next field or end */ @@ -2040,7 +2179,7 @@ /* read a new line from input, as at start of routine */ memset(buf, 0, len+1); - if (php_stream_gets(stream, buf, len) == NULL) { + if (php_stream_gets(stream, buf, len) == NULL) { efree(lineEnd); efree(temp); efree(buf); @@ -2064,7 +2203,7 @@ } } } else { - /* 2B. Handle non-quoted field */ + /* 2B. Handle non-enclosure field */ while ((*bptr != delimiter) && *bptr) *tptr++ = *bptr++; *tptr=0; /* terminate temporary string */ @@ -2091,7 +2230,7 @@ /* }}} */ -#if (!defined(PHP_WIN32) && !defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS) +#if (!defined(PHP_WIN32) && !defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) /* {{{ proto string realpath(string path) Return the resolved path */ PHP_FUNCTION(realpath) 1.4 +23 -20 php4/ext/standard/file.h Index: file.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/file.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- file.h 30 Apr 2002 08:15:07 -0000 1.3 +++ file.h 6 Oct 2002 21:54:32 -0000 1.4 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.h,v 1.60 2002/04/30 00:28:24 wez Exp $ */ +/* $Id: file.h,v 1.70 2002/09/28 22:14:21 wez Exp $ */ /* Synced with php 3.0 revision 1.30 1999-06-16 [ssb] */ @@ -55,15 +55,14 @@ PHP_FUNCTION(file); PHP_FUNCTION(file_get_contents); PHP_FUNCTION(set_socket_blocking); /* deprecated */ -PHP_FUNCTION(socket_set_blocking); -PHP_FUNCTION(socket_set_timeout); -PHP_FUNCTION(socket_get_status); -PHP_FUNCTION(set_file_buffer); +PHP_FUNCTION(stream_set_blocking); +PHP_FUNCTION(stream_select); +PHP_FUNCTION(stream_set_timeout); +PHP_FUNCTION(stream_set_write_buffer); PHP_FUNCTION(get_meta_tags); PHP_FUNCTION(flock); PHP_FUNCTION(fd_set); PHP_FUNCTION(fd_isset); -PHP_FUNCTION(select); #if (!defined(PHP_WIN32) && !defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS) PHP_FUNCTION(realpath); PHP_FUNCTION(fnmatch); @@ -71,16 +70,17 @@ PHP_NAMED_FUNCTION(php_if_ftruncate); PHP_NAMED_FUNCTION(php_if_fstat); -PHP_FUNCTION(file_get_wrapper_data); -PHP_FUNCTION(file_register_wrapper); +PHP_FUNCTION(stream_get_meta_data); +PHP_FUNCTION(stream_register_wrapper); PHP_FUNCTION(stream_context_create); PHP_FUNCTION(stream_context_set_params); PHP_FUNCTION(stream_context_set_option); PHP_FUNCTION(stream_context_get_options); +PHP_FUNCTION(stream_filter_prepend); +PHP_FUNCTION(stream_filter_append); PHP_MINIT_FUNCTION(user_streams); -PHPAPI int php_set_sock_blocking(int socketd, int block); -PHPAPI int php_file_le_stream(void); +PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC); PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC); #define META_DEF_BUFSIZE 8192 @@ -98,21 +98,24 @@ } php_meta_tags_token; typedef struct _php_meta_tags_data { - php_stream *stream; - int ulc; - int lc; - char *input_buffer; - char *token_data; - int token_len; - int in_meta; + php_stream *stream; + int ulc; + int lc; + char *input_buffer; + char *token_data; + int token_len; + int in_meta; } php_meta_tags_data; php_meta_tags_token php_next_meta_token(php_meta_tags_data * TSRMLS_DC); typedef struct { - int pclose_ret; - HashTable ht_persistent_socks; - size_t def_chunk_size; + int pclose_ret; + size_t def_chunk_size; + int auto_detect_line_endings; + int default_socket_timeout; + char *user_agent; + char *user_stream_current_filename; /* for simple recursion protection */ } php_file_globals; #ifdef ZTS 1.4 +87 -25 php4/ext/standard/filestat.c Index: filestat.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/filestat.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- filestat.c 2 Aug 2002 22:05:24 -0000 1.3 +++ filestat.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: filestat.c,v 1.92 2002/05/16 01:07:21 sniper Exp $ */ +/* $Id: filestat.c,v 1.112 2002/10/04 01:05:03 sas Exp $ */ #include "php.h" #include "safe_mode.h" @@ -54,6 +54,8 @@ #if HAVE_PWD_H # ifdef PHP_WIN32 # include "win32/pwd.h" +# elif defined(NETWARE) +# include "netware/pwd.h" # else # include <pwd.h> # endif @@ -142,7 +144,7 @@ /* These are used by GetDiskFreeSpaceEx, if available. */ ULARGE_INTEGER FreeBytesAvailableToCaller; ULARGE_INTEGER TotalNumberOfBytes; - ULARGE_INTEGER TotalNumberOfFreeBytes; + ULARGE_INTEGER TotalNumberOfFreeBytes; /* These are used by GetDiskFreeSpace otherwise. */ DWORD SectorsPerCluster; @@ -198,14 +200,14 @@ } } else { - php_error(E_WARNING, "Unable to load kernel32.dll"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load kernel32.dll"); RETURN_FALSE; } #elif defined(OS2) { FSALLOCATE fsinfo; - char drive = Z_STRVAL_PP(path)[0] & 95; + char drive = Z_STRVAL_PP(path)[0] & 95; if (DosQueryFSInfo( drive ? drive - 64 : 0, FSIL_ALLOC, &fsinfo, sizeof( fsinfo ) ) == 0) bytestotal = (double)fsinfo.cbSector * fsinfo.cSectorUnit * fsinfo.cUnit; @@ -245,7 +247,7 @@ /* These are used by GetDiskFreeSpaceEx, if available. */ ULARGE_INTEGER FreeBytesAvailableToCaller; ULARGE_INTEGER TotalNumberOfBytes; - ULARGE_INTEGER TotalNumberOfFreeBytes; + ULARGE_INTEGER TotalNumberOfFreeBytes; /* These are used by GetDiskFreeSpace otherwise. */ DWORD SectorsPerCluster; @@ -301,14 +303,14 @@ } } else { - php_error(E_WARNING, "Unable to load kernel32.dll"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load kernel32.dll"); RETURN_FALSE; } #elif defined(OS2) { FSALLOCATE fsinfo; - char drive = Z_STRVAL_PP(path)[0] & 95; + char drive = Z_STRVAL_PP(path)[0] & 95; if (DosQueryFSInfo( drive ? drive - 64 : 0, FSIL_ALLOC, &fsinfo, sizeof( fsinfo ) ) == 0) bytesfree = (double)fsinfo.cbSector * fsinfo.cSectorUnit * fsinfo.cUnitAvail; @@ -335,7 +337,7 @@ Change file group */ PHP_FUNCTION(chgrp) { -#ifndef WINDOWS +#if !defined(WINDOWS) && !defined(NETWARE) /* I guess 'chgrp' won't be available on NetWare */ pval **filename, **group; gid_t gid; struct group *gr=NULL; @@ -348,7 +350,7 @@ if (Z_TYPE_PP(group) == IS_STRING) { gr = getgrnam(Z_STRVAL_PP(group)); if (!gr) { - php_error(E_WARNING, "unable to find gid for %s", + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_PP(group)); RETURN_FALSE; } @@ -369,7 +371,7 @@ ret = VCWD_CHOWN(Z_STRVAL_PP(filename), -1, gid); if (ret == -1) { - php_error(E_WARNING, "chgrp failed: %s", strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } RETURN_TRUE; @@ -383,7 +385,7 @@ Change file owner */ PHP_FUNCTION(chown) { -#ifndef WINDOWS +#if !defined(WINDOWS) && !defined(NETWARE) /* I guess 'chown' won't be available on NetWare */ pval **filename, **user; int ret; uid_t uid; @@ -396,7 +398,7 @@ if (Z_TYPE_PP(user) == IS_STRING) { pw = getpwnam(Z_STRVAL_PP(user)); if (!pw) { - php_error(E_WARNING, "unable to find uid for %s", + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_PP(user)); RETURN_FALSE; } @@ -417,7 +419,7 @@ ret = VCWD_CHOWN(Z_STRVAL_PP(filename), uid, -1); if (ret == -1) { - php_error(E_WARNING, "chown failed: %s", strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } #endif @@ -454,11 +456,11 @@ that safe mode doesn't give them. */ if(PG(safe_mode)) - imode &= 0777; + imode &= 0777; ret = VCWD_CHMOD(Z_STRVAL_PP(filename), imode); if (ret == -1) { - php_error(E_WARNING, "chmod failed: %s", strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } RETURN_TRUE; @@ -472,25 +474,30 @@ { pval **filename, **filetime, **fileatime; int ret; +#if defined(NETWARE) && defined(CLIB_STAT_PATCH) + struct stat_libc sb; +#else struct stat sb; +#endif FILE *file; struct utimbuf newtimebuf; struct utimbuf *newtime = NULL; int ac = ZEND_NUM_ARGS(); - newtime = &newtimebuf; if (ac == 1 && zend_get_parameters_ex(1, &filename) != FAILURE) { #ifndef HAVE_UTIME_NULL + newtime = &newtimebuf; newtime->modtime = newtime->actime = time(NULL); #endif } else if (ac == 2 && zend_get_parameters_ex(2, &filename, &filetime) != FAILURE) { convert_to_long_ex(filetime); - newtime->actime = time(NULL); + newtime = &newtimebuf; newtime->modtime = newtime->actime = Z_LVAL_PP(filetime); } else if (ac == 3 && zend_get_parameters_ex(3, &filename, &filetime, &fileatime) != FAILURE) { convert_to_long_ex(fileatime); convert_to_long_ex(filetime); + newtime = &newtimebuf; newtime->actime = Z_LVAL_PP(fileatime); newtime->modtime = Z_LVAL_PP(filetime); } else { @@ -512,7 +519,7 @@ if (ret == -1) { file = VCWD_FOPEN(Z_STRVAL_PP(filename), "w"); if (file == NULL) { - php_error(E_WARNING, "unable to create file %s because %s", Z_STRVAL_PP(filename), strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create file %s because %s", Z_STRVAL_PP(filename), strerror(errno)); RETURN_FALSE; } fclose(file); @@ -520,7 +527,7 @@ ret = VCWD_UTIME(Z_STRVAL_PP(filename), newtime); if (ret == -1) { - php_error(E_WARNING, "utime failed: %s", strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Utime failed: %s", strerror(errno)); RETURN_FALSE; } RETURN_TRUE; @@ -548,11 +555,37 @@ { zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev, *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks; +#if defined(NETWARE) && defined(CLIB_STAT_PATCH) + struct stat_libc *stat_sb; +#else struct stat *stat_sb; +#endif int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */ char *stat_sb_names[13]={"dev", "ino", "mode", "nlink", "uid", "gid", "rdev", "size", "atime", "mtime", "ctime", "blksize", "blocks"}; + if (PG(safe_mode) &&(!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { + RETURN_FALSE; + } + + if (php_check_open_basedir(filename TSRMLS_CC)) { + RETURN_FALSE; + } + +#ifndef PHP_WIN32 + + switch (type) { + case FS_IS_W: + RETURN_BOOL (!VCWD_ACCESS(filename, W_OK)); + case FS_IS_R: + RETURN_BOOL (!VCWD_ACCESS(filename, R_OK)); + case FS_IS_X: + RETURN_BOOL (!VCWD_ACCESS(filename, X_OK)); + case FS_EXISTS: + RETURN_BOOL (!VCWD_ACCESS(filename, F_OK)); + } +#endif + stat_sb = &BG(sb); if (!BG(CurrentStatFile) || strcmp(filename, BG(CurrentStatFile))) { @@ -570,7 +603,7 @@ #endif if (VCWD_STAT(BG(CurrentStatFile), &BG(sb)) == -1) { if (!IS_LINK_OPERATION(type) && (!IS_EXISTS_CHECK(type) || errno != ENOENT)) { /* fileexists() test must print no error */ - php_error(E_WARNING, "stat failed for %s (errno=%d - %s)", BG(CurrentStatFile), errno, strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Stat failed for %s (errno=%d - %s)", BG(CurrentStatFile), errno, strerror(errno)); } efree(BG(CurrentStatFile)); BG(CurrentStatFile) = NULL; @@ -585,7 +618,7 @@ /* do lstat if the buffer is empty */ if (VCWD_LSTAT(filename, &BG(lsb)) == -1) { if (!IS_EXISTS_CHECK(type) || errno != ENOENT) { /* fileexists() test must print no error */ - php_error(E_WARNING, "lstat failed for %s (errno=%d - %s)", BG(CurrentStatFile), errno, strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Lstat failed for %s (errno=%d - %s)", BG(CurrentStatFile), errno, strerror(errno)); } RETURN_FALSE; } @@ -593,6 +626,7 @@ #endif +#ifndef NETWARE if (type >= FS_IS_W && type <= FS_IS_X) { if(BG(sb).st_uid==getuid()) { rmask=S_IRUSR; @@ -622,6 +656,7 @@ } } } +#endif switch (type) { case FS_PERMS: @@ -635,11 +670,23 @@ case FS_GROUP: RETURN_LONG((long)BG(sb).st_gid); case FS_ATIME: +#if defined(NETWARE) && defined(NEW_LIBC) + RETURN_LONG((long)(BG(sb).st_atime).tv_nsec); +#else RETURN_LONG((long)BG(sb).st_atime); +#endif case FS_MTIME: - RETURN_LONG((long)BG(sb).st_mtime); +#if defined(NETWARE) && defined(NEW_LIBC) + RETURN_LONG((long)(BG(sb).st_mtime).tv_nsec); +#else + RETURN_LONG((long)BG(sb).st_mtime); +#endif case FS_CTIME: +#if defined(NETWARE) && defined(NEW_LIBC) + RETURN_LONG((long)(BG(sb).st_ctime).tv_nsec); +#else RETURN_LONG((long)BG(sb).st_ctime); +#endif case FS_TYPE: #if HAVE_SYMLINK if (S_ISLNK(BG(lsb).st_mode)) { @@ -656,19 +703,28 @@ case S_IFSOCK: RETURN_STRING("socket", 1); #endif } - php_error(E_WARNING, "Unknown file type (%d)", BG(sb).st_mode&S_IFMT); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown file type (%d)", BG(sb).st_mode&S_IFMT); RETURN_STRING("unknown", 1); case FS_IS_W: +#ifdef NETWARE + RETURN_LONG(0); +#endif if (getuid()==0) { RETURN_TRUE; /* root */ } RETURN_BOOL((BG(sb).st_mode & wmask) != 0); case FS_IS_R: +#ifdef NETWARE + RETURN_LONG(0); +#endif if (getuid()==0) { RETURN_TRUE; /* root */ } RETURN_BOOL((BG(sb).st_mode&rmask)!=0); case FS_IS_X: +#ifdef NETWARE + RETURN_LONG(0); +#endif if (getuid()==0) { xmask = S_IXROOT; /* root */ } @@ -694,7 +750,7 @@ if (array_init(return_value) == FAILURE) { RETURN_FALSE; } - + MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev); MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino); MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode); @@ -707,9 +763,15 @@ MAKE_LONG_ZVAL_INCREF(stat_rdev, -1); #endif MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size); +#if defined(NETWARE) && defined(NEW_LIBC) + MAKE_LONG_ZVAL_INCREF(stat_atime, (stat_sb->st_atime).tv_nsec); + MAKE_LONG_ZVAL_INCREF(stat_mtime, (stat_sb->st_mtime).tv_nsec); + MAKE_LONG_ZVAL_INCREF(stat_ctime, (stat_sb->st_ctime).tv_nsec); +#else MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime); MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime); MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime); +#endif #ifdef HAVE_ST_BLKSIZE MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize); #else @@ -753,7 +815,7 @@ return; } - php_error(E_WARNING, "didn't understand stat call"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call"); RETURN_FALSE; } /* }}} */ 1.3 +9 -1 php4/ext/standard/flock_compat.c Index: flock_compat.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/flock_compat.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- flock_compat.c 29 Apr 2002 02:31:01 -0000 1.2 +++ flock_compat.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: flock_compat.c,v 1.16 2002/02/28 08:26:45 sebastian Exp $ */ +/* $Id: flock_compat.c,v 1.17 2002/09/05 14:21:55 hyanantha Exp $ */ #include <php.h> #include <errno.h> @@ -30,6 +30,14 @@ #ifdef PHP_WIN32 #include <windows.h> #include <io.h> +#endif + +#ifdef NETWARE +#ifdef NEW_LIBC +#include <netinet/in.h> +#else +#include <sys/socket.h> +#endif #endif #ifndef HAVE_FLOCK 1.3 +43 -16 php4/ext/standard/formatted_print.c Index: formatted_print.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/formatted_print.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- formatted_print.c 29 Apr 2002 02:31:01 -0000 1.2 +++ formatted_print.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: formatted_print.c,v 1.47 2002/03/22 09:09:18 derick Exp $ */ +/* $Id: formatted_print.c,v 1.53 2002/09/21 15:08:59 sas Exp $ */ #include <math.h> /* modf() */ #include "php.h" @@ -25,6 +25,10 @@ #include "zend_execute.h" #include <stdio.h> +#ifdef HAVE_LOCALE_H +#include <locale.h> +#endif + #define ALIGN_LEFT 0 #define ALIGN_RIGHT 1 #define ADJ_WIDTH 1 @@ -140,7 +144,7 @@ { if ((*pos + 1) >= *size) { *size <<= 1; - PRINTF_DEBUG(("%s: ereallocing buffer to %d bytes\n", get_active_function_name(TSRMLS_C), *size)); + PRINTF_DEBUG(("%s(): ereallocing buffer to %d bytes\n", get_active_function_name(TSRMLS_C), *size)); *buffer = erealloc(*buffer, *size); } PRINTF_DEBUG(("sprintf: appending '%c', pos=\n", add, *pos)); @@ -196,7 +200,8 @@ inline static void php_sprintf_appendint(char **buffer, int *pos, int *size, long number, - int width, char padding, int alignment) + int width, char padding, int alignment, + int always_sign) { char numbuf[NUM_BUF_SIZE]; register unsigned long magn, nmagn; @@ -225,6 +230,8 @@ while (magn > 0 && i > 0); if (neg) { numbuf[--i] = '-'; + } else if (always_sign) { + numbuf[--i] = '+'; } PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n", number, &numbuf[i], i)); @@ -236,7 +243,7 @@ inline static void php_sprintf_appenduint(char **buffer, int *pos, int *size, unsigned long number, - int width, char padding, int alignment) + int width, char padding, int alignment, int always_sign) { char numbuf[NUM_BUF_SIZE]; register unsigned long magn, nmagn; @@ -256,8 +263,10 @@ numbuf[--i] = (unsigned char)(magn - (nmagn * 10)) + '0'; magn = nmagn; - } - while (magn > 0 && i > 0); + } while (magn > 0 && i > 0); + + if (always_sign) + numbuf[--i] = '+'; PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n", number, &numbuf[i], i)); php_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0, padding, alignment, (NUM_BUF_SIZE - 1) - i, 0, 0); @@ -268,12 +277,21 @@ int *size, double number, int width, char padding, int alignment, int precision, - int adjust, char fmt) + int adjust, char fmt, + int always_sign) { char numbuf[NUM_BUF_SIZE]; char *cvt; register int i = 0, j = 0; int sign, decpt; + char decimal_point = '.'; +#ifdef HAVE_LOCALECONV + struct lconv l; + + localeconv_r(&l); + + decimal_point = l.decimal_point[0]; +#endif PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n", *buffer, pos, size, number, width, padding, alignment, fmt)); @@ -301,6 +319,8 @@ if (sign) { numbuf[i++] = '-'; + } else if (always_sign) { + numbuf[i++] = '+'; } if (fmt == 'f') { @@ -308,7 +328,7 @@ numbuf[i++] = '0'; if (precision > 0) { int k = precision; - numbuf[i++] = '.'; + numbuf[i++] = decimal_point; while ((decpt++ < 0) && k--) { numbuf[i++] = '0'; } @@ -317,12 +337,12 @@ while (decpt-- > 0) numbuf[i++] = cvt[j++]; if (precision > 0) - numbuf[i++] = '.'; + numbuf[i++] = decimal_point; } } else { numbuf[i++] = cvt[j++]; if (precision > 0) - numbuf[i++] = '.'; + numbuf[i++] = decimal_point; } while (cvt[j]) { @@ -393,6 +413,7 @@ * "-" left adjusted field * n field size * "."n precision (floats only) + * "+" Always place a sign (+ or -) in front of a number * * Type specifiers: * @@ -414,6 +435,7 @@ int argc, size = 240, inpos = 0, outpos = 0, temppos; int alignment, width, precision, currarg, adjusting, argnum; char *format, *result, padding; + int always_sign; argc = ZEND_NUM_ARGS(); @@ -463,13 +485,14 @@ if (currarg >= argc && format[inpos + 1] != '%') { efree(result); efree(args); - php_error(E_WARNING, "%s(): too few arguments", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments"); return NULL; } /* starting a new format specifier, reset variables */ alignment = ALIGN_RIGHT; adjusting = 0; padding = ' '; + always_sign = 0; inpos++; /* skip the '%' */ PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n", @@ -484,7 +507,7 @@ if (argnum == 0) { efree(result); efree(args); - php_error(E_WARNING, "%s(): zero is not a valid argument number", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero is not a valid argument number"); return NULL; } @@ -495,7 +518,7 @@ if (argnum >= argc) { efree(result); efree(args); - php_error(E_WARNING, "%s(): too few arguments", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments"); return NULL; } @@ -509,6 +532,8 @@ } else if (format[inpos] == '-') { alignment = ALIGN_LEFT; /* space padding, the default */ + } else if (format[inpos] == '+') { + always_sign = 1; } else if (format[inpos] == '\'') { padding = format[++inpos]; } else { @@ -571,14 +596,16 @@ convert_to_long_ex(args[argnum]); php_sprintf_appendint(&result, &outpos, &size, Z_LVAL_PP(args[argnum]), - width, padding, alignment); + width, padding, alignment, + always_sign); break; case 'u': convert_to_long_ex(args[argnum]); php_sprintf_appenduint(&result, &outpos, &size, Z_LVAL_PP(args[argnum]), - width, padding, alignment); + width, padding, alignment, + always_sign); break; case 'e': @@ -589,7 +616,7 @@ Z_DVAL_PP(args[argnum]), width, padding, alignment, precision, adjusting, - format[inpos]); + format[inpos], always_sign); break; case 'c': 1.3 +74 -29 php4/ext/standard/fsock.c Index: fsock.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/fsock.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- fsock.c 29 Apr 2002 02:31:01 -0000 1.2 +++ fsock.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fsock.c,v 1.95 2002/04/19 10:06:41 wez Exp $ */ +/* $Id: fsock.c,v 1.104 2002/09/25 15:25:11 wez Exp $ */ /* converted to PHP Streams and moved much code to main/network.c [wez] */ @@ -47,6 +47,19 @@ #endif #ifdef PHP_WIN32 #include <winsock.h> +#elif defined(NETWARE) +#ifdef NEW_LIBC +#ifdef USE_WINSOCK +#include <novsock2.h> +#else +#include <netinet/in.h> +#include <netdb.h> +/*#include <sys/socket.h>*/ +#include <sys/select.h> +/*#else +#include <sys/socket.h>*/ +#endif +#endif #else #include <netinet/in.h> #include <netdb.h> @@ -54,7 +67,7 @@ #include <arpa/inet.h> #endif #endif -#if defined(PHP_WIN32) || defined(__riscos__) +#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) #undef AF_UNIX #endif #if defined(AF_UNIX) @@ -88,6 +101,10 @@ #ifdef PHP_WIN32 #define EWOULDBLOCK WSAEWOULDBLOCK +#elif defined(NETWARE) +#ifdef USE_WINSOCK +#define EWOULDBLOCK WSAEWOULDBLOCK +#endif #else #include "build-defs.h" #endif @@ -122,25 +139,35 @@ int host_len; int port = -1; zval *zerrno = NULL, *zerrstr = NULL; - double timeout = 60; + double timeout = FG(default_socket_timeout); unsigned long conv; struct timeval tv; char *hashkey = NULL; php_stream *stream = NULL; +#ifdef PHP_WIN32 + int err; +#endif + + RETVAL_FALSE; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzzd", &host, &host_len, &port, &zerrno, &zerrstr, &timeout) == FAILURE) { RETURN_FALSE; } - hashkey = emalloc(host_len + 10); - sprintf(hashkey, "%s:%d", host, port); - if (persistent && zend_hash_find(&FG(ht_persistent_socks), hashkey, strlen(hashkey) + 1, - (void *) &stream) == SUCCESS) - { - efree(hashkey); - php_stream_to_zval(stream, return_value); - return; + if (persistent) { + spprintf(&hashkey, 0, "pfsockopen__%s:%d", host, port); + + switch(php_stream_from_persistent_id(hashkey, &stream TSRMLS_CC)) { + case PHP_STREAM_PERSISTENT_SUCCESS: + /* TODO: could check if the socket is still alive here */ + php_stream_to_zval(stream, return_value); + + /* fall through */ + case PHP_STREAM_PERSISTENT_FAILURE: + efree(hashkey); + return; + } } /* prepare the timeout value for use */ @@ -152,7 +179,7 @@ zval_dtor(zerrno); ZVAL_LONG(zerrno, 0); } - if (zerrstr) { + if (zerrstr) { zval_dtor(zerrstr); ZVAL_STRING(zerrno, "", 1); } @@ -187,15 +214,19 @@ } #if !HAVE_OPENSSL_EXT if (ssl_flags != php_ssl_none) { - zend_error(E_WARNING, "%s(): no SSL support in this build", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "no SSL support in this build"); } else #endif - stream = php_stream_sock_open_host(host, (unsigned short)port, socktype, (int)timeout, persistent); + stream = php_stream_sock_open_host(host, (unsigned short)port, socktype, &tv, hashkey); + +#ifdef PHP_WIN32 + /* Preserve error */ + err = WSAGetLastError(); +#endif if (stream == NULL) { - zend_error(E_WARNING, "%s(): unable to connect to %s:%d", - get_active_function_name(TSRMLS_C), host, port); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s:%d", host, port); } #if HAVE_OPENSSL_EXT @@ -203,39 +234,53 @@ int ssl_ret = FAILURE; switch(ssl_flags) { case php_ssl_v23: - ssl_ret = php_stream_sock_ssl_activate_with_method(stream, 1, SSLv23_client_method() TSRMLS_CC); + ssl_ret = php_stream_sock_ssl_activate_with_method(stream, 1, SSLv23_client_method(), NULL TSRMLS_CC); break; case php_ssl_tls: - ssl_ret = php_stream_sock_ssl_activate_with_method(stream, 1, TLSv1_client_method() TSRMLS_CC); + ssl_ret = php_stream_sock_ssl_activate_with_method(stream, 1, TLSv1_client_method(), NULL TSRMLS_CC); break; default: /* unknown ?? */ + break; } if (ssl_ret == FAILURE) - zend_error(E_WARNING, "%s(): failed to activate SSL mode %d", get_active_function_name(TSRMLS_C), ssl_flags); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to activate SSL mode %d", ssl_flags); } #endif } else - stream = php_stream_sock_open_unix(host, host_len, persistent, &tv); + stream = php_stream_sock_open_unix(host, host_len, hashkey, &tv); - if (stream && persistent) { - zend_hash_update(&FG(ht_persistent_socks), hashkey, strlen(hashkey) + 1, - &stream, sizeof(stream), NULL); - } - - efree(hashkey); + if (hashkey) + efree(hashkey); if (stream == NULL) { - if (zerrno) { + if (zerrno) { zval_dtor(zerrno); +#ifndef PHP_WIN32 ZVAL_LONG(zerrno, errno); +#else + ZVAL_LONG(zerrno, err); +#endif } - if (zerrstr) { +#ifndef PHP_WIN32 + if (zerrstr) { zval_dtor(zerrstr); - ZVAL_STRING(zerrno, strerror(errno), 1); + ZVAL_STRING(zerrstr, strerror(errno), 1); } +#else + if (zerrstr) { + char *buf; + if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, + Z_LVAL_P(zerrno), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL)) { + RETURN_FALSE; + } + + ZVAL_STRING(zerrstr, buf, 1); + LocalFree(buf); + } +#endif RETURN_FALSE; } 1.3 +9 -1 php4/ext/standard/fsock.h Index: fsock.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/fsock.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- fsock.h 29 Apr 2002 02:31:01 -0000 1.2 +++ fsock.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -18,12 +18,20 @@ +----------------------------------------------------------------------+ */ -/* $Id: fsock.h,v 1.42 2002/03/15 21:03:04 wez Exp $ */ +/* $Id: fsock.h,v 1.43 2002/09/05 14:21:55 hyanantha Exp $ */ /* Synced with php 3.0 revision 1.24 1999-06-18 [ssb] */ #ifndef FSOCK_H #define FSOCK_H + +#ifdef NETWARE +#ifdef NEW_LIBC +#include "sys/timeval.h" +#else +#include "netware/time_nw.h" /* For 'timeval' */ +#endif +#endif #include "file.h" 1.3 +3 -3 php4/ext/standard/ftok.c Index: ftok.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/ftok.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ftok.c 29 Apr 2002 02:31:01 -0000 1.2 +++ ftok.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ftok.c,v 1.4 2002/02/28 08:26:45 sebastian Exp $ */ +/* $Id: ftok.c,v 1.6 2002/08/24 01:19:28 helly Exp $ */ #include "php.h" @@ -41,12 +41,12 @@ convert_to_string_ex(proj); if (Z_STRLEN_PP(pathname)==0){ - php_error(E_WARNING, "Invalid argument 1 in ftok"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument invalid"); RETURN_LONG(-1); } if (Z_STRLEN_PP(proj)!=1){ - php_error(E_WARNING, "Invalid argument 2 in ftok"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument invalid"); RETURN_LONG(-1); } 1.3 +147 -24 php4/ext/standard/ftp_fopen_wrapper.c Index: ftp_fopen_wrapper.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/ftp_fopen_wrapper.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ftp_fopen_wrapper.c 29 Apr 2002 02:31:01 -0000 1.2 +++ ftp_fopen_wrapper.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -17,7 +17,7 @@ | Hartmut Holzgraefe <hholz****@php*****> | +----------------------------------------------------------------------+ */ -/* $Id: ftp_fopen_wrapper.c,v 1.23 2002/04/16 22:14:23 wez Exp $ */ +/* $Id: ftp_fopen_wrapper.c,v 1.36 2002/10/04 21:58:39 sesser Exp $ */ #include "php.h" #include "php_globals.h" @@ -35,6 +35,14 @@ #include <winsock.h> #define O_RDONLY _O_RDONLY #include "win32/param.h" +#elif defined(NETWARE) +/*#include <ws2nlm.h>*/ +/*#include <sys/socket.h>*/ +#ifdef NEW_LIBC +#include <sys/param.h> +#else +#include "netware/param.h" +#endif #else #include <sys/param.h> #endif @@ -48,6 +56,9 @@ #ifdef PHP_WIN32 #include <winsock.h> +#elif defined(NETWARE) && defined(USE_WINSOCK) +/*#include <ws2nlm.h>*/ +#include <novsock2.h> #else #include <netinet/in.h> #include <netdb.h> @@ -56,7 +67,7 @@ #endif #endif -#if defined(PHP_WIN32) || defined(__riscos__) +#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) #undef AF_UNIX #endif @@ -72,11 +83,12 @@ while (php_stream_gets(stream, buffer, buffer_size-1) && !(isdigit((int) buffer[0]) && isdigit((int) buffer[1]) && isdigit((int) buffer[2]) && buffer[3] == ' ')); - return strtol(buffer, NULL, 10); } #define GET_FTP_RESULT(stream) get_ftp_result((stream), tmp_line, sizeof(tmp_line) TSRMLS_CC) +#define FTPS_ENCRYPT_DATA 1 + static int php_stream_ftp_stream_stat(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb @@ -88,11 +100,28 @@ } +static int php_stream_ftp_stream_close(php_stream_wrapper *wrapper, + php_stream *stream + TSRMLS_DC) +{ + php_stream *controlstream = (php_stream *)stream->wrapperdata; + + if (controlstream) { + php_stream_write_string(controlstream, "QUIT\r\n"); + php_stream_close(controlstream); + stream->wrapperdata = NULL; + } + return 0; +} + + static php_stream_wrapper_ops ftp_stream_wops = { php_stream_url_wrap_ftp, - NULL, + php_stream_ftp_stream_close, /* stream_close */ php_stream_ftp_stream_stat, - NULL + NULL, /* stat_url */ + NULL, /* opendir */ + "FTP" }; php_stream_wrapper php_stream_ftp_wrapper = { @@ -106,25 +135,33 @@ */ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { - php_stream *stream=NULL; + php_stream *stream=NULL, *datastream=NULL, *reuseid=NULL; php_url *resource=NULL; char tmp_line[512]; + char ip[sizeof("123.123.123.123")]; unsigned short portno; char *scratch; int result; - int i; - char *tpath, *ttpath; + int i, use_ssl, use_ssl_on_data=0; + char *tpath, *ttpath, *hoststart=NULL; size_t file_size = 0; + + if (strchr(mode, 'a') || strchr(mode, '+')) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "FTP does not support simultaneous read/write connections."); + return NULL; + } resource = php_url_parse((char *) path); if (resource == NULL || resource->path == NULL) return NULL; + use_ssl = resource->scheme && (strlen(resource->scheme) > 3) && resource->scheme[3] == 's'; + /* use port 21 if one wasn't specified */ if (resource->port == 0) resource->port = 21; - stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, 0, 0); + stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, NULL, 0); if (stream == NULL) goto errexit; @@ -138,6 +175,66 @@ goto errexit; } +#if HAVE_OPENSSL_EXT + if (use_ssl) { + + /* send the AUTH TLS request name */ + php_stream_write_string(stream, "AUTH TLS\r\n"); + + /* get the response */ + result = GET_FTP_RESULT(stream); + if (result != 234) { + /* AUTH TLS not supported try AUTH SSL */ + php_stream_write_string(stream, "AUTH SSL\r\n"); + + /* get the response */ + result = GET_FTP_RESULT(stream); + if (result != 334) { + use_ssl = 0; + } else { + /* we must reuse the old SSL session id */ + /* if we talk to an old ftpd-ssl */ + reuseid = stream; + } + } else { + /* encrypt data etc */ + + + } + + } + + if (use_ssl) { + if (use_ssl && php_stream_sock_ssl_activate(stream, 1) == FAILURE) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Unable to activate SSL mode"); + php_stream_close(stream); + stream = NULL; + goto errexit; + } + + /* set PBSZ to 0 */ + php_stream_write_string(stream, "PBSZ 0\r\n"); + + /* ignore the response */ + result = GET_FTP_RESULT(stream); + + /* set data connection protection level */ +#if FTPS_ENCRYPT_DATA + php_stream_write_string(stream, "PROT P\r\n"); + + /* get the response */ + result = GET_FTP_RESULT(stream); + use_ssl_on_data = (result >= 200 && result<=299) || reuseid; +#else + php_stream_write_string(stream, "PROT C\r\n"); + + /* get the response */ + result = GET_FTP_RESULT(stream); +#endif + } + +#endif + /* send the user name */ php_stream_write_string(stream, "USER "); if (resource->user != NULL) { @@ -220,7 +317,7 @@ /* set up the passive connection */ - /* We try EPSV first, needed for IPv6 and works on some IPv4 servers */ + /* We try EPSV first, needed for IPv6 and works on some IPv4 servers */ php_stream_write_string(stream, "EPSV\r\n"); result = GET_FTP_RESULT(stream); @@ -240,15 +337,22 @@ for (tpath += 4; *tpath && !isdigit((int) *tpath); tpath++); if (!*tpath) goto errexit; - /* skip over the host ip, we just assume it's the same */ + /* skip over the host ip, to get the port */ + hoststart = tpath; for (i = 0; i < 4; i++) { for (; isdigit((int) *tpath); tpath++); if (*tpath != ',') goto errexit; + *tpath='.'; tpath++; } + tpath[-1] = '\0'; + memcpy(ip, hoststart, sizeof(ip)); + ip[sizeof(ip)-1] = '\0'; + hoststart = ip; + /* pull out the MSB of the port */ - portno = (unsigned short) strtol(tpath, &ttpath, 10) * 256; + portno = (unsigned short) strtoul(tpath, &ttpath, 10) * 256; if (ttpath == NULL) { /* didn't get correct response from PASV */ goto errexit; @@ -258,7 +362,7 @@ goto errexit; tpath++; /* pull out the LSB of the port */ - portno += (unsigned short) strtol(tpath, &ttpath, 10); + portno += (unsigned short) strtoul(tpath, &ttpath, 10); } else { /* parse epsv command (|||6446|) */ for (i = 0, tpath = tmp_line + 4; *tpath; tpath++) { @@ -271,7 +375,7 @@ if (i < 3) goto errexit; /* pull out the port */ - portno = (unsigned short) strtol(tpath + 1, &ttpath, 10); + portno = (unsigned short) strtoul(tpath + 1, &ttpath, 10); } if (ttpath == NULL) { @@ -291,21 +395,40 @@ } else { php_stream_write_string(stream, "/"); } - - /* close control connection */ - php_stream_write_string(stream, "\r\nQUIT\r\n"); - php_stream_close(stream); + php_stream_write_string(stream, "\r\n"); + + /* close control connection if not in ssl mode */ + if (!use_ssl) { + php_stream_write_string(stream, "QUIT\r\n"); + php_stream_close(stream); + stream = NULL; + } /* open the data channel */ - stream = php_stream_sock_open_host(resource->host, portno, SOCK_STREAM, 0, 0); - if (stream == NULL) + if (hoststart == NULL) { + hoststart = resource->host; + } + datastream = php_stream_sock_open_host(hoststart, portno, SOCK_STREAM, 0, 0); + if (datastream == NULL) goto errexit; - - php_stream_context_set(stream, context); + + php_stream_context_set(datastream, context); php_stream_notify_progress_init(context, 0, file_size); +#if HAVE_OPENSSL_EXT + if (use_ssl_on_data && php_stream_sock_ssl_activate_with_method(datastream, 1, SSLv23_method(), reuseid TSRMLS_CC) == FAILURE) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Unable to activate SSL mode"); + php_stream_close(datastream); + datastream = NULL; + goto errexit; + } +#endif + + /* remember control stream */ + datastream->wrapperdata = (zval *)stream; + php_url_free(resource); - return stream; + return datastream; errexit: php_url_free(resource); @@ -314,7 +437,7 @@ php_stream_close(stream); } if (tmp_line[0] != '\0') - zend_error(E_WARNING, "FTP server reports %s", tmp_line); + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "FTP server reports %s", tmp_line); return NULL; } /* }}} */ 1.4 +42 -15 php4/ext/standard/head.c Index: head.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/head.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- head.c 2 Aug 2002 22:05:24 -0000 1.3 +++ head.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -15,9 +15,14 @@ | Author: Rasmus Lerdorf <rasmu****@lerdo*****> | +----------------------------------------------------------------------+ */ -/* $Id: head.c,v 1.56 2002/05/17 07:10:19 jwoolley Exp $ */ +/* $Id: head.c,v 1.65 2002/09/17 13:54:40 hholzgra Exp $ */ #include <stdio.h> + +#if defined(NETWARE) && !defined(NEW_LIBC) +#include <sys/socket.h> +#endif + #include "php.h" #include "ext/standard/php_standard.h" #include "SAPI.h" @@ -35,19 +40,18 @@ /* Implementation of the language Header() function */ -/* {{{ proto void header(string header [, bool replace]) +/* {{{ proto void header(string header [, bool replace, [int http_response_code]]) Sends a raw HTTP header */ PHP_FUNCTION(header) { - char *header; - int header_len; - zend_bool replace = 1; + zend_bool rep = 1; + sapi_header_line ctr = {0}; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &header, - &header_len, &replace) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, + &ctr.line_len, &rep, &ctr.response_code) == FAILURE) return; - } - sapi_add_header_ex(header, header_len, 1, replace TSRMLS_CC); + + sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); } /* }}} */ @@ -69,7 +73,9 @@ int len=sizeof("Set-Cookie: "); time_t t; char *dt; - + sapi_header_line ctr = {0}; + int result; + len += name_len; if (value) { int encoded_value_len; @@ -121,7 +127,12 @@ strcat(cookie, "; secure"); } - return sapi_add_header_ex(cookie, strlen(cookie), 0, 0 TSRMLS_CC); + ctr.line = cookie; + ctr.line_len = strlen(cookie); + + result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC); + efree(cookie); + return result; } @@ -150,14 +161,30 @@ /* }}} */ -/* {{{ proto int headers_sent(void) +/* {{{ proto bool headers_sent([string &$file [, int &$line]]) Returns true if headers have already been sent, false otherwise */ PHP_FUNCTION(headers_sent) { - if (ZEND_NUM_ARGS() != 0) { - php_error(E_WARNING, "%s() expects no parameters, %d given", - get_active_function_name(TSRMLS_C), ZEND_NUM_ARGS()); + zval *arg1, *arg2; + char *file=""; + int line=0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &arg1, &arg2) == FAILURE) return; + + if (SG(headers_sent)) { + line = php_get_output_start_lineno(TSRMLS_C); + file = php_get_output_start_filename(TSRMLS_C); + } + + switch(ZEND_NUM_ARGS()) { + case 2: + zval_dtor(arg2); + ZVAL_LONG(arg2, line); + case 1: + zval_dtor(arg1); + ZVAL_STRING(arg1, file, 1); + break; } if (SG(headers_sent)) { 1.4 +68 -68 php4/ext/standard/html.c Index: html.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/html.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- html.c 9 May 2002 05:39:43 -0000 1.3 +++ html.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: html.c,v 1.46 2002/05/05 23:06:39 wez Exp $ */ +/* $Id: html.c,v 1.54 2002/10/03 12:06:52 andrey Exp $ */ #include "php.h" #include "reg.h" @@ -336,7 +336,7 @@ MB_WRITE((unsigned char)this_char); - switch(charset) { + switch (charset) { case cs_utf_8: { unsigned long utf = 0; @@ -347,12 +347,11 @@ * Code stolen from the mbstring extension */ do { - if (this_char < 0x80) { + if (this_char < 0x80) { more = 0; break; - } - else if (this_char < 0xc0) { - switch(stat) { + } else if (this_char < 0xc0) { + switch (stat) { case 0x10: /* 2, 2nd */ case 0x21: /* 3, 3rd */ case 0x32: /* 4, 4th */ @@ -394,30 +393,29 @@ else if (this_char < 0xe0) { stat = 0x10; /* 2 byte */ utf = (this_char & 0x1f) << 6; - } else if (this_char < 0xf0) { + } else if (this_char < 0xf0) { stat = 0x20; /* 3 byte */ utf = (this_char & 0xf) << 12; } else if (this_char < 0xf8) { stat = 0x30; /* 4 byte */ utf = (this_char & 0x7) << 18; - } else if (this_char < 0xfc) { + } else if (this_char < 0xfc) { stat = 0x40; /* 5 byte */ utf = (this_char & 0x3) << 24; - } else if (this_char < 0xfe) { + } else if (this_char < 0xfe) { stat = 0x50; /* 6 byte */ utf = (this_char & 0x1) << 30; - } - else { + } else { /* invalid; bail */ more = 0; break; } - if (more) - { + + if (more) { this_char = str[pos++]; MB_WRITE((unsigned char)this_char); } - } while(more); + } while (more); } break; case cs_big5: @@ -425,12 +423,11 @@ case cs_big5hkscs: { /* check if this is the first of a 2-byte sequence */ - if (this_char >= 0xa1 && this_char <= 0xf9) { + if (this_char >= 0xa1 && this_char <= 0xf9) { /* peek at the next char */ unsigned char next_char = str[pos]; if ((next_char >= 0x40 && next_char <= 0x73) || - (next_char >= 0xa1 && next_char <= 0xfe)) - { + (next_char >= 0xa1 && next_char <= 0xfe)) { /* yes, this a wide char */ this_char <<= 8; MB_WRITE(next_char); @@ -446,7 +443,7 @@ /* check if this is the first of a 2-byte sequence */ if ( (this_char >= 0x81 && this_char <= 0x9f) || (this_char >= 0xe0 && this_char <= 0xef) - ) { + ) { /* peek at the next char */ unsigned char next_char = str[pos]; if ((next_char >= 0x40 && next_char <= 0x7e) || @@ -465,11 +462,10 @@ case cs_eucjp: { /* check if this is the first of a multi-byte sequence */ - if (this_char >= 0xa1 && this_char <= 0xfe) { + if (this_char >= 0xa1 && this_char <= 0xfe) { /* peek at the next char */ unsigned char next_char = str[pos]; - if (next_char >= 0xa1 && next_char <= 0xfe) - { + if (next_char >= 0xa1 && next_char <= 0xfe) { /* yes, this a jis kanji char */ this_char <<= 8; MB_WRITE(next_char); @@ -477,11 +473,10 @@ pos++; } - } else if (this_char == 0x8e) { + } else if (this_char == 0x8e) { /* peek at the next char */ unsigned char next_char = str[pos]; - if (next_char >= 0xa1 && next_char <= 0xdf) - { + if (next_char >= 0xa1 && next_char <= 0xdf) { /* JIS X 0201 kana */ this_char <<= 8; MB_WRITE(next_char); @@ -489,13 +484,12 @@ pos++; } - } else if (this_char == 0x8f) { + } else if (this_char == 0x8f) { /* peek at the next two char */ unsigned char next_char = str[pos]; unsigned char next2_char = str[pos+1]; if ((next_char >= 0xa1 && next_char <= 0xfe) && - (next2_char >= 0xa1 && next2_char <= 0xfe)) - { + (next2_char >= 0xa1 && next2_char <= 0xfe)) { /* JIS X 0212 hojo-kanji */ this_char <<= 8; MB_WRITE(next_char); @@ -511,9 +505,7 @@ break; } default: - { - break; - } + break; } MB_RETURN; } @@ -522,11 +514,11 @@ /* {{{ entity_charset determine_charset * returns the charset identifier based on current locale or a hint. * defaults to iso-8859-1 */ -static enum entity_charset determine_charset(char *charset_hint) +static enum entity_charset determine_charset(char *charset_hint TSRMLS_DC) { int i; enum entity_charset charset = cs_8859_1; - int len; + int len = 0; /* Guarantee default behaviour for backwards compatibility */ if (charset_hint == NULL) @@ -538,8 +530,7 @@ charset_hint = nl_langinfo(CODESET); #endif #if HAVE_LOCALE_H - if (charset_hint == NULL) - { + if (charset_hint == NULL) { /* try to figure out the charset from the locale */ char *localename; char *dot, *at; @@ -548,7 +539,7 @@ localename = setlocale(LC_CTYPE, NULL); dot = strchr(localename, '.'); - if (dot) { + if (dot) { dot++; /* locale specifies a codeset */ at = strchr(dot, '@'); @@ -557,29 +548,36 @@ else len = strlen(dot); charset_hint = dot; - } - else { + } else { /* no explicit name; see if the name itself * is the charset */ charset_hint = localename; len = strlen(charset_hint); } - } - else + } else len = strlen(charset_hint); #else if (charset_hint) len = strlen(charset_hint); #endif } - if (charset_hint) { + if (charset_hint) { + int found = 0; + if (!len) + len = strlen(charset_hint); + /* now walk the charset map and look for the codeset */ for (i = 0; charset_map[i].codeset; i++) { if (strncasecmp(charset_hint, charset_map[i].codeset, len) == 0) { charset = charset_map[i].charset; + found = 1; break; } } + if (!found) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "charset `%s' not supported, assuming iso-8859-1", + charset_hint); + } } return charset; } @@ -587,24 +585,24 @@ /* {{{ php_unescape_html_entities */ -PHPAPI char *php_unescape_html_entities(unsigned char *old, int oldlen, int *newlen, int all, int quote_style, char *hint_charset) +PHPAPI char *php_unescape_html_entities(unsigned char *old, int oldlen, int *newlen, int all, int quote_style, char *hint_charset TSRMLS_DC) { int retlen; int j, k; char *replaced, *ret; - enum entity_charset charset = determine_charset(hint_charset); + enum entity_charset charset = determine_charset(hint_charset TSRMLS_CC); unsigned char replacement[15]; ret = estrdup(old); retlen = oldlen; - if (all) { + if (all) { /* look for a match in the maps for this charset */ - for (j=0; entity_map[j].charset != cs_terminator; j++) { + for (j = 0; entity_map[j].charset != cs_terminator; j++) { if (entity_map[j].charset != charset) continue; - for (k = entity_map[j].basechar; k <= entity_map[j].endchar; k++) { + for (k = entity_map[j].basechar; k <= entity_map[j].endchar; k++) { unsigned char entity[32]; int entity_length = 0; @@ -620,8 +618,9 @@ entity_length += 2; /* When we have MBCS entities in the tables above, this will need to handle it */ - if (k > 0xff) + if (k > 0xff) { zend_error(E_WARNING, "cannot yet handle MBCS in html_entity_decode()!"); + } replacement[0] = k; replacement[1] = '\0'; @@ -655,11 +654,11 @@ /* {{{ php_escape_html_entities */ -PHPAPI char *php_escape_html_entities(unsigned char *old, int oldlen, int *newlen, int all, int quote_style, char *hint_charset) +PHPAPI char *php_escape_html_entities(unsigned char *old, int oldlen, int *newlen, int all, int quote_style, char *hint_charset TSRMLS_DC) { int i, j, maxlen, len; char *replaced; - enum entity_charset charset = determine_charset(hint_charset); + enum entity_charset charset = determine_charset(hint_charset TSRMLS_CC); int matches_map; maxlen = 2 * oldlen; @@ -679,18 +678,18 @@ if (len + 9 > maxlen) replaced = erealloc (replaced, maxlen += 128); - if (all) { + if (all) { /* look for a match in the maps for this charset */ unsigned char *rep; - for (j=0; entity_map[j].charset != cs_terminator; j++) { + for (j = 0; entity_map[j].charset != cs_terminator; j++) { if (entity_map[j].charset == charset && this_char >= entity_map[j].basechar && this_char <= entity_map[j].endchar) { rep = (unsigned char*)entity_map[j].table[this_char - entity_map[j].basechar]; - if (rep == NULL) { + if (rep == NULL) { /* there is no entity for this position; fall through and * just output the character itself */ break; @@ -701,17 +700,17 @@ } } - if (matches_map) { + if (matches_map) { replaced[len++] = '&'; strcpy(replaced + len, rep); len += strlen(rep); replaced[len++] = ';'; } } - if (!matches_map) { + if (!matches_map) { int is_basic = 0; - for (j = 0; basic_entities[j].charcode != 0; j++) { + for (j = 0; basic_entities[j].charcode != 0; j++) { if ((basic_entities[j].charcode != this_char) || (basic_entities[j].flags && (quote_style & basic_entities[j].flags) == 0)) continue; @@ -723,18 +722,19 @@ break; } - if (!is_basic) { - if (this_char > 0xff) { + if (!is_basic) { + if (this_char > 0xff) { /* a wide char without a named entity; pass through the original sequence */ memcpy(replaced + len, mbsequence, mbseqlen); len += mbseqlen; - } else - replaced [len++] = (unsigned char)this_char; + } else { + replaced[len++] = (unsigned char)this_char; + } } } } - replaced [len] = '\0'; + replaced[len] = '\0'; *newlen = len; return replaced; @@ -748,7 +748,8 @@ static void php_html_entities(INTERNAL_FUNCTION_PARAMETERS, int all) { char *str, *hint_charset = NULL; - int str_len, hint_charset_len, len, quote_style = ENT_COMPAT; + int str_len, hint_charset_len = 0; + int len, quote_style = ENT_COMPAT; char *replaced; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls", &str, &str_len, @@ -756,7 +757,7 @@ return; } - replaced = php_escape_html_entities(str, str_len, &len, all, quote_style, hint_charset); + replaced = php_escape_html_entities(str, str_len, &len, all, quote_style, hint_charset TSRMLS_CC); RETVAL_STRINGL(replaced, len, 0); } /* }}} */ @@ -785,7 +786,7 @@ /* }}} */ /* {{{ proto string html_entity_decode(string string [, int quote_style][, string charset]) - Convert all applicable characters to HTML entities */ + Convert all HTML entities to their applicable characters */ PHP_FUNCTION(html_entity_decode) { char *str, *hint_charset = NULL; @@ -797,7 +798,7 @@ return; } - replaced = php_unescape_html_entities(str, str_len, &len, 1, quote_style, hint_charset); + replaced = php_unescape_html_entities(str, str_len, &len, 1, quote_style, hint_charset TSRMLS_CC); RETVAL_STRINGL(replaced, len, 0); } /* }}} */ @@ -818,7 +819,7 @@ int which = HTML_SPECIALCHARS, quote_style = ENT_COMPAT; int i, j; char ind[2]; - enum entity_charset charset = determine_charset(NULL); + enum entity_charset charset = determine_charset(NULL TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &which, "e_style) == FAILURE) { return; @@ -830,11 +831,10 @@ switch (which) { case HTML_ENTITIES: - for (j=0; entity_map[j].charset != cs_terminator; j++) { + for (j=0; entity_map[j].charset != cs_terminator; j++) { if (entity_map[j].charset != charset) continue; - for (i = 0; i < entity_map[j].endchar - entity_map[j].basechar; i++) - { + for (i = 0; i <= entity_map[j].endchar - entity_map[j].basechar; i++) { char buffer[16]; if (entity_map[j].table[i] == NULL) @@ -849,7 +849,7 @@ /* break thru */ case HTML_SPECIALCHARS: - for (j = 0; basic_entities[j].charcode != 0; j++) { + for (j = 0; basic_entities[j].charcode != 0; j++) { if (basic_entities[j].flags && (quote_style & basic_entities[j].flags) == 0) continue; 1.3 +2 -2 php4/ext/standard/html.h Index: html.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/html.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- html.h 29 Apr 2002 02:31:01 -0000 1.2 +++ html.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: html.h,v 1.14 2002/03/16 01:34:52 wez Exp $ */ +/* $Id: html.h,v 1.15 2002/09/26 18:13:32 sebastian Exp $ */ #ifndef HTML_H #define HTML_H @@ -36,6 +36,6 @@ PHP_FUNCTION(html_entity_decode); PHP_FUNCTION(get_html_translation_table); -PHPAPI char *php_escape_html_entities(unsigned char *old, int oldlen, int *newlen, int all, int quote_style, char *hint_charset); +PHPAPI char *php_escape_html_entities(unsigned char *old, int oldlen, int *newlen, int all, int quote_style, char *hint_charset TSRMLS_DC); #endif /* HTML_H */ 1.5 +128 -68 php4/ext/standard/http_fopen_wrapper.c Index: http_fopen_wrapper.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/http_fopen_wrapper.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- http_fopen_wrapper.c 9 May 2002 05:39:43 -0000 1.4 +++ http_fopen_wrapper.c 6 Oct 2002 21:54:32 -0000 1.5 @@ -18,12 +18,14 @@ | Wez Furlong <wez****@thebr*****> | +----------------------------------------------------------------------+ */ -/* $Id: http_fopen_wrapper.c,v 1.35 2002/05/04 17:16:28 sas Exp $ */ +/* $Id: http_fopen_wrapper.c,v 1.52 2002/09/28 22:14:21 wez Exp $ */ #include "php.h" #include "php_globals.h" #include "php_streams.h" #include "php_network.h" +#include "php_ini.h" +#include "ext/standard/basic_functions.h" #include <stdio.h> #include <stdlib.h> @@ -37,6 +39,14 @@ #include <winsock.h> #define O_RDONLY _O_RDONLY #include "win32/param.h" +#elif defined(NETWARE) +/*#include <ws2nlm.h>*/ +/*#include <sys/socket.h>*/ +#ifdef NEW_LIBC +#include <sys/param.h> +#else +#include "netware/param.h" +#endif #else #include <sys/param.h> #endif @@ -50,6 +60,9 @@ #ifdef PHP_WIN32 #include <winsock.h> +#elif defined(NETWARE) && defined(USE_WINSOCK) +/*#include <ws2nlm.h>*/ +#include <novsock2.h> #else #include <netinet/in.h> #include <netdb.h> @@ -58,7 +71,7 @@ #endif #endif -#if defined(PHP_WIN32) || defined(__riscos__) +#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) #undef AF_UNIX #endif @@ -77,6 +90,8 @@ int use_ssl; char *scratch = NULL; char *tmp = NULL; + char *ua_str = NULL; + zval **ua_zval = NULL; int scratch_len = 0; int body = 0; char location[HTTP_HEADER_BLOCK_SIZE]; @@ -86,11 +101,16 @@ char tmp_line[128]; size_t chunk_size = 0, file_size = 0; + if (strchr(mode, 'a') || strchr(mode, '+') || strchr(mode, 'w')) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP wrapper does not support writeable connections."); + return NULL; + } + resource = php_url_parse(path); if (resource == NULL) return NULL; - use_ssl = resource->scheme && resource->scheme[4] == 's'; + use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's'; /* choose default ports */ if (use_ssl && resource->port == 0) @@ -98,13 +118,13 @@ else if (resource->port == 0) resource->port = 80; - stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, 0, 0); + stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, NULL, 0); if (stream == NULL) goto out; /* avoid buffering issues while reading header */ if (options & STREAM_WILL_CAST) - chunk_size = php_stream_sock_set_chunk_size(stream, 1 TSRMLS_CC); + chunk_size = php_stream_set_chunk_size(stream, 1); php_stream_context_set(stream, context); @@ -113,9 +133,7 @@ #if HAVE_OPENSSL_EXT if (use_ssl) { if (php_stream_sock_ssl_activate(stream, 1) == FAILURE) { - if (options & REPORT_ERRORS) { - zend_error(E_WARNING, "Unable to activate SSL mode"); - } + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Unable to activate SSL mode"); php_stream_close(stream); stream = NULL; goto out; @@ -146,8 +164,12 @@ /* send it */ php_stream_write(stream, scratch, strlen(scratch)); - /* authz header if it was specified */ + /* auth header if it was specified */ if (resource->user && resource->pass) { + /* decode the strings first */ + php_url_decode(resource->user, strlen(resource->user)); + php_url_decode(resource->pass, strlen(resource->pass)); + /* scratch is large enough, since it was made large enough for the whole URL */ strcpy(scratch, resource->user); strcat(scratch, ":"); @@ -178,7 +200,37 @@ else if (snprintf(scratch, scratch_len, "Host: %s\r\n", resource->host) > 0) php_stream_write(stream, scratch, strlen(scratch)); - php_stream_write_string(stream, "User-Agent: PHP/" PHP_VERSION "\r\n\r\n"); + if (context && + php_stream_context_get_option(context, "http", "user_agent", &ua_zval) == SUCCESS) { + ua_str = Z_STRVAL_PP(ua_zval); + } else if (FG(user_agent)) { + ua_str = FG(user_agent); + } + + if (ua_str) { +#define _UA_HEADER "User-Agent: %s\r\n" + char *ua; + size_t ua_len; + + ua_len = sizeof(_UA_HEADER) + strlen(ua_str); + + /* ensure the header is only sent if user_agent is not blank */ + if (ua_len > sizeof(_UA_HEADER)) { + ua = emalloc(ua_len + 1); + if ((ua_len = snprintf(ua, ua_len, _UA_HEADER, ua_str)) > 0) { + ua[ua_len] = 0; + php_stream_write(stream, ua, ua_len); + } else { + php_error(E_WARNING, "Cannot construct User-agent header"); + } + + if (ua) { + efree(ua); + } + } + } + + php_stream_write(stream, "\r\n", sizeof("\r\n")-1); location[0] = '\0'; @@ -194,18 +246,18 @@ MAKE_STD_ZVAL(http_response); response_code = atoi(tmp_line + 9); - if (response_code == 200) { - reqok = 1; - } else { - switch(response_code) { - case 403: - php_stream_notify_error(context, PHP_STREAM_NOTIFY_AUTH_RESULT, - tmp_line, response_code); - break; - default: - php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, - tmp_line, response_code); - } + switch(response_code) { + case 200: + case 302: + reqok = 1; + break; + case 403: + php_stream_notify_error(context, PHP_STREAM_NOTIFY_AUTH_RESULT, + tmp_line, response_code); + break; + default: + php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, + tmp_line, response_code); } Z_STRLEN_P(http_response) = strlen(tmp_line); @@ -223,59 +275,59 @@ } } - /* read past HTTP headers */ + if (reqok) { + /* read past HTTP headers */ - http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE); + http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE); - while (!body && !php_stream_eof(stream)) { + while (!body && !php_stream_eof(stream)) { - if (php_stream_gets(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE-1) != NULL) { - char *p; - int found_eol = 0; - int http_header_line_length; + if (php_stream_gets(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE-1) != NULL) { + char *p; + int found_eol = 0; + int http_header_line_length; - http_header_line[HTTP_HEADER_BLOCK_SIZE-1] = '\0'; - p = http_header_line; - while(*p) { - while(*p == '\n' || *p == '\r') { - *p = '\0'; - p--; - found_eol = 1; + http_header_line[HTTP_HEADER_BLOCK_SIZE-1] = '\0'; + p = http_header_line; + while(*p) { + while(*p == '\n' || *p == '\r') { + *p = '\0'; + p--; + found_eol = 1; + } + if (found_eol) + break; + p++; } - if (found_eol) - break; - p++; - } - http_header_line_length = p-http_header_line+1; + http_header_line_length = p-http_header_line+1; - if (!strncasecmp(http_header_line, "Location: ", 10)) { - strlcpy(location, http_header_line + 10, sizeof(location)); - } else if (!strncasecmp(http_header_line, "Content-Type: ", 14)) { - php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + 14, 0); - } else if (!strncasecmp(http_header_line, "Content-Length: ", 16)) { - file_size = atoi(http_header_line + 16); - php_stream_notify_file_size(context, file_size, http_header_line, 0); - } - + if (!strncasecmp(http_header_line, "Location: ", 10)) { + strlcpy(location, http_header_line + 10, sizeof(location)); + } else if (!strncasecmp(http_header_line, "Content-Type: ", 14)) { + php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + 14, 0); + } else if (!strncasecmp(http_header_line, "Content-Length: ", 16)) { + file_size = atoi(http_header_line + 16); + php_stream_notify_file_size(context, file_size, http_header_line, 0); + } - if (http_header_line[0] == '\0') - body = 1; - else { - zval *http_header; + if (http_header_line[0] == '\0') + body = 1; + else { + zval *http_header; - MAKE_STD_ZVAL(http_header); + MAKE_STD_ZVAL(http_header); - ZVAL_STRINGL(http_header, http_header_line, http_header_line_length, 1); + ZVAL_STRINGL(http_header, http_header_line, http_header_line_length, 1); - zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_header, sizeof(zval *), NULL); + zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_header, sizeof(zval *), NULL); + } } + else + break; } - else - break; - } - - if (!reqok) { - + } + + if (!reqok || location[0] != '\0') { if (location[0] != '\0') php_stream_notify_info(context, PHP_STREAM_NOTIFY_REDIRECTED, location, 0); @@ -319,8 +371,11 @@ FREE_ZVAL(stream->wrapperdata); } } else { - if (options & REPORT_ERRORS) - zend_error(E_WARNING, "HTTP request failed! %s", tmp_line); + + zval_dtor(response_header); + FREE_ZVAL(response_header); + + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed! %s", tmp_line); } } out: @@ -334,7 +389,10 @@ stream->wrapperdata = response_header; php_stream_notify_progress_init(context, 0, file_size); if (options & STREAM_WILL_CAST) - php_stream_sock_set_chunk_size(stream, chunk_size TSRMLS_CC); + php_stream_set_chunk_size(stream, chunk_size); + /* as far as streams are concerned, we are now at the start of + * the stream */ + stream->position = 0; } if (response_header) { @@ -361,9 +419,11 @@ static php_stream_wrapper_ops http_stream_wops = { php_stream_url_wrap_http, - NULL, + NULL, /* stream_close */ php_stream_http_stream_stat, - NULL + NULL, /* stat_url */ + NULL, /* opendir */ + "HTTP" }; php_stream_wrapper php_stream_http_wrapper = { 1.4 +273 -52 php4/ext/standard/image.c Index: image.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/image.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- image.c 9 May 2002 05:39:43 -0000 1.3 +++ image.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -16,7 +16,7 @@ | Marcus Boerger <helly****@php*****> | +----------------------------------------------------------------------+ */ -/* $Id: image.c,v 1.55 2002/05/04 17:24:08 sas Exp $ */ +/* $Id: image.c,v 1.69 2002/09/18 20:37:24 iliaa Exp $ */ /* * Based on Daniel Schmitt's imageinfo.c which carried the following * Copyright notice. @@ -39,6 +39,9 @@ #include "php.h" #include <stdio.h> +#if defined(NETWARE) && !defined(NEW_LIBC) +#include <sys/socket.h> +#endif #if HAVE_FCNTL_H #include <fcntl.h> #endif @@ -49,18 +52,26 @@ #endif #include "php_image.h" +#if HAVE_ZLIB +#include "zlib.h" +#endif + /* file type markers */ PHPAPI const char php_sig_gif[3] = {'G', 'I', 'F'}; PHPAPI const char php_sig_psd[4] = {'8', 'B', 'P', 'S'}; PHPAPI const char php_sig_bmp[2] = {'B', 'M'}; PHPAPI const char php_sig_swf[3] = {'F', 'W', 'S'}; +PHPAPI const char php_sig_swc[3] = {'C', 'W', 'S'}; PHPAPI const char php_sig_jpg[3] = {(char) 0xff, (char) 0xd8, (char) 0xff}; PHPAPI const char php_sig_png[8] = {(char) 0x89, (char) 0x50, (char) 0x4e, (char) 0x47, (char) 0x0d, (char) 0x0a, (char) 0x1a, (char) 0x0a}; PHPAPI const char php_sig_tif_ii[4] = {'I','I', (char)0x2A, (char)0x00}; PHPAPI const char php_sig_tif_mm[4] = {'M','M', (char)0x00, (char)0x2A}; PHPAPI const char php_sig_jpc[3] = {(char)0xFF, (char)0x4F, (char)0xff}; +PHPAPI const char php_sig_iff[4] = {'F','O','R','M'}; +/* REMEMBER TO ADD MIME-TYPE TO FUNCTION php_image_type_to_mime_type */ +/* PCX must check first 64bytes and byte 0=0x0a and byte2 < 0x06 */ /* return info as a struct, to make expansion easier */ @@ -71,6 +82,28 @@ unsigned int channels; }; +/* {{{ PHP_MINIT_FUNCTION(imagetypes) + * Register IMAGETYPE_<xxx> constants used by GetImageSize(), image_type_to_mime_type, ext/exif */ +PHP_MINIT_FUNCTION(imagetypes) +{ + REGISTER_LONG_CONSTANT("IMAGETYPE_GIF", IMAGE_FILETYPE_GIF, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_JPEG", IMAGE_FILETYPE_JPEG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_PNG", IMAGE_FILETYPE_PNG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_SWF", IMAGE_FILETYPE_SWF, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_PSD", IMAGE_FILETYPE_PSD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_BMP", IMAGE_FILETYPE_BMP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_TIFF_II", IMAGE_FILETYPE_TIFF_II, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_TIFF_MM", IMAGE_FILETYPE_TIFF_MM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_JPC", IMAGE_FILETYPE_JPC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_JP2", IMAGE_FILETYPE_JP2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_JPX", IMAGE_FILETYPE_JPX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_JB2", IMAGE_FILETYPE_JB2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_SWC", IMAGE_FILETYPE_SWC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_IFF", IMAGE_FILETYPE_IFF, CONST_CS | CONST_PERSISTENT); + return SUCCESS; +} +/* }}} */ + /* {{{ php_handle_gif * routine to handle GIF files. If only everything were that easy... ;} */ static struct gfxinfo *php_handle_gif (php_stream * stream TSRMLS_DC) @@ -88,6 +121,11 @@ php_stream_read(stream, a, sizeof(a)); /* fread(a, sizeof(a), 1, fp); */ result->height = (unsigned short)a[0] | (((unsigned short)a[1])<<8); + php_stream_read(stream, a, 1); + + result->bits = a[0]&0x80 ? ((a[0]&0x07) + 1) : 0; + result->channels = 3; /* allways */ + return result; } /* }}} */ @@ -112,8 +150,10 @@ in_width = (((unsigned long) a[ 4 ]) << 24) + (((unsigned long) a[ 5 ]) << 16) + (((unsigned long) a[ 6 ]) << 8) + ((unsigned long) a[ 7 ]); } - result->width = (unsigned int) in_width; - result->height = (unsigned int) in_height; + result->width = (unsigned int) in_width; + result->height = (unsigned int) in_height; + result->bits = 0; + result->channels = 0; return result; } @@ -134,8 +174,10 @@ php_stream_read(stream, temp, sizeof(temp)); php_stream_read(stream, (char*) &dim, sizeof(dim)); - result->width = dim.in_width; - result->height = dim.in_height; + result->width = dim.in_width; + result->height = dim.in_height; + result->bits = 0; + result->channels = 0; return result; } @@ -157,6 +199,80 @@ } /* }}} */ +#if HAVE_ZLIB +/* {{{ php_handle_swc + */ +static struct gfxinfo *php_handle_swc(php_stream * stream TSRMLS_DC) +{ + struct gfxinfo *result = NULL; + + long bits; + unsigned char a[64]; + unsigned long len=64, szlength; + int factor=1,maxfactor=16; + int slength, status=0; + char *b, *buf=NULL, *bufz=NULL; + + b = ecalloc (1, len + 1); + + result = (struct gfxinfo *) ecalloc (1, sizeof (struct gfxinfo)); + php_stream_seek(stream, 5, SEEK_CUR); + + php_stream_read(stream, a, sizeof(a)); /* fread(a, sizeof(a), 1, fp); */ + if (uncompress(b, &len, a, sizeof(a)) != Z_OK) { + /* failed to decompress the file, will try reading the rest of the file */ + php_stream_seek(stream, 8, SEEK_SET); + slength = php_stream_copy_to_mem(stream, &bufz, PHP_STREAM_COPY_ALL, 0); + + /* + * zlib::uncompress() wants to know the output data length + * if none was given as a parameter + * we try from input length * 2 up to input length * 2^8 + * doubling it whenever it wasn't big enough + * that should be eneugh for all real life cases + */ + + do { + szlength=slength*(1<<factor++); + buf = (char *) erealloc(buf,szlength); + if (!buf) { + status = 1; + break; + } + status = uncompress(buf, &szlength, bufz, slength); + } while ((status==Z_BUF_ERROR)&&(factor<maxfactor)); + + if (bufz) { + pefree(bufz, 0); + } + + if (status == Z_OK) { + memcpy(b, buf, len); + } + + if (buf) { + efree(buf); + } + } + + if (!status) { + bits = php_swf_get_bits (b, 0, 5); + result->width = (php_swf_get_bits (b, 5 + bits, bits) - + php_swf_get_bits (b, 5, bits)) / 20; + result->height = (php_swf_get_bits (b, 5 + (3 * bits), bits) - + php_swf_get_bits (b, 5 + (2 * bits), bits)) / 20; + } else { + result->width = result->height = 0; + } + + efree (b); + result->bits = 0; + result->channels = 0; + return result; +} +/* }}} */ +#endif + /* {{{ php_handle_swf */ static struct gfxinfo *php_handle_swf (php_stream * stream TSRMLS_DC) @@ -174,6 +290,8 @@ php_swf_get_bits (a, 5, bits)) / 20; result->height = (php_swf_get_bits (a, 5 + (3 * bits), bits) - php_swf_get_bits (a, 5 + (2 * bits), bits)) / 20; + result->bits = 0; + result->channels = 0; return result; } /* }}} */ @@ -286,7 +404,7 @@ { marker = 0xff; comment_correction--; - } else { + } else { last_marker = M_PSEUDO; /* stop skipping non 0xff for M_COM */ } } @@ -338,7 +456,7 @@ buffer = emalloc(length); if ( !buffer) return; - if (php_stream_read(stream, buffer, (long) length) <= 0) { + if (php_stream_read(stream, buffer, (long) length) <= 0) { efree(buffer); return; } @@ -515,8 +633,6 @@ #define TAG_FMT_SRATIONAL 10 #define TAG_FMT_SINGLE 11 #define TAG_FMT_DOUBLE 12 - -typedef unsigned char uchar; /* }}} */ /* {{{ php_ifd_get16u @@ -524,9 +640,9 @@ static int php_ifd_get16u(void *Short, int motorola_intel) { if (motorola_intel) { - return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1]; + return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1]; } else { - return (((uchar *)Short)[1] << 8) | ((uchar *)Short)[0]; + return (((unsigned char *)Short)[1] << 8) | ((unsigned char *)Short)[0]; } } /* }}} */ @@ -544,11 +660,11 @@ static int php_ifd_get32s(void *Long, int motorola_intel) { if (motorola_intel) { - return ((( char *)Long)[0] << 24) | (((uchar *)Long)[1] << 16) - | (((uchar *)Long)[2] << 8 ) | (((uchar *)Long)[3] << 0 ); + return ((( char *)Long)[0] << 24) | (((unsigned char *)Long)[1] << 16) + | (((unsigned char *)Long)[2] << 8 ) | (((unsigned char *)Long)[3] << 0 ); } else { - return ((( char *)Long)[3] << 24) | (((uchar *)Long)[2] << 16) - | (((uchar *)Long)[1] << 8 ) | (((uchar *)Long)[0] << 0 ); + return ((( char *)Long)[3] << 24) | (((unsigned char *)Long)[2] << 16) + | (((unsigned char *)Long)[1] << 8 ) | (((unsigned char *)Long)[0] << 0 ); } } /* }}} */ @@ -578,7 +694,7 @@ ifd_size = 2; ifd_data = emalloc(ifd_size); php_stream_read(stream, ifd_data, 2); - num_entries = php_ifd_get16u(ifd_data, motorola_intel); + num_entries = php_ifd_get16u(ifd_data, motorola_intel); dir_size = 2/*num dir entries*/ +12/*length of entry*/*num_entries +4/* offset to next ifd (points to thumbnail or NULL)*/; ifd_size = dir_size; ifd_data = erealloc(ifd_data,ifd_size); @@ -607,7 +723,7 @@ entry_value = php_ifd_get32s(dir_entry+8, motorola_intel); break; default: - continue; + continue; } switch(entry_tag) { case TAG_IMAGEWIDTH: @@ -624,14 +740,107 @@ if ( width && height) { /* not the same when in for-loop */ result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); - result->height = height; - result->width = width; + result->height = height; + result->width = width; + result->bits = 0; + result->channels = 0; return result; } return NULL; } /* }}} */ +/* {{{ php_handle_psd + */ +static struct gfxinfo *php_handle_iff(php_stream * stream TSRMLS_DC) +{ + struct gfxinfo *result = NULL; + unsigned char a[10]; + int chunkId; + int size; + + if (php_stream_read(stream, a, 8) != 8) + return NULL; + if (strncmp(a+4, "ILBM", 4) && strncmp(a+4, "PBM ", 4)) + return NULL; + + result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + + /* loop chunks to find BMHD chunk */ + do { + if (php_stream_read(stream, a, 8) != 8) { + efree(result); + return NULL; + } + chunkId = php_ifd_get32s(a+0, 1); + size = php_ifd_get32s(a+4, 1); + if ((size & 1) == 1) { + size++; + } + if (chunkId == 0x424d4844) { /* BMHD chunk */ + if (php_stream_read(stream, a, 9) != 9) { + efree(result); + return NULL; + } + result->width = php_ifd_get16s(a+0, 1); + result->height = php_ifd_get16s(a+2, 1); + result->bits = a[8] & 0xff; + result->channels = 0; + if (result->width > 0 && result->height > 0 && result->bits > 0 && result->bits < 33) + return result; + } else { + php_stream_seek(stream, size, SEEK_CUR); + } + } while (1); +} +/* }}} */ + +/* {{{ php_image_type_to_mime_type + * Convert internal image_type to mime type */ +PHPAPI const char * php_image_type_to_mime_type(int image_type) +{ + switch( image_type) { + case IMAGE_FILETYPE_GIF: + return "image/gif"; + case IMAGE_FILETYPE_JPEG: + case IMAGE_FILETYPE_JPC: + return "image/jpeg"; + case IMAGE_FILETYPE_PNG: + return "image/png"; + case IMAGE_FILETYPE_SWF: + case IMAGE_FILETYPE_SWC: + return "application/x-shockwave-flash"; + case IMAGE_FILETYPE_PSD: + return "image/psd"; + case IMAGE_FILETYPE_BMP: + return "image/bmp"; + case IMAGE_FILETYPE_TIFF_II: + case IMAGE_FILETYPE_TIFF_MM: + return "image/tiff"; + case IMAGE_FILETYPE_IFF: + return "image/iff"; + default: + case IMAGE_FILETYPE_UNKNOWN: + return "application/octet-stream"; /* suppose binary format */ + } +} +/* }}} */ + +/* {{{ proto array image_type_to_mime_type(int imagetype) + Get Mime-Type for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype */ +PHP_FUNCTION(image_type_to_mime_type) +{ + zval **p_image_type; + int arg_c = ZEND_NUM_ARGS(); + + if ((arg_c!=1) || zend_get_parameters_ex(arg_c, &p_image_type) == FAILURE) { + WRONG_PARAM_COUNT; + } + zval_dtor(*p_image_type); + ZVAL_STRING(return_value, (char*)php_image_type_to_mime_type(Z_LVAL_PP(p_image_type)), 1); +} +/* }}} */ + /* {{{ php_imagetype detect filetype from first bytes */ PHPAPI int php_getimagetype(php_stream * stream, char *filetype TSRMLS_DC) @@ -640,7 +849,7 @@ if ( !filetype) filetype = tmp; if((php_stream_read(stream, filetype, 3)) <= 0) { - php_error(E_WARNING, "getimagesize: Read error!"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!"); return IMAGE_FILETYPE_UNKNOWN; } @@ -653,27 +862,31 @@ if (!memcmp(filetype, php_sig_png, 8)) { return IMAGE_FILETYPE_PNG; } else { - php_error(E_WARNING, "PNG file corrupted by ASCII conversion"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "PNG file corrupted by ASCII conversion"); return IMAGE_FILETYPE_UNKNOWN; } } else if (!memcmp(filetype, php_sig_swf, 3)) { return IMAGE_FILETYPE_SWF; + } else if (!memcmp(filetype, php_sig_swc, 3)) { + return IMAGE_FILETYPE_SWC; } else if (!memcmp(filetype, php_sig_psd, 3)) { return IMAGE_FILETYPE_PSD; } else if (!memcmp(filetype, php_sig_bmp, 2)) { return IMAGE_FILETYPE_BMP; } else if (!memcmp(filetype, php_sig_jpc, 3)) { return IMAGE_FILETYPE_JPC; - } else { - php_stream_read(stream, filetype+3, 1); - if (!memcmp(filetype, php_sig_tif_ii, 4)) { - return IMAGE_FILETYPE_TIFF_II; - } else - if (!memcmp(filetype, php_sig_tif_mm, 4)) { - return IMAGE_FILETYPE_TIFF_MM; - } } - + php_stream_read(stream, filetype+3, 1); + if (!memcmp(filetype, php_sig_tif_ii, 4)) { + return IMAGE_FILETYPE_TIFF_II; + } else + if (!memcmp(filetype, php_sig_tif_mm, 4)) { + return IMAGE_FILETYPE_TIFF_MM; + } + if (!memcmp(filetype, php_sig_iff, 4)) { + return IMAGE_FILETYPE_IFF; + } + return IMAGE_FILETYPE_UNKNOWN; } /* }}} */ @@ -683,7 +896,7 @@ PHP_FUNCTION(getimagesize) { zval **arg1, **info = NULL; - int itype = 0; + int itype = 0; char temp[64]; struct gfxinfo *result = NULL; php_stream * stream = NULL; @@ -723,47 +936,54 @@ itype = php_getimagetype(stream, NULL TSRMLS_CC); switch( itype) { - case IMAGE_FILETYPE_GIF: + case IMAGE_FILETYPE_GIF: result = php_handle_gif (stream TSRMLS_CC); - break; - case IMAGE_FILETYPE_JPEG: + break; + case IMAGE_FILETYPE_JPEG: if (info) { result = php_handle_jpeg(stream, *info TSRMLS_CC); } else { result = php_handle_jpeg(stream, NULL TSRMLS_CC); } - break; - case IMAGE_FILETYPE_PNG: + break; + case IMAGE_FILETYPE_PNG: result = php_handle_png(stream TSRMLS_CC); - break; - case IMAGE_FILETYPE_SWF: + break; + case IMAGE_FILETYPE_SWF: result = php_handle_swf(stream TSRMLS_CC); - break; - case IMAGE_FILETYPE_PSD: + break; +#if HAVE_ZLIB + case IMAGE_FILETYPE_SWC: + result = php_handle_swc(stream TSRMLS_CC); + break; +#endif + case IMAGE_FILETYPE_PSD: result = php_handle_psd(stream TSRMLS_CC); - break; - case IMAGE_FILETYPE_BMP: + break; + case IMAGE_FILETYPE_BMP: result = php_handle_bmp(stream TSRMLS_CC); - break; - case IMAGE_FILETYPE_TIFF_II: + break; + case IMAGE_FILETYPE_TIFF_II: result = php_handle_tiff(stream, NULL, 0 TSRMLS_CC); - break; - case IMAGE_FILETYPE_TIFF_MM: + break; + case IMAGE_FILETYPE_TIFF_MM: result = php_handle_tiff(stream, NULL, 1 TSRMLS_CC); - break; - case IMAGE_FILETYPE_JPC: + break; + case IMAGE_FILETYPE_JPC: result = php_handle_jpc(stream TSRMLS_CC); - break; + break; + case IMAGE_FILETYPE_IFF: + result = php_handle_iff(stream TSRMLS_CC); default: - case IMAGE_FILETYPE_UNKNOWN: - break; + case IMAGE_FILETYPE_UNKNOWN: + break; } php_stream_close(stream); if (result) { if (array_init(return_value) == FAILURE) { - php_error(E_ERROR, "Unable to initialize array"); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to initialize array"); efree(result); return; } @@ -779,6 +999,7 @@ if (result->channels != 0) { add_assoc_long(return_value, "channels", result->channels); } + add_assoc_string(return_value, "mime", (char*)php_image_type_to_mime_type(itype), 1); efree(result); } else { RETURN_FALSE; 1.3 +6 -8 php4/ext/standard/incomplete_class.c Index: incomplete_class.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/incomplete_class.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- incomplete_class.c 29 Apr 2002 02:31:01 -0000 1.2 +++ incomplete_class.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -17,7 +17,7 @@ */ -/* $Id: incomplete_class.c,v 1.13 2001/12/11 15:30:32 sebastian Exp $ */ +/* $Id: incomplete_class.c,v 1.14 2002/07/24 09:55:11 yohgaki Exp $ */ #include "php.h" #include "basic_functions.h" @@ -30,12 +30,10 @@ "you are trying to operate on was loaded _before_ " \ "the session was started" -#define INCOMPLETE_CLASS "__PHP_Incomplete_Class" -#define MAGIC_MEMBER "__PHP_Incomplete_Class_Name" /* {{{ incomplete_class_message */ -static void incomplete_class_message(zend_property_reference *ref) +static void incomplete_class_message(zend_property_reference *ref, int error_type) { char buf[1024]; char *class_name; @@ -49,7 +47,7 @@ efree(class_name); - php_error(E_ERROR, "%s", buf); + php_error(error_type, "%s", buf); } /* }}} */ @@ -57,7 +55,7 @@ */ static void incomplete_class_call_func(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference) { - incomplete_class_message(property_reference); + incomplete_class_message(property_reference, E_ERROR); } /* }}} */ @@ -65,7 +63,7 @@ */ static int incomplete_class_set_property(zend_property_reference *property_reference, zval *value) { - incomplete_class_message(property_reference); + incomplete_class_message(property_reference, E_NOTICE); /* does not reach this point */ return (0); @@ -78,7 +76,7 @@ { zval foo; - incomplete_class_message(property_reference); + incomplete_class_message(property_reference, E_NOTICE); /* does not reach this point */ memset(&foo, 0, sizeof(zval)); /* shut warnings up */ 1.6 +432 -171 php4/ext/standard/info.c Index: info.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/info.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- info.c 2 Aug 2002 22:05:24 -0000 1.5 +++ info.c 6 Oct 2002 21:54:32 -0000 1.6 @@ -14,33 +14,52 @@ +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf <rasmu****@php*****> | | Zeev Suraski <zeev****@zend*****> | + | Colin Viebrock <colin****@easyd*****> | +----------------------------------------------------------------------+ */ -/* $Id: info.c,v 1.180 2002/05/13 17:43:04 zeev Exp $ */ +/* $Id: info.c,v 1.213 2002/10/05 10:58:55 wez Exp $ */ #include "php.h" #include "php_ini.h" #include "php_globals.h" #include "ext/standard/head.h" +#include "ext/standard/html.h" #include "info.h" #include "credits.h" +#include "css.h" #include "SAPI.h" #include <time.h> #include "php_main.h" -#if !defined(PHP_WIN32) +#if !defined(PHP_WIN32) && !defined(NETWARE) #include "build-defs.h" #endif #include "zend_globals.h" /* needs ELS */ #include "zend_extensions.h" -#include "zend_highlight.h" #ifdef HAVE_SYS_UTSNAME_H #include <sys/utsname.h> #endif -#define SECTION(name) PUTS("<h2 align=\"center\">" name "</h2>\n") +#if HAVE_MBSTRING +#include "ext/mbstring/php_mb.h" +ZEND_EXTERN_MODULE_GLOBALS(mbstring) +#endif + +#if HAVE_ICONV +#include "ext/iconv/php_iconv.h" +ZEND_EXTERN_MODULE_GLOBALS(iconv) +#endif + +#define SECTION(name) if (PG(html_errors)) { \ + PUTS("<h2>" name "</h2>\n"); \ + } else { \ + php_info_print_table_start(); \ + php_info_print_table_header(1, name); \ + php_info_print_table_end(); \ + } \ PHPAPI extern char *php_ini_opened_path; +PHPAPI extern char *php_ini_scanned_files; /* {{{ _display_module_info */ @@ -49,13 +68,24 @@ int show_info_func = *((int *) arg); if (show_info_func && module->info_func) { - php_printf("<h2 align=\"center\"><a name=\"module_%s\">%s</a></h2>\n", module->name, module->name); + if (PG(html_errors)) { + php_printf("<h2><a name=\"module_%s\">%s</a></h2>\n", module->name, module->name); + } else { + php_info_print_table_start(); + php_info_print_table_header(1, module->name); + php_info_print_table_end(); + } module->info_func(module TSRMLS_CC); } else if (!show_info_func && !module->info_func) { - php_printf("<tr valign=\"baseline\" bgcolor=\"" PHP_CONTENTS_COLOR "\">"); - php_printf("<td>"); - php_printf("%s", module->name); - php_printf("</td></tr>\n"); + if (PG(html_errors)) { + php_printf("<tr>"); + php_printf("<td>"); + php_printf("%s", module->name); + php_printf("</td></tr>\n"); + } else { + php_printf(module->name); + php_printf("\n"); + } } return 0; } @@ -74,33 +104,71 @@ && (Z_TYPE_PP(data)==IS_ARRAY)) { zend_hash_internal_pointer_reset(Z_ARRVAL_PP(data)); while (zend_hash_get_current_data(Z_ARRVAL_PP(data), (void **) &tmp) == SUCCESS) { - PUTS("<tr valign=\"baseline\" bgcolor=\"" PHP_CONTENTS_COLOR "\">"); - PUTS("<td bgcolor=\"" PHP_ENTRY_NAME_COLOR "\"><b>"); + if (PG(html_errors)) { + PUTS("<tr>"); + PUTS("<td class=\"e\">"); + + } + PUTS(name); PUTS("[\""); + switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(data), &string_key, &string_len, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: - zend_html_puts(string_key, string_len-1); + if (PG(html_errors)) { + PUTS(php_info_html_esc(string_key TSRMLS_CC)); + } else { + PUTS(string_key); + } break; case HASH_KEY_IS_LONG: php_printf("%ld", num_key); break; } - PUTS("\"]</b></td><td>"); + PUTS("\"]"); + if (PG(html_errors)) { + PUTS("</td><td class=\"v\">"); + } else { + PUTS(" => "); + } if (Z_TYPE_PP(tmp) == IS_ARRAY) { - PUTS("<pre>"); + if (PG(html_errors)) { + PUTS("<pre>"); + } zend_print_zval_r(*tmp, 0); - PUTS("</pre>"); + if (PG(html_errors)) { + PUTS("</pre>"); + } } else if (Z_TYPE_PP(tmp) != IS_STRING) { tmp2 = **tmp; zval_copy_ctor(&tmp2); convert_to_string(&tmp2); - zend_html_puts(Z_STRVAL(tmp2), Z_STRLEN(tmp2)); + if (PG(html_errors)) { + if (Z_STRLEN(tmp2) == 0) { + PUTS("<i>no value</i>"); + } else { + PUTS(php_info_html_esc(Z_STRVAL(tmp2) TSRMLS_CC)); + } + } else { + PUTS(Z_STRVAL(tmp2)); + } zval_dtor(&tmp2); } else { - zend_html_puts(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); + if (PG(html_errors)) { + if (Z_STRLEN_PP(tmp) == 0) { + PUTS("<i>no value</i>"); + } else { + PUTS(php_info_html_esc(Z_STRVAL_PP(tmp) TSRMLS_CC)); + } + } else { + PUTS(Z_STRVAL_PP(tmp)); + } } - PUTS(" </td></tr>\n"); + if (PG(html_errors)) { + PUTS("</td></tr>\n"); + } else { + PUTS("\n"); + } zend_hash_move_forward(Z_ARRVAL_PP(data)); } } @@ -112,16 +180,22 @@ void php_info_print_style(void) { php_printf("<style type=\"text/css\"><!--\n"); - php_printf("a { text-decoration: none; }\n"); - php_printf("a:hover { text-decoration: underline; }\n"); - php_printf("h1 { font-family: arial, helvetica, sans-serif; font-size: 18pt; font-weight: bold;}\n"); - php_printf("h2 { font-family: arial, helvetica, sans-serif; font-size: 14pt; font-weight: bold;}\n"); - php_printf("body, td { font-family: arial, helvetica, sans-serif; font-size: 10pt; }\n"); - php_printf("th { font-family: arial, helvetica, sans-serif; font-size: 11pt; font-weight: bold; }\n"); + php_info_print_css(); php_printf("//--></style>\n"); } /* }}} */ + +/* {{{ php_info_html_esc + */ +PHPAPI char *php_info_html_esc(char *string TSRMLS_DC) +{ + int new_len; + return php_escape_html_entities(string, strlen(string), &new_len, 1, ENT_COMPAT, NULL TSRMLS_CC); +} +/* }}} */ + + /* {{{ php_get_uname */ PHPAPI char *php_get_uname(char mode) @@ -134,71 +208,115 @@ DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); DWORD dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); - if (mode == 's') { - if (dwVersion < 0x80000000) { - php_uname = "Windows NT"; - } else { - php_uname = "Windows 9x"; - } - } else if (mode == 'r') { - snprintf(tmp_uname, sizeof(tmp_uname), "%d.%d", - dwWindowsMajorVersion, dwWindowsMinorVersion); - php_uname = tmp_uname; - } else if (mode == 'n') { - // XXX HOW TO GET THIS ON WINDOWS? - php_uname = "localhost"; - } else if (mode == 'v') { - dwBuild = (DWORD)(HIWORD(dwVersion)); - snprintf(tmp_uname, sizeof(tmp_uname), "build %d", dwBuild); - php_uname = tmp_uname; - } else if (mode == 'm') { - // XXX HOW TO GET THIS ON WINDOWS? - php_uname = "i386"; - } else { // assume mode == 'a' - /* Get build numbers for Windows NT or Win95 */ - if (dwVersion < 0x80000000){ - dwBuild = (DWORD)(HIWORD(dwVersion)); - snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d build %d", - "Windows NT", "localhost", - dwWindowsMajorVersion, dwWindowsMinorVersion, dwBuild); - } else { - snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d", - "Windows 9x", "localhost", - dwWindowsMajorVersion, dwWindowsMinorVersion); - } - php_uname = tmp_uname; - } + if (mode == 's') { + if (dwVersion < 0x80000000) { + php_uname = "Windows NT"; + } else { + php_uname = "Windows 9x"; + } + } else if (mode == 'r') { + snprintf(tmp_uname, sizeof(tmp_uname), "%d.%d", dwWindowsMajorVersion, dwWindowsMinorVersion); + php_uname = tmp_uname; + } else if (mode == 'n') { + /* XXX HOW TO GET THIS ON WINDOWS? */ + php_uname = "localhost"; + } else if (mode == 'v') { + dwBuild = (DWORD)(HIWORD(dwVersion)); + snprintf(tmp_uname, sizeof(tmp_uname), "build %d", dwBuild); + php_uname = tmp_uname; + } else if (mode == 'm') { + /* XXX HOW TO GET THIS ON WINDOWS? */ + php_uname = "i386"; + } else { /* assume mode == 'a' */ + /* Get build numbers for Windows NT or Win95 */ + if (dwVersion < 0x80000000){ + dwBuild = (DWORD)(HIWORD(dwVersion)); + snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d build %d", + "Windows NT", "localhost", + dwWindowsMajorVersion, dwWindowsMinorVersion, dwBuild); + } else { + snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d", + "Windows 9x", "localhost", + dwWindowsMajorVersion, dwWindowsMinorVersion); + } + php_uname = tmp_uname; + } #else #ifdef HAVE_SYS_UTSNAME_H - struct utsname buf; - if (uname((struct utsname *)&buf) == -1) { - php_uname = PHP_UNAME; - } else { - if (mode == 's') { - php_uname = buf.sysname; - } else if (mode == 'r') { - php_uname = buf.release; - } else if (mode == 'n') { - php_uname = buf.nodename; - } else if (mode == 'v') { - php_uname = buf.version; - } else if (mode == 'm') { - php_uname = buf.machine; - } else { // assume mode == 'a' - snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %s %s %s", - buf.sysname, buf.nodename, buf.release, buf.version, - buf.machine); - php_uname = tmp_uname; - } - } + struct utsname buf; + if (uname((struct utsname *)&buf) == -1) { + php_uname = PHP_UNAME; + } else { + if (mode == 's') { + php_uname = buf.sysname; + } else if (mode == 'r') { + php_uname = buf.release; + } else if (mode == 'n') { + php_uname = buf.nodename; + } else if (mode == 'v') { + php_uname = buf.version; + } else if (mode == 'm') { + php_uname = buf.machine; + } else { /* assume mode == 'a' */ + snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %s %s %s", + buf.sysname, buf.nodename, buf.release, buf.version, + buf.machine); + php_uname = tmp_uname; + } + } #else - php_uname = PHP_UNAME; + php_uname = PHP_UNAME; #endif #endif return estrdup(php_uname); } /* }}} */ + +/* {{{ php_print_info_htmlhead + */ +PHPAPI void php_print_info_htmlhead(TSRMLS_D) +{ + const char *charset = NULL; + + if (SG(default_charset)) { + charset = SG(default_charset); + } + +#if HAVE_MBSTRING + if (php_ob_handler_used("mb_output_handler" TSRMLS_CC)) { + if ( !PHP_MB_IS_VALID_ENCODING(MBSTRG(internal_encoding_r)) + || MBSTRG(internal_encoding_r)->id == php_mb_encid_pass + || MBSTRG(internal_encoding_r)->mime_name == NULL ) { + charset = "US-ASCII"; + } else { + charset = MBSTRG(internal_encoding_r)->mime_name; + } + } +#endif + +#if HAVE_ICONV + if (php_ob_handler_used("ob_iconv_handler" TSRMLS_CC)) { + charset = ICONVG(output_encoding); + } +#endif + + if (!charset || !charset[0]) { + charset = "US-ASCII"; + } + + PUTS("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/xhtml1-transitional.dtd\">\n"); + PUTS("<html>"); + PUTS("<head>\n"); + php_info_print_style(); + PUTS("<title>phpinfo()</title>"); + php_printf("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\" />\n", charset); + PUTS("</head>\n"); + PUTS("<body><center>\n"); +} +/* }}} */ + + /* {{{ php_print_info */ PHPAPI void php_print_info(int flag TSRMLS_DC) @@ -208,40 +326,43 @@ int expose_php = INI_INT("expose_php"); time_t the_time; struct tm *ta, tmbuf; - char php_api_no[9]; - char mod_api_no[9]; - char ext_api_no[9]; the_time = time(NULL); ta = php_localtime_r(&the_time, &tmbuf); - snprintf (php_api_no, 9, "%d", PHP_API_VERSION); - snprintf (mod_api_no, 9, "%d", ZEND_MODULE_API_NO); - snprintf (ext_api_no, 9, "%d", ZEND_EXTENSION_API_NO); - - PUTS("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html>\n"); + if (PG(html_errors)) { + php_print_info_htmlhead(TSRMLS_C); + } else { + PUTS("phpinfo()\n"); + } if (flag & PHP_INFO_GENERAL) { char *zend_version = get_zend_version(); + char temp_api[9]; php_uname = php_get_uname('a'); - PUTS("<head>"); - php_info_print_style(); - PUTS("<title>phpinfo()</title></head><body>"); - - php_info_print_box_start(1); - if (expose_php) { - PUTS("<a href=\"http://www.php.net/\"><img src=\""); + + if (PG(html_errors)) { + php_info_print_box_start(1); + } + + if (expose_php && PG(html_errors)) { + PUTS("<a href=\"http://www.php.net/\"><img border=\"0\" src=\""); if (SG(request_info).request_uri) { PUTS(SG(request_info).request_uri); } if ((ta->tm_mon==3) && (ta->tm_mday==1)) { - PUTS("?="PHP_EGG_LOGO_GUID"\" border=0 align=\"right\" alt=\"Thies!\"></a>"); + PUTS("?="PHP_EGG_LOGO_GUID"\" alt=\"Thies!\" /></a>"); } else { - PUTS("?="PHP_LOGO_GUID"\" border=0 align=\"right\" alt=\"PHP Logo\"></a>"); + PUTS("?="PHP_LOGO_GUID"\" alt=\"PHP Logo\" /></a>"); } } - php_printf("<h1>PHP Version %s</h1>\n", PHP_VERSION); + + if (PG(html_errors)) { + php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION); + } else { + php_info_print_table_row(2, "PHP Version", PHP_VERSION); + } php_info_print_box_end(); php_info_print_table_start(); php_info_print_table_row(2, "System", php_uname ); @@ -261,9 +382,21 @@ php_info_print_table_row(2, "Configuration File (php.ini) Path", php_ini_opened_path?php_ini_opened_path:PHP_CONFIG_FILE_PATH); - php_info_print_table_row(2, "PHP API No.", php_api_no); - php_info_print_table_row(2, "PHP Extensions API No.", mod_api_no); - php_info_print_table_row(2, "Zend Extensions API No.", ext_api_no); + if(strlen(PHP_CONFIG_FILE_SCAN_DIR)) { + php_info_print_table_row(2, "Scan this dir for additional .ini files", PHP_CONFIG_FILE_SCAN_DIR); + if(php_ini_scanned_files) { + php_info_print_table_row(2, "additional .ini files parsed", php_ini_scanned_files); + } + } + + snprintf(temp_api, sizeof(temp_api), "%d", PHP_API_VERSION); + php_info_print_table_row(2, "PHP API", temp_api); + + snprintf(temp_api, sizeof(temp_api), "%d", ZEND_MODULE_API_NO); + php_info_print_table_row(2, "PHP Extension", temp_api); + + snprintf(temp_api, sizeof(temp_api), "%d", ZEND_EXTENSION_API_NO); + php_info_print_table_row(2, "Zend Extension", temp_api); #if ZEND_DEBUG php_info_print_table_row(2, "Debug Build", "yes" ); @@ -277,33 +410,65 @@ php_info_print_table_row(2, "Thread Safety", "disabled" ); #endif - php_info_print_table_row(2, "PHP Streams", "enabled"); + { + HashTable *url_stream_wrappers_hash; + char *stream_protocol, *stream_protocols_buf = NULL; + int stream_protocol_len, stream_protocols_buf_len = 0; + + if ((url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash())) { + for (zend_hash_internal_pointer_reset(url_stream_wrappers_hash); + zend_hash_get_current_key_ex(url_stream_wrappers_hash, &stream_protocol, &stream_protocol_len, NULL, 0, NULL) == HASH_KEY_IS_STRING; + zend_hash_move_forward(url_stream_wrappers_hash)) { + if (NULL == (stream_protocols_buf = erealloc(stream_protocols_buf, + stream_protocols_buf_len + stream_protocol_len + 2 /* ", " */ + 1 /* 0 byte at end */))) { + break; + } + memcpy(stream_protocols_buf + stream_protocols_buf_len, stream_protocol, stream_protocol_len); + stream_protocols_buf[stream_protocols_buf_len + stream_protocol_len] = ','; + stream_protocols_buf[stream_protocols_buf_len + stream_protocol_len + 1] = ' '; + stream_protocols_buf_len += stream_protocol_len + 2; + } + if (stream_protocols_buf) { + stream_protocols_buf[stream_protocols_buf_len - 2] = ' '; + stream_protocols_buf[stream_protocols_buf_len] = 0; + php_info_print_table_row(2, "Registered PHP Streams", stream_protocols_buf); + efree(stream_protocols_buf); + } else { + /* Any chances we will ever hit this? */ + php_info_print_table_row(2, "Registered PHP Streams", "no streams registered"); + } + } else { + /* Any chances we will ever hit this? */ + php_info_print_table_row(2, "PHP Streams", "disabled"); /* ?? */ + } + } php_info_print_table_end(); /* Zend Engine */ php_info_print_box_start(0); - if (expose_php) { - PUTS("<a href=\"http://www.zend.com/\"><img src=\""); + if (expose_php && PG(html_errors)) { + PUTS("<a href=\"http://www.zend.com/\"><img border=\"0\" src=\""); if (SG(request_info).request_uri) { PUTS(SG(request_info).request_uri); } - PUTS("?="ZEND_LOGO_GUID"\" border=\"0\" align=\"right\" alt=\"Zend logo\"></a>\n"); + PUTS("?="ZEND_LOGO_GUID"\" alt=\"Zend logo\" /></a>\n"); } - php_printf("This program makes use of the Zend Scripting Language Engine:<br />"); - zend_html_puts(zend_version, strlen(zend_version)); + PUTS("This program makes use of the Zend Scripting Language Engine:"); + PUTS(PG(html_errors)?"<br />":"\n"); + PUTS(zend_version); php_info_print_box_end(); efree(php_uname); } - if ((flag & PHP_INFO_CREDITS) && expose_php) { + if ((flag & PHP_INFO_CREDITS) && expose_php && PG(html_errors)) { php_info_print_hr(); - PUTS("<h1 align=\"center\"><a href=\""); + PUTS("<h1><a href=\""); if (SG(request_info).request_uri) { PUTS(SG(request_info).request_uri); } PUTS("?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000\">"); - PUTS("PHP 4 Credits"); + PUTS("PHP Credits"); PUTS("</a></h1>\n"); } @@ -311,8 +476,12 @@ if (flag & PHP_INFO_CONFIGURATION) { php_info_print_hr(); - PUTS("<h1 align=\"center\">Configuration</h1>\n"); - SECTION("PHP Core\n"); + if (PG(html_errors)) { + PUTS("<h1>Configuration</h1>\n"); + } else { + SECTION("Configuration"); + } + SECTION("PHP Core"); display_ini_entries(NULL); } @@ -324,6 +493,7 @@ SECTION("Additional Modules"); php_info_print_table_start(); + php_info_print_table_header(1, "Module Name"); show_info_func = 0; zend_hash_apply_with_argument(&module_registry, (apply_func_arg_t) _display_module_info, &show_info_func TSRMLS_CC); php_info_print_table_end(); @@ -377,65 +547,117 @@ } if (flag & PHP_INFO_LICENSE) { - SECTION("PHP License"); - php_info_print_box_start(0); - PUTS("<p>\n"); - PUTS("This program is free software; you can redistribute it and/or modify "); - PUTS("it under the terms of the PHP License as published by the PHP Group "); - PUTS("and included in the distribution in the file: LICENSE\n"); - PUTS("</p>\n"); - PUTS("<p>"); - PUTS("This program is distributed in the hope that it will be useful, "); - PUTS("but WITHOUT ANY WARRANTY; without even the implied warranty of "); - PUTS("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); - PUTS("</p>\n"); - PUTS("<p>"); - PUTS("If you did not receive a copy of the PHP license, or have any questions about "); - PUTS("PHP licensing, please contact licen****@php*****.\n"); - PUTS("</p>\n"); - php_info_print_box_end(); - } - - PUTS("</body></html>"); + if (PG(html_errors)) { + SECTION("PHP License"); + php_info_print_box_start(0); + PUTS("<p>\n"); + PUTS("This program is free software; you can redistribute it and/or modify "); + PUTS("it under the terms of the PHP License as published by the PHP Group "); + PUTS("and included in the distribution in the file: LICENSE\n"); + PUTS("</p>\n"); + PUTS("<p>"); + PUTS("This program is distributed in the hope that it will be useful, "); + PUTS("but WITHOUT ANY WARRANTY; without even the implied warranty of "); + PUTS("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + PUTS("</p>\n"); + PUTS("<p>"); + PUTS("If you did not receive a copy of the PHP license, or have any questions about "); + PUTS("PHP licensing, please contact licen****@php*****.\n"); + PUTS("</p>\n"); + php_info_print_box_end(); + } else { + PUTS("\nPHP License\n"); + PUTS("This program is free software; you can redistribute it and/or modify\n"); + PUTS("it under the terms of the PHP License as published by the PHP Group\n"); + PUTS("and included in the distribution in the file: LICENSE\n"); + PUTS("\n"); + PUTS("This program is distributed in the hope that it will be useful,\n"); + PUTS("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); + PUTS("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + PUTS("\n"); + PUTS("If you did not receive a copy of the PHP license, or have any\n"); + PUTS("questions about PHP licensing, please contact licen****@php*****.\n"); + } + } + if (PG(html_errors)) { + PUTS("</center></body></html>"); + } } /* }}} */ PHPAPI void php_info_print_table_start() { - php_printf("<table border=\"0\" cellpadding=\"3\" cellspacing=\"1\" width=\"600\" bgcolor=\"#000000\" align=\"center\">\n"); + TSRMLS_FETCH(); + + if (PG(html_errors)) { + php_printf("<table border=\"0\" cellpadding=\"3\" width=\"600\">\n"); + } else { + php_printf("\n"); + } } PHPAPI void php_info_print_table_end() { - php_printf("</table><br />\n"); + TSRMLS_FETCH(); + + if (PG(html_errors)) { + php_printf("</table><br />\n"); + } } PHPAPI void php_info_print_box_start(int flag) { + TSRMLS_FETCH(); + php_info_print_table_start(); if (flag) { - php_printf("<tr valign=\"middle\" bgcolor=\"" PHP_HEADER_COLOR "\"><td align=\"left\">\n"); + if (PG(html_errors)) { + php_printf("<tr class=\"h\"><td>\n"); + } } else { - php_printf("<tr valign=\"top\" bgcolor=\"" PHP_CONTENTS_COLOR "\"><td align=\"left\">\n"); + if (PG(html_errors)) { + php_printf("<tr class=\"v\"><td>\n"); + } else { + php_printf("\n"); + } } } PHPAPI void php_info_print_box_end() { - php_printf("</td></tr>\n"); + TSRMLS_FETCH(); + + if (PG(html_errors)) { + php_printf("</td></tr>\n"); + } php_info_print_table_end(); } PHPAPI void php_info_print_hr() { - php_printf("<hr noshade size=\"1\" width=\"600\">\n"); + TSRMLS_FETCH(); + + if (PG(html_errors)) { + php_printf("<hr />\n"); + } else { + php_printf("\n\n _______________________________________________________________________\n\n"); + } } PHPAPI void php_info_print_table_colspan_header(int num_cols, char *header) { - php_printf("<tr bgcolor=\"" PHP_HEADER_COLOR "\"><th colspan=\"%d\">%s</th></tr>\n", num_cols, header ); + int spaces; + + TSRMLS_FETCH(); + + if (PG(html_errors)) { + php_printf("<tr class=\"h\"><th colspan=\"%d\">%s</th></tr>\n", num_cols, header ); + } else { + spaces = (74 - strlen(header)); + php_printf("%*s%s%*s\n", (int)(spaces/2), " ", header, (int)(spaces/2), " "); + } } /* {{{ php_info_print_table_header @@ -446,17 +668,33 @@ va_list row_elements; char *row_element; - va_start(row_elements, num_cols); + TSRMLS_FETCH(); - php_printf("<tr valign=\"middle\" bgcolor=\"" PHP_HEADER_COLOR "\">"); + va_start(row_elements, num_cols); + if (PG(html_errors)) { + php_printf("<tr class=\"h\">"); + } for (i=0; i<num_cols; i++) { row_element = va_arg(row_elements, char *); if (!row_element || !*row_element) { - row_element = " "; + row_element = " "; } - php_printf("<th>%s</th>", row_element); - } - php_printf("</tr>\n"); + if (PG(html_errors)) { + PUTS("<th>"); + PUTS(row_element); + PUTS("</th>"); + } else { + PUTS(row_element); + if (i < num_cols-1) { + PUTS(" => "); + } else { + PUTS("\n"); + } + } + } + if (PG(html_errors)) { + php_printf("</tr>\n"); + } va_end(row_elements); } @@ -469,27 +707,50 @@ int i; va_list row_elements; char *row_element; +/* + char *elem_esc; + int elem_esc_len; +*/ + TSRMLS_FETCH(); va_start(row_elements, num_cols); - - php_printf("<tr valign=\"baseline\" bgcolor=\"" PHP_CONTENTS_COLOR "\">"); + if (PG(html_errors)) { + php_printf("<tr>"); + } for (i=0; i<num_cols; i++) { - php_printf("<td %s>%s", - (i==0?"bgcolor=\"" PHP_ENTRY_NAME_COLOR "\" ":"align=\"left\""), - (i==0?"<b>":"")); - + if (PG(html_errors)) { + php_printf("<td class=\"%s\">", + (i==0 ? "e" : "v" ) + ); + } row_element = va_arg(row_elements, char *); if (!row_element || !*row_element) { - php_printf(" "); + if (PG(html_errors)) { + PUTS( "<i>no value</i>" ); + } else { + PUTS( " " ); + } } else { - zend_html_puts(row_element, strlen(row_element)); + if (PG(html_errors)) { + PUTS(php_info_html_esc(row_element TSRMLS_CC)); + } else { + PUTS(row_element); + if (i < num_cols-1) { + PUTS(" => "); + } else { + PUTS("\n"); + } + } } - - php_printf("%s</td>", (i==0?"</b>":"")); + if (PG(html_errors)) { + php_printf(" </td>"); + } } - php_printf("</tr>\n"); - + if (PG(html_errors)) { + php_printf("</tr>\n"); + } + va_end(row_elements); } /* }}} */ @@ -546,22 +807,22 @@ Return the current PHP version */ PHP_FUNCTION(phpversion) { - zval **arg; - int argc = ZEND_NUM_ARGS(); + zval **arg; + int argc = ZEND_NUM_ARGS(); if (argc == 0) { - RETURN_STRING(PHP_VERSION, 1); + RETURN_STRING(PHP_VERSION, 1); } else if (argc == 1 && zend_get_parameters_ex(1, &arg) == SUCCESS) { - char *version; - convert_to_string_ex(arg); - version = zend_get_module_version(Z_STRVAL_PP(arg)); - if (version == NULL) { - RETURN_FALSE; - } - RETURN_STRING(version, 1); - } else { + char *version; + convert_to_string_ex(arg); + version = zend_get_module_version(Z_STRVAL_PP(arg)); + if (version == NULL) { + RETURN_FALSE; + } + RETURN_STRING(version, 1); + } else { WRONG_PARAM_COUNT; - } + } } /* }}} */ @@ -642,8 +903,8 @@ Return information about the system PHP was built on */ PHP_FUNCTION(php_uname) { - char *mode = "a"; - int modelen; + char *mode = "a"; + int modelen; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &mode, &modelen) == FAILURE) { return; } 1.3 +3 -1 php4/ext/standard/info.h Index: info.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/info.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- info.h 29 Apr 2002 02:31:01 -0000 1.2 +++ info.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: info.h,v 1.26 2002/02/28 08:26:46 sebastian Exp $ */ +/* $Id: info.h,v 1.28 2002/09/26 19:48:56 sebastian Exp $ */ #ifndef INFO_H #define INFO_H @@ -63,6 +63,8 @@ PHP_FUNCTION(php_egg_logo_guid); PHP_FUNCTION(php_sapi_name); PHP_FUNCTION(php_uname); +PHPAPI char *php_info_html_esc(char *string TSRMLS_DC); +PHPAPI void php_print_info_htmlhead(TSRMLS_D); PHPAPI void php_print_info(int flag TSRMLS_DC); PHPAPI void php_print_style(void); PHPAPI void php_info_print_style(void); 1.4 +4 -4 php4/ext/standard/iptc.c Index: iptc.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/iptc.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- iptc.c 9 May 2002 05:39:43 -0000 1.3 +++ iptc.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: iptc.c,v 1.39 2002/05/04 17:41:51 sas Exp $ */ +/* $Id: iptc.c,v 1.41 2002/08/24 01:19:28 helly Exp $ */ /* * Functions to parse & compse IPTC data. @@ -213,7 +213,7 @@ } if ((fp = VCWD_FOPEN(Z_STRVAL_PP(jpeg_file), "rb")) == 0) { - php_error(E_WARNING, "Unable to open %s", Z_STRVAL_PP(jpeg_file)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open %s", Z_STRVAL_PP(jpeg_file)); RETURN_FALSE; } @@ -354,7 +354,7 @@ if (tagsfound == 0) { /* found the 1st tag - initialize the return array */ if (array_init(return_value) == FAILURE) { - php_error(E_ERROR, "Unable to initialize array"); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to initialize array"); RETURN_FALSE; } } @@ -363,7 +363,7 @@ ALLOC_ZVAL(values); INIT_PZVAL(values); if (array_init(values) == FAILURE) { - php_error(E_ERROR, "Unable to initialize array"); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to initialize array"); RETURN_FALSE; } 1.3 +7 -1 php4/ext/standard/lcg.c Index: lcg.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/lcg.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- lcg.c 29 Apr 2002 02:31:02 -0000 1.2 +++ lcg.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: lcg.c,v 1.32 2002/02/28 08:26:46 sebastian Exp $ */ +/* $Id: lcg.c,v 1.33 2002/09/06 07:27:27 hyanantha Exp $ */ #include "php.h" #include "php_lcg.h" @@ -27,6 +27,12 @@ #ifdef PHP_WIN32 #include "win32/time.h" +#elif defined(NETWARE) +#ifdef NEW_LIBC +#include <sys/timeval.h> +#else +#include "netware/time_nw.h" +#endif #else #include <sys/time.h> #endif 1.3 +2 -2 php4/ext/standard/levenshtein.c Index: levenshtein.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/levenshtein.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- levenshtein.c 29 Apr 2002 02:31:02 -0000 1.2 +++ levenshtein.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -15,7 +15,7 @@ | Author: Hartmut Holzgraefe <hartm****@six*****> | +----------------------------------------------------------------------+ */ -/* $Id: levenshtein.c,v 1.23 2002/04/07 19:46:45 hholzgra Exp $ */ +/* $Id: levenshtein.c,v 1.25 2002/08/24 01:19:28 helly Exp $ */ #include "php.h" #include <stdlib.h> @@ -138,7 +138,7 @@ } if(distance<0) { - php_error(E_WARNING, "levenshtein(): argument string(s) too long"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument string(s) too long"); } RETURN_LONG(distance); 1.3 +31 -1 php4/ext/standard/link.c Index: link.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/link.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- link.c 29 Apr 2002 02:31:02 -0000 1.2 +++ link.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: link.c,v 1.37 2002/02/28 08:26:46 sebastian Exp $ */ +/* $Id: link.c,v 1.40 2002/09/06 07:30:51 derick Exp $ */ #include "php.h" #include "php_filestat.h" @@ -33,6 +33,8 @@ #if HAVE_PWD_H #ifdef PHP_WIN32 #include "win32/pwd.h" +#elif defined(NETWARE) +#include "netware/pwd.h" #else #include <pwd.h> #endif @@ -79,7 +81,11 @@ PHP_FUNCTION(linkinfo) { zval **filename; +#if defined(NETWARE) && defined(CLIB_STAT_PATCH) + struct stat_libc sb; +#else struct stat sb; +#endif int ret; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) { @@ -114,6 +120,18 @@ RETURN_FALSE; } + if (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(frompath), NULL, CHECKUID_CHECK_FILE_AND_DIR)) { + RETURN_FALSE; + } + + if (php_check_open_basedir(Z_STRVAL_PP(topath) TSRMLS_CC)) { + RETURN_FALSE; + } + + if (php_check_open_basedir(Z_STRVAL_PP(frompath) TSRMLS_CC)) { + RETURN_FALSE; + } + if (!strncasecmp(Z_STRVAL_PP(topath), "http://", 7) || !strncasecmp(Z_STRVAL_PP(topath), "ftp://", 6)) { php_error(E_WARNING, "Unable to symlink to a URL"); RETURN_FALSE; @@ -143,6 +161,18 @@ convert_to_string_ex(frompath); if (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(topath), NULL, CHECKUID_CHECK_FILE_AND_DIR)) { + RETURN_FALSE; + } + + if (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(frompath), NULL, CHECKUID_CHECK_FILE_AND_DIR)) { + RETURN_FALSE; + } + + if (php_check_open_basedir(Z_STRVAL_PP(topath) TSRMLS_CC)) { + RETURN_FALSE; + } + + if (php_check_open_basedir(Z_STRVAL_PP(frompath) TSRMLS_CC)) { RETURN_FALSE; } 1.4 +61 -31 php4/ext/standard/mail.c Index: mail.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/mail.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- mail.c 2 Aug 2002 22:05:24 -0000 1.3 +++ mail.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -16,14 +16,14 @@ +----------------------------------------------------------------------+ */ -/* $Id: mail.c,v 1.52 2002/05/14 20:43:48 mfischer Exp $ */ +/* $Id: mail.c,v 1.65 2002/09/22 16:23:44 derick Exp $ */ #include <stdlib.h> #include <ctype.h> #include <stdio.h> #include "php.h" #include "ext/standard/info.h" -#if !defined(PHP_WIN32) +#if !defined(PHP_WIN32) && !defined(NETWARE) #include "build-defs.h" #if HAVE_SYSEXITS_H #include <sysexits.h> @@ -42,11 +42,16 @@ #include "win32/sendmail.h" #endif +#ifdef NETWARE +#include "netware/pipe.h" /* For popen(), pclose() */ +#include "netware/sysexits.h" /* For exit status codes like EX_OK */ +#endif + /* {{{ proto int ezmlm_hash(string addr) Calculate EZMLM list hash value. */ PHP_FUNCTION(ezmlm_hash) { - char *str=NULL; + char *str = NULL; unsigned long h = 5381L; int j, str_len; @@ -55,11 +60,11 @@ return; } - for (j=0; j<str_len; j++) { - h = (h + (h<<5)) ^ (unsigned long) (unsigned char) tolower(str[j]); + for (j = 0; j < str_len; j++) { + h = (h + (h << 5)) ^ (unsigned long) (unsigned char) tolower(str[j]); } - h = (h%53); + h = (h % 53); RETURN_LONG((int) h); } @@ -69,9 +74,15 @@ Send an email message */ PHP_FUNCTION(mail) { - char *to=NULL, *message=NULL, *headers=NULL, *subject=NULL, *extra_cmd=NULL; - int to_len,message_len,headers_len,subject_len,extra_cmd_len; - + char *to=NULL, *message=NULL, *headers=NULL; + char *subject=NULL, *extra_cmd=NULL; + int to_len, message_len, headers_len; + int subject_len, extra_cmd_len, i; + + if (PG(safe_mode) && (ZEND_NUM_ARGS() == 5)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect. The fifth parameter is disabled in SAFE MODE."); + RETURN_FALSE; + } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss", &to, &to_len, @@ -83,18 +94,37 @@ return; } - for(to_len--;to_len;to_len--) { - if(!isspace(to[to_len]))break; - to[to_len]='\0'; + if (to_len > 0) { + for (; to_len; to_len--) { + if (!isspace((unsigned char) to[to_len - 1])) { + break; + } + to[to_len - 1] = '\0'; + } + for (i = 0; to[i]; i++) { + if (iscntrl((unsigned char) to[i])) { + to[i] = ' '; + } + } } - for(subject_len--;subject_len;subject_len--) { - if(!isspace(subject[subject_len]))break; - subject[subject_len]='\0'; + if (subject_len > 0) { + for (; subject_len; subject_len--) { + if (!isspace((unsigned char) subject[subject_len - 1])) { + break; + } + subject[subject_len - 1] = '\0'; + } + for(i = 0; subject[i]; i++) { + if (iscntrl((unsigned char) subject[i])) { + subject[i] = ' '; + } + } } - if(extra_cmd) - extra_cmd = php_escape_shell_arg(extra_cmd); + if (extra_cmd) { + extra_cmd = php_escape_shell_cmd(extra_cmd); + } if (php_mail(to, subject, message, headers, extra_cmd TSRMLS_CC)) { RETVAL_TRUE; @@ -102,7 +132,9 @@ RETVAL_FALSE; } - if (extra_cmd) efree (extra_cmd); + if (extra_cmd) { + efree (extra_cmd); + } } /* }}} */ @@ -110,8 +142,8 @@ */ PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd TSRMLS_DC) { -#ifdef PHP_WIN32 - int tsm_err; +#if (defined PHP_WIN32 || defined NETWARE) + int tsm_err; char *tsm_errmsg = NULL; #endif FILE *sendmail; @@ -120,16 +152,16 @@ char *sendmail_cmd = NULL; if (!sendmail_path) { -#ifdef PHP_WIN32 +#if (defined PHP_WIN32 || defined NETWARE) /* handle old style win smtp sending */ - if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, headers, subject, to, message) == FAILURE) { - if (tsm_errmsg) { - php_error(E_WARNING, "%s() %s", get_active_function_name(TSRMLS_C), tsm_errmsg); - efree(tsm_errmsg); + if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, headers, subject, to, message, NULL, NULL, NULL) == FAILURE) { + if (tsm_errmsg) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", tsm_errmsg); + efree(tsm_errmsg); } else { - php_error(E_WARNING, "%s() %s", get_active_function_name(TSRMLS_C), GetSMErrorText(tsm_err)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", GetSMErrorText(tsm_err)); } - return 0; + return 0; } return 1; #else @@ -160,8 +192,7 @@ if (sendmail) { #ifndef PHP_WIN32 if (EACCES == errno) { - php_error(E_WARNING, "%s() permission denied; unable to execute shell to run mail delivery binary", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Permission denied: unable to execute shell to run mail delivery binary"); pclose(sendmail); return 0; } @@ -188,8 +219,7 @@ return 1; } } else { - php_error(E_WARNING, "%s() could not execute mail delivery program", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute mail delivery program"); return 0; } 1.3 +35 -20 php4/ext/standard/math.c Index: math.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/math.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- math.c 29 Apr 2002 02:31:02 -0000 1.2 +++ math.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: math.c,v 1.83 2002/04/01 09:19:57 derick Exp $ */ +/* $Id: math.c,v 1.89 2002/10/04 02:21:33 sas Exp $ */ #include "php.h" #include "php_math.h" @@ -314,7 +314,7 @@ /* }}} */ -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(NETWARE) /* {{{ proto float asinh(float number) Returns the inverse hyperbolic sine of the number, i.e. the value whose hyperbolic sine is number */ @@ -471,7 +471,7 @@ /* }}} */ -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(NETWARE) /* {{{ proto float expm1(float number) Returns exp(number) - 1, computed in a way that accurate even when the value of number is close to zero */ @@ -670,11 +670,13 @@ */ PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret) { - long num = 0, digit, onum; + long num = 0; double fnum; int i; int mode = 0; char c, *s; + unsigned long cutoff; + int cutlim; if (Z_TYPE_P(arg) != IS_STRING || base < 2 || base > 36) { return FAILURE; @@ -682,30 +684,37 @@ s = Z_STRVAL_P(arg); + cutoff = LONG_MAX / base; + cutlim = LONG_MAX % base; + for (i = Z_STRLEN_P(arg); i > 0; i--) { c = *s++; - digit = (c >= '0' && c <= '9') ? c - '0' - : (c >= 'A' && c <= 'Z') ? c - 'A' + 10 - : (c >= 'a' && c <= 'z') ? c - 'a' + 10 - : base; + /* might not work for EBCDIC */ + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + continue; - if (digit >= base) + if (c >= base) continue; switch (mode) { case 0: /* Integer */ - onum = num; - num = num * base + digit; - - if (num > onum) - break; /* No overflow, continue */ - - fnum = onum; - mode = 1; + if (num < cutoff || (num == cutoff && c <= cutlim)) { + num = num * base + c; + break; + } else { + fnum = num; + mode = 1; + } /* fall-through */ case 1: /* Float */ - fnum = fnum * base + digit; + fnum = fnum * base + c; } } @@ -757,7 +766,7 @@ * the number. */ PHPAPI char * -_php_math_zvaltobase(zval *arg, int base) +_php_math_zvaltobase(zval *arg, int base TSRMLS_DC) { static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; @@ -770,6 +779,12 @@ char *ptr, *end; char buf[(sizeof(double) << 3) + 1]; + /* Don't try to convert +/- infinity */ + if (fvalue == HUGE_VAL || fvalue == -HUGE_VAL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number too large"); + return empty_string; + } + end = ptr = buf + sizeof(buf) - 1; *ptr = '\0'; @@ -930,7 +945,7 @@ if(_php_math_basetozval(*number, Z_LVAL_PP(frombase), &temp) != SUCCESS) { RETURN_FALSE; } - result = _php_math_zvaltobase(&temp, Z_LVAL_PP(tobase)); + result = _php_math_zvaltobase(&temp, Z_LVAL_PP(tobase) TSRMLS_CC); RETVAL_STRING(result, 0); } 1.3 +2 -2 php4/ext/standard/md5.c Index: md5.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/md5.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- md5.c 29 Apr 2002 02:31:02 -0000 1.2 +++ md5.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: md5.c,v 1.26 2002/02/28 08:26:46 sebastian Exp $ */ +/* $Id: md5.c,v 1.28 2002/08/24 01:19:28 helly Exp $ */ /* * md5.c - Copyright 1997 Lachlan Roche @@ -90,7 +90,7 @@ } if ((fp = VCWD_FOPEN(Z_STRVAL_PP(arg), "rb")) == NULL) { - php_error(E_WARNING, "md5_file(): Unable to open file"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file"); RETURN_FALSE; } 1.3 +12 -1 php4/ext/standard/microtime.c Index: microtime.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/microtime.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- microtime.c 29 Apr 2002 02:31:02 -0000 1.2 +++ microtime.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: microtime.c,v 1.36 2002/02/28 08:26:46 sebastian Exp $ */ +/* $Id: microtime.c,v 1.38 2002/09/06 07:44:30 hyanantha Exp $ */ #include "php.h" @@ -25,6 +25,12 @@ #endif #ifdef PHP_WIN32 #include "win32/time.h" +#elif defined(NETWARE) +#ifdef NEW_LIBC +#include <sys/timeval.h> +#else +#include "netware/time_nw.h" +#endif #else #include <sys/time.h> #endif @@ -43,6 +49,7 @@ #define NUL '\0' #define MICRO_IN_SEC 1000000.00 +#define SEC_IN_MIN 60 /* {{{ proto string microtime(void) Returns a string containing the current time in seconds and microseconds */ @@ -81,7 +88,11 @@ array_init(return_value); add_assoc_long(return_value, "sec", tp.tv_sec); add_assoc_long(return_value, "usec", tp.tv_usec); +#ifdef PHP_WIN32 + add_assoc_long(return_value, "minuteswest", tz.tz_minuteswest/SEC_IN_MIN); +#else add_assoc_long(return_value, "minuteswest", tz.tz_minuteswest); +#endif add_assoc_long(return_value, "dsttime", tz.tz_dsttime); return; } else 1.3 +20 -2 php4/ext/standard/pack.c Index: pack.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/pack.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- pack.c 29 Apr 2002 02:31:02 -0000 1.2 +++ pack.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -15,7 +15,7 @@ | Author: Chris Schneider <cschn****@relog*****> | +----------------------------------------------------------------------+ */ -/* $Id: pack.c,v 1.37 2002/02/28 08:26:46 sebastian Exp $ */ +/* $Id: pack.c,v 1.40 2002/09/06 07:44:30 hyanantha Exp $ */ #include "php.h" @@ -30,6 +30,18 @@ #include <winsock.h> #define O_RDONLY _O_RDONLY #include "win32/param.h" +#elif defined(NETWARE) +#ifdef USE_WINSOCK +/*#include <ws2nlm.h>*/ +#include <novsock2.h> +#else +#include <sys/socket.h> +#endif +#ifdef NEW_LIBC +#include <sys/param.h> +#else +#include "netware/param.h" +#endif #else #include <sys/param.h> #endif @@ -40,6 +52,8 @@ #if HAVE_PWD_H #ifdef PHP_WIN32 #include "win32/pwd.h" +#elif defined(NETWARE) +#include "netware/pwd.h" #else #include <pwd.h> #endif @@ -209,6 +223,9 @@ break; default: + efree(argv); + efree(formatcodes); + efree(formatargs); php_error(E_WARNING, "pack type %c: unknown format code", code); RETURN_FALSE; } @@ -518,7 +535,7 @@ inputpos = 0; if (array_init(return_value) == FAILURE) - return; + RETURN_FALSE; while (formatlen-- > 0) { char type = *(format++); @@ -809,6 +826,7 @@ break; } else { php_error(E_WARNING, "pack type %c: not enough input, need %d, have %d", type, size, inputlen - inputpos); + zval_dtor(return_value); RETURN_FALSE; } } 1.3 +32 -2 php4/ext/standard/pageinfo.c Index: pageinfo.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/pageinfo.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- pageinfo.c 29 Apr 2002 02:31:02 -0000 1.2 +++ pageinfo.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pageinfo.c,v 1.30 2002/02/28 08:26:46 sebastian Exp $ */ +/* $Id: pageinfo.c,v 1.34 2002/09/06 07:47:49 derick Exp $ */ #include "php.h" #include "pageinfo.h" @@ -27,14 +27,33 @@ #if HAVE_PWD_H #ifdef PHP_WIN32 #include "win32/pwd.h" +#elif defined(NETWARE) +#ifdef ZTS +extern int basic_globals_id; +#endif +#include "netware/pwd.h" #else #include <pwd.h> #endif #endif +#if HAVE_GRP_H +# ifdef PHP_WIN32 +# include "win32/grp.h" +# else +# include <grp.h> +# endif +#endif +#ifdef PHP_WIN32 +#undef getgid +#define getgroups(a, b) 0 +#define getgid() 1 +#define getuid() 1 +#endif #if HAVE_UNISTD_H #include <unistd.h> #endif #include <sys/stat.h> +#include <sys/types.h> #ifdef PHP_WIN32 #include <process.h> #endif @@ -45,7 +64,11 @@ */ PHPAPI void php_statpage(TSRMLS_D) { +#if defined(NETWARE) && defined(CLIB_STAT_PATCH) + struct stat_libc *pstat; +#else struct stat *pstat; +#endif pstat = sapi_get_stat(TSRMLS_C); @@ -54,8 +77,15 @@ BG(page_uid) = pstat->st_uid; BG(page_gid) = pstat->st_gid; BG(page_inode) = pstat->st_ino; +#if defined(NETWARE) && defined(NEW_LIBC) + BG(page_mtime) = (pstat->st_mtime).tv_nsec; +#else BG(page_mtime) = pstat->st_mtime; - } +#endif + } else { /* handler for situations where there is no source file, ex. php -r */ + BG(page_uid) = getuid(); + BG(page_gid) = getgid(); + } } } /* }}} */ 1.3 +3 -1 php4/ext/standard/parsedate.y Index: parsedate.y =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/parsedate.y,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- parsedate.y 29 Apr 2002 02:31:02 -0000 1.2 +++ parsedate.y 6 Oct 2002 21:54:32 -0000 1.3 @@ -8,6 +8,8 @@ ** This code is in the public domain and has no copyright. */ +/* $Id: parsedate.y,v 1.34 2002/09/09 19:11:35 wez Exp $ */ + #include "php.h" #ifdef PHP_WIN32 @@ -520,7 +522,7 @@ { "now", tDAY_UNIT, 0 }, { "last", tUNUMBER, -1 }, { "this", tMINUTE_UNIT, 0 }, - { "next", tUNUMBER, 1 }, + { "next", tUNUMBER, 2 }, { "first", tUNUMBER, 1 }, /* { "second", tUNUMBER, 2 }, */ { "third", tUNUMBER, 3 }, 1.4 +4 -2 php4/ext/standard/php_array.h Index: php_array.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_array.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- php_array.h 2 Aug 2002 22:05:24 -0000 1.3 +++ php_array.h 6 Oct 2002 21:54:32 -0000 1.4 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_array.h,v 1.35 2002/05/13 17:28:38 andrei Exp $ */ +/* $Id: php_array.h,v 1.39 2002/09/21 14:50:04 andrey Exp $ */ #ifndef PHP_ARRAY_H #define PHP_ARRAY_H @@ -75,7 +75,9 @@ PHP_FUNCTION(array_rand); PHP_FUNCTION(array_unique); PHP_FUNCTION(array_intersect); +PHP_FUNCTION(array_intersect_assoc); PHP_FUNCTION(array_diff); +PHP_FUNCTION(array_diff_assoc); PHP_FUNCTION(array_sum); PHP_FUNCTION(array_filter); PHP_FUNCTION(array_map); @@ -83,7 +85,7 @@ PHP_FUNCTION(array_chunk); HashTable* php_splice(HashTable *, int, int, zval ***, int, HashTable **); -PHPAPI void php_array_merge(HashTable *dest, HashTable *src, int recursive); +PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC); int multisort_compare(const void *a, const void *b TSRMLS_DC); typedef struct { 1.3 +3 -1 php4/ext/standard/php_filestat.h Index: php_filestat.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_filestat.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_filestat.h 29 Apr 2002 02:31:02 -0000 1.2 +++ php_filestat.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_filestat.h,v 1.16 2002/04/26 23:46:51 yohgaki Exp $ */ +/* $Id: php_filestat.h,v 1.17 2002/07/03 06:45:01 derick Exp $ */ #ifndef PHP_FILESTAT_H #define PHP_FILESTAT_H @@ -36,7 +36,9 @@ PHP_FUNCTION(filetype); PHP_FUNCTION(is_writable); PHP_FUNCTION(is_readable); +#ifndef PHP_WIN32 PHP_FUNCTION(is_executable); +#endif PHP_FUNCTION(is_file); PHP_FUNCTION(is_dir); PHP_FUNCTION(is_link); 1.3 +46 -5 php4/ext/standard/php_fopen_wrapper.c Index: php_fopen_wrapper.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_fopen_wrapper.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_fopen_wrapper.c 29 Apr 2002 02:31:02 -0000 1.2 +++ php_fopen_wrapper.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -17,7 +17,7 @@ | Hartmut Holzgraefe <hholz****@php*****> | +----------------------------------------------------------------------+ */ -/* $Id: php_fopen_wrapper.c,v 1.21 2002/04/16 22:14:24 wez Exp $ */ +/* $Id: php_fopen_wrapper.c,v 1.26 2002/10/05 10:35:12 wez Exp $ */ #include <stdio.h> #include <stdlib.h> @@ -29,6 +29,42 @@ #include "php_globals.h" #include "php_standard.h" #include "php_fopen_wrappers.h" +#include "SAPI.h" + +static size_t php_stream_output_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +{ + PHPWRITE(buf, count); + return count; +} + +static size_t php_stream_output_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +{ + stream->eof = 1; + return 0; +} + +static int php_stream_output_close(php_stream *stream, int close_handle TSRMLS_DC) +{ + return 0; +} + +static int php_stream_output_flush(php_stream *stream TSRMLS_DC) +{ + sapi_flush(TSRMLS_C); + return 0; +} + +php_stream_ops php_stream_output_ops = { + php_stream_output_write, + php_stream_output_read, + php_stream_output_close, + php_stream_output_flush, + "Output", + NULL, /* seek */ + NULL, /* cast */ + NULL, /* stat */ + NULL /* set_option */ +}; php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { @@ -38,6 +74,10 @@ if (!strncasecmp(path, "php://", 6)) path += 6; + if (!strcasecmp(path, "output")) { + return php_stream_alloc(&php_stream_output_ops, NULL, 0, "wb"); + } + if (!strcasecmp(path, "stdin")) { fp = fdopen(dup(STDIN_FILENO), mode); } else if (!strcasecmp(path, "stdout")) { @@ -45,7 +85,6 @@ } else if (!strcasecmp(path, "stderr")) { fp = fdopen(dup(STDERR_FILENO), mode); } - /* TODO: implement php://output as a stream to write to the current output buffer ? */ if (fp) { stream = php_stream_fopen_from_file(fp, mode); @@ -57,9 +96,11 @@ static php_stream_wrapper_ops php_stdio_wops = { php_stream_url_wrap_php, - NULL, - NULL, - NULL + NULL, /* close */ + NULL, /* fstat */ + NULL, /* stat */ + NULL, /* opendir */ + "PHP" }; php_stream_wrapper php_stream_php_wrapper = { 1.3 +11 -2 php4/ext/standard/php_image.h Index: php_image.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_image.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_image.h 29 Apr 2002 02:31:02 -0000 1.2 +++ php_image.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -17,13 +17,15 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_image.h,v 1.13 2002/03/18 18:54:28 wez Exp $ */ +/* $Id: php_image.h,v 1.19 2002/06/24 19:36:26 helly Exp $ */ #ifndef PHP_IMAGE_H #define PHP_IMAGE_H PHP_FUNCTION(getimagesize); +PHP_FUNCTION(image_type_to_mime_type); + /* {{{ enum image_filetype This enum is used to have ext/standard/image.c and ext/exif/exif.c use the same constants for file types. @@ -41,10 +43,17 @@ IMAGE_FILETYPE_JPC, IMAGE_FILETYPE_JP2, IMAGE_FILETYPE_JPX, - IMAGE_FILETYPE_JB2 + IMAGE_FILETYPE_JB2, + IMAGE_FILETYPE_SWC, + IMAGE_FILETYPE_IFF, +/* WHEN EXTENDING: PLEASE ALSO REGISTER IN image.c:PHP_MINIT_FUNCTION(imagetypes) */ } image_filetype; /* }}} */ +PHP_MINIT_FUNCTION(imagetypes); + PHPAPI int php_getimagetype(php_stream *stream, char *filetype TSRMLS_DC); + +PHPAPI const char * php_image_type_to_mime_type(int image_type); #endif /* PHP_IMAGE_H */ 1.3 +4 -3 php4/ext/standard/php_incomplete_class.h Index: php_incomplete_class.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_incomplete_class.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_incomplete_class.h 29 Apr 2002 02:31:02 -0000 1.2 +++ php_incomplete_class.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_incomplete_class.h,v 1.8 2001/12/11 15:30:35 sebastian Exp $ */ +/* $Id: php_incomplete_class.h,v 1.9 2002/07/24 09:55:11 yohgaki Exp $ */ #ifndef PHP_INCOMPLETE_CLASS_H #define PHP_INCOMPLETE_CLASS_H @@ -44,12 +44,13 @@ size_t name_len; \ zend_bool free_class_name = 0 \ - +#define INCOMPLETE_CLASS "__PHP_Incomplete_Class" +#define MAGIC_MEMBER "__PHP_Incomplete_Class_Name" #ifdef __cplusplus extern "C" { #endif - + zend_class_entry *php_create_incomplete_class(TSRMLS_D); char *php_lookup_class_name(zval *object, size_t *nlen, zend_bool del); 1.3 +4 -3 php4/ext/standard/php_mail.h Index: php_mail.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_mail.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_mail.h 29 Apr 2002 02:31:02 -0000 1.2 +++ php_mail.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,16 +16,17 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_mail.h,v 1.13 2002/03/16 12:45:43 mfischer Exp $ */ +/* $Id: php_mail.h,v 1.14 2002/08/08 17:53:52 helly Exp $ */ #ifndef PHP_MAIL_H #define PHP_MAIL_H +PHP_FUNCTION(mail); +PHP_MINFO_FUNCTION(mail); + #if HAVE_SENDMAIL -PHP_FUNCTION(mail); PHP_FUNCTION(ezmlm_hash); -PHP_MINFO_FUNCTION(mail); PHPAPI extern int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd TSRMLS_DC); #endif 1.3 +4 -1 php4/ext/standard/php_rand.h Index: php_rand.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_rand.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_rand.h 29 Apr 2002 02:31:02 -0000 1.2 +++ php_rand.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -20,7 +20,7 @@ | Based on code from: Shawn Cokus <Cokus****@math*****> | +----------------------------------------------------------------------+ */ -/* $Id: php_rand.h,v 1.18 2002/02/28 08:26:48 sebastian Exp $ */ +/* $Id: php_rand.h,v 1.19 2002/06/09 04:26:36 andrei Exp $ */ #ifndef PHP_RAND_H #define PHP_RAND_H @@ -38,6 +38,9 @@ #else #define PHP_RAND_MAX RAND_MAX #endif + +#define RAND_RANGE(__n, __min, __max, __tmax) \ + (__n) = (__min) + (long) ((double) ((__max) - (__min) + 1.0) * ((__n) / ((__tmax) + 1.0))) /* MT Rand */ #define PHP_MT_RAND_MAX ((long) (0x7FFFFFFF)) /* (1<<31) - 1 */ 1.4 +2 -2 php4/ext/standard/php_smart_str.h Index: php_smart_str.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_smart_str.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- php_smart_str.h 9 May 2002 05:39:43 -0000 1.3 +++ php_smart_str.h 6 Oct 2002 21:54:32 -0000 1.4 @@ -49,13 +49,13 @@ #define smart_str_append_long(dest, val) smart_str_append_long_ex(dest, val, 0) #define smart_str_append_unsigned(dest, val) smart_str_append_unsigned_ex(dest, val, 0) -static inline void smart_str_appendc_ex(smart_str *dest, char c, int what) +static inline void smart_str_appendc_ex(smart_str *dest, unsigned char c, int what) { size_t newlen; smart_str_alloc(dest, 1, what); dest->len = newlen; - dest->c[dest->len - 1] = c; + ((unsigned char *) dest->c)[dest->len - 1] = c; } 1.3 +2 -1 php4/ext/standard/php_standard.h Index: php_standard.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_standard.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_standard.h 29 Apr 2002 02:31:02 -0000 1.2 +++ php_standard.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_standard.h,v 1.15 2002/02/28 08:26:48 sebastian Exp $ */ +/* $Id: php_standard.h,v 1.16 2002/07/28 19:18:08 sesser Exp $ */ #include "basic_functions.h" #include "php_math.h" @@ -27,6 +27,7 @@ #include "reg.h" #include "php_mail.h" #include "md5.h" +#include "sha1.h" #include "html.h" #include "exec.h" #include "file.h" 1.3 +12 -6 php4/ext/standard/php_string.h Index: php_string.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_string.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_string.h 29 Apr 2002 02:31:02 -0000 1.2 +++ php_string.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_string.h,v 1.56 2002/03/20 14:38:11 wez Exp $ */ +/* $Id: php_string.h,v 1.61 2002/09/25 18:06:05 andrey Exp $ */ /* Synced with php 3.0 revision 1.43 1999-06-16 [ssb] */ @@ -82,10 +82,16 @@ PHP_FUNCTION(substr_count); PHP_FUNCTION(str_pad); PHP_FUNCTION(sscanf); +PHP_FUNCTION(str_shuffle); #ifdef HAVE_STRCOLL PHP_FUNCTION(strcoll); #endif +#if HAVE_STRFMON +PHP_FUNCTION(money_format); +#endif +PHP_MINIT_FUNCTION(string_filters); +PHP_MSHUTDOWN_FUNCTION(string_filters); #if defined(HAVE_LOCALECONV) && defined(ZTS) PHP_MINIT_FUNCTION(localeconv); @@ -101,6 +107,10 @@ strnatcmp_ex(a, strlen(a), b, strlen(b), 1) PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case); +#ifdef HAVE_LOCALECONV +struct lconv *localeconv_r(struct lconv *out); +#endif + PHPAPI char *php_strtoupper(char *s, size_t len); PHPAPI char *php_strtolower(char *s, size_t len); PHPAPI char *php_strtr(char *str, int len, char *str_from, char *str_to, int trlen); @@ -113,12 +123,9 @@ PHPAPI char *php_stristr(unsigned char *s, unsigned char *t, size_t s_len, size_t t_len); PHPAPI char *php_str_to_str(char *haystack, int length, char *needle, int needle_len, char *str, int str_len, int *_new_length); -PHPAPI void php_trim(zval **str, zval *return_value, int mode TSRMLS_DC); -PHPAPI void php_trim2(zval **str, zval **what, zval *return_value, int mode TSRMLS_DC); +PHPAPI char *php_trim(char *c, int len, char *what, int what_len, zval *return_value, int mode TSRMLS_DC); PHPAPI void php_strip_tags(char *rbuf, int len, int *state, char *allow, int allow_len); - PHPAPI int php_char_to_str(char *str, uint len, char from, char *to, int to_len, pval *result); - PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value); PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit); @@ -151,6 +158,5 @@ #endif void register_string_constants(INIT_FUNC_ARGS); -int php_charmask(unsigned char *input, int len, char *mask TSRMLS_DC); #endif /* PHP_STRING_H */ 1.3 +3 -3 php4/ext/standard/php_var.h Index: php_var.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/php_var.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_var.h 29 Apr 2002 02:31:02 -0000 1.2 +++ php_var.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_var.h,v 1.20 2002/02/28 08:26:48 sebastian Exp $ */ +/* $Id: php_var.h,v 1.21 2002/08/04 23:45:37 shane Exp $ */ #ifndef PHP_VAR_H #define PHP_VAR_H @@ -55,8 +55,8 @@ #define PHP_VAR_UNSERIALIZE_DESTROY(var_hash) \ var_destroy(&(var_hash)) -void var_replace(php_unserialize_data_t *var_hash, zval *ozval, zval **nzval); -void var_destroy(php_unserialize_data_t *var_hash); +PHPAPI void var_replace(php_unserialize_data_t *var_hash, zval *ozval, zval **nzval); +PHPAPI void var_destroy(php_unserialize_data_t *var_hash); #define PHP_VAR_UNSERIALIZE_ZVAL_CHANGED(var_hash, ozval, nzval) \ var_replace((var_hash), (ozval), &(nzval)) 1.3 +5 -3 php4/ext/standard/rand.c Index: rand.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/rand.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- rand.c 29 Apr 2002 02:31:02 -0000 1.2 +++ rand.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -20,7 +20,7 @@ | Based on code from: Shawn Cokus <Cokus****@math*****> | +----------------------------------------------------------------------+ */ -/* $Id: rand.c,v 1.58 2002/02/28 08:26:48 sebastian Exp $ */ +/* $Id: rand.c,v 1.60 2002/09/06 07:44:30 hyanantha Exp $ */ #include <stdlib.h> @@ -31,6 +31,10 @@ # include <windows.h> #endif +#if defined(NETWARE) && !defined(NEW_LIBC) /* For getpid() used below */ +#include "netware/pwd.h" +#endif + #include "php.h" #include "php_math.h" #include "php_rand.h" @@ -315,8 +319,6 @@ * * -RL */ -#define RAND_RANGE(__n, __min, __max, __tmax) \ - (__n) = (__min) + (long) ((double) ((__max) - (__min) + 1.0) * ((__n) / ((__tmax) + 1.0))) /* {{{ proto int rand([int min, int max]) Returns a random number */ 1.4 +29 -33 php4/ext/standard/reg.c Index: reg.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/reg.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- reg.c 9 May 2002 05:39:43 -0000 1.3 +++ reg.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -17,19 +17,16 @@ | Jaakko Hyv〓tti <jaakk****@hyvat*****> | +----------------------------------------------------------------------+ */ -/* $Id: reg.c,v 1.62 2002/05/04 11:20:12 hirokawa Exp $ */ +/* $Id: reg.c,v 1.66 2002/09/25 14:02:34 andrei Exp $ */ #include <stdio.h> +#include <ctype.h> #include "php.h" #include "php_string.h" #include "reg.h" #include "ext/standard/info.h" -#ifdef ZTS -int reg_globals_id; -#else -static php_reg_globals reg_globals; -#endif +ZEND_DECLARE_MODULE_GLOBALS(reg) typedef struct { regex_t preg; @@ -74,25 +71,28 @@ #undef regcomp #define regcomp(a, b, c) _php_regcomp(a, b, c) -static void php_reg_init_globals(php_reg_globals *reg_globals TSRMLS_DC) +static void php_reg_init_globals(zend_reg_globals *reg_globals TSRMLS_DC) { zend_hash_init(®_globals->ht_rc, 0, NULL, (void (*)(void *)) _free_reg_cache, 1); } -PHP_MINIT_FUNCTION(regex) +static void php_reg_destroy_globals(zend_reg_globals *reg_globals TSRMLS_DC) { -#ifdef ZTS - ts_allocate_id(®_globals_id, sizeof(php_reg_globals), (ts_allocate_ctor) php_reg_init_globals, NULL); -#else - php_reg_init_globals(®_globals TSRMLS_CC); -#endif + zend_hash_destroy(®_globals->ht_rc); +} +PHP_MINIT_FUNCTION(regex) +{ + ZEND_INIT_MODULE_GLOBALS(reg, php_reg_init_globals, php_reg_destroy_globals); return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(regex) { - zend_hash_destroy(®(ht_rc)); +#ifndef ZTS + php_reg_destroy_globals(®_globals TSRMLS_CC); +#endif + return SUCCESS; } @@ -340,12 +340,10 @@ new_l = strlen(buf) + subs[0].rm_so; /* part before the match */ walk = replace; while (*walk) - if ('\\' == *walk - && '0' <= walk[1] && '9' >= walk[1] - && subs[walk[1] - '0'].rm_so > -1 - && subs[walk[1] - '0'].rm_eo > -1) { - new_l += subs[walk[1] - '0'].rm_eo - - subs[walk[1] - '0'].rm_so; + if ('\\' == *walk && isdigit(walk[1]) && walk[1] - '0' <= ((char) re.re_nsub)) { + if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1) { + new_l += subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so; + } walk += 2; } else { new_l++; @@ -367,21 +365,19 @@ walkbuf = &buf[tmp + subs[0].rm_so]; walk = replace; while (*walk) - if ('\\' == *walk - && '0' <= walk[1] && '9' >= walk[1] - && subs[walk[1] - '0'].rm_so > -1 - && subs[walk[1] - '0'].rm_eo > -1 - /* this next case shouldn't happen. it does. */ - && subs[walk[1] - '0'].rm_so <= subs[walk[1] - '0'].rm_eo) { - tmp = subs[walk[1] - '0'].rm_eo - - subs[walk[1] - '0'].rm_so; - memcpy (walkbuf, - &string[pos + subs[walk[1] - '0'].rm_so], - tmp); - walkbuf += tmp; + if ('\\' == *walk && isdigit(walk[1]) && walk[1] - '0' <= re.re_nsub) { + if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1 + /* this next case shouldn't happen. it does. */ + && subs[walk[1] - '0'].rm_so <= subs[walk[1] - '0'].rm_eo) { + + tmp = subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so; + memcpy (walkbuf, &string[pos + subs[walk[1] - '0'].rm_so], tmp); + walkbuf += tmp; + } walk += 2; - } else + } else { *walkbuf++ = *walk++; + } *walkbuf = '\0'; /* and get ready to keep looking for replacements */ 1.3 +4 -4 php4/ext/standard/reg.h Index: reg.h =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/reg.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- reg.h 29 Apr 2002 02:31:02 -0000 1.2 +++ reg.h 6 Oct 2002 21:54:32 -0000 1.3 @@ -17,7 +17,7 @@ */ -/* $Id: reg.h,v 1.15 2002/02/28 08:26:49 sebastian Exp $ */ +/* $Id: reg.h,v 1.17 2002/09/25 17:48:10 andrei Exp $ */ #ifndef REG_H #define REG_H @@ -32,9 +32,9 @@ PHP_FUNCTION(spliti); PHPAPI PHP_FUNCTION(sql_regcase); -typedef struct { +ZEND_BEGIN_MODULE_GLOBALS(reg) HashTable ht_rc; -} php_reg_globals; +ZEND_END_MODULE_GLOBALS(reg) PHP_MINIT_FUNCTION(regex); PHP_MSHUTDOWN_FUNCTION(regex); @@ -42,7 +42,7 @@ #ifdef ZTS -#define REG(v) TSRMG(reg_globals_id, php_reg_globals *, v) +#define REG(v) TSRMG(reg_globals_id, zend_reg_globals *, v) #else #define REG(v) (reg_globals.v) #endif 1.3 +3 -5 php4/ext/standard/scanf.c Index: scanf.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/scanf.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- scanf.c 29 Apr 2002 02:31:02 -0000 1.2 +++ scanf.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: scanf.c,v 1.15 2002/02/28 08:26:49 sebastian Exp $ */ +/* $Id: scanf.c,v 1.16 2002/08/24 01:19:28 helly Exp $ */ /* scanf.c -- @@ -408,8 +408,7 @@ gotSequential = 1; if (gotXpg) { mixedXPG: - php_error(E_WARNING, - "cannot mix \"%\" and \"%n$\" conversion specifiers in %s", get_active_function_name(TSRMLS_C) ); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot mix \"%\" and \"%n$\" conversion specifiers"); goto error; } @@ -642,8 +641,7 @@ if (numVars) { for (i = varStart;i < argCount;i++){ if ( ! PZVAL_IS_REF( *args[ i ] ) ) { - php_error(E_WARNING, "Parameter %d to %s() must be passed by reference", - i, get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter %d must be passed by reference", i); scan_set_error_return(numVars, return_value); return SCAN_ERROR_VAR_PASSED_BYVAL; } 1.5 +661 -459 php4/ext/standard/string.c Index: string.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/string.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- string.c 2 Aug 2002 22:05:24 -0000 1.4 +++ string.c 6 Oct 2002 21:54:32 -0000 1.5 @@ -18,13 +18,14 @@ +----------------------------------------------------------------------+ */ -/* $Id: string.c,v 1.274 2002/05/16 16:04:45 pbannister Exp $ */ +/* $Id: string.c,v 1.314 2002/10/06 11:28:11 sander Exp $ */ /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ #include <stdio.h> #include "php.h" #include "reg.h" +#include "php_rand.h" #include "php_string.h" #include "php_variables.h" #ifdef HAVE_LOCALE_H @@ -33,6 +34,9 @@ #ifdef HAVE_LANGINFO_H # include <langinfo.h> #endif +#ifdef HAVE_MONETARY_H +# include <monetary.h> +#endif #include "scanf.h" #include "zend_API.h" #include "zend_execute.h" @@ -51,6 +55,9 @@ #define PHP_PATHINFO_EXTENSION 4 #define PHP_PATHINFO_ALL (PHP_PATHINFO_DIRNAME | PHP_PATHINFO_BASENAME | PHP_PATHINFO_EXTENSION) +#define STR_STRSPN 0 +#define STR_STRCSPN 1 + /* {{{ register_string_constants */ void register_string_constants(INIT_FUNC_ARGS) @@ -106,11 +113,11 @@ size_t i, j; result = (char *) emalloc(oldlen * 2 * sizeof(char) + 1); - if(!result) { + if (!result) { return result; } - for(i = j = 0; i < oldlen; i++) { + for (i = j = 0; i < oldlen; i++) { result[j++] = hexconvtab[old[i] >> 4]; result[j++] = hexconvtab[old[i] & 15]; } @@ -177,8 +184,7 @@ char *result; size_t newlen; - if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &data) == FAILURE) { + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &data) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(data); @@ -193,39 +199,71 @@ } /* }}} */ -/* {{{ proto int strspn(string str, string mask) - Finds length of initial segment consisting entirely of characters found in mask */ -PHP_FUNCTION(strspn) +static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior) { - zval **s1, **s2; + char *s11, *s22; + long len1, len2, start, len; - if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) { - WRONG_PARAM_COUNT; + start = 0; + len = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll", &s11, &len1, + &s22, &len2, &start, &len) == FAILURE) { + return; + } + + if (ZEND_NUM_ARGS() < 4) { + len = len1; + } + + /* look at substr() function for more information */ + + if (start < 0) { + start += len1; + if (start < 0) { + start = 0; + } + } else if (start > len1) { + RETURN_FALSE; + } + + if (len < 0) { + len += (len1 - start); + if (len < 0) { + len = 0; + } + } + + if ((start + len) > len1) { + len = len1 - start; } - convert_to_string_ex(s1); - convert_to_string_ex(s2); - RETURN_LONG(php_strspn(Z_STRVAL_PP(s1), Z_STRVAL_PP(s2), - Z_STRVAL_PP(s1) + Z_STRLEN_PP(s1), - Z_STRVAL_PP(s2) + Z_STRLEN_PP(s2))); + if (behavior == STR_STRSPN) { + RETURN_LONG(php_strspn(s11 + start /*str1_start*/, + s22 /*str2_start*/, + s11 + start + len /*str1_end*/, + s22 + len2 /*str2_end*/)); + } else if (behavior == STR_STRCSPN) { + RETURN_LONG(php_strcspn(s11 + start /*str1_start*/, + s22 /*str2_start*/, + s11 + start + len /*str1_end*/, + s22 + len2 /*str2_end*/)); + } + +} + +/* {{{ proto int strspn(string str, string mask [, start [, len]]) + Finds length of initial segment consisting entirely of characters found in mask. If start or/and length is provided works like strspn(substr($s,$start,$len),$good_chars) */ +PHP_FUNCTION(strspn) +{ + php_spn_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, STR_STRSPN); } /* }}} */ -/* {{{ proto int strcspn(string str, string mask) - Finds length of initial segment consisting entirely of characters not found in mask */ +/* {{{ proto int strcspn(string str, string mask [, start [, len]]) + Finds length of initial segment consisting entirely of characters not found in mask. If start or/and length is provide works like strcspn(substr($s,$start,$len),$bad_chars) */ PHP_FUNCTION(strcspn) { - zval **s1, **s2; - - if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(s1); - convert_to_string_ex(s2); - - RETURN_LONG(php_strcspn(Z_STRVAL_PP(s1), Z_STRVAL_PP(s2), - Z_STRVAL_PP(s1) + Z_STRLEN_PP(s1), - Z_STRVAL_PP(s2) + Z_STRLEN_PP(s2))); + php_spn_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, STR_STRCSPN); } /* }}} */ @@ -412,10 +450,9 @@ convert_to_long_ex(item); value = nl_langinfo(Z_LVAL_PP(item)); - if (value == NULL) { + if (value == NULL) { RETURN_FALSE; - } - else { + } else { RETURN_STRING(value, 1); } } @@ -446,39 +483,39 @@ * it needs to be incrementing. * Returns: FAILURE/SUCCESS wether the input was correct (i.e. no range errors) */ -int php_charmask(unsigned char *input, int len, char *mask TSRMLS_DC) +static inline int php_charmask(unsigned char *input, int len, char *mask TSRMLS_DC) { unsigned char *end; unsigned char c; int result = SUCCESS; memset(mask, 0, 256); - for (end=input+len; input<end; input++) { + for (end = input+len; input < end; input++) { c=*input; - if (input+3<end && input[1] == '.' && input[2] == '.' + if ((input+3 < end) && input[1] == '.' && input[2] == '.' && input[3] >= c) { memset(mask+c, 1, input[3] - c + 1); input+=3; - } else if (input+1<end && input[0] == '.' && input[1] == '.') { + } else if ((input+1 < end) && input[0] == '.' && input[1] == '.') { /* Error, try to be as helpful as possible: (a range ending/starting with '.' won't be captured here) */ - if (end-len>=input) { /* there was no 'left' char */ - php_error(E_WARNING, "Invalid '..'-range passed to %s(), no character to the left of '..'", get_active_function_name(TSRMLS_C)); + if (end-len >= input) { /* there was no 'left' char */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range, no character to the left of '..'."); result = FAILURE; continue; } - if (input+2>=end) { /* there is no 'right' char */ - php_error(E_WARNING, "Invalid '..'-range passed to %s(), no character to the right of '..'", get_active_function_name(TSRMLS_C)); + if (input+2 >= end) { /* there is no 'right' char */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range, no character to the right of '..'."); result = FAILURE; continue; } if (input[-1] > input[2]) { /* wrong order */ - php_error(E_WARNING, "Invalid '..'-range passed to %s(), '..'-range needs to be incrementing", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range, '..'-range needs to be incrementing."); result = FAILURE; continue; } /* FIXME: better error (a..b..c is the only left possibility?) */ - php_error(E_WARNING, "Invalid '..'-range passed to %s()", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range."); result = FAILURE; continue; } else { @@ -489,33 +526,20 @@ } /* }}} */ -/* {{{ php_trim - Compatibility function, ports old-API to new one. (DEPRECATED) -*/ -void php_trim(zval **str, zval *return_value, int mode TSRMLS_DC) -{ - php_trim2(str, NULL, return_value, mode TSRMLS_CC); -} -/* }}} */ - -/* {{{ php_trim2 +/* {{{ php_trim() + * mode 1 : trim left + * mode 2 : trim right + * mode 3 : trim left and right + * what indicates which chars are to be trimmed. NULL->default (' \t\n\r\v\0') */ -PHPAPI void php_trim2(zval **str, zval **what, zval *return_value, int mode TSRMLS_DC) -/* mode 1 : trim left - mode 2 : trim right - mode 3 : trim left and right - - what indicates which chars are to be trimmed. NULL->default (' \t\n\r\v\0') -*/ +PHPAPI char *php_trim(char *c, int len, char *what, int what_len, zval *return_value, int mode TSRMLS_DC) { register int i; - int len = Z_STRLEN_PP(str); int trimmed = 0; - char *c = Z_STRVAL_PP(str); char mask[256]; if (what) { - php_charmask(Z_STRVAL_PP(what), Z_STRLEN_PP(what), mask TSRMLS_CC); + php_charmask(what, what_len, mask TSRMLS_CC); } else { php_charmask(" \n\r\t\v\0", 6, mask TSRMLS_CC); } @@ -540,32 +564,37 @@ } } } - RETVAL_STRINGL(c, len, 1); -} -/* }}} */ -/* {{{ proto string chop(string str [, string character_mask]) - An alias for rtrim */ + if (return_value) { + RETVAL_STRINGL(c, len, 1); + } else { + return estrndup(c, len); + } + return ""; +} /* }}} */ -/* {{{ proto string rtrim(string str [, string character_mask]) - Removes trailing whitespace */ -PHP_FUNCTION(rtrim) +/* {{{ php_do_trim + * Base for trim(), rtrim() and ltrim() functions. + */ +static void php_do_trim(INTERNAL_FUNCTION_PARAMETERS, int mode) { zval **str; zval **what = NULL; int argc = ZEND_NUM_ARGS(); - if (argc < 1 || argc > 2 || - zend_get_parameters_ex(argc, &str, &what) == FAILURE) { + if (argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &str, &what) == FAILURE) { WRONG_PARAM_COUNT; } + convert_to_string_ex(str); + if (argc > 1) { convert_to_string_ex(what); + php_trim(Z_STRVAL_PP(str), Z_STRLEN_PP(str), Z_STRVAL_PP(what), Z_STRLEN_PP(what), return_value, mode TSRMLS_CC); + } else { + php_trim(Z_STRVAL_PP(str), Z_STRLEN_PP(str), NULL, 0, return_value, mode TSRMLS_CC); } - - php_trim2(str, what, return_value, 2 TSRMLS_CC); } /* }}} */ @@ -573,20 +602,15 @@ Strips whitespace from the beginning and end of a string */ PHP_FUNCTION(trim) { - zval **str; - zval **what = NULL; - int argc = ZEND_NUM_ARGS(); - - if (argc < 1 || argc > 2 || - zend_get_parameters_ex(argc, &str, &what) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - if (argc > 1) { - convert_to_string_ex(what); - } + php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3); +} +/* }}} */ - php_trim2(str, what, return_value, 3 TSRMLS_CC); +/* {{{ proto string rtrim(string str [, string character_mask]) + Removes trailing whitespace */ +PHP_FUNCTION(rtrim) +{ + php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2); } /* }}} */ @@ -594,20 +618,7 @@ Strips whitespace from the beginning of a string */ PHP_FUNCTION(ltrim) { - zval **str; - zval **what = NULL; - int argc = ZEND_NUM_ARGS(); - - if (argc < 1 || argc > 2 || - zend_get_parameters_ex(argc, &str, &what) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - if (argc > 1) { - convert_to_string_ex(what); - } - - php_trim2(str, what, return_value, 1 TSRMLS_CC); + php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } /* }}} */ @@ -630,7 +641,7 @@ RETURN_FALSE; if (linelength == 0 && docut) { - php_error(E_WARNING, "%s() can't force cut when width is zero",get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't force cut when width is zero."); RETURN_FALSE; } @@ -663,13 +674,14 @@ else { /* Multiple character line break or forced cut */ if (linelength > 0) { - newtextlen = textlen + (textlen/linelength + 1) * breakcharlen + 1; + /* Add extra 10% to accomodate strings with unpredicatable number of breaks */ + newtextlen = textlen + (int)((textlen/linelength + 1) * breakcharlen * 1.1) + 1; } else { newtextlen = textlen * (breakcharlen + 1) + 1; } newtext = emalloc(newtextlen); - + /* now keep track of the actual new text length */ newtextlen = 0; @@ -728,6 +740,8 @@ } newtext[newtextlen] = '\0'; + /* free unused memory */ + newtext = erealloc(newtext, newtextlen+1); RETURN_STRINGL(newtext, newtextlen, 0); } @@ -768,8 +782,7 @@ int limit = -1; int argc = ZEND_NUM_ARGS(); - if (argc < 2 || argc > 3 || - zend_get_parameters_ex(argc, &delim, &str, &zlimit) == FAILURE) { + if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &delim, &str, &zlimit) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(str); @@ -781,7 +794,7 @@ } if (! Z_STRLEN_PP(delim)) { - php_error(E_WARNING, "Empty delimiter"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); RETURN_FALSE; } @@ -805,73 +818,83 @@ */ PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value) { - zval **tmp; - char *tmp_str; - int len = 0, count = 0, target = 0; - HashPosition pos; + zval **tmp; + HashPosition pos; + smart_str implstr = {0}; + int numelems, i = 0; - /* convert everything to strings, and calculate length */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos); - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **) &tmp, &pos) == SUCCESS) { - convert_to_string_ex(tmp); - len += Z_STRLEN_PP(tmp); - if (count > 0) { - len += Z_STRLEN_P(delim); - } + numelems = zend_hash_num_elements(Z_ARRVAL_P(arr)); - count++; - zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos); + if(numelems == 0) { + RETURN_EMPTY_STRING(); } - /* do it */ - tmp_str = (char *) emalloc(len + 1); - tmp_str[0] = 0; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos); - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **) &tmp, &pos) == SUCCESS) { - count--; - memcpy(tmp_str + target, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); - target += Z_STRLEN_PP(tmp); - if (count > 0) { - memcpy(tmp_str + target, Z_STRVAL_P(delim), Z_STRLEN_P(delim)); - target += Z_STRLEN_P(delim); + while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), + (void **) &tmp, + &pos) == SUCCESS) { + convert_to_string_ex(tmp); + + smart_str_appendl(&implstr, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); + if (++i != numelems) { + smart_str_appendl(&implstr, Z_STRVAL_P(delim), Z_STRLEN_P(delim)); } zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos); } - tmp_str[len] = 0; - - RETURN_STRINGL(tmp_str, len, 0); + smart_str_0(&implstr); + + RETURN_STRINGL(implstr.c, implstr.len, 0); } /* }}} */ -/* {{{ proto string implode(array src, string glue) +/* {{{ proto string implode([string glue,] array pieces) Joins array elements placing glue string between items and return one string */ PHP_FUNCTION(implode) { - zval **arg1, **arg2, *delim, *arr; - - if (ZEND_NUM_ARGS() != 2 || - zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) { + zval **arg1 = NULL, **arg2 = NULL, *delim, *arr; + int argc = ZEND_NUM_ARGS(); + + if (argc < 1 || argc > 2 || + zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; } - if (Z_TYPE_PP(arg1) == IS_ARRAY) { + if (argc == 1) { + MAKE_STD_ZVAL(delim); +#define _IMPL_EMPTY "" + ZVAL_STRINGL(delim, _IMPL_EMPTY, sizeof(_IMPL_EMPTY) - 1, 0); + + if (Z_TYPE_PP(arg1) != IS_ARRAY) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument to implode must be an array."); + return; + } + SEPARATE_ZVAL(arg1); arr = *arg1; - convert_to_string_ex(arg2); - delim = *arg2; - } else if (Z_TYPE_PP(arg2) == IS_ARRAY) { - SEPARATE_ZVAL(arg2) - arr = *arg2; - convert_to_string_ex(arg1); - delim = *arg1; } else { - php_error(E_WARNING, "Bad arguments to %s()", - get_active_function_name(TSRMLS_C)); - return; + if (Z_TYPE_PP(arg1) == IS_ARRAY) { + SEPARATE_ZVAL(arg1); + arr = *arg1; + convert_to_string_ex(arg2); + delim = *arg2; + } else if (Z_TYPE_PP(arg2) == IS_ARRAY) { + SEPARATE_ZVAL(arg2); + arr = *arg2; + convert_to_string_ex(arg1); + delim = *arg1; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad arguments."); + return; + } } php_implode(delim, arr, return_value); + zval_ptr_dtor(arg1); + if (arg2) { + zval_ptr_dtor(arg2); + } else { + FREE_ZVAL(delim); + } } /* }}} */ @@ -966,14 +989,14 @@ */ PHPAPI char *php_strtoupper(char *s, size_t len) { - char *c; - int ch; - size_t i; - + char *c, *e; + c = s; - for (i=0; i<len; i++) { - ch = toupper((unsigned char)*c); - *c++ = ch; + e = c+len; + + while (c < e) { + *c = toupper(*c); + c++; } return s; } @@ -1000,14 +1023,14 @@ */ PHPAPI char *php_strtolower(char *s, size_t len) { - register int ch; - char *c; - size_t i; - + char *c, *e; + c = s; - for (i=0; i<len; i++) { - ch = tolower((unsigned char)*c); - *c++ = ch; + e = c+len; + + while (c < e) { + *c = tolower(*c); + c++; } return s; } @@ -1039,8 +1062,8 @@ c = s + len - 1; /* do suffix removal as the unix command does */ - if(suffix && (len > sufflen)) { - if(!strncmp(suffix, c-sufflen+1, sufflen)) { + if (suffix && (len > sufflen)) { + if (!strncmp(suffix, c-sufflen+1, sufflen)) { c -= sufflen; buf2 = *(c + 1); /* Save overwritten char */ *(c + 1) = '\0'; /* overwrite char */ @@ -1056,7 +1079,7 @@ #endif ) c--; - if(c < s+len-1) { + if (c < s+len-1) { buf = *(c + 1); /* Save overwritten char */ *(c + 1) = '\0'; /* overwrite char */ p = c + 1; /* Save pointer to overwritten char */ @@ -1071,8 +1094,8 @@ } else { ret = estrdup(s); } - if(buf) *p = buf; - if(buf2) *p2 = buf2; + if (buf) *p = buf; + if (buf2) *p2 = buf2; return (ret); } /* }}} */ @@ -1164,8 +1187,7 @@ zval **str; char *ret; - if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &str) == FAILURE) { + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(str); @@ -1249,9 +1271,8 @@ /* }}} */ /* {{{ php_stristr - * case insensitve strstr */ -PHPAPI char *php_stristr(unsigned char *s, unsigned char *t, - size_t s_len, size_t t_len) + case insensitve strstr */ +PHPAPI char *php_stristr(unsigned char *s, unsigned char *t, size_t s_len, size_t t_len) { php_strtolower(s, s_len); php_strtolower(t, t_len); @@ -1305,8 +1326,7 @@ char *haystack_orig; char needle_char[2]; - if (ZEND_NUM_ARGS() != 2 || - zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { WRONG_PARAM_COUNT; } @@ -1315,36 +1335,27 @@ convert_to_string_ex(haystack); - if (!Z_STRLEN_PP(needle)) { - php_error(E_WARNING, "Empty Delimiter"); - RETURN_FALSE; - } - haystack_orig = estrndup(Z_STRVAL_PP(haystack), Z_STRLEN_PP(haystack)); if (Z_TYPE_PP(needle) == IS_STRING) { if (!Z_STRLEN_PP(needle)) { - php_error(E_WARNING, "Empty Delimiter"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); RETURN_FALSE; } found = php_stristr(Z_STRVAL_PP(haystack), Z_STRVAL_PP(needle), Z_STRLEN_PP(haystack), Z_STRLEN_PP(needle)); - } - else { + } else { convert_to_long_ex(needle); needle_char[0] = (char) Z_LVAL_PP(needle); needle_char[1] = 0; - found = php_stristr(Z_STRVAL_PP(haystack), needle_char, - Z_STRLEN_PP(haystack), 1); + found = php_stristr(Z_STRVAL_PP(haystack), needle_char, Z_STRLEN_PP(haystack), 1); } - + if (found) { found_offset = found - Z_STRVAL_PP(haystack); - RETVAL_STRINGL(haystack_orig + found_offset, - Z_STRLEN_PP(haystack) - found_offset, - 1); + RETVAL_STRINGL(haystack_orig + found_offset, Z_STRLEN_PP(haystack) - found_offset, 1); } else { RETVAL_FALSE; } @@ -1360,6 +1371,7 @@ zval **haystack, **needle; char *found = NULL; char needle_char[2]; + long found_offset; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { @@ -1369,27 +1381,26 @@ if (Z_TYPE_PP(needle) == IS_STRING) { if (!Z_STRLEN_PP(needle)) { - php_error(E_WARNING, "Empty Delimiter"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); RETURN_FALSE; } found = php_memnstr(Z_STRVAL_PP(haystack), - Z_STRVAL_PP(needle), - Z_STRLEN_PP(needle), - Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); - } - else { + Z_STRVAL_PP(needle), + Z_STRLEN_PP(needle), + Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); + } else { convert_to_long_ex(needle); needle_char[0] = (char) Z_LVAL_PP(needle); needle_char[1] = 0; - found = php_memnstr(Z_STRVAL_PP(haystack), - needle_char, 1, + found = php_memnstr(Z_STRVAL_PP(haystack), needle_char, 1, Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); } if (found) { - RETURN_STRING(found, 1); + found_offset = found - Z_STRVAL_PP(haystack); + RETURN_STRINGL(found, Z_STRLEN_PP(haystack) - found_offset, 1); } else { RETURN_FALSE; } @@ -1422,28 +1433,26 @@ } if (offset < 0 || offset > Z_STRLEN_PP(haystack)) { - php_error(E_WARNING, "Offset not contained in string"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string."); RETURN_FALSE; } if (Z_TYPE_PP(needle) == IS_STRING) { if (!Z_STRLEN_PP(needle)) { - php_error(E_WARNING, "Empty Delimiter"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); RETURN_FALSE; } found = php_memnstr(Z_STRVAL_PP(haystack) + offset, - Z_STRVAL_PP(needle), - Z_STRLEN_PP(needle), - Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); - } - else { + Z_STRVAL_PP(needle), + Z_STRLEN_PP(needle), + Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); + } else { convert_to_long_ex(needle); needle_char[0] = (char) Z_LVAL_PP(needle); needle_char[1] = 0; - found = php_memnstr(Z_STRVAL_PP(haystack) + offset, - needle_char, 1, + found = php_memnstr(Z_STRVAL_PP(haystack) + offset, needle_char, 1, Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); } @@ -1489,6 +1498,7 @@ { zval **haystack, **needle; char *found = NULL; + long found_offset; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { @@ -1505,7 +1515,8 @@ } if (found) { - RETURN_STRING(found, 1); + found_offset = found - Z_STRVAL_PP(haystack); + RETURN_STRINGL(found, Z_STRLEN_PP(haystack) - found_offset, 1); } else { RETURN_FALSE; } @@ -1527,7 +1538,7 @@ dest = emalloc((srclen + (chunks + 1) * endlen + 1) * sizeof(char)); - for(p = src, q = dest; p < (src + srclen - chunklen + 1); ) { + for (p = src, q = dest; p < (src + srclen - chunklen + 1); ) { memcpy(q, p, chunklen); q += chunklen; memcpy(q, end, endlen); @@ -1535,7 +1546,7 @@ p += chunklen; } - if(restlen) { + if (restlen) { memcpy(q, p, restlen); q += restlen; memcpy(q, end, endlen); @@ -1581,7 +1592,7 @@ } if (chunklen <= 0) { - php_error(E_WARNING, "Chunk length should be greater than zero"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Chunk length should be greater than zero."); RETURN_FALSE; } @@ -1589,8 +1600,7 @@ RETURN_EMPTY_STRING(); } - result = php_chunk_split(Z_STRVAL_PP(p_str), Z_STRLEN_PP(p_str), - end, endlen, chunklen, &result_len); + result = php_chunk_split(Z_STRVAL_PP(p_str), Z_STRLEN_PP(p_str), end, endlen, chunklen, &result_len); if (result) { RETURN_STRINGL(result, result_len, 0); } else { @@ -1608,8 +1618,7 @@ int f; int argc = ZEND_NUM_ARGS(); - if (argc < 2 || argc > 3 || - zend_get_parameters_ex(argc, &str, &from, &len) == FAILURE) { + if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &str, &from, &len) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(str); @@ -1618,8 +1627,7 @@ if (argc > 2) { convert_to_long_ex(len); l = Z_LVAL_PP(len); - } - else { + } else { l = Z_STRLEN_PP(str); } @@ -1649,7 +1657,7 @@ RETURN_FALSE; } - if((f + l) > Z_STRLEN_PP(str)) { + if ((f + l) > Z_STRLEN_PP(str)) { l = Z_STRLEN_PP(str) - f; } @@ -1661,20 +1669,20 @@ Replaces part of a string with another string */ PHP_FUNCTION(substr_replace) { - zval **str; - zval **from; - zval **len; - zval **repl; - char *result; - int result_len; - int l; - int f; - int argc = ZEND_NUM_ARGS(); + zval **str; + zval **from; + zval **len; + zval **repl; + char *result; + int result_len; + int l; + int f; + int argc = ZEND_NUM_ARGS(); - if (argc < 3 || argc > 4 || - zend_get_parameters_ex(argc, &str, &repl, &from, &len) == FAILURE) { + if (argc < 3 || argc > 4 || zend_get_parameters_ex(argc, &str, &repl, &from, &len) == FAILURE) { WRONG_PARAM_COUNT; } + convert_to_string_ex(str); convert_to_string_ex(repl); convert_to_long_ex(from); @@ -1711,7 +1719,7 @@ } } - if((f + l) > Z_STRLEN_PP(str)) { + if ((f + l) > Z_STRLEN_PP(str)) { l = Z_STRLEN_PP(str) - f; } @@ -1720,8 +1728,7 @@ memcpy(result, Z_STRVAL_PP(str), f); memcpy(&result[f], Z_STRVAL_PP(repl), Z_STRLEN_PP(repl)); - memcpy(&result[f + Z_STRLEN_PP(repl)], Z_STRVAL_PP(str) + f + l, - Z_STRLEN_PP(str) - f - l); + memcpy(&result[f + Z_STRLEN_PP(repl)], Z_STRVAL_PP(str) + f + l, Z_STRLEN_PP(str) - f - l); RETURN_STRINGL(result, result_len, 0); } @@ -1737,8 +1744,7 @@ char *p, *q; char c; - if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &arg) == FAILURE) { + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(arg); @@ -1752,9 +1758,9 @@ str = emalloc(2 * Z_STRLEN_PP(arg) + 1); - for(p = old, q = str; p != old_end; p++) { + for (p = old, q = str; p != old_end; p++) { c = *p; - switch(c) { + switch (c) { case '.': case '\\': case '+': @@ -1819,14 +1825,13 @@ { zval **str; - if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &str) == FAILURE) { + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(str); if (!Z_STRLEN_PP(str)) { - RETURN_FALSE; + RETURN_EMPTY_STRING(); } ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); @@ -1847,7 +1852,7 @@ convert_to_string_ex(str); if (!Z_STRLEN_PP(str)) { - RETURN_FALSE; + RETURN_EMPTY_STRING(); } ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); @@ -1992,14 +1997,14 @@ } if (ac == 2 && Z_TYPE_PP(from) != IS_ARRAY) { - php_error(E_WARNING, "arg2 must be passed an array"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument is not an array."); RETURN_FALSE; } convert_to_string_ex(str); /* shortcut for empty string */ - if(Z_STRLEN_PP(str) == 0) { + if (Z_STRLEN_PP(str) == 0) { RETURN_EMPTY_STRING(); } @@ -2028,7 +2033,7 @@ int i, len; char c; - if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &str)==FAILURE) { + if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &str) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(str); @@ -2071,8 +2076,7 @@ /* {{{ php_similar_char */ -static int php_similar_char(const char *txt1, int len1, - const char *txt2, int len2) +static int php_similar_char(const char *txt1, int len1, const char *txt2, int len2) { int sum; int pos1, pos2, max; @@ -2098,26 +2102,27 @@ int ac = ZEND_NUM_ARGS(); int sim; - if (ac < 2 || ac > 3 || - zend_get_parameters_ex(ac, &t1, &t2, &percent) == FAILURE) { + if (ac < 2 || ac > 3 || zend_get_parameters_ex(ac, &t1, &t2, &percent) == FAILURE) { WRONG_PARAM_COUNT; } + convert_to_string_ex(t1); convert_to_string_ex(t2); + if (ac > 2) { convert_to_double_ex(percent); } if (Z_STRLEN_PP(t1) + Z_STRLEN_PP(t2) == 0) { - if(ac > 2) { + if (ac > 2) { Z_DVAL_PP(percent) = 0; } RETURN_LONG(0); } - sim = php_similar_char(Z_STRVAL_PP(t1), Z_STRLEN_PP(t1), - Z_STRVAL_PP(t2), Z_STRLEN_PP(t2)); + sim = php_similar_char(Z_STRVAL_PP(t1), Z_STRLEN_PP(t1), Z_STRVAL_PP(t2), Z_STRLEN_PP(t2)); + if (ac > 2) { Z_DVAL_PP(percent) = sim * 200.0 / (Z_STRLEN_PP(t1) + Z_STRLEN_PP(t2)); } @@ -2133,8 +2138,6 @@ { char *s, *t; int l; - char escape_char='\\'; - if (len != NULL) { l = *len; @@ -2146,15 +2149,23 @@ if (PG(magic_quotes_sybase)) { while (l > 0) { - if(*t=='\'') { - if((l>0) && (t[1]=='\'')) { + if (*t == '\'') { + if ((l > 0) && (t[1] == '\'')) { t++; if (len != NULL) (*len)--; l--; } - } - *s++ = *t++; + *s++ = *t++; + } else if (*t == '\\' && l > 0 && t[1] == '0') { + *s++='\0'; + t += 2; + if (len != NULL) + (*len)--; + l--; + } else { + *s++ = *t++; + } l--; } *s = '\0'; @@ -2163,13 +2174,13 @@ } while (l > 0) { - if (*t == escape_char) { + if (*t == '\\') { t++; /* skip the slash */ if (len != NULL) (*len)--; l--; if (l > 0) { - if(*t=='0') { + if (*t == '0') { *s++='\0'; t++; } else { @@ -2199,8 +2210,7 @@ { zval **str, **what; - if (ZEND_NUM_ARGS() != 2 || - zend_get_parameters_ex(2, &str, &what) == FAILURE) { + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &str, &what) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(str); @@ -2218,8 +2228,7 @@ Z_STRLEN_PP(str), &Z_STRLEN_P(return_value), 0, Z_STRVAL_PP(what), - Z_STRLEN_PP(what) TSRMLS_CC), - 0); + Z_STRLEN_PP(what) TSRMLS_CC), 0); } /* }}} */ @@ -2229,8 +2238,7 @@ { zval **str; - if (ZEND_NUM_ARGS() != 1 || - zend_get_parameters_ex(1, &str) == FAILURE) { + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(str); @@ -2242,8 +2250,7 @@ RETURN_STRING(php_addslashes(Z_STRVAL_PP(str), Z_STRLEN_PP(str), &Z_STRLEN_P(return_value), 0 - TSRMLS_CC), - 0); + TSRMLS_CC), 0); } /* }}} */ @@ -2303,8 +2310,8 @@ int nlen = *len, i; char numtmp[4]; - for (source=str, end=str+nlen, target=str; source<end; source++) { - if (*source == '\\' && source+1<end) { + for (source=str, end=str+nlen, target=str; source < end; source++) { + if (*source == '\\' && source+1 < end) { source++; switch (*source) { case 'n': *target++='\n'; nlen--; break; @@ -2315,9 +2322,9 @@ case 'b': *target++='\b'; nlen--; break; case 'f': *target++='\f'; nlen--; break; case '\\': *target++='\\'; nlen--; break; - case 'x': if (source+1<end && isxdigit((int)(*(source+1)))) { + case 'x': if (source+1 < end && isxdigit((int)(*(source+1)))) { numtmp[0] = *++source; - if (source+1<end && isxdigit((int)(*(source+1)))) { + if (source+1 < end && isxdigit((int)(*(source+1)))) { numtmp[1] = *++source; numtmp[2] = '\0'; nlen-=3; @@ -2330,7 +2337,7 @@ } /* break is left intentionally */ default: i=0; - while (source<end && *source>='0' && *source<='7' && i<3) { + while (source < end && *source >= '0' && *source <= '7' && i<3) { numtmp[i++] = *source++; } if (i) { @@ -2348,7 +2355,7 @@ } } - if(nlen != 0) { + if (nlen != 0) { *target='\0'; } @@ -2377,7 +2384,7 @@ php_charmask(what, wlength, flags TSRMLS_CC); - for (source=str, end=source+length, target=new_str; (c=*source) || source<end; source++) { + for (source = str, end = source+length, target = new_str; (c=*source) || (source < end); source++) { if (flags[(unsigned char)c]) { if ((unsigned char)c<32 || (unsigned char)c>126) { *target++ = '\\'; @@ -2399,7 +2406,7 @@ } *target = 0; newlen = target-new_str; - if (target-new_str<length*4) { + if (target-new_str < length*4) { new_str = erealloc(new_str, newlen+1); } if (new_length) { @@ -2428,9 +2435,9 @@ } new_str = (char *) emalloc((length?length:(length=strlen(str)))*2+1); if (PG(magic_quotes_sybase)) { - for (source=str, end=source+length, target=new_str; source<end; source++) { + for (source = str, end = source+length, target = new_str; source < end; source++) { c = *source; - switch(c) { + switch (c) { case '\0': *target++ = '\\'; *target++ = '0'; @@ -2444,11 +2451,10 @@ break; } } - } - else { - for (source=str, end=source+length, target=new_str; source<end; source++) { + } else { + for (source = str, end = source+length, target = new_str; source < end; source++) { c = *source; - switch(c) { + switch (c) { case '\0': *target++ = '\\'; *target++ = '0'; @@ -2471,6 +2477,7 @@ if (should_free) { STR_FREE(str); } + new_str = (char *) erealloc(new_str, *new_length+1); return new_str; } /* }}} */ @@ -2489,13 +2496,13 @@ int replaced = 0; char *source, *target, *tmp, *source_end=str+len, *tmp_end = NULL; - for (source=str; source<source_end; source++) { - if (*source==from) { + for (source = str; source < source_end; source++) { + if (*source == from) { char_count++; } } - if (char_count==0) { + if (char_count == 0) { ZVAL_STRINGL(result, str, len, 1); return 0; } @@ -2672,7 +2679,7 @@ while (zend_hash_get_current_data(Z_ARRVAL_P(search), (void **) &search_entry) == SUCCESS) { /* Make sure we're dealing with strings. */ convert_to_string_ex(search_entry); - if(Z_STRLEN_PP(search_entry) == 0) { + if (Z_STRLEN_PP(search_entry) == 0) { zend_hash_move_forward(Z_ARRVAL_P(search)); continue; } @@ -2696,7 +2703,7 @@ } } - if(Z_STRLEN_PP(search_entry) == 1) { + if (Z_STRLEN_PP(search_entry) == 1) { php_char_to_str(Z_STRVAL_P(result), Z_STRLEN_P(result), Z_STRVAL_PP(search_entry)[0], @@ -2751,7 +2758,7 @@ ulong num_key; int boyer = 0; - if(ZEND_NUM_ARGS() < 3 || + if (ZEND_NUM_ARGS() < 3 || ZEND_NUM_ARGS() > 4 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &search, &replace, &subject, &pboyer) == FAILURE) { @@ -2788,7 +2795,7 @@ MAKE_STD_ZVAL(result); php_str_replace_in_subject(*search, *replace, subject_entry, result, boyer); /* Add to return array */ - switch(zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key, + switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key, &string_key_len, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: add_assoc_zval_ex(return_value, string_key, string_key_len, result); @@ -2821,14 +2828,14 @@ int begin, end, char_count, orig_begin; - switch(ZEND_NUM_ARGS()) { + switch (ZEND_NUM_ARGS()) { case 1: - if (zend_get_parameters_ex(1, &str)==FAILURE) { + if (zend_get_parameters_ex(1, &str) == FAILURE) { RETURN_FALSE; } break; case 2: - if (zend_get_parameters_ex(2, &str, &max_chars_per_line)==FAILURE) { + if (zend_get_parameters_ex(2, &str, &max_chars_per_line) == FAILURE) { RETURN_FALSE; } convert_to_long_ex(max_chars_per_line); @@ -2841,7 +2848,7 @@ convert_to_string_ex(str); - if (Z_STRLEN_PP(str)==0) { + if (Z_STRLEN_PP(str) == 0) { RETURN_FALSE; } @@ -2862,13 +2869,13 @@ } do { - if (block_type==_HEB_BLOCK_TYPE_HEB) { - while((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end<Z_STRLEN_PP(str)-1) { + if (block_type == _HEB_BLOCK_TYPE_HEB) { + while ((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end<Z_STRLEN_PP(str)-1) { tmp++; block_end++; block_length++; } - for (i=block_start; i<=block_end; i++) { + for (i = block_start; i<= block_end; i++) { *target = Z_STRVAL_PP(str)[i]; switch (*target) { case '(': @@ -2908,23 +2915,23 @@ } block_type = _HEB_BLOCK_TYPE_ENG; } else { - while(!isheb(*(tmp+1)) && (int)*(tmp+1)!='\n' && block_end<Z_STRLEN_PP(str)-1) { + while (!isheb(*(tmp+1)) && (int)*(tmp+1)!='\n' && block_end < Z_STRLEN_PP(str)-1) { tmp++; block_end++; block_length++; } - while ((_isblank((int)*tmp) || ispunct((int)*tmp)) && *tmp!='/' && *tmp!='-' && block_end>block_start) { + while ((_isblank((int)*tmp) || ispunct((int)*tmp)) && *tmp!='/' && *tmp!='-' && block_end > block_start) { tmp--; block_end--; } - for (i=block_end; i>=block_start; i--) { + for (i = block_end; i >= block_start; i--) { *target = Z_STRVAL_PP(str)[i]; target--; } block_type = _HEB_BLOCK_TYPE_HEB; } block_start=block_end+1; - } while(block_end<Z_STRLEN_PP(str)-1); + } while (block_end < Z_STRLEN_PP(str)-1); broken_str = (char *) emalloc(Z_STRLEN_PP(str)+1); @@ -2933,28 +2940,28 @@ while (1) { char_count=0; - while ((!max_chars || char_count<max_chars) && begin>0) { + while ((!max_chars || char_count < max_chars) && begin > 0) { char_count++; begin--; - if (begin<=0 || _isnewline(heb_str[begin])) { - while(begin>0 && _isnewline(heb_str[begin-1])) { + if (begin <= 0 || _isnewline(heb_str[begin])) { + while (begin > 0 && _isnewline(heb_str[begin-1])) { begin--; char_count++; } break; } } - if (char_count==max_chars) { /* try to avoid breaking words */ + if (char_count == max_chars) { /* try to avoid breaking words */ int new_char_count=char_count, new_begin=begin; - while (new_char_count>0) { + while (new_char_count > 0) { if (_isblank(heb_str[new_begin]) || _isnewline(heb_str[new_begin])) { break; } new_begin++; new_char_count--; } - if (new_char_count>0) { + if (new_char_count > 0) { char_count=new_char_count; begin=new_begin; } @@ -2964,20 +2971,20 @@ if (_isblank(heb_str[begin])) { heb_str[begin]='\n'; } - while (begin<=end && _isnewline(heb_str[begin])) { /* skip leading newlines */ + while (begin <= end && _isnewline(heb_str[begin])) { /* skip leading newlines */ begin++; } - for (i=begin; i<=end; i++) { /* copy content */ + for (i = begin; i <= end; i++) { /* copy content */ *target = heb_str[i]; target++; } - for (i=orig_begin; i<=end && _isnewline(heb_str[i]); i++) { + for (i = orig_begin; i <= end && _isnewline(heb_str[i]); i++) { *target = heb_str[i]; target++; } begin=orig_begin; - if (begin<=0) { + if (begin <= 0) { *target = 0; break; } @@ -3038,12 +3045,9 @@ int new_length, length; char *p, *end, *target; int repl_cnt = 0; - - int state = 0; - /* 0 - initial; 1 - \r found; 2 - \n found; */ - - int action; - /* actions: + int state = 0; /* 0 - initial; 1 - \r found; 2 - \n found; */ + int action; + /* actions: 0 - do nothing; 1 - replace \n; 2 - replace \r 3 - replace \n\r; 4 - replace \r\n; */ @@ -3127,14 +3131,14 @@ char *allowed_tags=NULL; int allowed_tags_len=0; - switch(ZEND_NUM_ARGS()) { + switch (ZEND_NUM_ARGS()) { case 1: - if(zend_get_parameters_ex(1, &str)==FAILURE) { + if (zend_get_parameters_ex(1, &str) == FAILURE) { RETURN_FALSE; } break; case 2: - if(zend_get_parameters_ex(2, &str, &allow)==FAILURE) { + if (zend_get_parameters_ex(2, &str, &allow) == FAILURE) { RETURN_FALSE; } convert_to_string_ex(allow); @@ -3152,68 +3156,95 @@ } /* }}} */ -/* {{{ proto string setlocale(mixed category, string locale) +/* {{{ proto string setlocale(mixed category, string locale [, string ...]) Set locale information */ PHP_FUNCTION(setlocale) { + pval ***args = (pval ***) emalloc(sizeof(pval **)*ZEND_NUM_ARGS()); zval **pcategory, **plocale; - zval *category, *locale; - int cat; + int i, cat, n_args=ZEND_NUM_ARGS(); char *loc, *retval; - if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &pcategory, &plocale)==FAILURE) + if (zend_get_parameters_array_ex(n_args, args) == FAILURE || n_args < 2) { + efree(args); WRONG_PARAM_COUNT; + } #ifdef HAVE_SETLOCALE - convert_to_string_ex(plocale); - locale = *plocale; - + pcategory = args[0]; if (Z_TYPE_PP(pcategory) == IS_LONG) { convert_to_long_ex(pcategory); cat = Z_LVAL_PP(pcategory); } else { /* FIXME: The following behaviour should be removed. */ - php_error(E_NOTICE, "Passing locale category name as string is deprecated. Use the LC_* -constants instead."); + char *category; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passing locale category name as string is deprecated. Use the LC_* -constants instead."); convert_to_string_ex(pcategory); - category = *pcategory; + category = Z_STRVAL_P(*pcategory); - if (!strcasecmp ("LC_ALL", Z_STRVAL_P(category))) + if (!strcasecmp ("LC_ALL", category)) cat = LC_ALL; - else if (!strcasecmp ("LC_COLLATE", Z_STRVAL_P(category))) + else if (!strcasecmp ("LC_COLLATE", category)) cat = LC_COLLATE; - else if (!strcasecmp ("LC_CTYPE", Z_STRVAL_P(category))) + else if (!strcasecmp ("LC_CTYPE", category)) cat = LC_CTYPE; #ifdef LC_MESSAGES - else if (!strcasecmp ("LC_MESSAGES", Z_STRVAL_P(category))) + else if (!strcasecmp ("LC_MESSAGES", category)) cat = LC_MESSAGES; #endif - else if (!strcasecmp ("LC_MONETARY", Z_STRVAL_P(category))) + else if (!strcasecmp ("LC_MONETARY", category)) cat = LC_MONETARY; - else if (!strcasecmp ("LC_NUMERIC", Z_STRVAL_P(category))) + else if (!strcasecmp ("LC_NUMERIC", category)) cat = LC_NUMERIC; - else if (!strcasecmp ("LC_TIME", Z_STRVAL_P(category))) + else if (!strcasecmp ("LC_TIME", category)) cat = LC_TIME; else { - php_error(E_WARNING, "Invalid locale category name %s, must be one of LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC or LC_TIME", Z_STRVAL_P(category)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid locale category name %s, must be one of LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, or LC_TIME.", category); RETURN_FALSE; } } - if (!strcmp ("0", Z_STRVAL_P(locale))) { - loc = NULL; + + if (Z_TYPE_PP(args[1]) == IS_ARRAY) { + zend_hash_internal_pointer_reset(Z_ARRVAL_PP(args[1])); } else { - loc = Z_STRVAL_P(locale); + i=1; } - - retval = setlocale (cat, loc); - if (retval) { - /* Remember if locale was changed */ - if (loc) { - STR_FREE(BG(locale_string)); - BG(locale_string) = estrdup(retval); + while (1) { + if (Z_TYPE_PP(args[1]) == IS_ARRAY) { + zend_hash_get_current_data(Z_ARRVAL_PP(args[1]),(void **)&plocale); + } else { + plocale = args[i]; } - RETVAL_STRING(retval, 1); - return; + convert_to_string_ex(plocale); + + if (!strcmp ("0", Z_STRVAL_PP(plocale))) { + loc = NULL; + } else { + loc = Z_STRVAL_PP(plocale); + } + + retval = setlocale (cat, loc); + if (retval) { + /* Remember if locale was changed */ + if (loc) { + STR_FREE(BG(locale_string)); + BG(locale_string) = estrdup(retval); + } + + efree(args); + RETVAL_STRING(retval, 1); + return; + } + + if (Z_TYPE_PP(args[1]) == IS_ARRAY) { + zend_hash_move_forward(Z_ARRVAL_PP(args[1])); + } else { + if (++i >= n_args) break; + } } + #endif + efree(args); + RETURN_FALSE; } /* }}} */ @@ -3230,7 +3261,7 @@ int old_rg; argCount = ARG_COUNT(ht); - if(argCount < 1 || argCount > 2 || zend_get_parameters_ex(argCount, &arg, &arrayArg) == FAILURE) { + if (argCount < 1 || argCount > 2 || zend_get_parameters_ex(argCount, &arg, &arrayArg) == FAILURE) { WRONG_PARAM_COUNT; } @@ -3241,16 +3272,16 @@ } old_rg = PG(register_globals); - if(argCount == 1) { + if (argCount == 1) { PG(register_globals) = 1; - php_treat_data(PARSE_STRING, res, NULL TSRMLS_CC); + sapi_module.treat_data(PARSE_STRING, res, NULL TSRMLS_CC); } else { PG(register_globals) = 0; /* Clear out the array that was passed in. */ zval_dtor(*arrayArg); array_init(*arrayArg); - php_treat_data(PARSE_STRING, res, *arrayArg TSRMLS_CC); + sapi_module.treat_data(PARSE_STRING, res, *arrayArg TSRMLS_CC); } PG(register_globals) = old_rg; } @@ -3283,32 +3314,34 @@ if (!len) { return 0; } - while(!done) { - switch(c) { - case '<': - *(n++) = c; - break; - case '>': - done =1; - break; - default: - if(!isspace((int)c)) { - if(state==0) { - state=1; - if(c!='/') *(n++) = c; + while (!done) { + switch (c) { + case '<': + *(n++) = c; + break; + case '>': + done =1; + break; + default: + if (!isspace((int)c)) { + if (state == 0) { + state=1; + if (c != '/') + *(n++) = c; + } else { + *(n++) = c; + } } else { - *(n++) = c; + if (state == 1) + done=1; } - } else { - if(state==1) done=1; - } - break; + break; } c = tolower(*(++t)); } *(n++) = '>'; *n = '\0'; - if(strstr(set, norm)) { + if (strstr(set, norm)) { done=1; } else { done=0; @@ -3320,7 +3353,7 @@ /* {{{ php_strip_tags - A simple little state-machine to strip out html and php tags + A simple little state-machine to strip out html and php tags State 0 is the output state, State 1 means we are inside a normal html tag and state 2 means we are inside a php tag. @@ -3341,7 +3374,7 @@ PHPAPI void php_strip_tags(char *rbuf, int len, int *stateptr, char *allow, int allow_len) { char *tbuf, *buf, *p, *tp, *rp, c, lc; - int br, i=0; + int br, i=0, depth=0; int state = 0; if (stateptr) @@ -3353,7 +3386,7 @@ p = buf; rp = rbuf; br = 0; - if(allow) { + if (allow) { php_strtolower(allow, allow_len); tbuf = emalloc(PHP_TAG_BUF_SIZE+1); tp = tbuf; @@ -3361,21 +3394,23 @@ tbuf = tp = NULL; } - while(i<len) { + while (i < len) { switch (c) { case '<': if (state == 0) { lc = '<'; state = 1; - if(allow) { + if (allow) { *(tp++) = '<'; } + } else if (state == 1) { + depth++; } break; case '(': if (state == 2) { - if (lc != '\"') { + if (lc != '"' && lc != '\'') { lc = '('; br++; } @@ -3388,7 +3423,7 @@ case ')': if (state == 2) { - if (lc != '\"') { + if (lc != '"' && lc != '\'') { lc = ')'; br--; } @@ -3400,34 +3435,53 @@ break; case '>': - if (state == 1) { - lc = '>'; - state = 0; - if(allow) { - *(tp++) = '>'; - *tp='\0'; - if(php_tag_find(tbuf, tp-tbuf, allow)) { - memcpy(rp, tbuf, tp-tbuf); - rp += tp-tbuf; - } - tp = tbuf; - } - } else if (state == 2) { - if (!br && lc != '\"' && *(p-1)=='?') { + if (depth) { + depth--; + break; + } + + switch (state) { + case 1: /* HTML/XML */ + lc = '>'; state = 0; - tp = tbuf; - } - } else { - *(rp++) = c; + if (allow) { + *(tp++) = '>'; + *tp='\0'; + if (php_tag_find(tbuf, tp-tbuf, allow)) { + memcpy(rp, tbuf, tp-tbuf); + rp += tp-tbuf; + } + tp = tbuf; + } + break; + + case 2: /* PHP */ + if (!br && lc != '\"' && *(p-1) == '?') { + state = 0; + tp = tbuf; + } + break; + + case 3: /* JavaScript/CSS/etc... */ + if (*(p-1) == '-' && *(p-2) == '-') { + state = 0; + tp = tbuf; + } + break; + + default: + *(rp++) = c; + break; } break; - case '\"': - if (state == 2) { - if (lc == '\"') { + case '"': + case '\'': + if (state == 2 && *(p-1) != '\\') { + if (lc == c) { lc = '\0'; } else if (lc != '\\') { - lc = '\"'; + lc = c; } } else if (state == 0) { *(rp++) = c; @@ -3435,10 +3489,17 @@ *(tp++) = c; } break; - + + case '!': + /* JavaScript & Other HTML scripting languages */ + if (state == 1 && *(p-1) == '<') { + state = 3; + } + break; + case '?': - if (state==1 && *(p-1)=='<') { + if (state == 1 && *(p-1)=='<') { br=0; state=2; break; @@ -3450,7 +3511,7 @@ * state == 2 (PHP). Switch back to HTML. */ - if(state == 2 && *(p-1) == 'm' && *(p-2) == 'x') { + if (state == 2 && *(p-1) == 'm' && *(p-2) == 'x') { state = 1; break; } @@ -3459,9 +3520,9 @@ default: if (state == 0) { *(rp++) = c; - } else if(allow && state == 1) { + } else if (allow && state == 1) { *(tp++) = c; - if( (tp-tbuf)>=PHP_TAG_BUF_SIZE ) { /* no buffer overflows */ + if ( (tp-tbuf) >= PHP_TAG_BUF_SIZE ) { /* no buffer overflows */ tp = tbuf; } } @@ -3472,7 +3533,8 @@ } *rp = '\0'; efree(buf); - if(allow) efree(tbuf); + if (allow) + efree(tbuf); if (stateptr) *stateptr = state; } @@ -3483,10 +3545,9 @@ PHP_FUNCTION(str_repeat) { zval **input_str; /* Input string */ - zval **mult; /* Multiplier */ - char *result; /* Resulting string */ - int result_len; /* Length of the resulting string */ - int i; + zval **mult; /* Multiplier */ + char *result; /* Resulting string */ + int result_len; /* Length of the resulting string */ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) { WRONG_PARAM_COUNT; @@ -3497,8 +3558,7 @@ convert_to_long_ex(mult); if (Z_LVAL_PP(mult) < 0) { - php_error(E_WARNING, "Second argument to %s() has to be greater than or equal to 0", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument has to be greater than or equal to 0."); return; } @@ -3514,12 +3574,24 @@ result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult); result = (char *)emalloc(result_len + 1); - /* Copy the input string into the result as many times as necessary */ - for (i=0; i<Z_LVAL_PP(mult); i++) { - memcpy(result + Z_STRLEN_PP(input_str) * i, - Z_STRVAL_PP(input_str), - Z_STRLEN_PP(input_str)); + /* Heavy optimization for situations where input string is 1 byte long */ + if (Z_STRLEN_PP(input_str) == 1) { + memset(result, *(Z_STRVAL_PP(input_str)), Z_LVAL_PP(mult)); + } else { + char *s, *e, *ee; + int l=0; + memcpy(result, Z_STRVAL_PP(input_str), Z_STRLEN_PP(input_str)); + s = result; + e = result + Z_STRLEN_PP(input_str); + ee = result + result_len; + + while (e<ee) { + l = (e-s) < (ee-e) ? (e-s) : (ee-e); + memmove(e, s, l); + e += l; + } } + result[result_len] = '\0'; RETURN_STRINGL(result, result_len, 0); @@ -3550,7 +3622,7 @@ mymode = Z_LVAL_PP(mode); if (mymode < 0 || mymode > 4) { - php_error(E_WARNING, "unknown mode"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown mode."); RETURN_FALSE; } } @@ -3569,31 +3641,31 @@ array_init(return_value); } - for (inx=0; inx < 256; inx++) { + for (inx = 0; inx < 256; inx++) { switch (mymode) { - case 0: - add_index_long(return_value, inx, chars[inx]); - break; - case 1: - if (chars[inx] != 0) { + case 0: add_index_long(return_value, inx, chars[inx]); - } - break; - case 2: - if (chars[inx] == 0) { - add_index_long(return_value, inx, chars[inx]); - } - break; - case 3: - if (chars[inx] != 0) { - retstr[retlen++] = inx; - } - break; - case 4: - if (chars[inx] == 0) { - retstr[retlen++] = inx; - } - break; + break; + case 1: + if (chars[inx] != 0) { + add_index_long(return_value, inx, chars[inx]); + } + break; + case 2: + if (chars[inx] == 0) { + add_index_long(return_value, inx, chars[inx]); + } + break; + case 3: + if (chars[inx] != 0) { + retstr[retlen++] = inx; + } + break; + case 4: + if (chars[inx] == 0) { + retstr[retlen++] = inx; + } + break; } } @@ -3662,14 +3734,14 @@ /* Grab the grouping data out of the array */ len = strlen(currlocdata.grouping); - for (i=0;i<len;i++) { + for (i = 0; i < len; i++) { add_index_long(grouping, i, currlocdata.grouping[i]); } /* Grab the monetary grouping data out of the array */ len = strlen(currlocdata.mon_grouping); - for (i=0;i<len;i++) { + for (i = 0; i < len; i++) { add_index_long(mon_grouping, i, currlocdata.mon_grouping[i]); } @@ -3744,7 +3816,7 @@ convert_to_string_ex(needle); if (Z_STRLEN_PP(needle) == 0) { - php_error(E_WARNING, "Empty substring"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty substring."); RETURN_FALSE; } else if (Z_STRLEN_PP(needle) == 1) { /* Special optimized case to avoid calls to php_memnstr(). */ @@ -3759,7 +3831,7 @@ p = Z_STRVAL_PP(haystack); endp = p + Z_STRLEN_PP(haystack); while (p <= endp) { - if( (p = php_memnstr(p, Z_STRVAL_PP(needle), Z_STRLEN_PP(needle), endp)) != NULL ) { + if ( (p = php_memnstr(p, Z_STRVAL_PP(needle), Z_STRLEN_PP(needle), endp)) != NULL ) { p += Z_STRLEN_PP(needle); count++; } else { @@ -3815,8 +3887,7 @@ if (ZEND_NUM_ARGS() > 2) { convert_to_string_ex(pad_string); if (Z_STRLEN_PP(pad_string) == 0) { - php_error(E_WARNING, "Padding string cannot be empty in %s()", - get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding string cannot be empty."); return; } pad_str_val = Z_STRVAL_PP(pad_string); @@ -3826,7 +3897,7 @@ convert_to_long_ex(pad_type); pad_type_val = Z_LVAL_PP(pad_type); if (pad_type_val < STR_PAD_LEFT || pad_type_val > STR_PAD_BOTH) { - php_error(E_WARNING, "Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH in %s()", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH."); return; } } @@ -3874,8 +3945,8 @@ Implements an ANSI C compatible sscanf */ PHP_FUNCTION(sscanf) { - zval ***args; - int result; + zval ***args; + int result; int argc = ZEND_NUM_ARGS(); if (argc < 2) { @@ -3903,29 +3974,160 @@ } /* }}} */ +static char rot13_from[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static char rot13_to[] = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM"; + /* {{{ proto string str_rot13(string str) Perform the rot13 transform on a string */ PHP_FUNCTION(str_rot13) { + zval **arg; + + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg)) { + WRONG_PARAM_COUNT; + } + convert_to_string_ex(arg); + *return_value = **arg; + zval_copy_ctor(return_value); + + php_strtr(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), rot13_from, rot13_to, 52); +} +/* }}} */ + + +static int php_string_shuffle(const void *a, const void *b TSRMLS_DC) +{ + long rnd; + rnd = php_rand(TSRMLS_C); + if (rnd % 3) + return 1; + else if (rnd % 5) + return 0; + else + return -1; +} + +/* {{{ proto string str_shuffle(string str) + Shuffles string. One permutation of all possible is created */ +PHP_FUNCTION(str_shuffle) +{ + /* Note : by using current php_string_shuffle for string */ + /* with 6 chars (6! permutations) about 2/3 of them are */ + /* computed for 6! calls for the function. So it isn't so */ + /* unique. The ratio is the same for other lengths. */ char *str; - int str_len; - static char xfrom[] = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - static char xto[] = "nopqrstuvwxyzabcdefghijklm" - "NOPQRSTUVWXYZABCDEFGHIJKLM"; + int i, str_len; + + i = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { + RETURN_FALSE; + } + zend_qsort((void *)str, str_len, sizeof(char), php_string_shuffle TSRMLS_CC); + RETURN_STRINGL(str, str_len, 1); +} +/* }}} */ + - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", - &str, &str_len) == FAILURE) { +#if HAVE_STRFMON +/* {{{ proto string money_format(string format , float value) + Convert monetary value(s) to string */ + +PHP_FUNCTION(money_format) { + int format_len = 0, str_len; + char *format, *str; + double value; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sd", + &format, &format_len, &value) == FAILURE) { return; } - php_strtr(str, str_len, xfrom, xto, 52); - RETURN_STRINGL(str, str_len, 1); + str_len = format_len + 1024; + str = emalloc(str_len); + str_len = strfmon(str, str_len, format, value); + str[str_len] = 0; + + RETURN_STRINGL(erealloc(str, str_len + 1), str_len, 0); } + /* }}} */ +#endif + +/* {{{ rot13 stream filter implementation */ +static size_t strfilter_rot13_write(php_stream *stream, php_stream_filter *thisfilter, + const char *buf, size_t count TSRMLS_DC) +{ + char rotbuf[1024]; + size_t chunk; + size_t wrote = 0; + + while (count > 0) { + chunk = count; + if (chunk > sizeof(rotbuf)) + chunk = sizeof(rotbuf); + + PHP_STRLCPY(rotbuf, buf, sizeof(rotbuf), chunk); + buf += chunk; + count -= chunk; + + php_strtr(rotbuf, chunk, rot13_from, rot13_to, 52); + wrote += php_stream_filter_write_next(stream, thisfilter, rotbuf, chunk); + } + + return wrote; +} + +static size_t strfilter_rot13_read(php_stream *stream, php_stream_filter *thisfilter, + char *buf, size_t count TSRMLS_DC) +{ + size_t read; + read = php_stream_filter_read_next(stream, thisfilter, buf, count); + php_strtr(buf, read, rot13_from, rot13_to, 52); + return read; +} + +static int strfilter_rot13_flush(php_stream *stream, php_stream_filter *thisfilter, int closing TSRMLS_DC) +{ + return php_stream_filter_flush_next(stream, thisfilter, closing); +} +static int strfilter_rot13_eof(php_stream *stream, php_stream_filter *thisfilter TSRMLS_DC) +{ + return php_stream_filter_eof_next(stream, thisfilter); +} + + +static php_stream_filter_ops strfilter_rot13_ops = { + strfilter_rot13_write, + strfilter_rot13_read, + strfilter_rot13_flush, + strfilter_rot13_eof, + NULL, + "string.rot13" +}; + +static php_stream_filter *strfilter_rot13_create(const char *filtername, const char *filterparams, + int filterparamslen, int persistent TSRMLS_DC) +{ + return php_stream_filter_alloc(&strfilter_rot13_ops, NULL, persistent); +} + +static php_stream_filter_factory strfilter_rot13_factory = { + strfilter_rot13_create +}; + +PHP_MINIT_FUNCTION(string_filters) +{ + return php_stream_filter_register_factory("string.rot13", &strfilter_rot13_factory TSRMLS_CC); +} + +PHP_MSHUTDOWN_FUNCTION(string_filters) +{ + return php_stream_filter_unregister_factory("string.rot13" TSRMLS_CC); +} +/* }}} */ /* * Local variables: 1.3 +3 -5 php4/ext/standard/syslog.c Index: syslog.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/syslog.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- syslog.c 29 Apr 2002 02:31:02 -0000 1.2 +++ syslog.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: syslog.c,v 1.39 2002/03/10 23:45:02 mfischer Exp $ */ +/* $Id: syslog.c,v 1.40 2002/08/24 01:19:28 helly Exp $ */ #include "php.h" @@ -192,8 +192,7 @@ PHP_FUNCTION(define_syslog_variables) { if (ZEND_NUM_ARGS() != 0) { - php_error(E_WARNING, "%s() expects no parameters, %d given", - get_active_function_name(TSRMLS_C), ZEND_NUM_ARGS()); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "expects no parameters, %d given", ZEND_NUM_ARGS()); return; } @@ -234,8 +233,7 @@ PHP_FUNCTION(closelog) { if (ZEND_NUM_ARGS() != 0) { - php_error(E_WARNING, "%s() expects no parameters, %d given", - get_active_function_name(TSRMLS_C), ZEND_NUM_ARGS()); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "expects no parameters, %d given", ZEND_NUM_ARGS()); return; } 1.3 +12 -3 php4/ext/standard/type.c Index: type.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/type.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- type.c 29 Apr 2002 02:31:02 -0000 1.2 +++ type.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,9 +16,10 @@ +----------------------------------------------------------------------+ */ -/* $Id: type.c,v 1.15 2002/02/28 08:26:49 sebastian Exp $ */ +/* $Id: type.c,v 1.20 2002/08/24 01:19:28 helly Exp $ */ #include "php.h" +#include "php_incomplete_class.h" /* {{{ proto string gettype(mixed var) Returns the type of the variable */ @@ -115,10 +116,10 @@ } else if (!strcasecmp(new_type, "null")) { convert_to_null(*var); } else if (!strcasecmp(new_type, "resource")) { - php_error(E_WARNING, "settype: cannot convert to resource type"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot convert to resource type"); RETURN_FALSE; } else { - php_error(E_WARNING, "settype: invalid type"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type"); RETURN_FALSE; } RETVAL_TRUE; @@ -195,10 +196,18 @@ pval **arg; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only one argument expected"); RETURN_FALSE; } if (Z_TYPE_PP(arg) == type) { + if (type == IS_OBJECT) { + zend_class_entry *ce; + ce = Z_OBJCE_PP(arg); + if (!strcmp(ce->name, INCOMPLETE_CLASS)) { + RETURN_FALSE; + } + } RETURN_TRUE; } else { RETURN_FALSE; 1.3 +149 -82 php4/ext/standard/url.c Index: url.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/url.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- url.c 29 Apr 2002 02:31:03 -0000 1.2 +++ url.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -15,7 +15,7 @@ | Author: Jim Winstead <jimw****@php*****> | +----------------------------------------------------------------------+ */ -/* $Id: url.c,v 1.51 2002/02/28 08:26:49 sebastian Exp $ */ +/* $Id: url.c,v 1.53 2002/10/06 16:14:42 iliaa Exp $ */ #include <stdlib.h> #include <string.h> @@ -58,103 +58,170 @@ } /* }}} */ +/* {{{ php_replace_controlchars + */ +PHPAPI char *php_replace_controlchars(char *str) +{ + unsigned char *s = (unsigned char *)str; + + if (!str) { + return (NULL); + } + + while (*s) { + + if (iscntrl(*s)) { + *s='_'; + } + s++; + } + + return (str); +} +/* }}} */ + + /* {{{ php_url_parse */ PHPAPI php_url *php_url_parse(char *str) { - regex_t re; - regmatch_t subs[11]; - int err; int length = strlen(str); - char *result; + char port_buf[5]; php_url *ret = ecalloc(1, sizeof(php_url)); + char *s, *e, *p, *pp, *ue; + + s = str; + ue = s + length; - /* from Appendix B of draft-fielding-url-syntax-09, - http://www.ics.uci.edu/~fielding/url/url.txt */ - err = regcomp(&re, "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", REG_EXTENDED); - if (err) { - /*php_error(E_WARNING, "Unable to compile regex: %d\n", err);*/ - efree(ret); - return NULL; - } - err = regexec(&re, str, 10, subs, 0); - if (err) { - /*php_error(E_WARNING, "Error with regex\n");*/ - efree(ret); - regfree(&re); - return NULL; - } - /* no processing necessary on the scheme */ - if (subs[2].rm_so != -1 && subs[2].rm_so <= length) { - ret->scheme = estrndup(str + subs[2].rm_so, subs[2].rm_eo - subs[2].rm_so); - } - - /* the path to the resource */ - if (subs[5].rm_so != -1 && subs[5].rm_so <= length) { - ret->path = estrndup(str + subs[5].rm_so, subs[5].rm_eo - subs[5].rm_so); - } - - /* the query part */ - if (subs[7].rm_so != -1 && subs[7].rm_so <= length) { - ret->query = estrndup(str + subs[7].rm_so, subs[7].rm_eo - subs[7].rm_so); - } - - /* the fragment */ - if (subs[9].rm_so != -1 && subs[9].rm_so <= length) { - ret->fragment = estrndup(str + subs[9].rm_so, subs[9].rm_eo - subs[9].rm_so); - } - - /* extract the username, pass, and port from the hostname */ - if (subs[4].rm_so != -1 && subs[4].rm_so <= length) { - - int cerr; - /* extract username:pass @ host:port from regex results */ - result = estrndup(str + subs[4].rm_so, subs[4].rm_eo - subs[4].rm_so); - length = strlen(result); - - regfree(&re); /* free the old regex */ + /* parse scheme */ + if ((e = strchr(s, ':')) && *(e+1) == '/' && *(e+2) == '/' && (e-s)) { + ret->scheme = estrndup(s, (e-s)); + php_replace_controlchars(ret->scheme); + s = e + 3; + } else if (e) { /* no scheme, look for port */ + p = e + 1; + pp = p; - if (length) { - if ((cerr=regcomp(&re, "^(([^@:]+)(:([^@:]+))?@)?((\\[([^]]+)\\])|([^:@]+))(:([^:@]+))?", REG_EXTENDED)) - || (err=regexec(&re, result, 11, subs, 0))) { + while (pp-p < 6 && isdigit(*pp)) { + pp++; + } + + if (pp-p < 6 && (*pp == '/' || *pp == '\0')) { + memcpy(port_buf, p, (pp-p)); + port_buf[pp-p] = '\0'; + ret->port = atoi(port_buf); + } else { + goto just_path; + } + } else { + just_path: + ret->path = estrndup(str, length); + php_replace_controlchars(ret->path); + return ret; + } + + if (!(e = strchr(s, '/'))) { + e = ue; + } + + /* check for login and password */ + if ((p = memchr(s, '@', (e-s)))) { + if ((pp = memchr(s, ':', (p-s)))) { + if ((pp-s) > 0) { + ret->user = estrndup(s, (pp-s)); + php_replace_controlchars(ret->user); + } + + if (p-pp > 1) { + ret->pass = estrndup(++pp, (p-pp-1)); + php_replace_controlchars(ret->pass); + } + } + + s = p + 1; + } + + /* check for port */ + if ((p = memchr(s, ':', (e-s)))) { + if (!ret->port) { + p++; + if ( e-p > 5 || e-p < 1 ) { /* port cannot be longer then 5 characters */ STR_FREE(ret->scheme); - STR_FREE(ret->path); - STR_FREE(ret->query); - STR_FREE(ret->fragment); + STR_FREE(ret->user); + STR_FREE(ret->pass); efree(ret); - efree(result); - /*php_error(E_WARNING, "Unable to compile regex: %d\n", err);*/ - if (!cerr) regfree(&re); return NULL; } - /* now deal with all of the results */ - if (subs[2].rm_so != -1 && subs[2].rm_so < length) { - ret->user = estrndup(result + subs[2].rm_so, subs[2].rm_eo - subs[2].rm_so); - } - if (subs[4].rm_so != -1 && subs[4].rm_so < length) { - ret->pass = estrndup(result + subs[4].rm_so, subs[4].rm_eo - subs[4].rm_so); - } - if (subs[7].rm_so != -1 && subs[7].rm_so < length) { - ret->host = estrndup(result + subs[7].rm_so, subs[7].rm_eo - subs[7].rm_so); - } else if (subs[8].rm_so != -1 && subs[8].rm_so < length) { - ret->host = estrndup(result + subs[8].rm_so, subs[8].rm_eo - subs[8].rm_so); - } - if (subs[10].rm_so != -1 && subs[10].rm_so < length) { - ret->port = (unsigned short) strtol(result + subs[10].rm_so, NULL, 10); - } - } - efree(result); - } - else if (ret->scheme && !strcmp(ret->scheme, "http")) { + + memcpy(port_buf, p, (e-p)); + port_buf[e-p] = '\0'; + ret->port = atoi(port_buf); + p--; + } + } else { + p = e; + } + + /* check if we have a valid host, if we don't reject the string as url */ + if ((p-s) < 1) { STR_FREE(ret->scheme); - STR_FREE(ret->path); - STR_FREE(ret->query); - STR_FREE(ret->fragment); + STR_FREE(ret->user); + STR_FREE(ret->pass); efree(ret); - regfree(&re); return NULL; } - regfree(&re); + + ret->host = estrndup(s, (p-s)); + php_replace_controlchars(ret->host); + + if (e == ue) { + return ret; + } + + s = e; + + if ((p = strchr(s, '?'))) { + pp = strchr(s, '#'); + + if (pp && pp < p) { + p = pp; + pp = strchr(pp+2, '#'); + } + + if (p - s) { + ret->path = estrndup(s, (p-s)); + php_replace_controlchars(ret->path); + } + + if (pp) { + if (pp - ++p) { + ret->query = estrndup(p, (pp-p)); + php_replace_controlchars(ret->query); + } + p = pp; + goto label_parse; + } else if (++p - ue) { + ret->query = estrndup(p, (ue-p)); + php_replace_controlchars(ret->query); + } + } else if ((p = strchr(s, '#'))) { + if (p - s) { + ret->path = estrndup(s, (p-s)); + php_replace_controlchars(ret->path); + } + + label_parse: + p++; + + if (ue - p) { + ret->fragment = estrndup(p, (ue-p)); + php_replace_controlchars(ret->fragment); + } + } else { + ret->path = estrndup(s, (ue-s)); + php_replace_controlchars(ret->path); + } + return ret; } /* }}} */ 1.3 +3 -1 php4/ext/standard/url_scanner.c Index: url_scanner.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/url_scanner.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- url_scanner.c 29 Apr 2002 02:31:03 -0000 1.2 +++ url_scanner.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -15,7 +15,7 @@ | Author: Hartmut Holzgraefe <hartm****@six*****> | +----------------------------------------------------------------------+ */ -/* $Id: url_scanner.c,v 1.37 2001/12/11 15:30:37 sebastian Exp $ */ +/* $Id: url_scanner.c,v 1.38 2002/08/28 06:13:49 kalowsky Exp $ */ #include "php.h" @@ -361,6 +361,8 @@ US.p = US.val+US.l; } } + break; + default: break; } 1.6 +141 -104 php4/ext/standard/url_scanner_ex.c Index: url_scanner_ex.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/url_scanner_ex.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- url_scanner_ex.c 2 Aug 2002 22:05:24 -0000 1.5 +++ url_scanner_ex.c 6 Oct 2002 21:54:32 -0000 1.6 @@ -1,5 +1,5 @@ -/* Generated by re2c 0.5 on Wed May 8 08:08:09 2002 */ -#line 1 "/home/rasmus/php4/ext/standard/url_scanner_ex.re" +/* Generated by re2c 0.5 on Mon Sep 30 06:55:58 2002 */ +#line 1 "/home/sas/src/php4/ext/standard/url_scanner_ex.re" /* +----------------------------------------------------------------------+ | PHP Version 4 | @@ -83,10 +83,10 @@ } PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("url_rewriter.tags", "a=href,area=href,frame=src,form=fakeentry", PHP_INI_ALL, OnUpdateTags, url_adapt_state_ex, php_basic_globals, basic_globals) + STD_PHP_INI_ENTRY("url_rewriter.tags", "a=href,area=href,frame=src,form=,fieldset=", PHP_INI_ALL, OnUpdateTags, url_adapt_state_ex, php_basic_globals, basic_globals) PHP_INI_END() -#line 91 +#line 92 #define YYFILL(n) goto done @@ -151,25 +151,25 @@ if(yych >= ';') goto yy4; yy2: yych = *++YYCURSOR; yy3: -#line 109 +#line 110 { smart_str_append(dest, url); return; } yy4: yych = *++YYCURSOR; yy5: -#line 110 +#line 111 { sep = separator; goto scan; } yy6: yych = *++YYCURSOR; yy7: -#line 111 +#line 112 { bash = p - 1; goto done; } yy8: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy9: if(yybm[0+yych] & 128) goto yy8; yy10: -#line 112 +#line 113 { goto scan; } } -#line 113 +#line 114 done: @@ -235,20 +235,48 @@ #define STD_PARA url_adapt_state_ex_t *ctx, char *start, char *YYCURSOR TSRMLS_DC #define STD_ARGS ctx, start, xp TSRMLS_CC +#if SCANNER_DEBUG +#define scdebug(x) printf x +#else +#define scdebug(x) +#endif + static inline void passthru(STD_PARA) { + scdebug(("appending %d chars, starting with %c\n", YYCURSOR-start, *start)); smart_str_appendl(&ctx->result, start, YYCURSOR - start); } -static inline void handle_form(STD_PARA) +/* + * This function appends a hidden input field after a <form> or + * <fieldset>. The latter is important for XHTML. + */ + +static void handle_form(STD_PARA) { - if (ctx->form_app.len > 0 - && ctx->tag.len == 4 - && strncasecmp(ctx->tag.c, "form", 4) == 0) { - smart_str_append(&ctx->result, &ctx->form_app); + int doit = 0; + + if (ctx->form_app.len > 0) { + switch (ctx->tag.len) { + +#define RECOGNIZE(x) do { \ + case sizeof(x)-1: \ + if (strncasecmp(ctx->tag.c, x, sizeof(x)-1) == 0) \ + doit = 1; \ + break; \ +} while (0) + + RECOGNIZE("form"); + RECOGNIZE("fieldset"); + } + + if (doit) + smart_str_append(&ctx->result, &ctx->form_app); } } + + /* * HANDLE_TAG copies the HTML Tag and checks whether we * have that tag in our table. If we might modify it, @@ -282,12 +310,6 @@ tag_arg(ctx, quotes, type TSRMLS_CC); } -#ifdef SCANNER_DEBUG -#define scdebug(x) printf x -#else -#define scdebug(x) -#endif - static inline void xx_mainloop(url_adapt_state_ex_t *ctx, const char *newdata, size_t newlen TSRMLS_DC) { char *end, *q; @@ -360,17 +382,17 @@ if(yybm[0+yych] & 128) goto yy15; yy13: yych = *++YYCURSOR; yy14: -#line 259 +#line 282 { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; } yy15: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy16: if(yybm[0+yych] & 128) goto yy15; yy17: -#line 260 +#line 283 { passthru(STD_ARGS); goto state_plain; } } -#line 261 +#line 284 state_tag: @@ -424,11 +446,11 @@ yy20: yych = *++YYCURSOR; goto yy25; yy21: -#line 266 +#line 289 { handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; } yy22: yych = *++YYCURSOR; yy23: -#line 267 +#line 290 { passthru(STD_ARGS); goto state_plain_begin; } yy24: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); @@ -436,7 +458,7 @@ yy25: if(yybm[0+yych] & 128) goto yy24; goto yy21; } -#line 268 +#line 291 state_next_arg_begin: @@ -507,20 +529,20 @@ } yy28: yych = *++YYCURSOR; yy29: -#line 276 +#line 299 { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; } yy30: yych = *++YYCURSOR; goto yy37; yy31: -#line 277 +#line 300 { passthru(STD_ARGS); goto state_next_arg; } yy32: yych = *++YYCURSOR; yy33: -#line 278 +#line 301 { --YYCURSOR; STATE = STATE_ARG; goto state_arg; } yy34: yych = *++YYCURSOR; yy35: -#line 279 +#line 302 { passthru(STD_ARGS); goto state_plain_begin; } yy36: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); @@ -528,7 +550,7 @@ yy37: if(yybm[0+yych] & 128) goto yy36; goto yy31; } -#line 280 +#line 303 state_arg: @@ -542,7 +564,7 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, @@ -582,11 +604,11 @@ yy40: yych = *++YYCURSOR; goto yy45; yy41: -#line 285 +#line 308 { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; } yy42: yych = *++YYCURSOR; yy43: -#line 286 +#line 309 { passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; } yy44: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); @@ -594,7 +616,7 @@ yy45: if(yybm[0+yych] & 128) goto yy44; goto yy41; } -#line 287 +#line 310 state_before_val: @@ -649,12 +671,12 @@ if(yych == ' ') goto yy55; if(yych == '=') goto yy53; yy49: -#line 293 +#line 316 { --YYCURSOR; goto state_next_arg_begin; } yy50: yych = *++YYCURSOR; goto yy54; yy51: -#line 292 +#line 315 { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; } yy52: yych = *++YYCURSOR; goto yy49; @@ -673,7 +695,7 @@ case 0: goto yy49; } } -#line 294 +#line 317 @@ -683,50 +705,50 @@ YYCTYPE yych; unsigned int yyaccept; static unsigned char yybm[] = { - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 192, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 192, 224, 64, 224, 224, 224, 224, 128, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 0, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 160, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 160, 248, 56, 248, 248, 248, 248, 200, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 0, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, }; goto yy58; yy59: ++YYCURSOR; yy58: - if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; if(yych <= '!'){ if(yych <= '\n'){ if(yych <= '\t') goto yy63; - goto yy65; + goto yy64; } else { - if(yych == ' ') goto yy65; + if(yych == ' ') goto yy64; goto yy63; } } else { @@ -735,56 +757,74 @@ if(yych <= '&') goto yy63; goto yy62; } else { - if(yych == '>') goto yy65; + if(yych == '>') goto yy64; goto yy63; } } yy60: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if(yych != '>') goto yy74; + goto yy77; yy61: -#line 303 - { passthru(STD_ARGS); goto state_next_arg_begin; } +#line 325 + { handle_val(STD_ARGS, 0, '\0'); goto state_next_arg_begin; } yy62: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if(yych == '>') goto yy61; goto yy69; yy63: yych = *++YYCURSOR; goto yy67; -yy64: -#line 302 - { handle_val(STD_ARGS, 0, '"'); goto state_next_arg_begin; } -yy65: yych = *++YYCURSOR; - goto yy61; +yy64: yych = *++YYCURSOR; +yy65: +#line 326 + { passthru(STD_ARGS); goto state_next_arg_begin; } yy66: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy67: if(yybm[0+yych] & 32) goto yy66; - goto yy64; -yy68: ++YYCURSOR; +yy67: if(yybm[0+yych] & 8) goto yy66; + goto yy61; +yy68: yyaccept = 0; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy69: if(yybm[0+yych] & 16) goto yy68; + if(yych <= '&') goto yy72; + if(yych >= '(') goto yy61; +yy70: yych = *++YYCURSOR; + if(yybm[0+yych] & 8) goto yy66; +yy71: +#line 324 + { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; } +yy72: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy69: if(yybm[0+yych] & 64) goto yy68; - if(yych <= '=') goto yy71; -yy70: YYCURSOR = YYMARKER; +yy73: if(yybm[0+yych] & 32) goto yy72; + if(yych <= '=') goto yy75; +yy74: YYCURSOR = YYMARKER; switch(yyaccept){ case 0: goto yy61; } -yy71: yych = *++YYCURSOR; -yy72: -#line 301 - { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; } -yy73: ++YYCURSOR; +yy75: yych = *++YYCURSOR; + goto yy71; +yy76: yyaccept = 0; + YYMARKER = ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy74: if(yybm[0+yych] & 128) goto yy73; - if(yych >= '>') goto yy70; -yy75: yych = *++YYCURSOR; -yy76: -#line 300 +yy77: if(yybm[0+yych] & 64) goto yy76; + if(yych <= '!') goto yy80; + if(yych >= '#') goto yy61; +yy78: yych = *++YYCURSOR; + if(yybm[0+yych] & 8) goto yy66; +yy79: +#line 323 { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; } +yy80: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy81: if(yybm[0+yych] & 128) goto yy80; + if(yych >= '>') goto yy74; +yy82: yych = *++YYCURSOR; + goto yy79; } -#line 304 +#line 327 stop: @@ -886,11 +926,8 @@ smart_str val; if (! BG(url_adapt_state_ex).active) { - int chunk_size = 4096; /* XXX where should we get chunk_size from? */ - php_url_scanner_ex_activate(TSRMLS_C); - php_start_ob_buffer(NULL, chunk_size, 1 TSRMLS_CC); - php_ob_set_internal_handler(php_url_scanner_output_handler, chunk_size, estrdup("URL-Rewriter"), 1 TSRMLS_CC); + php_ob_set_internal_handler(php_url_scanner_output_handler, 0, "URL-Rewriter", 1 TSRMLS_CC); BG(url_adapt_state_ex).active = 1; } 1.4 +38 -18 php4/ext/standard/url_scanner_ex.re Index: url_scanner_ex.re =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/url_scanner_ex.re,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- url_scanner_ex.re 9 May 2002 05:39:43 -0000 1.3 +++ url_scanner_ex.re 6 Oct 2002 21:54:32 -0000 1.4 @@ -81,13 +81,14 @@ } PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("url_rewriter.tags", "a=href,area=href,frame=src,form=fakeentry", PHP_INI_ALL, OnUpdateTags, url_adapt_state_ex, php_basic_globals, basic_globals) + STD_PHP_INI_ENTRY("url_rewriter.tags", "a=href,area=href,frame=src,form=,fieldset=", PHP_INI_ALL, OnUpdateTags, url_adapt_state_ex, php_basic_globals, basic_globals) PHP_INI_END() /*!re2c any = [\000-\377]; N = (any\[<]); alpha = [a-zA-Z]; +alphadash = ([a-zA-Z] | "-"); */ #define YYFILL(n) goto done @@ -175,20 +176,48 @@ #define STD_PARA url_adapt_state_ex_t *ctx, char *start, char *YYCURSOR TSRMLS_DC #define STD_ARGS ctx, start, xp TSRMLS_CC +#if SCANNER_DEBUG +#define scdebug(x) printf x +#else +#define scdebug(x) +#endif + static inline void passthru(STD_PARA) { + scdebug(("appending %d chars, starting with %c\n", YYCURSOR-start, *start)); smart_str_appendl(&ctx->result, start, YYCURSOR - start); } -static inline void handle_form(STD_PARA) +/* + * This function appends a hidden input field after a <form> or + * <fieldset>. The latter is important for XHTML. + */ + +static void handle_form(STD_PARA) { - if (ctx->form_app.len > 0 - && ctx->tag.len == 4 - && strncasecmp(ctx->tag.c, "form", 4) == 0) { - smart_str_append(&ctx->result, &ctx->form_app); + int doit = 0; + + if (ctx->form_app.len > 0) { + switch (ctx->tag.len) { + +#define RECOGNIZE(x) do { \ + case sizeof(x)-1: \ + if (strncasecmp(ctx->tag.c, x, sizeof(x)-1) == 0) \ + doit = 1; \ + break; \ +} while (0) + + RECOGNIZE("form"); + RECOGNIZE("fieldset"); + } + + if (doit) + smart_str_append(&ctx->result, &ctx->form_app); } } + + /* * HANDLE_TAG copies the HTML Tag and checks whether we * have that tag in our table. If we might modify it, @@ -222,12 +251,6 @@ tag_arg(ctx, quotes, type TSRMLS_CC); } -#ifdef SCANNER_DEBUG -#define scdebug(x) printf x -#else -#define scdebug(x) -#endif - static inline void xx_mainloop(url_adapt_state_ex_t *ctx, const char *newdata, size_t newlen TSRMLS_DC) { char *end, *q; @@ -282,7 +305,7 @@ state_arg: start = YYCURSOR; /*!re2c - alpha+ { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; } + alpha alphadash* { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; } any { passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; } */ @@ -299,7 +322,7 @@ /*!re2c ["] (any\[">])* ["] { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; } ['] (any\['>])* ['] { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; } - (any\[ \n>"'])+ { handle_val(STD_ARGS, 0, '"'); goto state_next_arg_begin; } + (any\[ \n>])+ { handle_val(STD_ARGS, 0, '\0'); goto state_next_arg_begin; } any { passthru(STD_ARGS); goto state_next_arg_begin; } */ @@ -402,11 +425,8 @@ smart_str val; if (! BG(url_adapt_state_ex).active) { - int chunk_size = 4096; /* XXX where should we get chunk_size from? */ - php_url_scanner_ex_activate(TSRMLS_C); - php_start_ob_buffer(NULL, chunk_size, 1 TSRMLS_CC); - php_ob_set_internal_handler(php_url_scanner_output_handler, chunk_size, estrdup("URL-Rewriter"), 1 TSRMLS_CC); + php_ob_set_internal_handler(php_url_scanner_output_handler, 0, "URL-Rewriter", 1 TSRMLS_CC); BG(url_adapt_state_ex).active = 1; } 1.4 +8 -16 php4/ext/standard/var.c Index: var.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/var.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- var.c 30 Apr 2002 08:15:07 -0000 1.3 +++ var.c 6 Oct 2002 21:54:32 -0000 1.4 @@ -86,30 +86,22 @@ break; case IS_ARRAY: myht = Z_ARRVAL_PP(struc); - if (++((*struc)->value.ht->nApplyCount) > 1) { + if (myht->nApplyCount > 1) { PUTS("*RECURSION*\n"); - (*struc)->value.ht->nApplyCount = 0; - break; + return; } php_printf("%sarray(%d) {\n", COMMON, zend_hash_num_elements(myht)); goto head_done; case IS_OBJECT: object = Z_OBJ_PP(struc); - if (++object->properties->nApplyCount > 1) { + myht = Z_OBJPROP_PP(struc); + if (myht->nApplyCount > 1) { PUTS("*RECURSION*\n"); - object->properties->nApplyCount = 0; return; } - myht = Z_OBJPROP_PP(struc); php_printf("%sobject(%s)(%d) {\n", COMMON, Z_OBJCE_PP(struc)->name, zend_hash_num_elements(myht)); head_done: zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_array_element_dump, 1, level); - if (Z_TYPE_PP(struc) == IS_ARRAY) { - (*struc)->value.ht->nApplyCount--; - } - else { - object->properties->nApplyCount--; - } if (level > 1) { php_printf("%*c", level-1, ' '); } @@ -350,19 +342,19 @@ PHP_FUNCTION(var_export) { zval *var; - zend_bool i = 0; + zend_bool return_output = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &i) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &return_output) == FAILURE) { return; } - if (i) { + if (return_output) { php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); } php_var_export(&var, 1 TSRMLS_CC); - if (i) { + if (return_output) { php_ob_get_buffer (return_value TSRMLS_CC); php_end_ob_buffer (0, 0 TSRMLS_CC); } 1.6 +33 -14 php4/ext/standard/var_unserializer.c Index: var_unserializer.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/var_unserializer.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- var_unserializer.c 9 May 2002 05:39:43 -0000 1.5 +++ var_unserializer.c 6 Oct 2002 21:54:32 -0000 1.6 @@ -1,4 +1,4 @@ -/* Generated by re2c 0.5 on Sun Apr 28 19:47:31 2002 */ +/* Generated by re2c 0.5 on Mon Aug 19 22:01:10 2002 */ #line 1 "var_unserializer.re" #include "php.h" #include "ext/standard/php_var.h" @@ -36,7 +36,7 @@ var_hash->data[var_hash->used_slots++] = *rval; } -void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval) +PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval) { int i; var_entries *var_hash = var_hashx->first; @@ -70,7 +70,7 @@ return SUCCESS; } -void var_destroy(php_unserialize_data_t *var_hashx) +PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) { void *next; var_entries *var_hash = var_hashx->first; @@ -319,7 +319,7 @@ yych = *(YYMARKER = ++YYCURSOR); if(yych == ':') goto yy75; yy4: -#line 404 +#line 410 { return 0; } yy5: yych = *++YYCURSOR; if(yych == ';') goto yy73; @@ -354,7 +354,7 @@ goto yy4; yy13: yych = *++YYCURSOR; yy14: -#line 398 +#line 404 { /* this is the case where we have less data than planned */ zend_error(E_NOTICE, "Unexpected end of serialized data"); @@ -427,12 +427,20 @@ zend_error(E_WARNING, "'unserialize_callback_func' (%s) hasn't defined the class it was called for", user_func->value.str.val); incomplete_class = 1; ce = PHP_IC_ENTRY; - } else + } else { +#ifdef ZEND_ENGINE_2 + ce = *(zend_class_entry **)ce; /* Bad hack, TBF! */ +#endif efree(class_name); + } } } - } else + } else { +#ifdef ZEND_ENGINE_2 + ce = *(zend_class_entry **)ce; /* Bad hack, TBF! */ +#endif efree(class_name); + } *p = YYCURSOR; elements = object_common1(UNSERIALIZE_PASSTHRU, ce); @@ -573,13 +581,24 @@ yy46: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy47: if(yych <= '/'){ - if(yych == '.') goto yy58; - goto yy2; +yy47: if(yych <= ':'){ + if(yych <= '.'){ + if(yych <= '-') goto yy2; + goto yy58; + } else { + if(yych <= '/') goto yy2; + if(yych <= '9') goto yy46; + goto yy2; + } } else { - if(yych <= '9') goto yy46; - if(yych == ';') goto yy51; - goto yy2; + if(yych <= 'E'){ + if(yych <= ';') goto yy51; + if(yych <= 'D') goto yy2; + goto yy53; + } else { + if(yych == 'e') goto yy53; + goto yy2; + } } yy48: yych = *++YYCURSOR; if(yych <= '/') goto yy2; @@ -761,7 +780,7 @@ return 1; } } -#line 406 +#line 412 return 0; 1.5 +13 -5 php4/ext/standard/var_unserializer.re Index: var_unserializer.re =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/var_unserializer.re,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- var_unserializer.re 9 May 2002 05:39:43 -0000 1.4 +++ var_unserializer.re 6 Oct 2002 21:54:32 -0000 1.5 @@ -34,7 +34,7 @@ var_hash->data[var_hash->used_slots++] = *rval; } -void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval) +PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval) { int i; var_entries *var_hash = var_hashx->first; @@ -68,7 +68,7 @@ return SUCCESS; } -void var_destroy(php_unserialize_data_t *var_hashx) +PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) { void *next; var_entries *var_hash = var_hashx->first; @@ -92,7 +92,7 @@ /*!re2c iv = [+-]? [0-9]+; nv = [+-]? ([0-9]* "." [0-9]+|[0-9]+ "." [0-9]+); -nvexp = nv [eE] [+-]? iv; +nvexp = (iv | nv) [eE] [+-]? iv; any = [\000-\277]; */ @@ -375,12 +375,20 @@ zend_error(E_WARNING, "'unserialize_callback_func' (%s) hasn't defined the class it was called for", user_func->value.str.val); incomplete_class = 1; ce = PHP_IC_ENTRY; - } else + } else { +#ifdef ZEND_ENGINE_2 + ce = *(zend_class_entry **)ce; /* Bad hack, TBF! */ +#endif efree(class_name); + } } } - } else + } else { +#ifdef ZEND_ENGINE_2 + ce = *(zend_class_entry **)ce; /* Bad hack, TBF! */ +#endif efree(class_name); + } *p = YYCURSOR; elements = object_common1(UNSERIALIZE_PASSTHRU, ce); 1.3 +69 -33 php4/ext/standard/versioning.c Index: versioning.c =================================================================== RCS file: /cvsroot/php-i18n/php4/ext/standard/versioning.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- versioning.c 29 Apr 2002 02:31:03 -0000 1.2 +++ versioning.c 6 Oct 2002 21:54:32 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: versioning.c,v 1.8 2002/02/28 08:26:50 sebastian Exp $ */ +/* $Id: versioning.c,v 1.12 2002/07/07 08:19:36 sebastian Exp $ */ #include <stdio.h> #include <sys/types.h> @@ -51,16 +51,28 @@ * s/([^\d\.])([^\D\.])/$1.$2/g; * s/([^\D\.])([^\d\.])/$1.$2/g; */ -#define isdigdot(x) (isdigit(x)||(x)=='.') +#define isdig(x) (isdigit(x)&&(x)!='.') +#define isndig(x) (!isdigit(x)&&(x)!='.') #define isspecialver(x) ((x)=='-'||(x)=='_'||(x)=='+') lq = *(q - 1); - if ((isdigdot(*p) != isdigdot(lp) || isspecialver(*p)) && - (lq != '.' && *p != '.')) { - lq = *q; - *q++ = '.'; - } - *q++ = lp = *p++; + if (isspecialver(*p)) { + if (lq != '.') { + lq = *q++ = '.'; + } + } else if ((isndig(lp) && isdig(*p)) || (isdig(lp) && isndig(*p))) { + if (lq != '.') { + *q++ = '.'; + } + lq = *q++ = *p; + } else if (!isalnum(*p)) { + if (lq != '.') { + lq = *q++ = '.'; + } + } else { + lq = *q++ = *p; + } + lp = *p++; } *q++ = '\0'; return buf; @@ -69,30 +81,37 @@ /* }}} */ /* {{{ compare_special_version_forms() */ +typedef struct { + const char *name; + int order; +} special_forms_t; + static int -compare_special_version_forms(const char *form1, const char *form2) +compare_special_version_forms(char *form1, char *form2) { - int i, found1 = -1, found2 = -1; - char **pp; - static char *special_forms[] = { - "dev", - "a", - "b", - "RC", - "#N#", - "pl", - NULL + int found1 = -1, found2 = -1; + special_forms_t special_forms[9] = { + {"dev", 0}, + {"alpha", 1}, + {"a", 1}, + {"beta", 2}, + {"b", 2}, + {"RC", 3}, + {"#", 4}, + {"pl", 5}, + {NULL, 0}, }; + special_forms_t *pp; - for (pp = special_forms, i = 0; *pp != NULL; pp++, i++) { - if (strncmp(form1, *pp, strlen(*pp)) == 0) { - found1 = i; + for (pp = special_forms; pp && pp->name; pp++) { + if (strncmp(form1, pp->name, strlen(pp->name)) == 0) { + found1 = pp->order; break; } } - for (pp = special_forms, i = 0; *pp != NULL; pp++, i++) { - if (strncmp(form2, *pp, strlen(*pp)) == 0) { - found2 = i; + for (pp = special_forms; pp && pp->name; pp++) { + if (strncmp(form2, pp->name, strlen(pp->name)) == 0) { + found2 = pp->order; break; } } @@ -105,12 +124,29 @@ PHPAPI int php_version_compare(const char *orig_ver1, const char *orig_ver2) { - char *ver1 = php_canonicalize_version(orig_ver1); - char *ver2 = php_canonicalize_version(orig_ver2); + char *ver1; + char *ver2; char *p1, *p2, *n1, *n2; long l1, l2; int compare = 0; + if (!*orig_ver1 || !*orig_ver2) { + if (!*orig_ver1 && !*orig_ver2) { + return 0; + } else { + return *orig_ver1 ? 1 : -1; + } + } + if (orig_ver1[0] == '#') { + ver1 = estrdup(orig_ver1); + } else { + ver1 = php_canonicalize_version(orig_ver1); + } + if (orig_ver2[0] == '#') { + ver2 = estrdup(orig_ver2); + } else { + ver2 = php_canonicalize_version(orig_ver2); + } p1 = n1 = ver1; p2 = n2 = ver2; while (*p1 && *p2 && n1 && n2) { @@ -187,22 +223,22 @@ if (argc == 2) { RETURN_LONG(compare); } - if (!strcmp(op, "<") || !strcmp(op, "lt")) { + if (!strncmp(op, "<", op_len) || !strncmp(op, "lt", op_len)) { RETURN_BOOL(compare == -1); } - if (!strcmp(op, "<=") || !strcmp(op, "le")) { + if (!strncmp(op, "<=", op_len) || !strncmp(op, "le", op_len)) { RETURN_BOOL(compare != 1); } - if (!strcmp(op, ">") || !strcmp(op, "gt")) { + if (!strncmp(op, ">", op_len) || !strncmp(op, "gt", op_len)) { RETURN_BOOL(compare == 1); } - if (!strcmp(op, ">=") || !strcmp(op, "ge")) { + if (!strncmp(op, ">=", op_len) || !strncmp(op, "ge", op_len)) { RETURN_BOOL(compare != -1); } - if (!strcmp(op, "==") || !strcmp(op, "=") || !strcmp(op, "eq")) { + if (!strncmp(op, "==", op_len) || !strncmp(op, "=", op_len) || !strncmp(op, "eq", op_len)) { RETURN_BOOL(compare == 0); } - if (!strcmp(op, "!=") || !strcmp(op, "<>") || !strcmp(op, "ne")) { + if (!strncmp(op, "!=", op_len) || !strncmp(op, "<>", op_len) || !strncmp(op, "ne", op_len)) { RETURN_BOOL(compare != 0); } RETURN_NULL(); 1.3 +185 -57 php4/main/SAPI.c Index: SAPI.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/SAPI.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- SAPI.c 29 Apr 2002 02:33:37 -0000 1.2 +++ SAPI.c 6 Oct 2002 21:54:34 -0000 1.3 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: SAPI.c,v 1.129 2002/01/14 13:36:54 sesser Exp $ */ +/* $Id: SAPI.c,v 1.150 2002/09/08 01:06:29 yohgaki Exp $ */ #include <ctype.h> #include <sys/stat.h> @@ -27,9 +27,13 @@ #include "SAPI.h" #include "ext/standard/php_string.h" #include "ext/standard/pageinfo.h" -#if HAVE_PCRE || HAVE_BUNDLED_PCRE +#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE) #include "ext/pcre/php_pcre.h" #endif +#if HAVE_ZLIB +#include "ext/zlib/php_zlib.h" +ZEND_EXTERN_MODULE_GLOBALS(zlib) +#endif #ifdef ZTS #include "TSRM.h" #endif @@ -216,7 +220,7 @@ charset = SG(default_charset) ? SG(default_charset) : SAPI_DEFAULT_CHARSET; if (strncasecmp(mimetype, "text/", 5) == 0 && *charset) { - int len = strlen(mimetype) + sizeof("; charset=") + strlen(charset); + int len = strlen(mimetype) + sizeof("; charset=") + strlen(charset); /* sizeof() includes \0 */ content_type = emalloc(len); snprintf(content_type, len, "%s; charset=%s", mimetype, charset); } else { @@ -256,16 +260,17 @@ size_t newlen; charset = SG(default_charset) ? SG(default_charset) : SAPI_DEFAULT_CHARSET; - if (*charset && strncmp(*mimetype, "text/", 5) == 0 && strstr(*mimetype, "charset=") == NULL) { - newlen = len + (sizeof(";charset=")-1) + strlen(charset); - newtype = emalloc(newlen + 1); - PHP_STRLCPY(newtype, *mimetype, newlen + 1, len); - strlcat(newtype, ";charset=", newlen + 1); - if (*mimetype != NULL) { + if (*mimetype != NULL) { + if (*charset && strncmp(*mimetype, "text/", 5) == 0 && strstr(*mimetype, "charset=") == NULL) { + newlen = len + (sizeof(";charset=")-1) + strlen(charset); + newtype = emalloc(newlen + 1); + PHP_STRLCPY(newtype, *mimetype, newlen + 1, len); + strlcat(newtype, ";charset=", newlen + 1); + strlcat(newtype, charset, newlen + 1); efree(*mimetype); + *mimetype = newtype; + return newlen; } - *mimetype = newtype; - return newlen; } return 0; } @@ -302,8 +307,16 @@ SG(rfc1867_uploaded_files) = NULL; if (SG(server_context)) { - if (SG(request_info).request_method - && !strcmp(SG(request_info).request_method, "POST")) { + if ( SG(request_info).request_method + && (!strcmp(SG(request_info).request_method, "POST") + || (PG(allow_webdav_methods) + && (!strcmp(SG(request_info).request_method, "PROPFIND") + || !strcmp(SG(request_info).request_method, "PROPPATCH") + || !strcmp(SG(request_info).request_method, "MKCOL") + || !strcmp(SG(request_info).request_method, "PUT") + || !strcmp(SG(request_info).request_method, "MOVE") + || !strcmp(SG(request_info).request_method, "COPY") + || !strcmp(SG(request_info).request_method, "LOCK"))))) { if (!SG(request_info).content_type) { SG(request_info).content_type_dup = NULL; if(PG(always_populate_raw_post_data)) { @@ -334,6 +347,14 @@ } +static void sapi_send_headers_free(TSRMLS_D) +{ + if (SG(sapi_headers).http_status_line) { + efree(SG(sapi_headers).http_status_line); + SG(sapi_headers).http_status_line = NULL; + } +} + SAPI_API void sapi_deactivate(TSRMLS_D) { zend_llist_destroy(&SG(sapi_headers).headers); @@ -358,6 +379,11 @@ if (SG(rfc1867_uploaded_files)) { destroy_uploaded_files_hash(TSRMLS_C); } + if (SG(sapi_headers).mimetype) { + efree(SG(sapi_headers).mimetype); + SG(sapi_headers).mimetype = NULL; + } + sapi_send_headers_free(TSRMLS_C); } @@ -385,36 +411,83 @@ return code; } -/* This function expects a *duplicated* string, that was previously emalloc()'d. - * Pointers sent to this functions will be automatically freed by the framework. - */ + +static void sapi_update_response_code(int ncode TSRMLS_DC) +{ + if (SG(sapi_headers).http_status_line) { + efree(SG(sapi_headers).http_status_line); + SG(sapi_headers).http_status_line = NULL; + } + SG(sapi_headers).http_response_code = ncode; +} + +static int sapi_find_matching_header(void *element1, void *element2) +{ + return strncasecmp(((sapi_header_struct*)element1)->header, (char*)element2, strlen((char*)element2)) == 0; +} + SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace TSRMLS_DC) { - int retval, free_header = 0; + sapi_header_line ctr = {0}; + int r; + + ctr.line = header_line; + ctr.line_len = header_line_len; + + r = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, + &ctr TSRMLS_CC); + + if (!duplicate) + efree(header_line); + + return r; +} + +SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) +{ + int retval; sapi_header_struct sapi_header; char *colon_offset; long myuid = 0L; - + char *header_line; + uint header_line_len; + zend_bool replace; + int http_response_code; + if (SG(headers_sent) && !SG(request_info).no_headers) { char *output_start_filename = php_get_output_start_filename(TSRMLS_C); int output_start_lineno = php_get_output_start_lineno(TSRMLS_C); if (output_start_filename) { - sapi_module.sapi_error(E_WARNING, "Cannot add header information - headers already sent by (output started at %s:%d)", + sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent by (output started at %s:%d)", output_start_filename, output_start_lineno); } else { - sapi_module.sapi_error(E_WARNING, "Cannot add header information - headers already sent"); - } - if (!duplicate) { - efree(header_line); + sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent"); } return FAILURE; } - if (duplicate) { - header_line = estrndup(header_line, header_line_len); + switch (op) { + case SAPI_HEADER_SET_STATUS: + sapi_update_response_code((int) arg TSRMLS_CC); + return SUCCESS; + + case SAPI_HEADER_REPLACE: + case SAPI_HEADER_ADD: { + sapi_header_line *p = arg; + header_line = p->line; + header_line_len = p->line_len; + http_response_code = p->response_code; + replace = (op == SAPI_HEADER_REPLACE); + break; + } + + default: + return FAILURE; } + header_line = estrndup(header_line, header_line_len); + /* cut of trailing spaces, linefeeds and carriage-returns */ while(isspace(header_line[header_line_len-1])) header_line[--header_line_len]='\0'; @@ -428,7 +501,7 @@ if (header_line_len>=5 && !strncasecmp(header_line, "HTTP/", 5)) { /* filter out the response code */ - SG(sapi_headers).http_response_code = sapi_extract_response_code(header_line); + sapi_update_response_code(sapi_extract_response_code(header_line) TSRMLS_CC); SG(sapi_headers).http_status_line = header_line; return SUCCESS; } else { @@ -436,13 +509,22 @@ if (colon_offset) { *colon_offset = 0; if (!STRCASECMP(header_line, "Content-Type")) { - char *ptr = colon_offset, *mimetype = NULL, *newheader; + char *ptr = colon_offset+1, *mimetype = NULL, *newheader; size_t len = header_line_len - (ptr - header_line), newlen; while (*ptr == ' ' && *ptr != '\0') { ptr++; } +#if HAVE_ZLIB + if(!strncmp(ptr, "image/", sizeof("image/")-1)) { + ZLIBG(output_compression) = 0; + } +#endif mimetype = estrdup(ptr); newlen = sapi_apply_default_charset(&mimetype, len TSRMLS_CC); + if (!SG(sapi_headers).mimetype){ + SG(sapi_headers).mimetype = estrdup(mimetype); + } + if (newlen != 0) { newlen += sizeof("Content-type: "); newheader = emalloc(newlen); @@ -450,30 +532,29 @@ strlcat(newheader, mimetype, newlen); sapi_header.header = newheader; sapi_header.header_len = newlen - 1; - colon_offset = strchr(newheader, ':'); - *colon_offset = '\0'; - free_header = 1; + efree(header_line); } efree(mimetype); SG(sapi_headers).send_default_content_type = 0; } else if (!STRCASECMP(header_line, "Location")) { - if (SG(sapi_headers).http_response_code < 300 || - SG(sapi_headers).http_response_code > 307) { - /* Return a Found Redirect if one is not already specified */ - SG(sapi_headers).http_response_code = 302; - } + if (SG(sapi_headers).http_response_code < 300 || + SG(sapi_headers).http_response_code > 307) { + /* Return a Found Redirect if one is not already specified */ + sapi_update_response_code(302 TSRMLS_CC); + } } else if (!STRCASECMP(header_line, "WWW-Authenticate")) { /* HTTP Authentication */ int newlen; char *result, *newheader; -#if HAVE_PCRE || HAVE_BUNDLED_PCRE - zval *repl_temp; - char *ptr = colon_offset+1; - int ptr_len=0, result_len = 0; -#endif - SG(sapi_headers).http_response_code = 401; /* authentication-required */ -#if HAVE_PCRE || HAVE_BUNDLED_PCRE - if(PG(safe_mode)) { + sapi_update_response_code(401 TSRMLS_CC); /* authentication-required */ + + if(PG(safe_mode)) +#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE) + { + zval *repl_temp; + char *ptr = colon_offset+1; + int ptr_len=0, result_len = 0; + myuid = php_getuid(); ptr_len = strlen(ptr); @@ -524,7 +605,7 @@ efree(repl_temp); } #else - if(PG(safe_mode)) { + { myuid = php_getuid(); result = emalloc(32); newlen = sprintf(result, "WWW-Authenticate: %ld", myuid); @@ -541,7 +622,9 @@ } } } - + if (http_response_code) { + sapi_update_response_code(http_response_code TSRMLS_CC); + } if (sapi_module.header_handler) { retval = sapi_module.header_handler(&sapi_header, &SG(sapi_headers) TSRMLS_CC); } else { @@ -551,11 +634,21 @@ zend_llist_clean(&SG(sapi_headers).headers); } if (retval & SAPI_HEADER_ADD) { + /* in replace mode first remove the header if it already exists in the headers llist */ + if (replace) { + colon_offset = strchr(sapi_header.header, ':'); + if (colon_offset) { + char sav; + colon_offset++; + sav = *colon_offset; + *colon_offset = 0; + zend_llist_del_element(&SG(sapi_headers).headers, sapi_header.header, (int(*)(void*, void*))sapi_find_matching_header); + *colon_offset = sav; + } + } + zend_llist_add_element(&SG(sapi_headers).headers, (void *) &sapi_header); } - if (free_header) { - efree(sapi_header.header); - } return SUCCESS; } @@ -569,6 +662,31 @@ return SUCCESS; } +#if HAVE_ZLIB + /* Add output compression headers at this late stage in order to make + it possible to switch it off inside the script. */ + if (ZLIBG(output_compression)) { + switch (ZLIBG(ob_gzip_coding)) { + case CODING_GZIP: + if (sapi_add_header("Content-Encoding: gzip", sizeof("Content-Encoding: gzip") - 1, 1)==FAILURE) { + return FAILURE; + } + if (sapi_add_header("Vary: Accept-Encoding", sizeof("Vary: Accept-Encoding") - 1, 1)==FAILURE) { + return FAILURE; + } + break; + case CODING_DEFLATE: + if (sapi_add_header("Content-Encoding: deflate", sizeof("Content-Encoding: deflate") - 1, 1)==FAILURE) { + return FAILURE; + } + if (sapi_add_header("Vary: Accept-Encoding", sizeof("Vary: Accept-Encoding") - 1, 1)==FAILURE) { + return FAILURE; + } + break; + } + } +#endif + /* Success-oriented. We set headers_sent to 1 here to avoid an infinite loop * in case of an error situation. */ @@ -584,12 +702,17 @@ case SAPI_HEADER_SENT_SUCCESSFULLY: ret = SUCCESS; break; - case SAPI_HEADER_DO_SEND: - if (SG(sapi_headers).http_status_line) { + case SAPI_HEADER_DO_SEND: { sapi_header_struct http_status_line; + char buf[255]; - http_status_line.header = SG(sapi_headers).http_status_line; - http_status_line.header_len = strlen(SG(sapi_headers).http_status_line); + if (SG(sapi_headers).http_status_line) { + http_status_line.header = SG(sapi_headers).http_status_line; + http_status_line.header_len = strlen(SG(sapi_headers).http_status_line); + } else { + http_status_line.header = buf; + http_status_line.header_len = sprintf(buf, "HTTP/1.0 %d X", SG(sapi_headers).http_response_code); + } sapi_module.send_header(&http_status_line, SG(server_context) TSRMLS_CC); } zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) sapi_module.send_header, SG(server_context) TSRMLS_CC); @@ -608,11 +731,9 @@ ret = FAILURE; break; } - - if (SG(sapi_headers).http_status_line) { - efree(SG(sapi_headers).http_status_line); - } - + + sapi_send_headers_free(TSRMLS_C); + return ret; } @@ -645,6 +766,13 @@ SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)) { sapi_module.default_post_reader = default_post_reader; + return SUCCESS; +} + + +SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)) +{ + sapi_module.treat_data = treat_data; return SUCCESS; } 1.4 +36 -2 php4/main/SAPI.h Index: SAPI.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/SAPI.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- SAPI.h 2 Aug 2002 22:05:24 -0000 1.3 +++ SAPI.h 6 Oct 2002 21:54:34 -0000 1.4 @@ -51,6 +51,7 @@ zend_llist headers; int http_response_code; unsigned char send_default_content_type; + char *mimetype; char *http_status_line; } sapi_headers_struct; @@ -133,9 +134,37 @@ SAPI_API void sapi_deactivate(TSRMLS_D); SAPI_API void sapi_initialize_empty_request(TSRMLS_D); +/* + * This is the preferred and maintained API for + * operating on HTTP headers. + */ + +/* + * Always specify a sapi_header_line this way: + * + * sapi_header_line ctr = {0}; + */ + +typedef struct { + char *line; /* If you allocated this, you need to free it yourself */ + uint line_len; + long response_code; /* long due to zend_parse_parameters compatibility */ +} sapi_header_line; + +typedef enum { /* Parameter: */ + SAPI_HEADER_REPLACE, /* sapi_header_line* */ + SAPI_HEADER_ADD, /* sapi_header_line* */ + SAPI_HEADER_SET_STATUS /* int */ +} sapi_header_op_enum; + +SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC); + + +/* Deprecated functions. Use sapi_header_op instead. */ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace TSRMLS_DC); -#define sapi_add_header(header_line, header_line_len, duplicate) \ - sapi_add_header_ex((header_line), (header_line_len), (duplicate), 1 TSRMLS_CC) +#define sapi_add_header(a, b, c) sapi_add_header_ex((a),(b),(c),1 TSRMLS_CC) + + SAPI_API int sapi_send_headers(TSRMLS_D); SAPI_API void sapi_free_header(sapi_header_struct *sapi_header); SAPI_API void sapi_handle_post(void *arg TSRMLS_DC); @@ -144,6 +173,7 @@ SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry); SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry); SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)); +SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); SAPI_API int sapi_flush(TSRMLS_D); SAPI_API struct stat *sapi_get_stat(TSRMLS_D); @@ -186,6 +216,7 @@ void (*unblock_interruptions)(void); void (*default_post_reader)(TSRMLS_D); + void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC); char *executable_location; }; @@ -214,8 +245,11 @@ #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) +#define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) + SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); +SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data); #define STANDARD_SAPI_MODULE_PROPERTIES NULL, NULL 1.3 +4 -1 php4/main/build-defs.h.in Index: build-defs.h.in =================================================================== RCS file: /cvsroot/php-i18n/php4/main/build-defs.h.in,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- build-defs.h.in 29 Apr 2002 02:33:37 -0000 1.2 +++ build-defs.h.in 6 Oct 2002 21:54:34 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: build-defs.h.in,v 1.9 2002/03/04 09:10:32 imajes Exp $ */ +/* $Id: build-defs.h.in,v 1.11 2002/10/04 04:47:34 rasmus Exp $ */ #define CONFIGURE_COMMAND "@CONFIGURE_COMMAND@" #define PHP_ADA_INCLUDE "" @@ -80,9 +80,12 @@ #define PEAR_INSTALLDIR "@EXPANDED_PEAR_INSTALLDIR@" #define PHP_INCLUDE_PATH "@INCLUDE_PATH@" #define PHP_EXTENSION_DIR "@EXPANDED_EXTENSION_DIR@" +#define PHP_PREFIX "@prefix@" #define PHP_BINDIR "@EXPANDED_BINDIR@" #define PHP_LIBDIR "@EXPANDED_LIBDIR@" #define PHP_DATADIR "@EXPANDED_DATADIR@" #define PHP_SYSCONFDIR "@EXPANDED_SYSCONFDIR@" #define PHP_LOCALSTATEDIR "@EXPANDED_LOCALSTATEDIR@" #define PHP_CONFIG_FILE_PATH "@EXPANDED_PHP_CONFIG_FILE_PATH@" +#define PHP_CONFIG_FILE_SCAN_DIR "@EXPANDED_PHP_CONFIG_FILE_SCAN_DIR@" +#define PHP_SHLIB_SUFFIX "@SHLIB_SUFFIX_NAME@" 1.4 +11 -2 php4/main/config.w32.h.in Index: config.w32.h.in =================================================================== RCS file: /cvsroot/php-i18n/php4/main/config.w32.h.in,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- config.w32.h.in 2 Aug 2002 22:05:24 -0000 1.3 +++ config.w32.h.in 6 Oct 2002 21:54:34 -0000 1.4 @@ -2,20 +2,22 @@ Build Configuration for Win32. This has only been tested with MS VisualC++ 6 (and later). - $Id: config.w32.h.in,v 1.2 2002/05/10 04:58:05 edink Exp $ + $Id: config.w32.h.in,v 1.13 2002/10/04 05:22:13 sebastian Exp $ */ /* Default PHP / PEAR directories */ #define CONFIGURATION_FILE_PATH "php.ini" +#define PEAR_INSTALLDIR "c:\\php4\\pear" #define PHP_BINDIR "c:\\php4" #define PHP_CONFIG_FILE_PATH (getenv("SystemRoot"))?getenv("SystemRoot"):"" +#define PHP_CONFIG_FILE_SCAN_DIR "" #define PHP_DATADIR "c:\\php4" #define PHP_EXTENSION_DIR "c:\\php4" #define PHP_INCLUDE_PATH ".;c:\\php4\\pear" #define PHP_LIBDIR "c:\\php4" #define PHP_LOCALSTATEDIR "c:\\php4" +#define PHP_PREFIX "c:\\php4" #define PHP_SYSCONFDIR "c:\\php4" -#define PEAR_INSTALLDIR "c:\\php4\\pear" /* Enable / Disable BCMATH extension (default: enabled) */ #define WITH_BCMATH 1 @@ -45,6 +47,7 @@ #define HAVE_MBSTR_CN 1 #define HAVE_MBSTR_JA 1 #define HAVE_MBSTR_KR 1 +#define HAVE_MBSTR_RU 1 #define HAVE_MBSTR_TW 1 /* Enable / Disable MySQL extension (default: enabled) */ @@ -160,3 +163,9 @@ #undef HAVE_RINT #define HAVE_STRFTIME 1 #define SIZEOF_INT 4 +#define HAVE_GLOB +#define PHP_SHLIB_SUFFIX "dll" + +/* Win32 supports strcoll */ +#define HAVE_STRCOLL 1 + 1.4 +42 -12 php4/main/fopen_wrappers.c Index: fopen_wrappers.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/fopen_wrappers.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- fopen_wrappers.c 2 Aug 2002 22:05:25 -0000 1.3 +++ fopen_wrappers.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -16,7 +16,7 @@ | Jim Winstead <jimw****@php*****> | +----------------------------------------------------------------------+ */ -/* $Id: fopen_wrappers.c,v 1.144 2002/05/11 19:58:40 rasmus Exp $ */ +/* $Id: fopen_wrappers.c,v 1.151 2002/10/04 22:16:16 bfrance Exp $ */ /* {{{ includes */ @@ -36,6 +36,14 @@ #include <winsock.h> #define O_RDONLY _O_RDONLY #include "win32/param.h" +#elif defined(NETWARE) +/*#include <ws2nlm.h>*/ +/*#include <sys/socket.h>*/ +#ifdef NEW_LIBC +#include <sys/param.h> +#else +#include "netware/param.h" +#endif #else #include <sys/param.h> #endif @@ -49,6 +57,8 @@ #if HAVE_PWD_H #ifdef PHP_WIN32 #include "win32/pwd.h" +#elif defined(NETWARE) +#include "netware/pwd.h" #else #include <pwd.h> #endif @@ -65,6 +75,9 @@ #ifdef PHP_WIN32 #include <winsock.h> +#elif defined(NETWARE) && defined(USE_WINSOCK) +/*#include <ws2nlm.h>*/ +#include <novsock2.h> #else #include <netinet/in.h> #include <netdb.h> @@ -73,7 +86,7 @@ #endif #endif -#if defined(PHP_WIN32) || defined(__riscos__) +#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) #undef AF_UNIX #endif @@ -88,12 +101,14 @@ When open_basedir is NULL, always return 0 */ -PHPAPI int php_check_specific_open_basedir(char *basedir, char *path TSRMLS_DC) +PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path TSRMLS_DC) { char resolved_name[MAXPATHLEN]; char resolved_basedir[MAXPATHLEN]; char local_open_basedir[MAXPATHLEN]; int local_open_basedir_pos; + int resolved_basedir_len; + int resolved_name_len; /* Special case basedir==".": Use script-directory */ if ((strcmp(basedir, ".") == 0) && @@ -115,11 +130,26 @@ /* Resolve the real path into resolved_name */ if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { + /* Handler for basedirs that end with a / */ + if (basedir[strlen(basedir)-1] == PHP_DIR_SEPARATOR) { + resolved_basedir_len = strlen(resolved_basedir); + resolved_basedir[resolved_basedir_len] = '/'; + resolved_basedir[++resolved_basedir_len] = '\0'; + } else { + resolved_basedir_len = strlen(resolved_basedir); + } + + if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { + resolved_name_len = strlen(resolved_name); + resolved_name[resolved_name_len] = '/'; + resolved_name[++resolved_name_len] = '\0'; + } + /* Check the path */ #ifdef PHP_WIN32 - if (strncasecmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) { + if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { #else - if (strncmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) { + if (strncmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { #endif /* File is in the right directory */ return 0; @@ -135,7 +165,7 @@ /* {{{ php_check_open_basedir */ -PHPAPI int php_check_open_basedir(char *path TSRMLS_DC) +PHPAPI int php_check_open_basedir(const char *path TSRMLS_DC) { /* Only check when open_basedir is available */ if (PG(open_basedir) && *PG(open_basedir)) { @@ -161,7 +191,7 @@ ptr = end; } - php_error(E_WARNING, "open_basedir restriction in effect. File is in wrong directory"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "open_basedir restriction in effect. File is in wrong directory"); efree(pathbuf); errno = EPERM; /* we deny permission to open it */ return -1; @@ -176,9 +206,9 @@ */ PHPAPI int php_check_safe_mode_include_dir(char *path TSRMLS_DC) { - /* Only check when safe_mode on and safe_mode_include_dir is available */ - if (PG(safe_mode) && PG(safe_mode_include_dir) && - *PG(safe_mode_include_dir)) + /* Only check when safe_mode or open_basedir is on and safe_mode_include_dir is available */ + if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && + PG(safe_mode_include_dir) && *PG(safe_mode_include_dir)) { char *pathbuf; char *ptr; @@ -219,7 +249,7 @@ } /* Nothing to check... */ - return -1; + return 0; } /* }}} */ @@ -317,7 +347,7 @@ fp = NULL; } if (!fp) { - php_error(E_ERROR, "Unable to open %s", filename); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to open %s", filename); STR_FREE(SG(request_info).path_translated); /* for same reason as above */ return FAILURE; } 1.3 +5 -3 php4/main/fopen_wrappers.h Index: fopen_wrappers.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/fopen_wrappers.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- fopen_wrappers.h 29 Apr 2002 02:33:37 -0000 1.2 +++ fopen_wrappers.h 6 Oct 2002 21:54:34 -0000 1.3 @@ -15,18 +15,19 @@ | Author: Jim Winstead <jimw****@php*****> | +----------------------------------------------------------------------+ */ -/* $Id: fopen_wrappers.h,v 1.36 2002/03/17 14:21:00 wez Exp $ */ +/* $Id: fopen_wrappers.h,v 1.38 2002/08/19 20:47:55 zeev Exp $ */ #ifndef FOPEN_WRAPPERS_H #define FOPEN_WRAPPERS_H +BEGIN_EXTERN_C() #include "php_globals.h" PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC); PHPAPI char *expand_filepath(const char *filepath, char *real_path TSRMLS_DC); -PHPAPI int php_check_open_basedir(char *path TSRMLS_DC); -PHPAPI int php_check_specific_open_basedir(char *basedir, char *path TSRMLS_DC); +PHPAPI int php_check_open_basedir(const char *path TSRMLS_DC); +PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path TSRMLS_DC); PHPAPI int php_check_safe_mode_include_dir(char *path TSRMLS_DC); @@ -34,6 +35,7 @@ PHPAPI int php_is_url(char *path); PHPAPI char *php_strip_url_passwd(char *path); +END_EXTERN_C() #endif /* 1.4 +5 -1 php4/main/internal_functions_win32.c Index: internal_functions_win32.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/internal_functions_win32.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- internal_functions_win32.c 30 Apr 2002 08:15:07 -0000 1.3 +++ internal_functions_win32.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -16,7 +16,7 @@ | Zeev Suraski <zeev****@zend*****> | +----------------------------------------------------------------------+ - $Id: internal_functions_win32.c,v 1.64 2002/04/28 17:50:09 sebastian Exp $ + $Id: internal_functions_win32.c,v 1.65 2002/09/04 13:55:52 sebastian Exp $ */ /* {{{ includes @@ -82,9 +82,11 @@ #if HAVE_MBSTRING #include "ext/mbstring/mbstring.h" #endif +#ifndef ZEND_ENGINE_2 #if HAVE_OVERLOAD #include "ext/overload/php_overload.h" #endif +#endif #if HAVE_TOKENIZER #include "ext/tokenizer/php_tokenizer.h" #endif @@ -118,8 +120,10 @@ #if HAVE_UODBC ,phpext_odbc_ptr #endif +#ifndef ZEND_ENGINE_2 #if HAVE_OVERLOAD ,phpext_overload_ptr +#endif #endif #if HAVE_PCRE || HAVE_BUNDLED_PCRE ,phpext_pcre_ptr 1.7 +221 -52 php4/main/main.c Index: main.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/main.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- main.c 2 Aug 2002 22:05:25 -0000 1.6 +++ main.c 6 Oct 2002 21:54:34 -0000 1.7 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: main.c,v 1.456 2002/05/13 08:46:24 zeev Exp $ */ +/* $Id: main.c,v 1.497 2002/10/04 19:20:13 sas Exp $ */ /* {{{ includes */ @@ -28,6 +28,18 @@ #include "win32/time.h" #include "win32/signal.h" #include <process.h> +#elif defined(NETWARE) +#ifdef NEW_LIBC +#include <sys/timeval.h> +#else +#include "netware/time_nw.h" +#endif +/*#include "netware/signal_nw.h"*/ +/*#include "netware/env.h"*/ /* Temporary */ +/*#include <process.h>*/ +#ifdef USE_WINSOCK +#include <novsock2.h> +#endif #else #include "build-defs.h" #endif @@ -80,6 +92,7 @@ #endif /* defined(ZEND_MULTIBYTE) && defined(HAVE_MBSTRING) */ #include "SAPI.h" +#include "rfc1867.h" /* }}} */ #ifndef ZTS @@ -233,7 +246,9 @@ STD_PHP_INI_BOOLEAN("display_startup_errors", "0", PHP_INI_ALL, OnUpdateBool, display_startup_errors, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("enable_dl", "1", PHP_INI_SYSTEM, OnUpdateBool, enable_dl, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("expose_php", "1", PHP_INI_SYSTEM, OnUpdateBool, expose_php, php_core_globals, core_globals) - STD_PHP_INI_BOOLEAN("html_errors", "1", PHP_INI_SYSTEM, OnUpdateBool, html_errors, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("docref_root", "http://www.php.net/", PHP_INI_ALL, OnUpdateString, docref_root, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("docref_ext", "", PHP_INI_ALL, OnUpdateString, docref_ext, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("html_errors", "1", PHP_INI_ALL, OnUpdateBool, html_errors, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("xmlrpc_errors", "0", PHP_INI_SYSTEM, OnUpdateBool, xmlrpc_errors, php_core_globals, core_globals) STD_PHP_INI_ENTRY("xmlrpc_error_number", "0", PHP_INI_ALL, OnUpdateInt, xmlrpc_error_number, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("ignore_user_abort", "0", PHP_INI_ALL, OnUpdateBool, ignore_user_abort, php_core_globals, core_globals) @@ -242,13 +257,14 @@ STD_PHP_INI_ENTRY("log_errors_max_len", "1024", PHP_INI_ALL, OnUpdateInt, log_errors_max_len, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("ignore_repeated_errors", "0", PHP_INI_ALL, OnUpdateBool, ignore_repeated_errors, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("ignore_repeated_source", "0", PHP_INI_ALL, OnUpdateBool, ignore_repeated_source, php_core_globals, core_globals) - STD_PHP_INI_BOOLEAN("magic_quotes_gpc", "1", PHP_INI_ALL, OnUpdateBool, magic_quotes_gpc, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("report_memleaks", "1", PHP_INI_SYSTEM, OnUpdateBool, report_memleaks, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("magic_quotes_gpc", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateBool, magic_quotes_gpc, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("magic_quotes_runtime", "0", PHP_INI_ALL, OnUpdateBool, magic_quotes_runtime, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("magic_quotes_sybase", "0", PHP_INI_ALL, OnUpdateBool, magic_quotes_sybase, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("output_buffering", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateInt, output_buffering, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("output_buffering", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateInt, output_buffering, php_core_globals, core_globals) STD_PHP_INI_ENTRY("output_handler", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateString, output_handler, php_core_globals, core_globals) - STD_PHP_INI_BOOLEAN("register_argc_argv", "1", PHP_INI_ALL, OnUpdateBool, register_argc_argv, php_core_globals, core_globals) - STD_PHP_INI_BOOLEAN("register_globals", "0", PHP_INI_ALL, OnUpdateBool, register_globals, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("register_argc_argv", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateBool, register_argc_argv, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("register_globals", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM,OnUpdateBool, register_globals, php_core_globals, core_globals) #if PHP_SAFE_MODE STD_PHP_INI_BOOLEAN("safe_mode", "1", PHP_INI_SYSTEM, OnUpdateBool, safe_mode, php_core_globals, core_globals) #else @@ -259,14 +275,14 @@ STD_PHP_INI_BOOLEAN("short_open_tag",DEFAULT_SHORT_OPEN_TAG, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, short_tags, zend_compiler_globals, compiler_globals) STD_PHP_INI_BOOLEAN("sql.safe_mode", "0", PHP_INI_SYSTEM, OnUpdateBool, sql_safe_mode, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("track_errors", "0", PHP_INI_ALL, OnUpdateBool, track_errors, php_core_globals, core_globals) - STD_PHP_INI_BOOLEAN("y2k_compliance", "0", PHP_INI_ALL, OnUpdateBool, y2k_compliance, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("y2k_compliance", "1", PHP_INI_ALL, OnUpdateBool, y2k_compliance, php_core_globals, core_globals) STD_PHP_INI_ENTRY("unserialize_callback_func", NULL, PHP_INI_ALL, OnUpdateString, unserialize_callback_func, php_core_globals, core_globals) STD_PHP_INI_ENTRY("arg_separator.output", "&", PHP_INI_ALL, OnUpdateStringUnempty, arg_separator.output, php_core_globals, core_globals) STD_PHP_INI_ENTRY("arg_separator.input", "&", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateStringUnempty, arg_separator.input, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("auto_append_file", NULL, PHP_INI_ALL, OnUpdateString, auto_append_file, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("auto_prepend_file", NULL, PHP_INI_ALL, OnUpdateString, auto_prepend_file, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("auto_append_file", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, auto_append_file, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("auto_prepend_file", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, auto_prepend_file, php_core_globals, core_globals) STD_PHP_INI_ENTRY("doc_root", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, doc_root, php_core_globals, core_globals) STD_PHP_INI_ENTRY("default_charset", SAPI_DEFAULT_CHARSET, PHP_INI_ALL, OnUpdateString, default_charset, sapi_globals_struct,sapi_globals) STD_PHP_INI_ENTRY("default_mimetype",SAPI_DEFAULT_MIMETYPE, PHP_INI_ALL, OnUpdateString, default_mimetype, sapi_globals_struct,sapi_globals) @@ -277,10 +293,12 @@ PHP_INI_ENTRY("max_execution_time", "30", PHP_INI_ALL, OnUpdateTimeout) STD_PHP_INI_ENTRY("open_basedir", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, open_basedir, php_core_globals, core_globals) STD_PHP_INI_ENTRY("safe_mode_exec_dir", "1", PHP_INI_SYSTEM, OnUpdateString, safe_mode_exec_dir, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("upload_max_filesize", "2M", PHP_INI_SYSTEM, OnUpdateInt, upload_max_filesize, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("file_uploads", "1", PHP_INI_ALL, OnUpdateBool, file_uploads, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("post_max_size", "8M", PHP_INI_SYSTEM, OnUpdateInt, post_max_size, sapi_globals_struct,sapi_globals) + + STD_PHP_INI_BOOLEAN("file_uploads", "1", PHP_INI_SYSTEM, OnUpdateBool, file_uploads, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("upload_max_filesize", "2M", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateInt, upload_max_filesize, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("post_max_size", "8M", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateInt, post_max_size, sapi_globals_struct,sapi_globals) STD_PHP_INI_ENTRY("upload_tmp_dir", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, upload_tmp_dir, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("user_dir", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, user_dir, php_core_globals, core_globals) STD_PHP_INI_ENTRY("variables_order", NULL, PHP_INI_ALL, OnUpdateStringUnempty, variables_order, php_core_globals, core_globals) @@ -288,6 +306,7 @@ STD_PHP_INI_ENTRY("error_prepend_string", NULL, PHP_INI_ALL, OnUpdateStringUnempty, error_prepend_string, php_core_globals, core_globals) PHP_INI_ENTRY("SMTP", "localhost",PHP_INI_ALL, NULL) + PHP_INI_ENTRY("smtp_port", "25", PHP_INI_ALL, NULL) PHP_INI_ENTRY("browscap", NULL, PHP_INI_SYSTEM, NULL) PHP_INI_ENTRY("error_reporting", NULL, PHP_INI_ALL, OnUpdateErrorReporting) #if MEMORY_LIMIT @@ -298,8 +317,9 @@ PHP_INI_ENTRY("sendmail_path", DEFAULT_SENDMAIL_PATH, PHP_INI_SYSTEM, NULL) PHP_INI_ENTRY("disable_functions", "", PHP_INI_SYSTEM, NULL) - STD_PHP_INI_ENTRY("allow_url_fopen", "1", PHP_INI_ALL, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("always_populate_raw_post_data", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, always_populate_raw_post_data, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_ALL, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("always_populate_raw_post_data", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, always_populate_raw_post_data, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("allow_webdav_methods", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, allow_webdav_methods, php_core_globals, core_globals) PHP_INI_END() /* }}} */ @@ -327,7 +347,7 @@ log_file = VCWD_FOPEN(PG(error_log), "a"); if (log_file != NULL) { time(&error_time); - strftime(error_time_str, 128, "%d-%b-%Y %H:%M:%S", php_localtime_r(&error_time, &tmbuf)); + strftime(error_time_str, sizeof(error_time_str), "%d-%b-%Y %H:%M:%S", php_localtime_r(&error_time, &tmbuf)); fprintf(log_file, "[%s] ", error_time_str); fprintf(log_file, "%s", log_message); fprintf(log_file, "\n"); @@ -344,9 +364,6 @@ } /* }}} */ -/* is 4K big enough? */ -#define PRINTF_BUFFER_SIZE 1024*4 - /* {{{ php_write wrapper for modules to use PHPWRITE */ PHPAPI int php_write(void *buf, uint size TSRMLS_DC) @@ -361,22 +378,143 @@ { va_list args; int ret; - char buffer[PRINTF_BUFFER_SIZE]; + char *buffer; int size; TSRMLS_FETCH(); va_start(args, format); - size = vsnprintf(buffer, sizeof(buffer), format, args); - if(size > sizeof(buffer) - 1) { - size = sizeof(buffer) - 1; + size = vspprintf(&buffer, 0, format, args); + if (buffer) { + ret = PHPWRITE(buffer, size); + efree(buffer); + } else { + php_error(E_ERROR, "Out of memory"); + ret = 0; } - ret = PHPWRITE(buffer, size); va_end(args); return ret; } /* }}} */ +/* {{{ php_verror */ +/* php_verror is called from php_error_docref<n> functions. + * Its purpose is to unify error messages and automatically generate clickable + * html error messages if correcponding ini setting (html_errors) is activated. + * See: CODING_STANDARDS for details. + */ +PHPAPI void php_verror(const char *docref, const char *params, int type, const char *format, va_list args TSRMLS_DC) +{ + char *buffer = NULL, *docref_buf = NULL, *ref = NULL, *target = NULL; + char *docref_target = "", *docref_root = ""; + char *function, *p; + + vspprintf(&buffer, 0, format, args); + if (buffer) { + if (docref && docref[0] == '#') { + docref_target = strchr(docref, '#'); + docref = NULL; + } + if (!docref) { + function = get_active_function_name(TSRMLS_C); + if (function) { + spprintf(&docref_buf, 0, "function.%s", function); + if (docref_buf) { + while((p=strchr(docref_buf, '_'))!=NULL) *p = '-'; + docref = docref_buf; + } + } + } + if (docref) { + if (strncmp(docref, "http://", 7)) { + docref_root = PG(docref_root); + /* now check copy of extension */ + ref = estrdup(docref); + if (ref) { + if (docref_buf) { + efree(docref_buf); + } + docref_buf = ref; + docref = docref_buf; + p = strrchr(ref, '#'); + if (p) { + target = estrdup(p); + if (target) { + docref_target = target; + *p = '\0'; + } + } + if ((!p || target) && PG(docref_ext) && strlen(PG(docref_ext))) { + spprintf(&docref_buf, 0, "%s%s", ref, PG(docref_ext)); + if (docref_buf) { + efree(ref); + docref = docref_buf; + } + } + } + } + if (PG(html_errors)) { + php_error(type, "%s(%s) [<a href='%s%s%s'>%s</a>]: %s", get_active_function_name(TSRMLS_C), params, docref_root, docref, docref_target, docref, buffer); + } else { + php_error(type, "%s(%s) [%s%s%s]: %s", get_active_function_name(TSRMLS_C), params, docref_root, docref, docref_target, buffer); + } + if (target) + efree(target); + } else { + docref = get_active_function_name(TSRMLS_C); + if (!docref) + docref = "Unknown"; + php_error(type, "%s(%s): %s", docref, params, buffer); + } + efree(buffer); + if (docref_buf) + efree(docref_buf); + } else { + php_error(E_ERROR, "%s(%s): Out of memory", get_active_function_name(TSRMLS_C), params); + } +} +/* }}} */ + +/* {{{ php_error_docref */ +/* See: CODING_STANDARDS for details. */ +PHPAPI void php_error_docref(const char *docref TSRMLS_DC, int type, const char *format, ...) +{ + va_list args; + + va_start(args, format); + php_verror(docref, "", type, format, args TSRMLS_CC); + va_end(args); +} +/* }}} */ + +/* {{{ php_error_docref1 */ +/* See: CODING_STANDARDS for details. */ +PHPAPI void php_error_docref1(const char *docref TSRMLS_DC, const char *param1, int type, const char *format, ...) +{ + va_list args; + + va_start(args, format); + php_verror(docref, param1, type, format, args TSRMLS_CC); + va_end(args); +} +/* }}} */ + +/* {{{ php_error_docref2 */ +/* See: CODING_STANDARDS for details. */ +PHPAPI void php_error_docref2(const char *docref TSRMLS_DC, const char *param1, const char *param2, int type, const char *format, ...) +{ + char *params; + va_list args; + + spprintf(¶ms, 0, "%s,%s", param1, param2); + va_start(args, format); + php_verror(docref, params ? params : "...", type, format, args TSRMLS_CC); + va_end(args); + if (params) + efree(params); +} +/* }}} */ + /* {{{ php_html_puts */ PHPAPI void php_html_puts(const char *str, uint size TSRMLS_DC) { @@ -536,7 +674,7 @@ } /* }}} */ -/* {{{ proto void set_time_limit(int seconds) +/* {{{ proto bool set_time_limit(int seconds) Sets the maximum time a script can run */ PHP_FUNCTION(set_time_limit) { @@ -552,7 +690,11 @@ } convert_to_string_ex(new_timeout); - zend_alter_ini_entry("max_execution_time", sizeof("max_execution_time"), Z_STRVAL_PP(new_timeout), Z_STRLEN_PP(new_timeout), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + if (zend_alter_ini_entry("max_execution_time", sizeof("max_execution_time"), Z_STRVAL_PP(new_timeout), Z_STRLEN_PP(new_timeout), PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == SUCCESS) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } } /* }}} */ @@ -562,7 +704,7 @@ { TSRMLS_FETCH(); - return php_stream_open_wrapper_as_file((char *)filename, "rb", USE_PATH|IGNORE_URL_WIN|REPORT_ERRORS, opened_path); + return php_stream_open_wrapper_as_file((char *)filename, "rb", ENFORCE_SAFE_MODE|USE_PATH|IGNORE_URL_WIN|REPORT_ERRORS, opened_path); } /* }}} */ @@ -605,7 +747,7 @@ case ZMSG_MEMORY_LEAK_REPEATED: { TSRMLS_FETCH(); - if (EG(error_reporting)&E_WARNING) { + if ((EG(error_reporting)&E_WARNING) && PG(report_memleaks)) { #if ZEND_DEBUG char memory_leak_buf[512]; @@ -651,6 +793,12 @@ } /* }}} */ + +void php_on_timeout(int seconds TSRMLS_DC) +{ + PG(connection_status) |= PHP_CONNECTION_TIMEOUT; +} + #if PHP_SIGCHILD /* {{{ sigchld_handler */ @@ -694,23 +842,14 @@ } if (PG(output_handler) && PG(output_handler)[0]) { - zval *output_handler; - - ALLOC_INIT_ZVAL(output_handler); - Z_STRLEN_P(output_handler) = strlen(PG(output_handler)); /* this can be optimized */ - Z_STRVAL_P(output_handler) = estrndup(PG(output_handler), Z_STRLEN_P(output_handler)); - Z_TYPE_P(output_handler) = IS_STRING; - php_start_ob_buffer(output_handler, 0, 1 TSRMLS_CC); - } - else if (PG(output_buffering)) { + php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC); + } else if (PG(output_buffering)) { if (PG(output_buffering)>1) { php_start_ob_buffer(NULL, PG(output_buffering), 0 TSRMLS_CC); - } - else { + } else { php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC); } - } - else if (PG(implicit_flush)) { + } else if (PG(implicit_flush)) { php_start_implicit_flush(TSRMLS_C); } @@ -766,7 +905,9 @@ int i; for (i=0; i<NUM_TRACK_VARS; i++) { - zval_ptr_dtor(&PG(http_globals)[i]); + if (PG(http_globals)[i]) { + zval_ptr_dtor(&PG(http_globals)[i]); + } } } zend_end_try(); @@ -828,7 +969,7 @@ /* {{{ php_module_startup */ -int php_module_startup(sapi_module_struct *sf) +int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules) { zend_utility_functions zuf; zend_utility_values zuv; @@ -840,9 +981,8 @@ void ***tsrm_ls; php_core_globals *core_globals; - sapi_globals_struct *sapi_globals = ts_resource(sapi_globals_id); #endif -#ifdef PHP_WIN32 +#if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) WORD wVersionRequested = MAKEWORD(2, 0); WSADATA wsaData; #endif @@ -886,6 +1026,7 @@ zuf.unblock_interruptions = sapi_module.unblock_interruptions; zuf.get_configuration_directive = php_get_configuration_directive_for_zend; zuf.ticks_function = php_run_ticks; + zuf.on_timeout = php_on_timeout; zend_startup(&zuf, NULL, 1); #ifdef ZTS @@ -908,7 +1049,7 @@ setlocale(LC_CTYPE, ""); #endif -#ifdef PHP_WIN32 +#if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) /* start up winsock services */ if (WSAStartup(wVersionRequested, &wsaData) != 0) { php_printf("\nwinsock.dll unusable. %d\n", WSAGetLastError()); @@ -931,7 +1072,7 @@ /* initialize stream wrappers registry * (this uses configuration parameters from php.ini) */ - if (php_init_stream_wrappers(TSRMLS_C) == FAILURE) { + if (php_init_stream_wrappers(module_number TSRMLS_CC) == FAILURE) { php_printf("PHP: Unable to initialize stream url wrappers.\n"); return FAILURE; } @@ -959,13 +1100,17 @@ REGISTER_MAIN_STRINGL_CONSTANT("PEAR_INSTALL_DIR", PEAR_INSTALLDIR, sizeof(PEAR_INSTALLDIR)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_STRINGL_CONSTANT("PEAR_EXTENSION_DIR", PHP_EXTENSION_DIR, sizeof(PHP_EXTENSION_DIR)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_STRINGL_CONSTANT("PHP_EXTENSION_DIR", PHP_EXTENSION_DIR, sizeof(PHP_EXTENSION_DIR)-1, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_STRINGL_CONSTANT("PHP_PREFIX", PHP_PREFIX, sizeof(PHP_PREFIX)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINDIR", PHP_BINDIR, sizeof(PHP_BINDIR)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_STRINGL_CONSTANT("PHP_LIBDIR", PHP_LIBDIR, sizeof(PHP_LIBDIR)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_STRINGL_CONSTANT("PHP_DATADIR", PHP_DATADIR, sizeof(PHP_DATADIR)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_STRINGL_CONSTANT("PHP_SYSCONFDIR", PHP_SYSCONFDIR, sizeof(PHP_SYSCONFDIR)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_STRINGL_CONSTANT("PHP_LOCALSTATEDIR", PHP_LOCALSTATEDIR, sizeof(PHP_LOCALSTATEDIR)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR, sizeof(PHP_CONFIG_FILE_SCAN_DIR)-1, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); php_output_register_constants(TSRMLS_C); + php_rfc1867_register_constants(TSRMLS_C); if (php_startup_ticks(TSRMLS_C) == FAILURE) { php_printf("Unable to start PHP ticks\n"); @@ -977,6 +1122,9 @@ php_printf("Unable to start builtin modules\n"); return FAILURE; } + /* start additional PHP extensions */ + php_startup_extensions(&additional_modules, num_additional_modules); + /* load and startup extensions compiled as shared objects (aka DLLs) as requested by php.ini entries @@ -990,8 +1138,13 @@ /* disable certain functions as requested by php.ini */ php_disable_functions(TSRMLS_C); + /* start Zend extensions */ zend_startup_extensions(); +#ifdef ZTS + zend_post_startup(TSRMLS_C); +#endif + /* */ module_initialized = 1; sapi_deactivate(TSRMLS_C); @@ -1026,7 +1179,7 @@ return; } -#ifdef PHP_WIN32 +#if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) /*close winsock */ WSACleanup(); #endif @@ -1036,7 +1189,7 @@ zend_shutdown(TSRMLS_C); - php_shutdown_stream_wrappers(TSRMLS_C); + php_shutdown_stream_wrappers(module_number TSRMLS_CC); php_shutdown_info_logos(); UNREGISTER_INI_ENTRIES(); @@ -1091,7 +1244,7 @@ char *p; unsigned char _gpc_flags[3] = {0, 0, 0}; zend_bool have_variables_order; - zval *dummy_track_vars_array; + zval *dummy_track_vars_array = NULL; zend_bool initialized_dummy_track_vars_array=0; int i; char *variables_order; @@ -1135,21 +1288,21 @@ case 'p': case 'P': if (!_gpc_flags[0] && !SG(headers_sent) && SG(request_info).request_method && !strcasecmp(SG(request_info).request_method, "POST")) { - php_treat_data(PARSE_POST, NULL, NULL TSRMLS_CC); /* POST Data */ + sapi_module.treat_data(PARSE_POST, NULL, NULL TSRMLS_CC); /* POST Data */ _gpc_flags[0]=1; } break; case 'c': case 'C': if (!_gpc_flags[1]) { - php_treat_data(PARSE_COOKIE, NULL, NULL TSRMLS_CC); /* Cookie Data */ + sapi_module.treat_data(PARSE_COOKIE, NULL, NULL TSRMLS_CC); /* Cookie Data */ _gpc_flags[1]=1; } break; case 'g': case 'G': if (!_gpc_flags[2]) { - php_treat_data(PARSE_GET, NULL, NULL TSRMLS_CC); /* GET Data */ + sapi_module.treat_data(PARSE_GET, NULL, NULL TSRMLS_CC); /* GET Data */ _gpc_flags[2]=1; } break; @@ -1349,6 +1502,21 @@ VCWD_CHDIR_FILE(primary_file->filename); } + if (primary_file->filename) { + char realfile[MAXPATHLEN]; + int realfile_len; + int dummy = 1; + if (VCWD_REALPATH(primary_file->filename, realfile)) { + realfile_len = strlen(realfile); + zend_hash_add(&EG(included_files), realfile, realfile_len+1, (void *)&dummy, sizeof(int), NULL); + if (primary_file->opened_path == NULL && strncmp(realfile, primary_file->filename, realfile_len)) { + primary_file->opened_path = emalloc(realfile_len+1); + memcpy(primary_file->opened_path, realfile, realfile_len); + primary_file->opened_path[realfile_len] = '\0'; + } + } + } + if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) { prepend_file.filename = PG(auto_prepend_file); prepend_file.opened_path = NULL; @@ -1358,6 +1526,7 @@ } else { prepend_file_p = NULL; } + if (PG(auto_append_file) && PG(auto_append_file)[0]) { append_file.filename = PG(auto_append_file); append_file.opened_path = NULL; 1.3 +23 -63 php4/main/memory_streams.c Index: memory_streams.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/memory_streams.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- memory_streams.c 29 Apr 2002 02:33:37 -0000 1.2 +++ memory_streams.c 6 Oct 2002 21:54:34 -0000 1.3 @@ -89,14 +89,6 @@ ms = stream->abstract; assert(ms != NULL); - if (buf == NULL && count == 0) { - /* check for EOF condition */ - if (ms->fpos >= ms->fsize) { - return EOF; - } - return 0; - } - if (ms->fpos + count > ms->fsize) { count = ms->fsize - ms->fpos; } @@ -105,6 +97,8 @@ assert(buf!= NULL); memcpy(buf, ms->data+ms->fpos, count); ms->fpos += count; + } else { + stream->eof = 1; } return count; } @@ -138,7 +132,7 @@ /* {{{ */ -static int php_stream_memory_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC) +static int php_stream_memory_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) { php_stream_memory_data *ms; @@ -146,8 +140,6 @@ ms = stream->abstract; assert(ms != NULL); - if (offset == 0 && whence == SEEK_CUR) - return ms->fpos; switch(whence) { case SEEK_CUR: if (offset < 0) { @@ -165,6 +157,7 @@ ms->fpos = ms->fpos + offset; } } + *newoffs = ms->fpos; return 0; case SEEK_SET: if (ms->fsize < (size_t)(offset)) { @@ -173,6 +166,7 @@ } else { ms->fpos = offset; } + *newoffs = ms->fpos; return 0; case SEEK_END: if (offset > 0) { @@ -184,6 +178,7 @@ } else { ms->fpos = ms->fsize + offset; } + *newoffs = ms->fpos; return 0; default: return 0; @@ -192,35 +187,6 @@ } /* }}} */ - -/* {{{ */ -static char *php_stream_memory_gets(php_stream *stream, char *buf, size_t maxlen TSRMLS_DC) -{ - size_t n = 1; - char *c = buf; - - php_stream_memory_data *ms; - - assert(stream != NULL); - ms = stream->abstract; - assert(ms != NULL); - assert(buf!= NULL); - assert(ms->data!= NULL); - - while(n < maxlen && ms->fpos<ms->fsize) { - n++; - if ((*c = ms->data[ms->fpos++]) == '\n') { - c++; - break; - } - c++; - } - *c = 0; - return buf; -} -/* }}} */ - - /* {{{ */ static int php_stream_memory_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) { @@ -234,9 +200,9 @@ php_stream_memory_close, php_stream_memory_flush, "MEMORY", php_stream_memory_seek, - php_stream_memory_gets, php_stream_memory_cast, - NULL + NULL, /* stat */ + NULL /* set_option */ }; @@ -244,6 +210,7 @@ PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC TSRMLS_DC) { php_stream_memory_data *self; + php_stream *stream; self = emalloc(sizeof(*self)); assert(self != NULL); @@ -252,7 +219,10 @@ self->fsize = 0; self->smax = -1; self->mode = mode; - return php_stream_alloc(&php_stream_memory_ops, self, 0, "rwb"); + + stream = php_stream_alloc(&php_stream_memory_ops, self, 0, "rwb"); + stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; + return stream; } /* }}} */ @@ -380,33 +350,22 @@ /* {{{ */ -static int php_stream_temp_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC) -{ - php_stream_temp_data *ts; - - assert(stream != NULL); - ts = stream->abstract; - assert(ts != NULL); - - return php_stream_seek(ts->innerstream, offset, whence); -} -/* }}} */ - - -/* {{{ */ -char *php_stream_temp_gets(php_stream *stream, char *buf, size_t maxlen TSRMLS_DC) +static int php_stream_temp_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) { php_stream_temp_data *ts; + int ret; assert(stream != NULL); ts = stream->abstract; assert(ts != NULL); - return php_stream_gets(ts->innerstream, buf, maxlen); + ret = php_stream_seek(ts->innerstream, offset, whence); + *newoffs = php_stream_tell(ts->innerstream); + + return ret; } /* }}} */ - /* {{{ */ static int php_stream_temp_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) { @@ -457,9 +416,9 @@ php_stream_temp_close, php_stream_temp_flush, "TEMP", php_stream_temp_seek, - php_stream_temp_gets, php_stream_temp_cast, - NULL + NULL, /* stat */ + NULL /* set_option */ }; @@ -474,8 +433,9 @@ self->smax = max_memory_usage; self->mode = mode; stream = php_stream_alloc(&php_stream_temp_ops, self, 0, "rwb"); + stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; self->innerstream = php_stream_memory_create(mode); -// php_stream_temp_write(stream, NULL, 0 TSRMLS_CC); + return stream; } /* }}} */ 1.3 +5 -0 php4/main/mergesort.c Index: mergesort.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/mergesort.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- mergesort.c 29 Apr 2002 02:33:37 -0000 1.2 +++ mergesort.c 6 Oct 2002 21:54:34 -0000 1.3 @@ -64,6 +64,11 @@ #include <winsock.h> /* Includes definition for u_char */ #endif +#if defined(NETWARE) && !defined(NEW_LIBC) +/*#include <ws2nlm.h>*/ +#include <sys/socket.h> +#endif + static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp)(const void *, const void * TSRMLS_DC) TSRMLS_DC); static void insertionsort(u_char *a, size_t n, size_t size, int (*cmp)(const void *, const void * TSRMLS_DC) TSRMLS_DC); 1.4 +252 -277 php4/main/network.c Index: network.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/network.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- network.c 30 Apr 2002 08:15:07 -0000 1.3 +++ network.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -13,12 +13,12 @@ | licen****@php***** so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stig Venaas <venaa****@unine*****> | + | Streams work by Wez Furlong <wez****@thebr*****> | +----------------------------------------------------------------------+ */ -/* $Id: network.c,v 1.50 2002/04/30 00:20:34 wez Exp $ */ +/* $Id: network.c,v 1.74 2002/10/05 10:35:13 wez Exp $ */ /*#define DEBUG_MAIN_NETWORK 1*/ -#define MAX_CHUNKS_PER_READ 10 #include "php.h" @@ -29,6 +29,13 @@ #include <winsock.h> #define O_RDONLY _O_RDONLY #include "win32/param.h" +#elif defined(NETWARE) +#ifdef NEW_LIBC +#include <sys/timeval.h> +#include <sys/param.h> +#else +#include "netware/time_nw.h" +#endif #else #include <sys/param.h> #endif @@ -49,7 +56,20 @@ #include <sys/poll.h> #endif -#ifndef PHP_WIN32 +#if defined(NETWARE) +#ifdef USE_WINSOCK +/*#include <ws2nlm.h>*/ +#include <novsock2.h> +#else +/* New headers for socket stuff */ +#ifdef NEW_LIBC +#include <netinet/in.h> +#include <netdb.h> +#include <sys/select.h> +#endif +#include <sys/socket.h> +#endif +#elif !defined(PHP_WIN32) #include <netinet/in.h> #include <netdb.h> #if HAVE_ARPA_INET_H @@ -58,12 +78,12 @@ #endif #ifndef HAVE_INET_ATON -int inet_aton(const char *, struct in_addr *); +int inet_aton(const char *, struct in_addr *); #endif #include "php_network.h" -#if defined(PHP_WIN32) || defined(__riscos__) +#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) #undef AF_UNIX #endif @@ -142,7 +162,7 @@ /* {{{ php_network_getaddresses * Returns number of addresses, 0 for none/error */ -static int php_network_getaddresses(const char *host, struct sockaddr ***sal) +static int php_network_getaddresses(const char *host, struct sockaddr ***sal TSRMLS_DC) { struct sockaddr **sap; int n; @@ -156,12 +176,16 @@ struct addrinfo hints, *res, *sai; memset(&hints, '\0', sizeof(hints)); +# ifdef HAVE_IPV6 hints.ai_family = AF_UNSPEC; +# else + hints.ai_family = AF_INET; +# endif if ((n = getaddrinfo(host, NULL, &hints, &res))) { - php_error(E_WARNING, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n)); return 0; } else if (res == NULL) { - php_error(E_WARNING, "php_network_getaddresses: getaddrinfo failed (null result pointer)"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_network_getaddresses: getaddrinfo failed (null result pointer)"); return 0; } @@ -197,7 +221,7 @@ /* XXX NOT THREAD SAFE */ host_info = gethostbyname(host); if (host_info == NULL) { - php_error(E_WARNING, "php_network_getaddresses: gethostbyname failed"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_network_getaddresses: gethostbyname failed"); return 0; } in = *((struct in_addr *) host_info->h_addr); @@ -289,35 +313,116 @@ } return ret; #else /* !defined(PHP_WIN32) && ... */ +#ifdef PHP_WIN32 + return php_connect_nonb_win32((SOCKET) sockfd, addr, addrlen, timeout); +#endif return connect(sockfd, addr, addrlen); #endif } /* }}} */ +#ifdef PHP_WIN32 +/* {{{ php_connect_nonb_win32 */ +PHPAPI int php_connect_nonb_win32(SOCKET sockfd, + const struct sockaddr *addr, + socklen_t addrlen, + struct timeval *timeout) +{ + int error = 0, error_len, ret; + u_long non_block = TRUE, block = FALSE; + + fd_set rset, wset; + + if (timeout == NULL) { + /* blocking mode */ + return connect(sockfd, addr, addrlen); + } + + /* Set the socket to be non-blocking */ + ioctlsocket(sockfd, FIONBIO, &non_block); + + if (connect(sockfd, addr, addrlen) == SOCKET_ERROR) { + if (WSAGetLastError() != WSAEWOULDBLOCK) { + return SOCKET_ERROR; + } + } + + FD_ZERO(&rset); + FD_SET(sockfd, &rset); + + FD_ZERO(&wset); + FD_SET(sockfd, &wset); + + if ((ret = select(sockfd + 1, &rset, &wset, NULL, timeout)) == 0) { + WSASetLastError(WSAETIMEDOUT); + return SOCKET_ERROR; + } + + if (ret == SOCKET_ERROR) { + return SOCKET_ERROR; + } + + if(FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) { + error_len = sizeof(error); + if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *) &error, &error_len) == SOCKET_ERROR) { + return SOCKET_ERROR; + } + } else { + /* whoops: sockfd has disappeared */ + return SOCKET_ERROR; + } + + /* Set the socket back to blocking */ + ioctlsocket(sockfd, FIONBIO, &block); + + if (error) { + WSASetLastError(error); + return SOCKET_ERROR; + } + + return 0; +} +/* }}} */ +#endif + /* {{{ php_hostconnect * Creates a socket of type socktype and connects to the given host and * port, returns the created socket on success, else returns -1. * timeout gives timeout in seconds, 0 means blocking mode. */ -int php_hostconnect(const char *host, unsigned short port, int socktype, int timeout) +int php_hostconnect(const char *host, unsigned short port, int socktype, struct timeval *timeout TSRMLS_DC) { int n, repeatto, s; struct sockaddr **sal, **psal; - struct timeval timeoutval; + struct timeval individual_timeout; + int set_timeout = 0; +#ifdef PHP_WIN32 + int err; +#endif - n = php_network_getaddresses(host, &sal); + n = php_network_getaddresses(host, &sal TSRMLS_CC); if (n == 0) return -1; - /* is this a good idea? 5s? */ - repeatto = timeout / n > 5; - if (repeatto) { - timeout /= n; - } - timeoutval.tv_sec = timeout; - timeoutval.tv_usec = 0; + if (timeout != NULL) { + /* is this a good idea? 5s? */ + repeatto = timeout->tv_sec / n > 5; + if (repeatto) { + individual_timeout.tv_sec = timeout->tv_sec / n; + } else { + individual_timeout.tv_sec = timeout->tv_sec; + } + individual_timeout.tv_usec = timeout->tv_usec; + } else { + individual_timeout.tv_sec = 0; + individual_timeout.tv_usec = 0; + } + + /* Boolean indicating whether to pass a timeout */ + set_timeout = individual_timeout.tv_sec + individual_timeout.tv_usec; + psal = sal; while (*sal != NULL) { s = socket((*sal)->sa_family, socktype, 0); @@ -332,7 +437,7 @@ sa->sin6_family = (*sal)->sa_family; sa->sin6_port = htons(port); if (php_connect_nonb(s, (struct sockaddr *) sa, - sizeof(*sa), timeout ? &timeoutval : NULL) != SOCK_CONN_ERR) + sizeof(*sa), (set_timeout) ? &individual_timeout : NULL) != SOCK_CONN_ERR) goto ok; } break; @@ -345,22 +450,28 @@ sa->sin_family = (*sal)->sa_family; sa->sin_port = htons(port); if (php_connect_nonb(s, (struct sockaddr *) sa, - sizeof(*sa), timeout ? &timeoutval : NULL) != SOCK_CONN_ERR) + sizeof(*sa), (set_timeout) ? &individual_timeout : NULL) != SOCK_CONN_ERR) goto ok; } break; } +#ifdef PHP_WIN32 + /* Preserve the last error */ + err = WSAGetLastError(); +#endif close (s); } sal++; - if (repeatto) { - timeoutval.tv_sec = timeout; - timeoutval.tv_usec = 0; - } } php_network_freeaddresses(psal); - php_error(E_WARNING, "php_hostconnect: connect failed"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_hostconnect: connect failed"); + +#ifdef PHP_WIN32 + /* Restore the last error */ + WSASetLastError(err); +#endif + return -1; ok: @@ -418,46 +529,53 @@ } /* }}} */ -PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, int persistent STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, const char *persistent_id STREAMS_DC TSRMLS_DC) { php_stream *stream; php_netstream_data_t *sock; - sock = pemalloc(sizeof(php_netstream_data_t), persistent); + sock = pemalloc(sizeof(php_netstream_data_t), persistent_id ? 1 : 0); memset(sock, 0, sizeof(php_netstream_data_t)); sock->is_blocked = 1; - sock->chunk_size = FG(def_chunk_size); - sock->timeout.tv_sec = -1; + sock->timeout.tv_sec = FG(default_socket_timeout); sock->socket = socket; - stream = php_stream_alloc_rel(&php_stream_socket_ops, sock, persistent, "r+"); + stream = php_stream_alloc_rel(&php_stream_socket_ops, sock, persistent_id, "r+"); + stream->flags |= PHP_STREAM_FLAG_AVOID_BLOCKING; if (stream == NULL) - pefree(sock, persistent); + pefree(sock, persistent_id ? 1 : 0); return stream; } PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port, - int socktype, int timeout, int persistent STREAMS_DC TSRMLS_DC) + int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC TSRMLS_DC) { int socket; + php_stream *stream; - socket = php_hostconnect(host, port, socktype, timeout); + socket = php_hostconnect(host, port, socktype, timeout TSRMLS_CC); if (socket == -1) return NULL; - return php_stream_sock_open_from_socket_rel(socket, persistent); + stream = php_stream_sock_open_from_socket_rel(socket, persistent_id); + + if (stream == NULL) + closesocket(socket); + + return stream; } -PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, int persistent, +PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, const char *persistent_id, struct timeval *timeout STREAMS_DC TSRMLS_DC) { #if defined(AF_UNIX) int socketd; struct sockaddr_un unix_addr; + php_stream *stream; socketd = socket(PF_UNIX, SOCK_STREAM, 0); if (socketd == SOCK_ERR) @@ -482,40 +600,63 @@ if (php_connect_nonb(socketd, (struct sockaddr *) &unix_addr, sizeof(unix_addr), timeout) == SOCK_CONN_ERR) return NULL; - return php_stream_sock_open_from_socket_rel(socketd, persistent); + stream = php_stream_sock_open_from_socket_rel(socketd, persistent_id); + if (stream == NULL) + closesocket(socketd); + return stream; #else return NULL; #endif } #if HAVE_OPENSSL_EXT -PHPAPI int php_stream_sock_ssl_activate_with_method(php_stream *stream, int activate, SSL_METHOD *method TSRMLS_DC) +PHPAPI int php_stream_sock_ssl_activate_with_method(php_stream *stream, int activate, SSL_METHOD *method, php_stream *session_stream TSRMLS_DC) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + php_netstream_data_t *psock = NULL; SSL_CTX *ctx = NULL; - if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET)) + + if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_stream_sock_ssl_activate_with_method: stream is not a network stream"); return FAILURE; + } + + if (session_stream) { + if (!php_stream_is(session_stream, PHP_STREAM_IS_SOCKET)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_stream_sock_ssl_activate_with_method: session_stream is not a network stream"); + return FAILURE; + } + psock = (php_netstream_data_t*)session_stream->abstract; + } if (activate == sock->ssl_active) return SUCCESS; /* already in desired mode */ if (activate && sock->ssl_handle == NULL) { ctx = SSL_CTX_new(method); - if (ctx == NULL) + if (ctx == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_stream_sock_ssl_activate_with_method: failed to create an SSL context"); return FAILURE; + } sock->ssl_handle = SSL_new(ctx); if (sock->ssl_handle == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_stream_sock_ssl_activate_with_method: failed to create an SSL handle"); SSL_CTX_free(ctx); return FAILURE; } SSL_set_fd(sock->ssl_handle, sock->socket); + + if (psock) { + SSL_copy_session_id(sock->ssl_handle, psock->ssl_handle); + } } if (activate) { if (SSL_connect(sock->ssl_handle) <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_stream_sock_ssl_activate_with_method: SSL handshake/connection failed"); SSL_shutdown(sock->ssl_handle); return FAILURE; } @@ -527,51 +668,40 @@ } return SUCCESS; } -#endif - -PHPAPI void php_stream_sock_set_timeout(php_stream *stream, struct timeval *timeout TSRMLS_DC) -{ - php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; - - if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET)) - return; - - sock->timeout = *timeout; - sock->timeout_event = 0; -} -PHPAPI int php_stream_sock_set_blocking(php_stream *stream, int mode TSRMLS_DC) -{ - int oldmode; - php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; - - if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET)) - return 0; - - oldmode = sock->is_blocked; - sock->is_blocked = mode; +#endif - return oldmode; -} -PHPAPI size_t php_stream_sock_set_chunk_size(php_stream *stream, size_t size TSRMLS_DC) +PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC) { - size_t oldsize; - php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + int ret = SUCCESS; + int flags; + int myflag = 0; - if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET)) - return 0; - - oldsize = sock->chunk_size; - sock->chunk_size = size; - - return oldsize; +#ifdef PHP_WIN32 + /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */ + flags = !block; + if (ioctlsocket(socketd, FIONBIO, &flags)==SOCKET_ERROR){ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", WSAGetLastError()); + ret = FALSE; + } +#else + flags = fcntl(socketd, F_GETFL); +#ifdef O_NONBLOCK + myflag = O_NONBLOCK; /* POSIX version */ +#elif defined(O_NDELAY) + myflag = O_NDELAY; /* old non-POSIX version */ +#endif + if (!block) { + flags |= myflag; + } else { + flags &= ~myflag; + } + fcntl(socketd, F_SETFL, flags); +#endif + return ret; } -#define TOREAD(sock) ((sock)->writepos - (sock)->readpos) -#define READPTR(sock) ((sock)->readbuf + (sock)->readpos) -#define WRITEPTR(sock) ((sock)->readbuf + (sock)->writepos) - static size_t php_sockop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; @@ -632,21 +762,10 @@ DUMP_SOCK_STATE("wait_for_data: done", sock); } - -static size_t php_sock_stream_read_internal(php_stream *stream, php_netstream_data_t *sock TSRMLS_DC) +static size_t php_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) { - char buf[PHP_SOCK_CHUNK_SIZE]; - int nr_bytes; - size_t nr_read = 0; - - /* For blocking sockets, we wait until there is some - data to read (real data or EOF) - - Otherwise, recv() may time out and return 0 and - therefore sock->eof would be set errornously. - */ - -DUMP_SOCK_STATE("read_internal entry", sock); + php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + size_t nr_bytes = 0; if(sock->is_blocked) { php_sock_stream_wait_for_data(stream, sock TSRMLS_CC); @@ -654,131 +773,24 @@ return 0; } -DUMP_SOCK_STATE("read_internal about to recv/SSL_read", sock); - - /* read at a maximum sock->chunk_size */ #if HAVE_OPENSSL_EXT + /* XXX: Where is the complex OpenSSL error handling? */ if (sock->ssl_active) - nr_bytes = SSL_read(sock->ssl_handle, buf, sock->chunk_size); + nr_bytes = SSL_read(sock->ssl_handle, buf, count); else #endif - nr_bytes = recv(sock->socket, buf, sock->chunk_size, 0); -DUMP_SOCK_STATE("read_internal after recv/SSL_read", sock); - -#if DEBUG_MAIN_NETWORK -printf("read_internal read %d/%d bytes\n", nr_bytes, sock->chunk_size); -#endif - - if(nr_bytes > 0) { - - php_stream_notify_progress_increment(stream->context, nr_bytes, 0); - - /* try to avoid an ever-expanding buffer */ - if (sock->readpos > 0) { - memmove(sock->readbuf, READPTR(sock), sock->readbuflen - sock->readpos); - sock->writepos -= sock->readpos; - sock->readpos = 0; - } - - if(sock->writepos + nr_bytes > sock->readbuflen) { - sock->readbuflen += sock->chunk_size; - sock->readbuf = perealloc(sock->readbuf, sock->readbuflen, - php_stream_is_persistent(stream)); - } - memcpy(WRITEPTR(sock), buf, nr_bytes); - sock->writepos += nr_bytes; - nr_read = nr_bytes; - } else if(nr_bytes == 0 || (nr_bytes < 0 && errno != EWOULDBLOCK)) { - sock->eof = 1; - } - - return nr_read; -} + nr_bytes = recv(sock->socket, buf, count, 0); -static size_t php_sock_stream_read(php_stream *stream, php_netstream_data_t *sock TSRMLS_DC) -{ - size_t nr_bytes; - size_t nr_read = 0; - int i; + php_stream_notify_progress_increment(stream->context, nr_bytes, 0); - for(i = 0; !sock->eof && i < MAX_CHUNKS_PER_READ; i++) { -DUMP_SOCK_STATE("read about to read_internal", sock); - nr_bytes = php_sock_stream_read_internal(stream, sock TSRMLS_CC); - if(nr_bytes == 0) - break; - - - nr_read += nr_bytes; + if(nr_bytes == 0 || (nr_bytes < 0 && streams_socket_errno != EWOULDBLOCK)) { + stream->eof = 1; } - return nr_read; + return nr_bytes; } -static size_t php_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) -{ - php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; - size_t ret = 0; - - if (buf == NULL && count == 0) { - /* check for EOF condition */ -DUMP_SOCK_STATE("check for EOF", sock); - - if (sock->eof) - return EOF; - - if (TOREAD(sock)) - return 0; - - /* no data in the buffer - lets examine the socket */ -#if HAVE_SYS_POLL_H - { - struct pollfd topoll; - - topoll.fd = sock->socket; - topoll.events = POLLIN; - topoll.revents = 0; - - if (poll(&topoll, 1, 0) == 1) { - return topoll.revents & POLLHUP ? EOF : 0; - } - } -#endif - - /* in the absence of other methods of checking if the - * socket is still active, try to read a chunk of data */ - sock->timeout_event = 0; - php_sock_stream_read_internal(stream, sock TSRMLS_CC); - - if (sock->timeout_event || sock->eof) - return EOF; - - return 0; - } - - if (sock->is_blocked) { - sock->timeout_event = 0; - while(!sock->eof && TOREAD(sock) < count && !sock->timeout_event) - if (php_sock_stream_read_internal(stream, sock TSRMLS_CC) == 0) - break; - } else { - php_sock_stream_read(stream, sock TSRMLS_CC); - } - - if(count < 0) - return ret; - - ret = MIN(TOREAD(sock), count); - if (ret) { - memcpy(buf, READPTR(sock), ret); - sock->readpos += ret; - } -#if DEBUG_MAIN_NETWORK - DUMP_SOCK_STATE("sockop_read", sock); - printf("sockop_read returning with %d bytes read\n", ret); -#endif - return ret; -} static int php_sockop_close(php_stream *stream, int close_handle TSRMLS_DC) { @@ -800,8 +812,6 @@ closesocket(sock->socket); } - if (sock->readbuf) - pefree(sock->readbuf, php_stream_is_persistent(stream)); pefree(sock, php_stream_is_persistent(stream)); @@ -820,6 +830,37 @@ return fstat(sock->socket, &ssb->sb); } +static int php_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +{ + int oldmode; + php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + + switch(option) { + case PHP_STREAM_OPTION_BLOCKING: + + oldmode = sock->is_blocked; + + /* no need to change anything */ + if (value == oldmode) + return oldmode; + + if (SUCCESS == php_set_sock_blocking(sock->socket, value TSRMLS_CC)) { + sock->is_blocked = value; + return oldmode; + } + + return PHP_STREAM_OPTION_RETURN_ERR; + + case PHP_STREAM_OPTION_READ_TIMEOUT: + sock->timeout = *(struct timeval*)ptrparam; + sock->timeout_event = 0; + return PHP_STREAM_OPTION_RETURN_OK; + + default: + return PHP_STREAM_OPTION_RETURN_NOTIMPL; + } +} + static int php_sockop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; @@ -831,9 +872,6 @@ return FAILURE; #endif if (ret) { - /* DANGER!: data buffered in stream->readbuf will be forgotten! */ - if (TOREAD(sock) > 0) - zend_error(E_WARNING, "%s(): %d bytes of buffered data lost during conversion to FILE*!", get_active_function_name(TSRMLS_C), TOREAD(sock)); *ret = fdopen(sock->socket, stream->mode); if (*ret) return SUCCESS; @@ -854,77 +892,14 @@ } } -#define SEARCHCR() do { \ - if (TOREAD(sock)) { \ - for (p = READPTR(sock), pe = p + MIN(TOREAD(sock), maxlen); \ - *p != '\n'; ) \ - if (++p >= pe) { \ - p = NULL; \ - break; \ - } \ - } else \ - p = NULL; \ -} while (0) - - -static char *php_sockop_gets(php_stream *stream, char *buf, size_t maxlen TSRMLS_DC) -{ - php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; - char *p = NULL, *pe; - char *ret = NULL; - size_t amount = 0; - - if (maxlen==0) { - buf[0] = 0; - return buf; - } - - SEARCHCR(); - - if(!p) { - if(sock->is_blocked) { - sock->timeout_event = 0; - - while(!p && !sock->eof && !sock->timeout_event && TOREAD(sock) < maxlen) { - php_sock_stream_read_internal(stream, sock TSRMLS_CC); - SEARCHCR(); - } - } else { - php_sock_stream_read(stream, sock TSRMLS_CC); - SEARCHCR(); - } - } - - if(p) { - amount = (ptrdiff_t) p - (ptrdiff_t) READPTR(sock) + 1; - } else { - amount = TOREAD(sock); - } - - amount = MIN(amount, maxlen); - - if(amount > 0) { - memcpy(buf, READPTR(sock), amount); - sock->readpos += amount; - } - buf[amount] = '\0'; - - /* signal error only, if we don't return data from this call and - if there is no data to read and if the eof flag is set */ - if(amount || TOREAD(sock) || !sock->eof) { - ret = buf; - } - - return ret; -} - php_stream_ops php_stream_socket_ops = { php_sockop_write, php_sockop_read, php_sockop_close, php_sockop_flush, "socket", - NULL, php_sockop_gets, + NULL, /* seek */ php_sockop_cast, - php_sockop_stat + php_sockop_stat, + php_sockop_set_option, }; 1.6 +331 -80 php4/main/output.c Index: output.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/output.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- output.c 2 Aug 2002 22:05:25 -0000 1.5 +++ output.c 6 Oct 2002 21:54:34 -0000 1.6 @@ -14,10 +14,11 @@ +----------------------------------------------------------------------+ | Authors: Zeev Suraski <zeev****@zend*****> | | Thies C. Arntzen <thies****@thies*****> | + | Marcus Boerger <helly****@php*****> | +----------------------------------------------------------------------+ */ -/* $Id: output.c,v 1.103 2002/05/12 22:17:58 zeev Exp $ */ +/* $Id: output.c,v 1.141 2002/10/06 12:02:53 zeev Exp $ */ #include "php.h" #include "ext/standard/head.h" @@ -25,12 +26,14 @@ #include "ext/standard/url_scanner_ex.h" #include "SAPI.h" +#define OB_DEFAULT_HANDLER_NAME "default output handler" + /* output functions */ static int php_ub_body_write(const char *str, uint str_length TSRMLS_DC); static int php_ub_body_write_no_header(const char *str, uint str_length TSRMLS_DC); static int php_b_body_write(const char *str, uint str_length TSRMLS_DC); -static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC); +static int php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC); static void php_ob_append(const char *text, uint text_length TSRMLS_DC); #if 0 static void php_ob_prepend(const char *text, uint text_length); @@ -42,13 +45,15 @@ php_output_globals output_globals; #endif -static int php_default_output_func(const char *str, uint str_len TSRMLS_DC) +/* {{{ php_default_output_func */ +static inline int php_default_output_func(const char *str, uint str_len TSRMLS_DC) { fwrite(str, 1, str_len, stderr); return str_len; } +/* }}} */ - +/* {{{ php_output_init_globals */ static void php_output_init_globals(php_output_globals *output_globals_p TSRMLS_DC) { OG(php_body_write) = php_default_output_func; @@ -57,9 +62,11 @@ OG(output_start_filename) = NULL; OG(output_start_lineno) = 0; } +/* }}} */ -/* Start output layer */ +/* {{{ php_output_startup + Start output layer */ PHPAPI void php_output_startup(void) { #ifdef ZTS @@ -68,8 +75,11 @@ php_output_init_globals(&output_globals TSRMLS_CC); #endif } +/* }}} */ +/* {{{ php_output_activate + Initilize output global for activation */ PHPAPI void php_output_activate(TSRMLS_D) { OG(php_body_write) = php_ub_body_write; @@ -80,27 +90,37 @@ OG(output_start_filename) = NULL; OG(output_start_lineno) = 0; } +/* }}} */ +/* {{{ php_output_set_status + Toggle output status. Do NOT use in application code, only in SAPIs where appropriate. */ PHPAPI void php_output_set_status(zend_bool status TSRMLS_DC) { OG(disable_output) = !status; } +/* }}} */ - +/* {{{ php_output_register_constants */ void php_output_register_constants(TSRMLS_D) { REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_START", PHP_OUTPUT_HANDLER_START, CONST_CS | CONST_PERSISTENT); REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_CONT", PHP_OUTPUT_HANDLER_CONT, CONST_CS | CONST_PERSISTENT); REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_END", PHP_OUTPUT_HANDLER_END, CONST_CS | CONST_PERSISTENT); } +/* }}} */ +/* {{{ php_body_wirte + * Write body part */ PHPAPI int php_body_write(const char *str, uint str_length TSRMLS_DC) { return OG(php_body_write)(str, str_length TSRMLS_CC); } +/* }}} */ +/* {{{ php_header_wirte + * Write HTTP header */ PHPAPI int php_header_write(const char *str, uint str_length TSRMLS_DC) { if (OG(disable_output)) { @@ -109,21 +129,52 @@ return OG(php_header_write)(str, str_length TSRMLS_CC); } } +/* }}} */ /* {{{ php_start_ob_buffer * Start output buffering */ PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC) { + uint initial_size, block_size; + if (OG(ob_lock)) { + if (SG(headers_sent) && !SG(request_info).headers_only) { + OG(php_body_write) = php_ub_body_write_no_header; + } else { + OG(php_body_write) = php_ub_body_write; + } + OG(ob_nesting_level) = 0; + php_error_docref("ref.outcontrol" TSRMLS_CC, E_ERROR, "Cannot use output buffering in output buffering display handlers"); return FAILURE; } if (chunk_size) { - php_ob_init((chunk_size*3/2), chunk_size/2, output_handler, chunk_size, erase TSRMLS_CC); + if (chunk_size==1) + chunk_size = 4096; + initial_size = (chunk_size*3/2); + block_size = chunk_size/2; } else { - php_ob_init(40*1024, 10*1024, output_handler, chunk_size, erase TSRMLS_CC); + initial_size = 40*1024; + block_size = 10*1024; } - OG(php_body_write) = php_b_body_write; - return SUCCESS; + return php_ob_init(initial_size, block_size, output_handler, chunk_size, erase TSRMLS_CC); +} +/* }}} */ + +/* {{{ php_start_ob_buffer_named + * Start output buffering */ +PHPAPI int php_start_ob_buffer_named(const char *output_handler_name, uint chunk_size, zend_bool erase TSRMLS_DC) +{ + zval *output_handler; + int result; + + ALLOC_INIT_ZVAL(output_handler); + Z_STRLEN_P(output_handler) = strlen(output_handler_name); /* this can be optimized */ + Z_STRVAL_P(output_handler) = estrndup(output_handler_name, Z_STRLEN_P(output_handler)); + Z_TYPE_P(output_handler) = IS_STRING; + result = php_start_ob_buffer(output_handler, chunk_size, erase TSRMLS_CC); + zval_dtor(output_handler); + FREE_ZVAL(output_handler); + return result; } /* }}} */ @@ -184,9 +235,11 @@ params[1] = &z_status; OG(ob_lock) = 1; if (call_user_function_ex(CG(function_table), NULL, OG(active_ob_buffer).output_handler, &alternate_buffer, 2, params, 1, NULL TSRMLS_CC)==SUCCESS) { - convert_to_string_ex(&alternate_buffer); - final_buffer = Z_STRVAL_P(alternate_buffer); - final_buffer_length = Z_STRLEN_P(alternate_buffer); + if (!(Z_TYPE_P(alternate_buffer)==IS_BOOL && Z_BVAL_P(alternate_buffer)==0)) { + convert_to_string_ex(&alternate_buffer); + final_buffer = Z_STRVAL_P(alternate_buffer); + final_buffer_length = Z_STRLEN_P(alternate_buffer); + } } OG(ob_lock) = 0; zval_ptr_dtor(&OG(active_ob_buffer).output_handler); @@ -196,7 +249,6 @@ FREE_ZVAL(orig_buffer); } zval_ptr_dtor(&z_status); - zval_ptr_dtor(&OG(active_ob_buffer).output_handler); } if (!final_buffer) { @@ -301,8 +353,8 @@ */ PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t internal_output_handler, uint buffer_size, char *handler_name, zend_bool erase TSRMLS_DC) { - if (OG(ob_nesting_level)==0) { - return; + if (OG(ob_nesting_level)==0 || OG(active_ob_buffer).internal_output_handler || strcmp(OG(active_ob_buffer).handler_name, OB_DEFAULT_HANDLER_NAME)) { + php_start_ob_buffer(NULL, buffer_size, erase TSRMLS_CC); } OG(active_ob_buffer).internal_output_handler = internal_output_handler; @@ -333,9 +385,23 @@ } /* }}} */ -/* {{{ php_ob_init +/* {{{ php_ob_init_conflict + * Returns 1 if handler_set is already used and generates error message + */ +PHPAPI int php_ob_init_conflict(char *handler_new, char *handler_set TSRMLS_DC) +{ + if (php_ob_handler_used(handler_set TSRMLS_CC)) + { + php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler '%s' conflicts with '%s'", handler_new, handler_set); + return 1; + } + return 0; +} +/* }}} */ + +/* {{{ php_ob_init_named */ -static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC) +static int php_ob_init_named(uint initial_size, uint block_size, char *handler_name, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC) { if (OG(ob_nesting_level)>0) { if (OG(ob_nesting_level)==1) { /* initialize stack */ @@ -352,24 +418,164 @@ OG(active_ob_buffer).chunk_size = chunk_size; OG(active_ob_buffer).status = 0; OG(active_ob_buffer).internal_output_handler = NULL; + OG(active_ob_buffer).handler_name = estrdup(handler_name&&handler_name[0]?handler_name:OB_DEFAULT_HANDLER_NAME); + OG(active_ob_buffer).erase = erase; + OG(php_body_write) = php_b_body_write; + return SUCCESS; +} +/* }}} */ + +/* {{{ php_ob_handler_from_string + * Create zval output handler from string + */ +static zval* php_ob_handler_from_string(const char *handler_name TSRMLS_DC) +{ + zval *output_handler; + + ALLOC_INIT_ZVAL(output_handler); + Z_STRLEN_P(output_handler) = strlen(handler_name); /* this can be optimized */ + Z_STRVAL_P(output_handler) = estrndup(handler_name, Z_STRLEN_P(output_handler)); + Z_TYPE_P(output_handler) = IS_STRING; + return output_handler; +} +/* }}} */ + +/* {{{ php_ob_init + */ +static int php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC) +{ + int res, result, len; + char *handler_name, *next_handler_name; + HashPosition pos; + zval **tmp; + zval *handler_zval; + if (output_handler && output_handler->type == IS_STRING) { - OG(active_ob_buffer).handler_name = estrndup(Z_STRVAL_P(output_handler), Z_STRLEN_P(output_handler)); + result = 0; + handler_name = Z_STRVAL_P(output_handler); + while ((next_handler_name=strchr(handler_name, ',')) != NULL) { + len = next_handler_name-handler_name; + next_handler_name = estrndup(handler_name, len); + handler_zval = php_ob_handler_from_string(next_handler_name TSRMLS_CC); + res = php_ob_init_named(initial_size, block_size, next_handler_name, handler_zval, chunk_size, erase TSRMLS_CC); + result &= res; + if (!res==SUCCESS) { + zval_dtor(handler_zval); + FREE_ZVAL(handler_zval); + } + handler_name += len+1; + efree(next_handler_name); + } + handler_zval = php_ob_handler_from_string(handler_name TSRMLS_CC); + res = php_ob_init_named(initial_size, block_size, handler_name, handler_zval, chunk_size, erase TSRMLS_CC); + result &= res; + if (!res==SUCCESS) { + zval_dtor(handler_zval); + FREE_ZVAL(handler_zval); + } + result = result ? SUCCESS : FAILURE; } else if (output_handler && output_handler->type == IS_ARRAY) { - /* FIXME: Array type is not supported yet. - See call_user_function_ex() for detials. */ - OG(active_ob_buffer).handler_name = estrdup("array is not supported yet"); + result = 0; + /* do we have array(object,method) */ + if (zend_is_callable(output_handler, 1, &handler_name)) { + SEPARATE_ZVAL(&output_handler); + output_handler->refcount++; + result = php_ob_init_named(initial_size, block_size, handler_name, output_handler, chunk_size, erase TSRMLS_CC); + efree(handler_name); + } else { + /* init all array elements recursively */ + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(output_handler), &pos); + while (zend_hash_get_current_data_ex(Z_ARRVAL_P(output_handler), (void **)&tmp, &pos) == SUCCESS) { + result &= php_ob_init(initial_size, block_size, *tmp, chunk_size, erase TSRMLS_CC); + zend_hash_move_forward_ex(Z_ARRVAL_P(output_handler), &pos); + } + } + result = result ? SUCCESS : FAILURE; + } + else if (output_handler && output_handler->type == IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "No method name given: use ob_start(array($object,'method')) to specify instance $object and the name of a method of class %s to use as output handler", Z_OBJCE_P(output_handler)->name); + result = FAILURE; } else { - OG(active_ob_buffer).handler_name = estrdup("default output handler"); + if (output_handler) { + SEPARATE_ZVAL(&output_handler); + output_handler->refcount++; + } + result = php_ob_init_named(initial_size, block_size, OB_DEFAULT_HANDLER_NAME, output_handler, chunk_size, erase TSRMLS_CC); + } + return result; +} +/* }}} */ + +/* {{{ php_ob_list_each + */ +static int php_ob_list_each(php_ob_buffer *ob_buffer, zval *ob_handler_array) +{ + add_next_index_string(ob_handler_array, ob_buffer->handler_name, 1); + return 0; +} +/* }}} */ + +/* {{{ proto false|array ob_list_handlers() + * List all output_buffers in an array + */ +PHP_FUNCTION(ob_list_handlers) +{ + if (ZEND_NUM_ARGS()!=0) { + WRONG_PARAM_COUNT; + RETURN_FALSE; + } + + if (array_init(return_value) == FAILURE) { + php_error_docref("ref.outcontrol" TSRMLS_CC, E_ERROR, "Unable to initialize array"); + RETURN_FALSE; + } + if (OG(ob_nesting_level)) { + if (OG(ob_nesting_level)>1) { + zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *element, void *)) php_ob_list_each, return_value); + } + php_ob_list_each(&OG(active_ob_buffer), return_value); } - OG(active_ob_buffer).erase = erase; +} +/* }}} */ + +/* {{{ php_ob_used_each + * Sets handler_name to NULL is found + */ +static int php_ob_handler_used_each(php_ob_buffer *ob_buffer, char **handler_name) +{ + if (!strcmp(ob_buffer->handler_name, *handler_name)) + { + *handler_name = NULL; + return 1; + } + return 0; +} +/* }}} */ + +/* {{{ php_ob_used + * returns 1 if given handler_name is used as output_handler + */ +PHPAPI int php_ob_handler_used(char *handler_name TSRMLS_DC) +{ + char *tmp = handler_name; + + if (OG(ob_nesting_level)) { + if (!strcmp(OG(active_ob_buffer).handler_name, handler_name)) { + return 1; + } + if (OG(ob_nesting_level)>1) { + zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *element, void *)) php_ob_handler_used_each, &tmp); + } + } + return tmp ? 0 : 1; } /* }}} */ /* {{{ php_ob_append */ -static void php_ob_append(const char *text, uint text_length TSRMLS_DC) +static inline void php_ob_append(const char *text, uint text_length TSRMLS_DC) { char *target; int original_ob_text_length; @@ -382,10 +588,11 @@ memcpy(target, text, text_length); target[text_length]=0; + /* If implicit_flush is On or chunked buffering, send contents to next buffer and return. */ if (OG(active_ob_buffer).chunk_size && OG(active_ob_buffer).text_length >= OG(active_ob_buffer).chunk_size) { zval *output_handler = OG(active_ob_buffer).output_handler; - + if (output_handler) { output_handler->refcount++; } @@ -396,7 +603,7 @@ /* }}} */ #if 0 -static void php_ob_prepend(const char *text, uint text_length) +static inline void php_ob_prepend(const char *text, uint text_length) { char *p, *start; TSRMLS_FETCH(); @@ -419,7 +626,7 @@ /* {{{ php_ob_get_buffer * Return the current output buffer */ -int php_ob_get_buffer(zval *p TSRMLS_DC) +PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC) { if (OG(ob_nesting_level)==0) { return FAILURE; @@ -431,7 +638,7 @@ /* {{{ php_ob_get_length * Return the size of the current output buffer */ -int php_ob_get_length(zval *p TSRMLS_DC) +PHPAPI int php_ob_get_length(zval *p TSRMLS_DC) { if (OG(ob_nesting_level) == 0) { return FAILURE; @@ -504,7 +711,7 @@ * HEAD support */ -/* {{{ proto void ob_start([ string user_function [, int chunk_size [, bool erase]]]) +/* {{{ proto bool ob_start([ string|array user_function [, int chunk_size [, bool erase]]]) Turn on Output Buffering (specifying an optional output handler). */ PHP_FUNCTION(ob_start) { @@ -515,20 +722,9 @@ if (zend_parse_parameters(argc TSRMLS_CC, "|zlb", &output_handler, &chunk_size, &erase) == FAILURE) - return; + RETURN_FALSE; - if (output_handler) { - SEPARATE_ZVAL(&output_handler); - output_handler->refcount++; - } if (php_start_ob_buffer(output_handler, chunk_size, erase TSRMLS_CC)==FAILURE) { - if (SG(headers_sent) && !SG(request_info).headers_only) { - OG(php_body_write) = php_ub_body_write_no_header; - } else { - OG(php_body_write) = php_ub_body_write; - } - OG(ob_nesting_level) = 0; - php_error(E_ERROR, "Cannot use output buffering in output buffering display handlers"); RETURN_FALSE; } RETURN_TRUE; @@ -536,23 +732,23 @@ /* }}} */ /* {{{ proto bool ob_flush(void) - Flush (send) contents of the output buffers */ + Flush (send) contents of the output buffer. The last buffer content is sent to next buffer */ PHP_FUNCTION(ob_flush) { if (ZEND_NUM_ARGS() != 0) WRONG_PARAM_COUNT; if (!OG(ob_nesting_level)) { - php_error(E_NOTICE, "%s() failed to flush buffer. No buffer to flush.", - get_active_function_name(TSRMLS_C)); + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to flush buffer. No buffer to flush."); RETURN_FALSE; } - + php_end_ob_buffer(1, 1 TSRMLS_CC); RETURN_TRUE; } /* }}} */ + /* {{{ proto bool ob_clean(void) Clean (delete) the current output buffer */ PHP_FUNCTION(ob_clean) @@ -562,13 +758,11 @@ if (!OG(ob_nesting_level)) { - php_error(E_NOTICE, "%s() failed to delete buffer. No buffer to delete.", - get_active_function_name(TSRMLS_C)); + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete."); RETURN_FALSE; } - if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) { - php_error(E_NOTICE, "%s() failed to delete buffer %s.", - get_active_function_name(TSRMLS_C), OG(active_ob_buffer).handler_name); + if (!OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) { + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s.", OG(active_ob_buffer).handler_name); RETURN_FALSE; } @@ -585,13 +779,11 @@ WRONG_PARAM_COUNT; if (!OG(ob_nesting_level)) { - php_error(E_NOTICE, "%s() failed to delete and flush buffer. No buffer to delete or flush.", - get_active_function_name(TSRMLS_C)); + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush."); RETURN_FALSE; } if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) { - php_error(E_NOTICE, "%s() failed to delete buffer %s.", - get_active_function_name(TSRMLS_C), OG(active_ob_buffer).handler_name); + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s.", OG(active_ob_buffer).handler_name); RETURN_FALSE; } @@ -608,13 +800,11 @@ WRONG_PARAM_COUNT; if (!OG(ob_nesting_level)) { - php_error(E_NOTICE, "%s() failed to delete buffer. No buffer to delete.", - get_active_function_name(TSRMLS_C)); + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete."); RETURN_FALSE; } if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) { - php_error(E_NOTICE, "%s() failed to delete buffer %s.", - get_active_function_name(TSRMLS_C), OG(active_ob_buffer).handler_name); + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s.", OG(active_ob_buffer).handler_name); RETURN_FALSE; } @@ -623,6 +813,56 @@ } /* }}} */ +/* {{{ proto bool ob_get_flush(void) + Get current buffer contents, flush (send) the output buffer, and delete current output buffer */ +PHP_FUNCTION(ob_get_flush) +{ + if (ZEND_NUM_ARGS() != 0) + WRONG_PARAM_COUNT; + + /* get contents */ + if (php_ob_get_buffer(return_value TSRMLS_CC)==FAILURE) { + RETURN_FALSE; + } + /* error checks */ + if (!OG(ob_nesting_level)) { + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush."); + RETURN_FALSE; + } + if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) { + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s.", OG(active_ob_buffer).handler_name); + RETURN_FALSE; + } + /* flush */ + php_end_ob_buffer(1, 0 TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto bool ob_get_clean(void) + Get current buffer contents and delete current output buffer */ +PHP_FUNCTION(ob_get_clean) +{ + if (ZEND_NUM_ARGS() != 0) + WRONG_PARAM_COUNT; + + /* get contents */ + if (php_ob_get_buffer(return_value TSRMLS_CC)==FAILURE) { + RETURN_FALSE; + } + /* error checks */ + if (!OG(ob_nesting_level)) { + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete."); + RETURN_FALSE; + } + if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) { + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s.", OG(active_ob_buffer).handler_name); + RETURN_FALSE; + } + /* delete buffer */ + php_end_ob_buffer(0, 0 TSRMLS_CC); +} +/* }}} */ + /* {{{ proto string ob_get_contents(void) Return the contents of the output buffer */ PHP_FUNCTION(ob_get_contents) @@ -636,7 +876,7 @@ } /* }}} */ -/* {{{ proto integer ob_get_level(void) +/* {{{ proto int ob_get_level(void) Return the nesting level of the output buffer */ PHP_FUNCTION(ob_get_level) { @@ -660,6 +900,7 @@ } /* }}} */ +/* {{{ int php_ob_buffer_status(php_ob_buffer *ob_buffer, zval *result) */ static int php_ob_buffer_status(php_ob_buffer *ob_buffer, zval *result) { zval *elem; @@ -669,8 +910,14 @@ return FAILURE; } + add_assoc_long(elem, "chunk_size", ob_buffer->chunk_size); + if (!ob_buffer->chunk_size) { + add_assoc_long(elem, "size", ob_buffer->size); + add_assoc_long(elem, "block_size", ob_buffer->block_size); + } if (ob_buffer->internal_output_handler) { add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_INTERNAL); + add_assoc_long(elem, "buffer_size", ob_buffer->internal_output_handler_buffer_size); } else { add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_USER); @@ -682,43 +929,32 @@ return SUCCESS; } +/* }}} */ -/* {{{ proto array ob_get_status([bool full_status]) - Return the nesting level of the output buffer */ +/* {{{ proto false|array ob_get_status([bool full_status]) + Return the status of the active or all output buffers */ PHP_FUNCTION(ob_get_status) { int argc = ZEND_NUM_ARGS(); zend_bool full_status = 0; if (zend_parse_parameters(argc TSRMLS_CC, "|b", &full_status) == FAILURE ) - return; + RETURN_FALSE; if (array_init(return_value) == FAILURE) { RETURN_FALSE; } if (full_status) { - zval *elem; - - zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *elem, void *))php_ob_buffer_status, return_value); - - MAKE_STD_ZVAL(elem); - if (array_init(elem)) - RETURN_FALSE; - - if (OG(active_ob_buffer).internal_output_handler) { - add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_INTERNAL); + if (OG(ob_nesting_level)>1) { + zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *elem, void *))php_ob_buffer_status, return_value); } - else { - add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_USER); + if (OG(ob_nesting_level)>0 && php_ob_buffer_status(&OG(active_ob_buffer), return_value)==FAILURE) { + RETURN_FALSE; } - add_assoc_long(elem, "status", OG(active_ob_buffer).status); - add_assoc_string(elem, "name", OG(active_ob_buffer).handler_name, 1); - add_assoc_bool(elem, "del", OG(active_ob_buffer).erase); - add_next_index_zval(return_value, elem); } - else { + else if (OG(ob_nesting_level)>0) { add_assoc_long(return_value, "level", OG(ob_nesting_level)); if (OG(active_ob_buffer).internal_output_handler) { add_assoc_long(return_value, "type", PHP_OUTPUT_HANDLER_INTERNAL); @@ -764,17 +1000,27 @@ } /* }}} */ + +/* {{{ char *php_get_output_start_filename(TSRMLS_D) + Return filename start output something */ PHPAPI char *php_get_output_start_filename(TSRMLS_D) { return OG(output_start_filename); } +/* }}} */ +/* {{{ char *php_get_output_start_lineno(TSRMLS_D) + Return line number start output something */ PHPAPI int php_get_output_start_lineno(TSRMLS_D) { return OG(output_start_lineno); } +/* }}} */ + +/* {{{ proto bool output_reset_rewrite_vars(void) + Reset(clear) URL rewriter values */ PHP_FUNCTION(output_reset_rewrite_vars) { if (php_url_scanner_reset_vars(TSRMLS_C) == SUCCESS) { @@ -783,7 +1029,11 @@ RETURN_FALSE; } } +/* }}} */ + +/* {{{ proto bool output_add_rewrite_var(string name, string value) + Add URL rewriter values */ PHP_FUNCTION(output_add_rewrite_var) { char *name, *value; @@ -799,6 +1049,7 @@ RETURN_FALSE; } } +/* }}} */ /* * Local variables: 1.4 +39 -5 php4/main/php.h Index: php.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- php.h 9 May 2002 05:39:43 -0000 1.3 +++ php.h 6 Oct 2002 21:54:34 -0000 1.4 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php.h,v 1.170 2002/05/07 22:00:33 sas Exp $ */ +/* $Id: php.h,v 1.176 2002/09/25 15:25:12 wez Exp $ */ #ifndef PHP_H #define PHP_H @@ -61,6 +61,12 @@ #define PHP_DIR_SEPARATOR '/' #endif +#ifdef NETWARE +#define PHP_UNAME "NetWare" /* For php_get_uname() function */ +#define PHP_OS PHP_UNAME /* This is obtained using 'uname' on Unix and assigned in the case of Windows; + we'll do it this way atleast for now */ +#endif + #include "php_regex.h" #if HAVE_ASSERT_H @@ -179,6 +185,13 @@ # ifdef PHP_WIN32 #include "win32/pwd.h" #include "win32/param.h" +#elif defined(NETWARE) +#ifdef NEW_LIBC +#include <sys/param.h> +#else +#include "NetWare/param.h" +#endif +#include "NetWare/pwd.h" # else #include <pwd.h> #include <sys/param.h> @@ -217,17 +230,24 @@ # endif #endif -#include "php_streams.h" -#include "php_memory_streams.h" -#include "fopen_wrappers.h" - /* global variables */ extern pval *data; #if !defined(PHP_WIN32) +#ifdef NETWARE +#ifdef NEW_LIBC +/*#undef environ*/ /* For now, so that our 'environ' implementation is used */ +#define php_sleep sleep +#else +#define php_sleep delay /* sleep() and usleep() are not available */ +#define usleep delay +#endif +extern char **environ; +#else extern char **environ; #define php_sleep sleep #endif +#endif #ifdef PHP_PWRITE_64 ssize_t pwrite(int, void *, size_t, off64_t); @@ -246,6 +266,15 @@ #define php_error zend_error +PHPAPI void php_verror(const char *docref, const char *params, int type, const char *format, va_list args TSRMLS_DC) ; + +/* PHPAPI void php_error(int type, const char *format, ...); */ +PHPAPI void php_error_docref0(const char *docref TSRMLS_DC, int type, const char *format, ...); +PHPAPI void php_error_docref1(const char *docref TSRMLS_DC, const char *param1, int type, const char *format, ...); +PHPAPI void php_error_docref2(const char *docref TSRMLS_DC, const char *param1, const char *param2, int type, const char *format, ...); + +#define php_error_docref php_error_docref0 + #define zenderror phperror #define zendlex phplex @@ -313,6 +342,11 @@ #ifdef ZTS #define VIRTUAL_DIR #endif + +#include "php_streams.h" +#include "php_memory_streams.h" +#include "fopen_wrappers.h" + /* Virtual current working directory support */ #include "tsrm_virtual_cwd.h" 1.3 +2 -0 php4/main/php_compat.h Index: php_compat.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_compat.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_compat.h 29 Apr 2002 02:33:38 -0000 1.2 +++ php_compat.h 6 Oct 2002 21:54:34 -0000 1.3 @@ -3,6 +3,8 @@ #ifdef PHP_WIN32 #include "config.w32.h" +#elif defined(NETWARE) +#include "config.nw.h" #else #include "php_config.h" #endif 1.3 +2 -1 php4/main/php_content_types.c Index: php_content_types.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_content_types.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_content_types.c 29 Apr 2002 02:33:38 -0000 1.2 +++ php_content_types.c 6 Oct 2002 21:54:34 -0000 1.3 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_content_types.c,v 1.20 2002/02/28 08:27:03 sebastian Exp $ */ +/* $Id: php_content_types.c,v 1.21 2002/08/02 06:53:48 hirokawa Exp $ */ #include "php.h" #include "SAPI.h" @@ -51,6 +51,7 @@ { sapi_register_post_entries(php_post_entries); sapi_register_default_post_reader(php_default_post_reader); + sapi_register_treat_data(php_default_treat_data); return SUCCESS; } /* }}} */ 1.3 +6 -1 php4/main/php_globals.h Index: php_globals.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_globals.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_globals.h 29 Apr 2002 02:33:38 -0000 1.2 +++ php_globals.h 6 Oct 2002 21:54:34 -0000 1.3 @@ -79,6 +79,7 @@ int log_errors_max_len; zend_bool ignore_repeated_errors; zend_bool ignore_repeated_source; + zend_bool report_memleaks; char *error_log; char *doc_root; @@ -119,6 +120,9 @@ zend_bool y2k_compliance; + char *docref_root; + char *docref_ext; + zend_bool html_errors; zend_bool xmlrpc_errors; @@ -134,7 +138,8 @@ zend_bool allow_url_fopen; zend_bool always_populate_raw_post_data; - + + zend_bool allow_webdav_methods; }; 1.4 +138 -39 php4/main/php_ini.c Index: php_ini.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_ini.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- php_ini.c 2 Aug 2002 22:05:25 -0000 1.3 +++ php_ini.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -16,13 +16,13 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ini.c,v 1.94 2002/05/12 14:48:20 sas Exp $ */ +/* $Id: php_ini.c,v 1.104 2002/10/04 04:47:35 rasmus Exp $ */ /* Check CWD for php.ini */ #define INI_CHECK_CWD #include "php.h" -#ifndef PHP_WIN32 +#if !defined(PHP_WIN32) && !defined(NETWARE) #include "build-defs.h" #endif #include "ext/standard/info.h" @@ -34,6 +34,10 @@ #include "SAPI.h" #include "php_main.h" +#ifndef S_ISREG +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif + typedef struct _php_extension_lists { zend_llist engine; zend_llist functions; @@ -44,6 +48,7 @@ static HashTable configuration_hash; PHPAPI char *php_ini_opened_path=NULL; static php_extension_lists extension_lists; +PHPAPI char *php_ini_scanned_files=NULL; /* {{{ php_ini_displayer_cb */ @@ -62,16 +67,26 @@ display_string_length = ini_entry->orig_value_length; esc_html=1; } else { - display_string = "<i>no value</i>"; - display_string_length = sizeof("<i>no value</i>")-1; + if (PG(html_errors)) { + display_string = "<i>no value</i>"; + display_string_length = sizeof("<i>no value</i>")-1; + } else { + display_string = "no value"; + display_string_length = sizeof("no value")-1; + } } } else if (ini_entry->value && ini_entry->value[0]) { display_string = ini_entry->value; display_string_length = ini_entry->value_length; esc_html=1; } else { - display_string = "<i>no value</i>"; - display_string_length = sizeof("<i>no value</i>")-1; + if (PG(html_errors)) { + display_string = "<i>no value</i>"; + display_string_length = sizeof("<i>no value</i>")-1; + } else { + display_string = "no value"; + display_string_length = sizeof("no value")-1; + } } if(esc_html) { php_html_puts(display_string, display_string_length TSRMLS_CC); @@ -89,15 +104,23 @@ if (ini_entry->module_number != module_number) { return 0; } - - PUTS("<tr valign=\"baseline\" bgcolor=\"" PHP_CONTENTS_COLOR "\">"); - PUTS("<td bgcolor=\"" PHP_ENTRY_NAME_COLOR "\"><b>"); - PHPWRITE(ini_entry->name, ini_entry->name_length-1); - PUTS("</b><br /></td><td align=\"center\">"); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE); - PUTS("</td><td align=\"center\">"); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG); - PUTS("</td></tr>\n"); + if (PG(html_errors)) { + PUTS("<tr>"); + PUTS("<td class=\"e\">"); + PHPWRITE(ini_entry->name, ini_entry->name_length-1); + PUTS("</td><td class=\"v\">"); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE); + PUTS("</td><td class=\"v\">"); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG); + PUTS("</td></tr>\n"); + } else { + PHPWRITE(ini_entry->name, ini_entry->name_length-1); + PUTS(" => "); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE); + PUTS(" => "); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG); + PUTS("\n"); + } return 0; } /* }}} */ @@ -116,7 +139,7 @@ } php_info_print_table_start(); php_info_print_table_header(3, "Directive", "Local Value", "Master Value"); - zend_hash_apply_with_argument(&EG(ini_directives), (apply_func_arg_t) php_ini_displayer, (void *) (long) module_number TSRMLS_CC); + zend_hash_apply_with_argument(EG(ini_directives), (apply_func_arg_t) php_ini_displayer, (void *) (long) module_number TSRMLS_CC); php_info_print_table_end(); } /* }}} */ @@ -210,6 +233,14 @@ char *open_basedir; int free_ini_search_path=0; zend_file_handle fh; + DIR *dirp = NULL; + struct dirent *dir_entry; + struct stat sb; + char ini_file[MAXPATHLEN]; + char *p; + zend_llist scanned_ini_list; + int l, total_l=0; + zend_llist_element *element; TSRMLS_FETCH(); if (zend_hash_init(&configuration_hash, 0, NULL, (dtor_func_t) pvalue_config_destructor, 1)==FAILURE) { @@ -218,6 +249,7 @@ zend_llist_init(&extension_lists.engine, sizeof(char *), (llist_dtor_func_t) free_estring, 1); zend_llist_init(&extension_lists.functions, sizeof(zval), (llist_dtor_func_t) ZVAL_DESTRUCTOR, 1); + zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1); safe_mode_state = PG(safe_mode); open_basedir = PG(open_basedir); @@ -231,7 +263,7 @@ free_ini_search_path = 0; } else { char *default_location; - char paths_separator[] = { ZEND_PATHS_SEPARATOR, 0 }; + static const char paths_separator[] = { ZEND_PATHS_SEPARATOR, 0 }; php_ini_search_path = (char *) emalloc(MAXPATHLEN*3+strlen(env_location)+3+1); free_ini_search_path = 1; @@ -244,8 +276,10 @@ /* Add cwd */ #ifdef INI_CHECK_CWD if (strcmp(sapi_module.name, "cli")!=0) { + if (*php_ini_search_path) { + strcat(php_ini_search_path, paths_separator); + } strcat(php_ini_search_path, "."); - strcat(php_ini_search_path, paths_separator); } #endif @@ -269,28 +303,37 @@ if (separator_location) { *(separator_location+1) = 0; } + if (*php_ini_search_path) { + strcat(php_ini_search_path, paths_separator); + } strcat(php_ini_search_path, binary_location); - strcat(php_ini_search_path, paths_separator); efree(binary_location); } /* Add environment location */ if (env_location[0]) { + if (*php_ini_search_path) { + strcat(php_ini_search_path, paths_separator); + } strcat(php_ini_search_path, env_location); - strcat(php_ini_search_path, paths_separator); } /* Add default location */ #ifdef PHP_WIN32 default_location = (char *) emalloc(MAXPATHLEN+1); - if (!GetWindowsDirectory(default_location, MAXPATHLEN)) { - default_location[0]=0; + if (0 < GetWindowsDirectory(default_location, MAXPATHLEN)) { + if (*php_ini_search_path) { + strcat(php_ini_search_path, paths_separator); + } + strcat(php_ini_search_path, default_location); } - strcat(php_ini_search_path, default_location); efree(default_location); #else default_location = PHP_CONFIG_FILE_PATH; + if (*php_ini_search_path) { + strcat(php_ini_search_path, paths_separator); + } strcat(php_ini_search_path, default_location); #endif } @@ -306,37 +349,90 @@ if (!VCWD_STAT(sapi_module.php_ini_path_override, &statbuf)) { if (!((statbuf.st_mode & S_IFMT) == S_IFDIR)) { fh.handle.fp = VCWD_FOPEN(sapi_module.php_ini_path_override, "r"); + fh.filename = sapi_module.php_ini_path_override; } } } + /* Search php-%sapi-module-name%.ini file in search path */ + if (!fh.handle.fp) { + const char *fmt = "php-%s.ini"; + char *ini_fname=emalloc(strlen(fmt)+strlen(sapi_module.name)); + sprintf(ini_fname, fmt, sapi_module.name); + fh.handle.fp = php_fopen_with_path(ini_fname, "r", php_ini_search_path, &php_ini_opened_path TSRMLS_CC); + efree(ini_fname); + if (fh.handle.fp) { + fh.filename = php_ini_opened_path; + } + } /* Search php.ini file in search path */ - if (!fh.handle.fp) + if (!fh.handle.fp) { fh.handle.fp = php_fopen_with_path("php.ini", "r", php_ini_search_path, &php_ini_opened_path TSRMLS_CC); + if (fh.handle.fp) { + fh.filename = php_ini_opened_path; + } + } if (free_ini_search_path) { efree(php_ini_search_path); } PG(safe_mode) = safe_mode_state; PG(open_basedir) = open_basedir; - if (!fh.handle.fp) { - return SUCCESS; /* having no configuration file is ok */ - } - fh.type = ZEND_HANDLE_FP; - fh.filename = php_ini_opened_path; + if (fh.handle.fp) { + fh.type = ZEND_HANDLE_FP; - zend_parse_ini_file(&fh, 1, php_config_ini_parser_cb, &extension_lists); + zend_parse_ini_file(&fh, 1, php_config_ini_parser_cb, &extension_lists); - if (php_ini_opened_path) { - zval tmp; + { + zval tmp; - Z_STRLEN(tmp) = strlen(php_ini_opened_path); - Z_STRVAL(tmp) = zend_strndup(php_ini_opened_path, Z_STRLEN(tmp)); - Z_TYPE(tmp) = IS_STRING; - zend_hash_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path"), (void *) &tmp, sizeof(zval), NULL); - efree(php_ini_opened_path); - php_ini_opened_path = zend_strndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); + Z_STRLEN(tmp) = strlen(fh.filename); + Z_STRVAL(tmp) = zend_strndup(fh.filename, Z_STRLEN(tmp)); + Z_TYPE(tmp) = IS_STRING; + zend_hash_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path"), (void *) &tmp, sizeof(zval), NULL); + if(php_ini_opened_path) + efree(php_ini_opened_path); + php_ini_opened_path = zend_strndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); + } + } + + /* If the config_file_scan_dir is set at compile-time, go and scan this directory and + * parse any .ini files found in this directory. */ + if(strlen(PHP_CONFIG_FILE_SCAN_DIR)) { + dirp = VCWD_OPENDIR(PHP_CONFIG_FILE_SCAN_DIR); + if (dirp) { + fh.type = ZEND_HANDLE_FP; + while ((dir_entry = readdir(dirp)) != NULL) { + /* check for a .ini extension */ + if ((p = strrchr(dir_entry->d_name,'.')) && strcmp(p,".ini")) continue; + snprintf(ini_file, MAXPATHLEN, "%s%c%s", PHP_CONFIG_FILE_SCAN_DIR, DEFAULT_SLASH, dir_entry->d_name); + if (VCWD_STAT(ini_file, &sb) == 0) { + if (S_ISREG(sb.st_mode)) { + if ((fh.handle.fp = VCWD_FOPEN(ini_file, "r"))) { + fh.filename = ini_file; + zend_parse_ini_file(&fh, 1, php_config_ini_parser_cb, &extension_lists); + /* Here, add it to the list of ini files read */ + l = strlen(ini_file); + total_l += l+2; + p = estrndup(ini_file,l); + zend_llist_add_element(&scanned_ini_list, &p); + } + } + } + } + closedir(dirp); + /* + * Don't need an extra byte for the \0 in this malloc as the last + * element will not get a trailing , which gives us the byte for the \0 + */ + php_ini_scanned_files = (char *)malloc(total_l); + *php_ini_scanned_files = '\0'; + for (element=scanned_ini_list.head; element; element=element->next) { + strcat(php_ini_scanned_files,*(char **)element->data); + strcat(php_ini_scanned_files,element->next ? ",\n":"\n"); + } + zend_llist_destroy(&scanned_ini_list); + } } - return SUCCESS; } /* }}} */ @@ -348,6 +444,9 @@ zend_hash_destroy(&configuration_hash); if (php_ini_opened_path) { free(php_ini_opened_path); + } + if (php_ini_scanned_files) { + free(php_ini_scanned_files); } return SUCCESS; } 1.4 +2 -6 php4/main/php_main.h Index: php_main.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_main.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- php_main.h 2 Aug 2002 22:05:25 -0000 1.3 +++ php_main.h 6 Oct 2002 21:54:34 -0000 1.4 @@ -18,7 +18,7 @@ */ -/* $Id: php_main.h,v 1.21 2002/05/12 14:48:20 sas Exp $ */ +/* $Id: php_main.h,v 1.23 2002/09/18 21:57:29 zeev Exp $ */ #ifndef PHP_MAIN_H @@ -31,7 +31,7 @@ PHPAPI int php_request_startup(TSRMLS_D); PHPAPI void php_request_shutdown(void *dummy); PHPAPI void php_request_shutdown_for_exec(void *dummy); -PHPAPI int php_module_startup(sapi_module_struct *sf); +PHPAPI int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules); PHPAPI void php_module_shutdown(TSRMLS_D); PHPAPI void php_module_shutdown_for_exec(void); PHPAPI int php_module_shutdown_wrapper(sapi_module_struct *sapi_globals); @@ -52,9 +52,5 @@ /* environment module */ extern int php_init_environ(void); extern int php_shutdown_environ(void); - -#if defined(MBSTR_ENC_TRANS) -#define php_treat_data mbstr_treat_data -#endif #endif 1.3 +18 -18 php4/main/php_network.h Index: php_network.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_network.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_network.h 29 Apr 2002 02:33:38 -0000 1.2 +++ php_network.h 6 Oct 2002 21:54:34 -0000 1.3 @@ -15,7 +15,7 @@ | Author: Stig Venaas <venaa****@unine*****> | +----------------------------------------------------------------------+ */ -/* $Id: php_network.h,v 1.20 2002/03/19 17:49:00 wez Exp $ */ +/* $Id: php_network.h,v 1.31 2002/10/05 10:59:34 wez Exp $ */ #ifndef _PHP_NETWORK_H #define _PHP_NETWORK_H @@ -43,6 +43,12 @@ # define ftruncate(a, b) chsize(a, b) #endif /* defined(PHP_WIN32) */ +#ifdef PHP_WIN32 +#define streams_socket_errno WSAGetLastError() +#else +#define streams_socket_errno errno +#endif + #ifdef HAVE_NETINET_IN_H # include <netinet/in.h> #endif @@ -85,20 +91,19 @@ #endif -int php_hostconnect(const char *host, unsigned short port, int socktype, int timeout); +int php_hostconnect(const char *host, unsigned short port, int socktype, struct timeval *timeout TSRMLS_DC); PHPAPI int php_connect_nonb(int sockfd, const struct sockaddr *addr, socklen_t addrlen, struct timeval *timeout); + +#ifdef PHP_WIN32 +PHPAPI int php_connect_nonb_win32(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen, struct timeval *timeout); +#endif + void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short port); int php_sockaddr_size(php_sockaddr_storage *addr); struct _php_netstream_data_t { int socket; - unsigned char *readbuf; - size_t readbuflen; - size_t readpos; - size_t writepos; - char eof; char is_blocked; - size_t chunk_size; struct timeval timeout; char timeout_event; #if HAVE_OPENSSL_EXT @@ -114,11 +119,11 @@ extern php_stream_ops php_stream_socket_ops; #define PHP_STREAM_IS_SOCKET (&php_stream_socket_ops) -PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, int persistent STREAMS_DC TSRMLS_DC ); +PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, const char *persistent_id STREAMS_DC TSRMLS_DC ); /* open a connection to a host using php_hostconnect and return a stream */ PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port, - int socktype, int timeout, int persistent STREAMS_DC TSRMLS_DC); -PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, int persistent, + int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC TSRMLS_DC); +PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, const char *persistent_id, struct timeval *timeout STREAMS_DC TSRMLS_DC); #define php_stream_sock_open_from_socket(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_CC TSRMLS_CC) @@ -132,14 +137,9 @@ /* }}} */ -PHPAPI void php_stream_sock_set_timeout(php_stream *stream, struct timeval *timeout TSRMLS_DC); -PHPAPI int php_stream_sock_set_blocking(php_stream *stream, int mode TSRMLS_DC); -/* set the chunk size for the stream; return the old chunk size */ -PHPAPI size_t php_stream_sock_set_chunk_size(php_stream *stream, size_t size TSRMLS_DC); - #if HAVE_OPENSSL_EXT -PHPAPI int php_stream_sock_ssl_activate_with_method(php_stream *stream, int activate, SSL_METHOD *method TSRMLS_DC); -#define php_stream_sock_ssl_activate(stream, activate) php_stream_sock_ssl_activate_with_method((stream), (activate), SSLv23_client_method() TSRMLS_CC) +PHPAPI int php_stream_sock_ssl_activate_with_method(php_stream *stream, int activate, SSL_METHOD *method, php_stream *session_stream TSRMLS_DC); +#define php_stream_sock_ssl_activate(stream, activate) php_stream_sock_ssl_activate_with_method((stream), (activate), SSLv23_client_method(), NULL TSRMLS_CC) #endif 1.4 +24 -0 php4/main/php_open_temporary_file.c Index: php_open_temporary_file.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_open_temporary_file.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- php_open_temporary_file.c 2 Aug 2002 22:05:25 -0000 1.3 +++ php_open_temporary_file.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -29,6 +29,19 @@ #define O_RDONLY _O_RDONLY #include "win32/param.h" #include "win32/winutil.h" +#elif defined(NETWARE) +#ifdef USE_WINSOCK +/*#include <ws2nlm.h>*/ +#include <novsock2.h> +#else +#include <sys/socket.h> +#endif +#ifdef NEW_LIBC +#include <sys/param.h> +#else +#include "netware/param.h" +#endif +#include "netware/mktemp.h" #else #include <sys/param.h> #include <sys/socket.h> @@ -95,6 +108,9 @@ #ifndef PHP_WIN32 int fd; #endif +#ifdef NETWARE + char *file_path = NULL; +#endif if (!path) { return NULL; @@ -115,6 +131,14 @@ #ifdef PHP_WIN32 if (GetTempFileName(path, pfx, 0, opened_path)) { fp = VCWD_FOPEN(opened_path, "wb"); + } else { + fp = NULL; + } +#elif defined(NETWARE) + /* Using standard mktemp() implementation for NetWare */ + file_path = mktemp(opened_path); + if (file_path) { + fp = VCWD_FOPEN(file_path, "wb"); } else { fp = NULL; } 1.4 +10 -2 php4/main/php_output.h Index: php_output.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_output.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- php_output.h 9 May 2002 05:39:43 -0000 1.3 +++ php_output.h 6 Oct 2002 21:54:34 -0000 1.4 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_output.h,v 1.37 2002/05/04 18:33:13 sas Exp $ */ +/* $Id: php_output.h,v 1.47 2002/10/06 09:06:24 zeev Exp $ */ #ifndef PHP_OUTPUT_H #define PHP_OUTPUT_H @@ -26,10 +26,11 @@ PHPAPI void php_output_startup(void); PHPAPI void php_output_activate(TSRMLS_D); PHPAPI void php_output_set_status(zend_bool status TSRMLS_DC); -void php_output_register_constants(TSRMLS_D); +PHPAPI void php_output_register_constants(TSRMLS_D); PHPAPI int php_body_write(const char *str, uint str_length TSRMLS_DC); PHPAPI int php_header_write(const char *str, uint str_length TSRMLS_DC); PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC); +PHPAPI int php_start_ob_buffer_named(const char *output_handler_name, uint chunk_size, zend_bool erase TSRMLS_DC); PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush TSRMLS_DC); PHPAPI void php_end_ob_buffers(zend_bool send_buffer TSRMLS_DC); PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC); @@ -39,17 +40,24 @@ PHPAPI char *php_get_output_start_filename(TSRMLS_D); PHPAPI int php_get_output_start_lineno(TSRMLS_D); PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t internal_output_handler, uint buffer_size, char *handler_name, zend_bool erase TSRMLS_DC); +PHPAPI int php_ob_handler_used(char *handler_name TSRMLS_DC); +PHPAPI int php_ob_init_conflict(char *handler_new, char *handler_set TSRMLS_DC); +PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC); +PHPAPI int php_ob_get_length(zval *p TSRMLS_DC); PHP_FUNCTION(ob_start); PHP_FUNCTION(ob_flush); PHP_FUNCTION(ob_clean); PHP_FUNCTION(ob_end_flush); PHP_FUNCTION(ob_end_clean); +PHP_FUNCTION(ob_get_flush); +PHP_FUNCTION(ob_get_clean); PHP_FUNCTION(ob_get_contents); PHP_FUNCTION(ob_get_length); PHP_FUNCTION(ob_get_level); PHP_FUNCTION(ob_get_status); PHP_FUNCTION(ob_implicit_flush); +PHP_FUNCTION(ob_list_handlers); typedef struct _php_ob_buffer { char *buffer; 1.4 +162 -20 php4/main/php_streams.h Index: php_streams.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_streams.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- php_streams.h 30 Apr 2002 08:15:07 -0000 1.3 +++ php_streams.h 6 Oct 2002 21:54:34 -0000 1.4 @@ -25,7 +25,8 @@ #include <sys/types.h> #include <sys/stat.h> -/* See README.STREAMS in php4 root dir for more info about this stuff */ +PHPAPI int php_file_le_stream(void); +PHPAPI int php_file_le_pstream(void); /* {{{ Streams memory debugging stuff */ @@ -91,6 +92,7 @@ typedef struct _php_stream php_stream; typedef struct _php_stream_wrapper php_stream_wrapper; typedef struct _php_stream_context php_stream_context; +typedef struct _php_stream_filter php_stream_filter; /* callback for status notifications */ typedef void (*php_stream_notification_func)(php_stream_context *context, @@ -100,8 +102,12 @@ void * ptr TSRMLS_DC); typedef struct _php_stream_statbuf { +#if defined(NETWARE) && defined(CLIB_STAT_PATCH) + struct stat_libc sb; /* regular info */ +#else struct stat sb; /* regular info */ - /* extended info to go here some day */ +#endif + /* extended info to go here some day: content-type etc. etc. */ } php_stream_statbuf; typedef struct _php_stream_dirent { @@ -143,10 +149,10 @@ const char *label; /* label for this ops structure */ /* these are optional */ - int (*seek)(php_stream *stream, off_t offset, int whence TSRMLS_DC); - char *(*gets)(php_stream *stream, char *buf, size_t size TSRMLS_DC); + int (*seek)(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC); int (*cast)(php_stream *stream, int castas, void **ret TSRMLS_DC); int (*stat)(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); + int (*set_option)(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); } php_stream_ops; typedef struct _php_stream_wrapper_ops { @@ -162,19 +168,76 @@ /* open a "directory" stream */ php_stream *(*dir_opener)(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); - + + const char *label; } php_stream_wrapper_ops; struct _php_stream_wrapper { php_stream_wrapper_ops *wops; /* operations the wrapper can perform */ void *abstract; /* context for the wrapper */ int is_url; /* so that PG(allow_url_fopen) can be respected */ + + /* support for wrappers to return (multiple) error messages to the stream opener */ + int err_count; + char **err_stack; +}; + +typedef struct _php_stream_filter_ops { + size_t (*write)(php_stream *stream, php_stream_filter *thisfilter, + const char *buf, size_t count TSRMLS_DC); + size_t (*read)(php_stream *stream, php_stream_filter *thisfilter, + char *buf, size_t count TSRMLS_DC); + int (*flush)(php_stream *stream, php_stream_filter *thisfilter, int closing TSRMLS_DC); + int (*eof)(php_stream *stream, php_stream_filter *thisfilter TSRMLS_DC); + void (*dtor)(php_stream_filter *thisfilter TSRMLS_DC); + const char *label; +} php_stream_filter_ops; + +struct _php_stream_filter { + php_stream_filter_ops *fops; + void *abstract; /* for use by filter implementation */ + php_stream_filter *next; + php_stream_filter *prev; + int is_persistent; + php_stream *stream; }; +#define php_stream_filter_write_next(stream, thisfilter, buf, size) \ + (thisfilter)->next ? (thisfilter)->next->fops->write((stream), (thisfilter)->next, (buf), (size) TSRMLS_CC) \ + : (stream)->ops->write((stream), (buf), (size) TSRMLS_CC) + +#define php_stream_filter_read_next(stream, thisfilter, buf, size) \ + (thisfilter)->next ? (thisfilter)->next->fops->read((stream), (thisfilter)->next, (buf), (size) TSRMLS_CC) \ + : (stream)->ops->read((stream), (buf), (size) TSRMLS_CC) + +#define php_stream_filter_flush_next(stream, thisfilter, closing) \ + (thisfilter)->next ? (thisfilter)->next->fops->flush((stream), (thisfilter), (closing) TSRMLS_CC) \ + : (stream)->ops->flush((stream) TSRMLS_CC) + +#define php_stream_filter_eof_next(stream, thisfilter) \ + (thisfilter)->next ? (thisfilter)->next->fops->eof((stream), (thisfilter) TSRMLS_CC) \ + : (stream)->ops->read((stream), NULL, 0 TSRMLS_CC) == EOF ? 1 : 0 + +#define PHP_STREAM_FLAG_NO_SEEK 1 +#define PHP_STREAM_FLAG_NO_BUFFER 2 + +#define PHP_STREAM_FLAG_EOL_UNIX 0 /* also includes DOS */ +#define PHP_STREAM_FLAG_DETECT_EOL 4 +#define PHP_STREAM_FLAG_EOL_MAC 8 + +/* set this when the stream might represent "interactive" data. + * When set, the read buffer will avoid certain operations that + * might otherwise cause the read to block for much longer than + * is strictly required. */ +#define PHP_STREAM_FLAG_AVOID_BLOCKING 16 + struct _php_stream { php_stream_ops *ops; void *abstract; /* convenience pointer for abstraction */ + php_stream_filter *filterhead; + php_stream_filter *filtertail; + php_stream_wrapper *wrapper; /* which wrapper was used to open the stream */ void *wrapperthis; /* convenience pointer for a instance of a wrapper */ zval *wrapperdata; /* fgetwrapperdata retrieves this */ @@ -190,9 +253,23 @@ FILE *stdiocast; /* cache this, otherwise we might leak! */ #if ZEND_DEBUG int __exposed; /* non-zero if exposed as a zval somewhere */ + char *__orig_path; /* it really helps when debugging "unclosed" streams */ #endif php_stream_context *context; + int flags; /* PHP_STREAM_FLAG_XXX */ + + /* buffer */ + off_t position; /* of underlying stream */ + unsigned char *readbuf; + size_t readbuflen; + off_t readpos; + off_t writepos; + + /* how much data to read when filling buffer */ + size_t chunk_size; + + int eof; }; /* php_stream */ /* state definitions when closing down; these are private to streams.c */ @@ -202,11 +279,31 @@ /* allocate a new stream for a particular ops */ PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, - int persistent, const char *mode STREAMS_DC TSRMLS_DC); -#define php_stream_alloc(ops, thisptr, persistent, mode) _php_stream_alloc((ops), (thisptr), (persistent), (mode) STREAMS_CC TSRMLS_CC) + const char *persistent_id, const char *mode STREAMS_DC TSRMLS_DC); +#define php_stream_alloc(ops, thisptr, persistent_id, mode) _php_stream_alloc((ops), (thisptr), (persistent_id), (mode) STREAMS_CC TSRMLS_CC) -#define php_stream_get_resource_id(stream) (stream)->rsrc_id +/* stack filter onto a stream */ +PHPAPI void php_stream_filter_prepend(php_stream *stream, php_stream_filter *filter); +PHPAPI void php_stream_filter_append(php_stream *stream, php_stream_filter *filter); +PHPAPI php_stream_filter *php_stream_filter_remove(php_stream *stream, php_stream_filter *filter, int call_dtor TSRMLS_DC); +PHPAPI void php_stream_filter_free(php_stream_filter *filter TSRMLS_DC); +PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC); +#define php_stream_filter_alloc(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC TSRMLS_CC) +#define php_stream_filter_alloc_rel(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC TSRMLS_CC) + +#define php_stream_filter_remove_head(stream, call_dtor) php_stream_filter_remove((stream), (stream)->filterhead, (call_dtor) TSRMLS_CC) +#define php_stream_filter_remove_tail(stream, call_dtor) php_stream_filter_remove((stream), (stream)->filtertail, (call_dtor) TSRMLS_CC) + +typedef struct _php_stream_filter_factory { + php_stream_filter *(*create_filter)(const char *filtername, const char *filterparams, int filterparamslen, int persistent TSRMLS_DC); +} php_stream_filter_factory; + +PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC); +PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern TSRMLS_DC); +PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, const char *filterparams, int filterparamslen, int persistent TSRMLS_DC); + +#define php_stream_get_resource_id(stream) (stream)->rsrc_id #if ZEND_DEBUG /* use this to tell the stream that it is OK if we don't explicitly close it */ # define php_stream_auto_cleanup(stream) { (stream)->__exposed++; } @@ -219,6 +316,14 @@ # define php_stream_to_zval(stream, zval) { ZVAL_RESOURCE(zval, (stream)->rsrc_id); } #endif +#define php_stream_from_zval(stream, ppzval) ZEND_FETCH_RESOURCE2((stream), php_stream *, (ppzval), -1, "stream", php_file_le_stream(), php_file_le_pstream()) +#define php_stream_from_zval_no_verify(stream, ppzval) (stream) = (php_stream*)zend_fetch_resource((ppzval) TSRMLS_CC, -1, "stream", NULL, 2, php_file_le_stream(), php_file_le_pstream()) + +PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC); +#define PHP_STREAM_PERSISTENT_SUCCESS 0 /* id exists */ +#define PHP_STREAM_PERSISTENT_FAILURE 1 /* id exists but is not a stream! */ +#define PHP_STREAM_PERSISTENT_NOT_EXIST 2 /* id does not exist */ + #define PHP_STREAM_FREE_CALL_DTOR 1 /* call ops->close */ #define PHP_STREAM_FREE_RELEASE_STREAM 2 /* pefree(stream) */ #define PHP_STREAM_FREE_PRESERVE_HANDLE 4 /* tell ops->close to not close it's underlying handle */ @@ -251,8 +356,8 @@ PHPAPI int _php_stream_putc(php_stream *stream, int c TSRMLS_DC); #define php_stream_putc(stream, c) _php_stream_putc((stream), (c) TSRMLS_CC) -PHPAPI int _php_stream_flush(php_stream *stream TSRMLS_DC); -#define php_stream_flush(stream) _php_stream_flush((stream) TSRMLS_CC) +PHPAPI int _php_stream_flush(php_stream *stream, int closing TSRMLS_DC); +#define php_stream_flush(stream) _php_stream_flush((stream), 0 TSRMLS_CC) PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRMLS_DC); #define php_stream_gets(stream, buf, maxlen) _php_stream_gets((stream), (buf), (maxlen) TSRMLS_CC) @@ -265,7 +370,7 @@ #define php_stream_stat(stream, ssb) _php_stream_stat((stream), (ssb) TSRMLS_CC) PHPAPI int _php_stream_stat_path(char *path, php_stream_statbuf *ssb TSRMLS_DC); -#define php_stream_stat_path(path, ssb) _php_stream_stat((path), (ssb) TSRMLS_CC) +#define php_stream_stat_path(path, ssb) _php_stream_stat_path((path), (ssb) TSRMLS_CC) PHPAPI php_stream *_php_stream_opendir(char *path, int options, php_stream_context *context STREAMS_DC TSRMLS_DC); #define php_stream_opendir(path, options, context) _php_stream_opendir((path), (options), (context) STREAMS_CC TSRMLS_CC) @@ -274,6 +379,30 @@ #define php_stream_closedir(dirstream) php_stream_close((dirstream)) #define php_stream_rewinddir(dirstream) php_stream_rewind((dirstream)) +PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); +#define php_stream_set_option(stream, option, value, ptrvalue) _php_stream_set_option((stream), (option), (value), (ptrvalue) TSRMLS_CC) + +#define php_stream_set_chunk_size(stream, size) php_stream_set_option((stream), PHP_STREAM_OPTION_SET_CHUNK_SIZE, (size), NULL TSRMLS_CC) + +/* change the blocking mode of stream: value == 1 => blocking, value == 0 => non-blocking. */ +#define PHP_STREAM_OPTION_BLOCKING 1 + +/* change the buffering mode of stream. value is a PHP_STREAM_BUFFER_XXXX value, ptrparam is a ptr to a size_t holding + * the required buffer size */ +#define PHP_STREAM_OPTION_READ_BUFFER 2 +#define PHP_STREAM_OPTION_WRITE_BUFFER 3 + +#define PHP_STREAM_BUFFER_NONE 0 /* unbuffered */ +#define PHP_STREAM_BUFFER_LINE 1 /* line buffered */ +#define PHP_STREAM_BUFFER_FULL 2 /* fully buffered */ + +/* set the timeout duration for reads on the stream. ptrparam is a pointer to a struct timeval * */ +#define PHP_STREAM_OPTION_READ_TIMEOUT 4 +#define PHP_STREAM_OPTION_SET_CHUNK_SIZE 5 + +#define PHP_STREAM_OPTION_RETURN_OK 0 /* option set OK */ +#define PHP_STREAM_OPTION_RETURN_ERR -1 /* problem setting option */ +#define PHP_STREAM_OPTION_RETURN_NOTIMPL -2 /* underlying stream does not implement; streams can handle it instead */ /* copy up to maxlen bytes from src to dest. If maxlen is PHP_STREAM_COPY_ALL, copy until eof(src). * Uses mmap if the src is a plain file and at offset 0 */ @@ -292,10 +421,6 @@ PHPAPI size_t _php_stream_passthru(php_stream * src STREAMS_DC TSRMLS_DC); #define php_stream_passthru(stream) _php_stream_passthru((stream) STREAMS_CC TSRMLS_CC) - -/* maybe implement someday */ -#define php_stream_error(stream) (0) - /* operations for a stdio FILE; use the php_stream_fopen_XXX funcs below */ PHPAPI extern php_stream_ops php_stream_stdio_ops; /* like fopen, but returns a stream */ @@ -361,28 +486,38 @@ * */ #define STREAM_WILL_CAST 32 +/* this flag applies to php_stream_locate_url_wrapper */ +#define STREAM_LOCATE_WRAPPERS_ONLY 64 + #ifdef PHP_WIN32 -# define IGNORE_URL_WIN IGNORE_URL +# define IGNORE_URL_WIN STREAM_MUST_SEEK #else # define IGNORE_URL_WIN 0 #endif -int php_init_stream_wrappers(TSRMLS_D); -int php_shutdown_stream_wrappers(TSRMLS_D); +int php_init_stream_wrappers(int module_number TSRMLS_DC); +int php_shutdown_stream_wrappers(int module_number TSRMLS_DC); +PHP_RSHUTDOWN_FUNCTION(streams); + PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC); PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char **path_for_open, int options TSRMLS_DC); #define php_stream_open_wrapper(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_CC TSRMLS_CC) #define php_stream_open_wrapper_ex(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_CC TSRMLS_CC) +/* pushes an error message onto the stack for a wrapper instance */ +PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...); + + #define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */ #define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */ #define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */ #define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */ -/* DO NOT call this on streams that are referenced by resources! */ #define PHP_STREAM_NO_PREFERENCE 0 #define PHP_STREAM_PREFER_STDIO 1 +/* DO NOT call this on streams that are referenced by resources! */ PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC TSRMLS_DC); #define php_stream_make_seekable(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_CC TSRMLS_CC) @@ -394,18 +529,21 @@ /* for user-space streams */ PHPAPI extern php_stream_ops php_stream_userspace_ops; +PHPAPI extern php_stream_ops php_stream_userspace_dir_ops; #define PHP_STREAM_IS_USERSPACE &php_stream_userspace_ops +#define PHP_STREAM_IS_USERSPACE_DIR &php_stream_userspace_dir_ops PHPAPI void php_stream_context_free(php_stream_context *context); PHPAPI php_stream_context *php_stream_context_alloc(void); PHPAPI int php_stream_context_get_option(php_stream_context *context, - const char *wrappername, const char *optionname, zval **optionvalue); + const char *wrappername, const char *optionname, zval ***optionvalue); PHPAPI int php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue); PHPAPI php_stream_notifier *php_stream_notification_alloc(void); PHPAPI void php_stream_notification_free(php_stream_notifier *notifier); +/* not all notification codes are implemented */ #define PHP_STREAM_NOTIFY_RESOLVE 1 #define PHP_STREAM_NOTIFY_CONNECT 2 #define PHP_STREAM_NOTIFY_AUTH_REQUIRED 3 @@ -452,6 +590,10 @@ php_stream_notification_notify((context), (code), PHP_STREAM_NOTIFY_SEVERITY_ERR, \ (xmsg), (xcode), 0, 0, NULL TSRMLS_CC); } } while(0) + +/* Give other modules access to the url_stream_wrappers_hash */ +PHPAPI HashTable *php_stream_get_url_stream_wrappers_hash(); + #endif /* 1.3 +5 -0 php4/main/php_syslog.h Index: php_syslog.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_syslog.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_syslog.h 29 Apr 2002 02:33:38 -0000 1.2 +++ php_syslog.h 6 Oct 2002 21:54:34 -0000 1.3 @@ -3,6 +3,11 @@ #ifdef PHP_WIN32 #include "win32/syslog.h" +#elif defined(NETWARE) +# include "config.nw.h" +#ifdef HAVE_SYSLOG_H +#include <syslog.h> +#endif #else #include "php_config.h" #ifdef HAVE_SYSLOG_H 1.4 +14 -5 php4/main/php_variables.c Index: php_variables.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_variables.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- php_variables.c 9 May 2002 05:39:43 -0000 1.3 +++ php_variables.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -16,7 +16,7 @@ | Zeev Suraski <zeev****@zend*****> | +----------------------------------------------------------------------+ */ -/* $Id: php_variables.c,v 1.36 2002/05/04 17:34:41 sas Exp $ */ +/* $Id: php_variables.c,v 1.44 2002/09/08 00:27:05 yohgaki Exp $ */ #include <stdio.h> #include "php.h" @@ -39,7 +39,8 @@ PHPAPI void php_register_variable_safe(char *var, char *strval, int str_len, zval *track_vars_array TSRMLS_DC) { zval new_entry; - + assert(strval != NULL); + /* Prepare value */ Z_STRLEN(new_entry) = str_len; if (PG(magic_quotes_gpc)) { @@ -64,6 +65,8 @@ HashTable *symtable1=NULL; HashTable *symtable2=NULL; + assert(var != NULL); + if (PG(register_globals)) { symtable1 = EG(active_symbol_table); } @@ -152,7 +155,7 @@ } else { ip = strchr(ip, ']'); if (!ip) { - php_error(E_WARNING, "Missing ] in %s variable", var); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing ] in %s variable", var); return; } *ip = 0; @@ -196,6 +199,10 @@ char *strtok_buf = NULL; zval *array_ptr = (zval *) arg; + if (SG(request_info).post_data==NULL) { + return; + } + var = php_strtok_r(SG(request_info).post_data, "&", &strtok_buf); while (var) { @@ -212,8 +219,7 @@ } } - -void php_treat_data(int arg, char *str, zval* destArray TSRMLS_DC) +SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) { char *res = NULL, *var, *val, *separator=NULL; const char *c_var; @@ -296,6 +302,9 @@ php_url_decode(var, strlen(var)); val_len = php_url_decode(val, strlen(val)); php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); + } else { + php_url_decode(var, strlen(var)); + php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC); } var = php_strtok_r(NULL, separator, &strtok_buf); } 1.3 +2 -2 php4/main/php_version.h Index: php_version.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/php_version.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- php_version.h 29 Apr 2002 02:33:38 -0000 1.2 +++ php_version.h 6 Oct 2002 21:54:34 -0000 1.3 @@ -1,7 +1,7 @@ /* automatically generated by configure */ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 4 -#define PHP_MINOR_VERSION 3 +#define PHP_MINOR_VERSION 4 #define PHP_RELEASE_VERSION 0 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "4.3.0-dev" +#define PHP_VERSION "4.4.0-dev" 1.3 +50 -0 php4/main/reentrancy.c Index: reentrancy.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/reentrancy.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- reentrancy.c 29 Apr 2002 02:33:38 -0000 1.2 +++ reentrancy.c 6 Oct 2002 21:54:34 -0000 1.3 @@ -28,6 +28,11 @@ #include "win32/readdir.h" #endif +#if defined(NETWARE) && !(NEW_LIBC) +/*#include <ws2nlm.h>*/ +#include <sys/socket.h> +#endif + #include "php_reentrancy.h" #include "ext/standard/php_rand.h" /* for RAND_MAX */ @@ -113,6 +118,51 @@ } #endif + +#if defined(NETWARE) +/* + Re-entrant versions of functions seem to be better for loading NLMs in different address space. + Since we have them now in LibC, we might as well make use of them. +*/ + +#define HAVE_LOCALTIME_R 1 +#define HAVE_CTIME_R 1 +#define HAVE_ASCTIME_R 1 +#define HAVE_GMTIME_R 1 + +PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm) +{ + /* Modified according to LibC definition */ + if (localtime_r(timep, p_tm) != NULL) + return (p_tm); + return (NULL); +} + +PHPAPI char *php_ctime_r(const time_t *clock, char *buf) +{ + /* Modified according to LibC definition */ + if (ctime_r(clock, buf) != NULL) + return (buf); + return (NULL); +} + +PHPAPI char *php_asctime_r(const struct tm *tm, char *buf) +{ + /* Modified according to LibC definition */ + if (asctime_r(tm, buf) != NULL) + return (buf); + return (NULL); +} + +PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm) +{ + /* Modified according to LibC definition */ + if (gmtime_r(timep, p_tm) != NULL) + return (p_tm); + return (NULL); +} + +#endif /* NETWARE */ #if !defined(HAVE_POSIX_READDIR_R) 1.4 +88 -32 php4/main/rfc1867.c Index: rfc1867.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/rfc1867.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- rfc1867.c 2 Aug 2002 22:05:25 -0000 1.3 +++ rfc1867.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -16,7 +16,7 @@ | Jani Taskinen <snipe****@php*****> | +----------------------------------------------------------------------+ */ -/* $Id: rfc1867.c,v 1.99 2002/05/11 11:58:16 zeev Exp $ */ +/* $Id: rfc1867.c,v 1.116 2002/08/17 11:48:21 sesser Exp $ */ /* * This product includes software developed by the Apache Group @@ -32,6 +32,9 @@ #include "php_variables.h" #include "rfc1867.h" +#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) +#include "ext/mbstring/php_mb.h" +#endif #undef DEBUG_FILE_UPLOAD @@ -52,11 +55,20 @@ #define MAX_SIZE_OF_INDEX sizeof("[tmp_name]") /* Errors */ -#define UPLOAD_ERROR_A 1 /* Uploaded file exceeded upload_max_filesize */ -#define UPLOAD_ERROR_B 2 /* Uploaded file exceeded MAX_FILE_SIZE */ -#define UPLOAD_ERROR_C 3 /* Only partiallly uploaded */ -#define UPLOAD_ERROR_D 4 /* No file uploaded */ -#define UPLOAD_ERROR_E 5 /* Uploaded file size 0 bytes */ +#define UPLOAD_ERROR_OK 0 /* File upload succesful */ +#define UPLOAD_ERROR_A 1 /* Uploaded file exceeded upload_max_filesize */ +#define UPLOAD_ERROR_B 2 /* Uploaded file exceeded MAX_FILE_SIZE */ +#define UPLOAD_ERROR_C 3 /* Partially uploaded */ +#define UPLOAD_ERROR_D 4 /* No file uploaded */ + +void php_rfc1867_register_constants(TSRMLS_D) +{ + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_OK", UPLOAD_ERROR_OK, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_INI_SIZE", UPLOAD_ERROR_A, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FORM_SIZE", UPLOAD_ERROR_B, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_PARTIAL", UPLOAD_ERROR_C, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); +} static void add_protected_variable(char *varname TSRMLS_DC) { @@ -158,7 +170,7 @@ */ static int fill_buffer(multipart_buffer *self TSRMLS_DC) { - int bytes_to_read, actual_read = 0; + int bytes_to_read, total_read = 0, actual_read = 0; /* shift the existing data if necessary */ if (self->bytes_in_buffer > 0 && self->buf_begin != self->buffer) { @@ -171,7 +183,7 @@ bytes_to_read = self->bufsize - self->bytes_in_buffer; /* read the required number of bytes */ - if (bytes_to_read > 0) { + while (bytes_to_read > 0) { char *buf = self->buffer + self->bytes_in_buffer; @@ -181,10 +193,14 @@ if (actual_read > 0) { self->bytes_in_buffer += actual_read; SG(read_post_bytes) += actual_read; + total_read += actual_read; + bytes_to_read -= actual_read; + } else { + break; } } - return actual_read; + return total_read; } @@ -334,7 +350,12 @@ /* add header to table */ char *key = line; - char *value = strchr(line, ':'); + char *value = NULL; + + /* space in the beginning means same header */ + if (!isspace(line[0])) { + value = strchr(line, ':'); + } if (value) { *value = 0; @@ -343,7 +364,7 @@ entry.value = estrdup(value); entry.key = estrdup(key); - } else if (zend_llist_remove_tail(header)) { /* If no ':' on the line, add to previous line */ + } else if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */ prev_len = strlen(prev_entry.value); cur_len = strlen(line); @@ -354,6 +375,10 @@ entry.value[cur_len + prev_len] = '\0'; entry.key = estrdup(prev_entry.key); + + zend_llist_remove_tail(header); + } else { + continue; } zend_llist_add_element(header, &entry); @@ -400,7 +425,9 @@ ++pos; } } - ++pos; + if (*pos) { + ++pos; + } } else ++pos; } @@ -421,17 +448,25 @@ } -static char *substring_conf(char *start, int len, char quote) +static char *substring_conf(char *start, int len, char quote TSRMLS_DC) { char *result = emalloc(len + 2); char *resp = result; int i; - for (i = 0; i < len; ++i) { + for (i = 0; i < len;) { if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) { - *resp++ = start[++i]; + *resp++ = start[i+1]; + i+=2; } else { - *resp++ = start[i]; +#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) + size_t nbytes = php_mb_mbchar_bytes(start+i); + while ( nbytes-- > 0 ) { + *resp++ = start[i++]; + } +#else + *resp++ = start[i++]; +#endif } } @@ -440,7 +475,7 @@ } -static char *php_ap_getword_conf(char **line) +static char *php_ap_getword_conf(char **line TSRMLS_DC) { char *str = *line, *strend, *res, quote; @@ -462,7 +497,7 @@ ++strend; } } - res = substring_conf(str + 1, strend - str - 1, quote); + res = substring_conf(str + 1, strend - str - 1, quote TSRMLS_CC); if (*strend == quote) { ++strend; @@ -474,7 +509,7 @@ while (*strend && !isspace(*strend)) { ++strend; } - res = substring_conf(str, strend - str, 0); + res = substring_conf(str, strend - str, 0 TSRMLS_CC); } while (*strend && isspace(*strend)) { @@ -584,7 +619,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) { - char *boundary, *s=NULL, *start_arr=NULL, *array_index=NULL; + char *boundary, *s=NULL, *boundary_end = NULL, *start_arr=NULL, *array_index=NULL; char *temp_filename=NULL, *lbuf=NULL, *abuf=NULL; int boundary_len=0, total_bytes=0, cancel_upload=0, is_arr_upload=0, array_len=0, max_file_size=0; zval *http_post_files=NULL; @@ -605,17 +640,24 @@ sapi_module.sapi_error(E_WARNING, "Missing boundary in multipart/form-data POST data"); return; } + boundary++; boundary_len = strlen(boundary); - if (boundary[0] == '"' && boundary[boundary_len-1] == '"') { - if (boundary_len < 2) { /* otherwise a single " passes */ + if (boundary[0] == '"') { + boundary++; + boundary_end = strchr(boundary, '"'); + if (!boundary_end) { sapi_module.sapi_error(E_WARNING, "Invalid boundary in multipart/form-data POST data"); return; } - boundary++; - boundary_len -= 2; - boundary[boundary_len] = '\0'; + } else { + /* search for the end of the boundary */ + boundary_end = strchr(boundary, ','); + } + if (boundary_end) { + boundary_end[0] = '\0'; + boundary_len = boundary_end-boundary; } /* Initialize the buffer */ @@ -671,12 +713,12 @@ if (param) { efree(param); } - param = php_ap_getword_conf(&pair); + param = php_ap_getword_conf(&pair TSRMLS_CC); } else if (!strcmp(key, "filename")) { if (filename) { efree(filename); } - filename = php_ap_getword_conf(&pair); + filename = php_ap_getword_conf(&pair TSRMLS_CC); } } if (key) { @@ -706,21 +748,29 @@ /* If file_uploads=off, skip the file part */ if (!PG(file_uploads)) { - efree(filename); - if (param) efree(param); + if (filename) { + efree(filename); + } + if (param) { + efree(param); + } continue; } /* Return with an error if the posted data is garbled */ if (!param) { sapi_module.sapi_error(E_WARNING, "File Upload Mime headers garbled"); - efree(filename); + if (filename) { + efree(filename); + } SAFE_RETURN; } /* Handle file */ fp = php_open_temporary_file(PG(upload_tmp_dir), "php", &temp_filename TSRMLS_CC); if (!fp) { + efree(param); + efree(filename); sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file"); SAFE_RETURN; } @@ -729,7 +779,9 @@ cancel_upload = 0; if(strlen(filename) == 0) { +#ifdef DEBUG_FILE_UPLOAD sapi_module.sapi_error(E_NOTICE, "No file uploaded"); +#endif cancel_upload = UPLOAD_ERROR_D; } @@ -757,7 +809,7 @@ #ifdef DEBUG_FILE_UPLOAD if(strlen(filename) > 0 && total_bytes == 0) { sapi_module.sapi_error(E_WARNING, "Uploaded file size 0 - file [%s=%s] not saved", param, filename); - cancel_upload = UPLOAD_ERROR_E; + cancel_upload = 5; } #endif @@ -800,7 +852,11 @@ sprintf(lbuf, "%s_name", param); } +#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) + s = php_mb_strrchr(filename, '\\'); +#else s = strrchr(filename, '\\'); +#endif if (s && s > filename) { safe_php_register_variable(lbuf, s+1, NULL, 0 TSRMLS_CC); } else { @@ -822,7 +878,7 @@ s = NULL; /* Possible Content-Type: */ - if (!(cd = php_mime_get_hdr_value(header, "Content-Type")) || filename == "") { + if (cancel_upload || !(cd = php_mime_get_hdr_value(header, "Content-Type"))) { cd = ""; } else { /* fix for Opera 6.01 */ 1.3 +1 -0 php4/main/rfc1867.h Index: rfc1867.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/rfc1867.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- rfc1867.h 29 Apr 2002 02:33:38 -0000 1.2 +++ rfc1867.h 6 Oct 2002 21:54:34 -0000 1.3 @@ -8,5 +8,6 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler); void destroy_uploaded_files_hash(TSRMLS_D); +void php_rfc1867_register_constants(TSRMLS_D); #endif /* RFC1867_H */ 1.3 +21 -12 php4/main/safe_mode.c Index: safe_mode.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/safe_mode.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- safe_mode.c 29 Apr 2002 02:33:38 -0000 1.2 +++ safe_mode.c 6 Oct 2002 21:54:34 -0000 1.3 @@ -15,7 +15,7 @@ | Author: Rasmus Lerdorf <rasmu****@lerdo*****> | +----------------------------------------------------------------------+ */ -/* $Id: safe_mode.c,v 1.44 2002/03/17 21:00:44 sesser Exp $ */ +/* $Id: safe_mode.c,v 1.50 2002/10/02 23:48:58 dreid Exp $ */ #include "php.h" @@ -31,16 +31,21 @@ #include "SAPI.h" #include "php_globals.h" +#ifdef __BEOS__ +#define realpath(x,y) strcpy(y,x) +#endif /* * php_checkuid * - * This function has four modes: + * This function has six modes: * * 0 - return invalid (0) if file does not exist * 1 - return valid (1) if file does not exist * 2 - if file does not exist, check directory * 3 - only check directory (needed for mkdir) + * 4 - check mode and param + * 5 - only check file */ PHPAPI int php_checkuid(const char *filename, char *fopen_mode, int mode) @@ -49,9 +54,13 @@ int ret, nofile=0; long uid=0L, gid=0L, duid=0L, dgid=0L; char path[MAXPATHLEN]; - char *s; + char *s, filenamecopy[MAXPATHLEN]; + php_stream_wrapper *wrapper = NULL; TSRMLS_FETCH(); + strlcpy(filenamecopy, filename, MAXPATHLEN); + filename=(char *)&filenamecopy; + if (!filename) { return 0; /* path must be provided */ } @@ -67,10 +76,10 @@ /* * If given filepath is a URL, allow - safe mode stuff * related to URL's is checked in individual functions - */ - if (!strncasecmp(filename,"http://", 7) || !strncasecmp(filename,"ftp://", 6)) { + */ + wrapper = php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC); + if (wrapper != NULL) return 1; - } /* First we see if the file is owned by the same user... * If that fails, passthrough and check directory... @@ -80,10 +89,10 @@ ret = VCWD_STAT(path, &sb); if (ret < 0) { if (mode == CHECKUID_DISALLOW_FILE_NOT_EXISTS) { - php_error(E_WARNING, "Unable to access %s", filename); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); return 0; } else if (mode == CHECKUID_ALLOW_FILE_NOT_EXISTS) { - php_error(E_WARNING, "Unable to access %s", filename); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); return 1; } nofile = 1; @@ -116,7 +125,7 @@ VCWD_REALPATH(filename, path); *s = DEFAULT_SLASH; } else { - VCWD_GETCWD(path, MAXPATHLEN); + VCWD_GETCWD(path, sizeof(path)); } } /* end CHECKUID_ALLOW_ONLY_DIR */ @@ -124,7 +133,7 @@ /* check directory */ ret = VCWD_STAT(path, &sb); if (ret < 0) { - php_error(E_WARNING, "Unable to access %s", filename); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); return 0; } duid = sb.st_uid; @@ -159,9 +168,9 @@ } if (PG(safe_mode_gid)) { - php_error(E_WARNING, "SAFE MODE Restriction in effect. The script whose uid/gid is %ld/%ld is not allowed to access %s owned by uid/gid %ld/%ld", php_getuid(), php_getgid(), filename, uid, gid); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect. The script whose uid/gid is %ld/%ld is not allowed to access %s owned by uid/gid %ld/%ld", php_getuid(), php_getgid(), filename, uid, gid); } else { - php_error(E_WARNING, "SAFE MODE Restriction in effect. The script whose uid is %ld is not allowed to access %s owned by uid %ld", php_getuid(), filename, uid); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect. The script whose uid is %ld is not allowed to access %s owned by uid %ld", php_getuid(), filename, uid); } return 0; } 1.4 +22 -15 php4/main/snprintf.c Index: snprintf.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/snprintf.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- snprintf.c 9 May 2002 05:39:43 -0000 1.3 +++ snprintf.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -361,7 +361,7 @@ { int sign, decpt; register char *p1, *p2; - register i; + register int i; char buf1[NDIG]; p1 = ap_php_ecvt(number, ndigit, &decpt, &sign, buf1); @@ -390,8 +390,10 @@ *p2++ = decpt % 10 + '0'; } else { if (decpt <= 0) { - if (*p1 != '0') + if (*p1 != '0') { + *p2++ = '0'; *p2++ = '.'; + } while (decpt < 0) { decpt++; *p2++ = '0'; @@ -444,14 +446,14 @@ * * NOTE: Evaluation of the c argument should not have any side-effects */ -#define INS_CHAR( c, sp, bep, cc ) \ - { \ - if ( sp < bep ) \ - { \ - *sp++ = c ; \ - cc++ ; \ - } \ - } +#define INS_CHAR(c, sp, bep, cc) \ + { \ + if (sp < bep) \ + { \ + *sp++ = c; \ + } \ + cc++; \ + } #define NUM( c ) ( c - '0' ) @@ -885,14 +887,19 @@ * Notice that if no length is given, we initialize buf_end to the * highest possible address. */ - od.buf_end = len ? &buf[len] : (char *) ~0; - od.nextb = buf; + if (len == 0) { + od.buf_end = (char *) ~0; + od.nextb = (char *) ~0; + } else { + od.buf_end = &buf[len-1]; + od.nextb = buf; + } /* * Do the conversion */ cc = format_converter(&od, format, ap); - if (len == 0 || od.nextb <= od.buf_end) + if (len != 0 && od.nextb <= od.buf_end) *(od.nextb) = '\0'; if (ccp) *ccp = cc; @@ -905,7 +912,7 @@ va_list ap; va_start(ap, format); - strx_printv(&cc, buf, (len - 1), format, ap); + strx_printv(&cc, buf, len, format, ap); va_end(ap); return (cc); } @@ -915,7 +922,7 @@ { int cc; - strx_printv(&cc, buf, (len - 1), format, ap); + strx_printv(&cc, buf, len, format, ap); return (cc); } 1.4 +43 -0 php4/main/snprintf.h Index: snprintf.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/snprintf.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- snprintf.h 9 May 2002 05:39:43 -0000 1.3 +++ snprintf.h 6 Oct 2002 21:54:34 -0000 1.4 @@ -16,6 +16,49 @@ +----------------------------------------------------------------------+ */ +/* + +Comparing: sprintf, snprintf, spprintf + +sprintf offers the ability to make a lot of failures since it does not know + the size of the buffer it uses. Therefore usage of sprintf often + results in possible entries for buffer overrun attacks. So please + use this version only if you are sure the call is safe. sprintf + allways terminstes the buffer it writes to. + +snprintf knows the buffers size and will not write behind it. But you will + have to use either a static buffer or allocate a dynamic buffer + before beeing able to call the function. In other words you must + be sure that you really know the maximum size of the buffer required. + A bad thing is having a big maximum while in most cases you would + only need a small buffer. If the size of the resulting string is + longer or equal to the buffer size than the buffer is not terminated. + +spprintf is the dynamical version of snprintf. It allocates the buffer in size + as needed and allows a maximum setting as snprintf (turn this feature + off by setting max_len to 0). spprintf is a little bit slower than + snprintf and offers possible memory leakes if you miss freeing the + buffer allocated by the function. Therfore this function should be + used where either no maximum is known or the maximum is much bigger + than normal size required. spprintf allways terminates the buffer. + +Example: + + #define MAX 1024 | #define MAX 1024 | #define MAX 1024 + char buffer[MAX] | char buffer[MAX] | char *buffer; + | | + | | // No need to initialize buffer: + | | // spprintf ignores value of buffer + sprintf(buffer, "test"); | snprintf(buffer, MAX, "test"); | spprintf(&buffer, MAX, "text"); + | | if (!buffer) + | | return OUT_OF_MEMORY + // sprintf allways terminates | // manual termination of | // spprintf allays terminates buffer + // buffer | // buffer *IS* required | + | buffer[MAX-1] = 0; | + action_with_buffer(buffer); | action_with_buffer(buffer); | action_with_buffer(buffer); + | | efree(buffer); +*/ + #ifndef SNPRINTF_H #define SNPRINTF_H 1.4 +18 -18 php4/main/spprintf.c Index: spprintf.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/spprintf.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- spprintf.c 9 May 2002 05:39:43 -0000 1.3 +++ spprintf.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -100,7 +100,7 @@ /* * Size for realloc operations */ -#define SPPRINTF_BLOCK_SIZE 10 +#define SPPRINTF_BLOCK_SIZE 128 /* * Descriptor for buffer area @@ -118,16 +118,15 @@ /* Resize xbuf so that add bytes can be added. Reallocation is done * in defined block size to minimize calls to realloc. */ -static int xbuf_resize(xbuffy *xbuf, size_t add) +static void xbuf_resize(xbuffy *xbuf, size_t add) { char *buf; - int ret; size_t size, offset; if (xbuf->buf) { offset = xbuf->nextb - xbuf->buf; if (offset+add < xbuf->size) { - return 0; /* do not change size if not necessary */ + return; /* do not change size if not necessary */ } } else { offset = 0; @@ -139,32 +138,27 @@ } if (xbuf->max_len && size > xbuf->max_len) { size = xbuf->max_len; - ret = 1; - } else { - ret = 0; } - + buf = erealloc(xbuf->buf, size+1); /* alloc space for NUL */ - if (!buf) { - return 1; - } else { + if (buf) { xbuf->buf = buf; xbuf->buf_end = xbuf->max_len ? &buf[size] : (char *) ~0; xbuf->nextb = buf+offset; xbuf->size = size; - return ret; } } /* Initialise xbuffy with size spprintf_BLOCK_SIZE */ -static int xbuf_init(xbuffy *xbuf, size_t max_len) +static char * xbuf_init(xbuffy *xbuf, size_t max_len) { xbuf->buf = NULL; xbuf->size = 0; xbuf->max_len = max_len; - return xbuf_resize(xbuf, 0); /* NOT max_len */ + xbuf_resize(xbuf, 0); /* NOT max_len */ + return xbuf->buf; } /* @@ -617,8 +611,9 @@ * Notice that if no length is given, we initialize buf_end to the * highest possible address. */ - if (xbuf_init(&xbuf, max_len)) { - *pbuf = NULL; + if (!xbuf_init(&xbuf, max_len)) { + if (pbuf) + *pbuf = NULL; return 0; } else { /* @@ -627,13 +622,18 @@ cc = xbuf_format_converter(&xbuf, format, ap); if (xbuf.nextb <= xbuf.buf_end) *(xbuf.nextb) = '\0'; - *pbuf = xbuf.buf; + else if (xbuf.size) + xbuf.buf[xbuf.size-1] = '\0'; + if (pbuf) + *pbuf = xbuf.buf; + else + efree(pbuf); return cc; } } -int spprintf(char **pbuf, size_t max_len, const char *format, ...) +PHPAPI int spprintf(char **pbuf, size_t max_len, const char *format, ...) { int cc; va_list ap; 1.3 +16 -1 php4/main/spprintf.h Index: spprintf.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/spprintf.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- spprintf.h 29 Apr 2002 02:33:38 -0000 1.2 +++ spprintf.h 6 Oct 2002 21:54:34 -0000 1.3 @@ -16,14 +16,29 @@ +----------------------------------------------------------------------+ */ +/* + +The pbuf parameter of all spprintf version receives a pointer to the allocated +buffer. This buffer must be freed manually after usage using efree() function. +The buffer will allways be terminated by a zero character. When pbuf is NULL +the function can be used to calculate the required size of the buffer but for +that purpose snprintf is faster. When both pbuf and the return value are 0 +than you are out of memory. + +There is also snprintf: See difference explained in snprintf.h + +*/ + #ifndef SPPRINTF_H #define SPPRINTF_H #include "snprintf.h" -extern int spprintf( char **pbuf, size_t max_len, const char *format, ...); +BEGIN_EXTERN_C() +PHPAPI extern int spprintf( char **pbuf, size_t max_len, const char *format, ...); PHPAPI extern int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap); +END_EXTERN_C() #endif /* SNPRINTF_H */ 1.4 +961 -154 php4/main/streams.c Index: streams.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/streams.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- streams.c 30 Apr 2002 08:15:07 -0000 1.3 +++ streams.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -20,6 +20,8 @@ +----------------------------------------------------------------------+ */ +/* $Id: streams.c,v 1.97 2002/10/05 10:59:34 wez Exp $ */ + #define _GNU_SOURCE #include "php.h" #include "php_globals.h" @@ -31,6 +33,10 @@ #include <sys/mman.h> #endif +#include <stddef.h> + +#include <fcntl.h> + #ifndef MAP_FAILED #define MAP_FAILED ((void *) -1) #endif @@ -70,26 +76,168 @@ /* }}} */ static HashTable url_stream_wrappers_hash; +static int le_stream = FAILURE; /* true global */ +static int le_pstream = FAILURE; /* true global */ + +PHPAPI int php_file_le_stream(void) +{ + return le_stream; +} + +PHPAPI int php_file_le_pstream(void) +{ + return le_pstream; +} + +static int forget_persistent_resource_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + php_stream *stream; + + if (Z_TYPE_P(rsrc) != le_pstream) + return 0; + + stream = (php_stream*)rsrc->ptr; + +#if STREAM_DEBUG +fprintf(stderr, "forget_persistent: %s:%p\n", stream->ops->label, stream); +#endif + + stream->rsrc_id = FAILURE; + + return 0; +} + +PHP_RSHUTDOWN_FUNCTION(streams) +{ + zend_hash_apply(&EG(persistent_list), (apply_func_t)forget_persistent_resource_id_numbers TSRMLS_CC); + return SUCCESS; +} + +PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC) +{ + list_entry *le; + + if (zend_hash_find(&EG(persistent_list), (char*)persistent_id, strlen(persistent_id)+1, (void*) &le) == SUCCESS) { + if (Z_TYPE_P(le) == le_pstream) { + if (stream) { + *stream = (php_stream*)le->ptr; + if ((*stream)->rsrc_id == FAILURE) { + /* first access this request; give it a valid id */ + (*stream)->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, *stream, le_pstream); + } + } + return PHP_STREAM_PERSISTENT_SUCCESS; + } + return PHP_STREAM_PERSISTENT_FAILURE; + } + return PHP_STREAM_PERSISTENT_NOT_EXIST; +} + +static void display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption TSRMLS_DC) +{ + char *tmp = estrdup(path); + char *msg; + int free_msg = 0; + + if (wrapper) { + if (wrapper->err_count > 0) { + int i; + size_t l; + int brlen; + char *br; + + if (PG(html_errors)) { + brlen = 7; + br = "<br />\n"; + } else { + brlen = 1; + br = "\n"; + } + + for (i = 0, l = 0; i < wrapper->err_count; i++) { + l += strlen(wrapper->err_stack[i]); + if (i < wrapper->err_count - 1) + l += brlen; + } + msg = emalloc(l + 1); + msg[0] = '\0'; + for (i = 0; i < wrapper->err_count; i++) { + strcat(msg, wrapper->err_stack[i]); + if (i < wrapper->err_count - 1) + strcat(msg, br); + } + + free_msg = 1; + } else { + msg = strerror(errno); + } + } else { + msg = "no suitable wrapper could be found"; + } + + php_strip_url_passwd(tmp); + php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "%s: %s", caption, msg); + efree(tmp); + if (free_msg) + efree(msg); +} + +static void tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC) +{ + if (wrapper) { + /* tidy up the error stack */ + int i; + + for (i = 0; i < wrapper->err_count; i++) + efree(wrapper->err_stack[i]); + if (wrapper->err_stack) + efree(wrapper->err_stack); + wrapper->err_stack = NULL; + wrapper->err_count = 0; + } +} + + /* allocate a new stream for a particular ops */ -PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, int persistent, const char *mode STREAMS_DC TSRMLS_DC) /* {{{ */ +PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, const char *persistent_id, const char *mode STREAMS_DC TSRMLS_DC) /* {{{ */ { php_stream *ret; - ret = (php_stream*) pemalloc_rel_orig(sizeof(php_stream), persistent); + ret = (php_stream*) pemalloc_rel_orig(sizeof(php_stream), persistent_id ? 1 : 0); memset(ret, 0, sizeof(php_stream)); #if STREAM_DEBUG -fprintf(stderr, "stream_alloc: %s:%p\n", ops->label, ret); +fprintf(stderr, "stream_alloc: %s:%p persistent=%s\n", ops->label, ret, persistent_id); #endif ret->ops = ops; ret->abstract = abstract; - ret->is_persistent = persistent; - ret->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ret, php_file_le_stream()); - strlcpy(ret->mode, mode, sizeof(ret->mode)); + ret->is_persistent = persistent_id ? 1 : 0; + ret->chunk_size = FG(def_chunk_size); + + if (FG(auto_detect_line_endings)) + ret->flags |= PHP_STREAM_FLAG_DETECT_EOL; + + if (persistent_id) { + list_entry le; + Z_TYPE(le) = le_pstream; + le.ptr = ret; + + if (FAILURE == zend_hash_update(&EG(persistent_list), (char *)persistent_id, + strlen(persistent_id) + 1, + (void *)&le, sizeof(list_entry), NULL)) { + + pefree(ret, 1); + return NULL; + } + } + + ret->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ret, persistent_id ? le_pstream : le_stream); + strlcpy(ret->mode, mode, sizeof(ret->mode)); + return ret; } /* }}} */ @@ -99,7 +247,7 @@ int ret = 1; #if STREAM_DEBUG -fprintf(stderr, "stream_free: %s:%p in_free=%d opts=%08x\n", stream->ops->label, stream, stream->in_free, close_options); +fprintf(stderr, "stream_free: %s:%p[%s] in_free=%d opts=%08x\n", stream->ops->label, stream, stream->__orig_path, stream->in_free, close_options); #endif if (stream->in_free) @@ -107,6 +255,8 @@ stream->in_free++; + _php_stream_flush(stream, 1 TSRMLS_CC); + if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) == 0) { /* Remove entry from the resource list */ zend_list_delete(stream->rsrc_id); @@ -135,6 +285,10 @@ } if (close_options & PHP_STREAM_FREE_RELEASE_STREAM) { + + while (stream->filterhead) { + php_stream_filter_remove_head(stream, 1); + } if (stream->wrapper && stream->wrapper->wops && stream->wrapper->wops->stream_closer) { stream->wrapper->wops->stream_closer(stream->wrapper, stream TSRMLS_CC); @@ -146,40 +300,281 @@ stream->wrapperdata = NULL; } + if (stream->readbuf) { + pefree(stream->readbuf, stream->is_persistent); + stream->readbuf = NULL; + } + #if ZEND_DEBUG if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) && (stream->__exposed == 0) && (EG(error_reporting) & E_WARNING)) { /* it leaked: Lets deliberately NOT pefree it so that the memory manager shows it * as leaked; it will log a warning, but lets help it out and display what kind * of stream it was. */ char leakbuf[512]; - snprintf(leakbuf, sizeof(leakbuf), __FILE__ "(%d) : Stream of type '%s' 0x%08X was not closed\n", __LINE__, stream->ops->label, (unsigned int)stream); + snprintf(leakbuf, sizeof(leakbuf), __FILE__ "(%d) : Stream of type '%s' 0x%08X (path:%s) was not closed\n", __LINE__, stream->ops->label, (unsigned int)stream, stream->__orig_path); + + STR_FREE(stream->__orig_path); + # if defined(PHP_WIN32) OutputDebugString(leakbuf); # else fprintf(stderr, leakbuf); # endif + } else { + STR_FREE(stream->__orig_path); + pefree(stream, stream->is_persistent); } - else -#endif +#else pefree(stream, stream->is_persistent); +#endif } return ret; } /* }}} */ +/* {{{ filter API */ +static HashTable stream_filters_hash; + +PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC) +{ + return zend_hash_add(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern), factory, sizeof(*factory), NULL); +} + +PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern TSRMLS_DC) +{ + return zend_hash_del(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern)); +} + +/* We allow very simple pattern matching for filter factories: + * if "charset.utf-8/sjis" is requested, we search first for an exact + * match. If that fails, we try "charset.*". + * This means that we don't need to clog up the hashtable with a zillion + * charsets (for example) but still be able to provide them all as filters */ +PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, const char *filterparams, int filterparamslen, int persistent TSRMLS_DC) +{ + php_stream_filter_factory *factory; + php_stream_filter *filter = NULL; + int n; + char *period; + + n = strlen(filtername); + + if (SUCCESS == zend_hash_find(&stream_filters_hash, (char*)filtername, n, (void**)&factory)) { + filter = factory->create_filter(filtername, filterparams, filterparamslen, persistent TSRMLS_CC); + } else if ((period = strchr(filtername, '.'))) { + /* try a wildcard */ + char wildname[128]; + + PHP_STRLCPY(wildname, filtername, sizeof(wildname) - 1, period-filtername + 1); + strcat(wildname, "*"); + + if (SUCCESS == zend_hash_find(&stream_filters_hash, wildname, strlen(wildname), (void**)&factory)) { + filter = factory->create_filter(filtername, filterparams, filterparamslen, persistent TSRMLS_CC); + } + } + + if (filter == NULL) { + /* TODO: these need correct docrefs */ + if (factory == NULL) + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to locate filter \"%s\"", filtername); + else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to create or locate filter \"%s\"", filtername); + } + + return filter; +} + +PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC) +{ + php_stream_filter *filter; + + filter = (php_stream_filter*) pemalloc_rel_orig(sizeof(php_stream_filter), persistent); + memset(filter, 0, sizeof(php_stream_filter)); + + filter->fops = fops; + filter->abstract = abstract; + filter->is_persistent = persistent; + + return filter; +} + +PHPAPI void php_stream_filter_free(php_stream_filter *filter TSRMLS_DC) +{ + if (filter->fops->dtor) + filter->fops->dtor(filter TSRMLS_CC); + pefree(filter, filter->is_persistent); +} + +PHPAPI void php_stream_filter_prepend(php_stream *stream, php_stream_filter *filter) +{ + filter->next = stream->filterhead; + filter->prev = NULL; + + if (stream->filterhead) { + stream->filterhead->prev = filter; + } else { + stream->filtertail = filter; + } + stream->filterhead = filter; + filter->stream = stream; +} + +PHPAPI void php_stream_filter_append(php_stream *stream, php_stream_filter *filter) +{ + filter->prev = stream->filtertail; + filter->next = NULL; + if (stream->filtertail) { + stream->filtertail->next = filter; + } else { + stream->filterhead = filter; + } + stream->filtertail = filter; + filter->stream = stream; +} + +PHPAPI php_stream_filter *php_stream_filter_remove(php_stream *stream, php_stream_filter *filter, int call_dtor TSRMLS_DC) +{ + assert(stream == filter->stream); + + if (filter->prev) { + filter->prev->next = filter->next; + } else { + stream->filterhead = filter->next; + } + if (filter->next) { + filter->next->prev = filter->prev; + } else { + stream->filtertail = filter->prev; + } + if (call_dtor) { + php_stream_filter_free(filter TSRMLS_CC); + return NULL; + } + return filter; +} +/* }}} */ + /* {{{ generic stream operations */ + +static void php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_DC) +{ + /* allocate/fill the buffer */ + + /* is there enough data in the buffer ? */ + if (stream->writepos - stream->readpos < (off_t)size) { + size_t justread = 0; + + /* no; so lets fetch more data */ + + /* reduce buffer memory consumption if possible, to avoid a realloc */ + if (stream->readbuflen - stream->writepos < stream->chunk_size) { + memmove(stream->readbuf, stream->readbuf + stream->readpos, stream->readbuflen - stream->readpos); + stream->writepos -= stream->readpos; + stream->readpos = 0; + } + + /* grow the buffer if required */ + if (stream->readbuflen - stream->writepos < stream->chunk_size) { + stream->readbuflen += stream->chunk_size; + stream->readbuf = perealloc(stream->readbuf, stream->readbuflen, + stream->is_persistent); + } + + if (stream->filterhead) { + justread = stream->filterhead->fops->read(stream, stream->filterhead, + stream->readbuf + stream->writepos, + stream->readbuflen - stream->writepos + TSRMLS_CC); + } else { + justread = stream->ops->read(stream, stream->readbuf + stream->writepos, + stream->readbuflen - stream->writepos + TSRMLS_CC); + } + + if (justread > 0) { + stream->writepos += justread; + } + } + +} + PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS_DC) { - return stream->ops->read == NULL ? 0 : stream->ops->read(stream, buf, size TSRMLS_CC); + size_t toread, didread = 0; + + if (size == 0) + return 0; + + /* take from the read buffer first. + * It is possible that a buffered stream was switched to non-buffered, so we + * drain the remainder of the buffer before using the "raw" read mode for + * the excess */ + if (stream->writepos > stream->readpos) { + + toread = stream->writepos - stream->readpos; + if (toread > size) + toread = size; + + memcpy(buf, stream->readbuf + stream->readpos, toread); + stream->readpos += toread; + size -= toread; + buf += toread; + didread += toread; + } + + if (size == 0) { + stream->position += didread; + + if (didread == 0) + stream->eof = 1; + + return didread; + } + + if (stream->flags & PHP_STREAM_FLAG_NO_BUFFER || stream->chunk_size == 1) { + if (stream->filterhead) { + didread += stream->filterhead->fops->read(stream, stream->filterhead, + buf, size + TSRMLS_CC); + } else { + didread += stream->ops->read(stream, buf, size TSRMLS_CC); + } + } else { + php_stream_fill_read_buffer(stream, size TSRMLS_CC); + + if ((off_t)size > stream->writepos - stream->readpos) + size = stream->writepos - stream->readpos; + + if (size) { + memcpy(buf, stream->readbuf + stream->readpos, size); + stream->readpos += size; + didread += size; + } + } + stream->position += size; + + if (didread == 0) + stream->eof = 1; + + return didread; } PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC) { + /* if there is data in the buffer, it's not EOF */ + if (stream->writepos - stream->readpos > 0) + return 0; + + return stream->eof; + /* we define our stream reading function so that it must return EOF when an EOF condition occurs, when working in unbuffered mode and called with these args */ - return stream->ops->read == NULL ? -1 : stream->ops->read(stream, NULL, 0 TSRMLS_CC) == EOF ? 1 : 0; + if (stream->filterhead) + return stream->filterhead->fops->eof(stream, stream->filterhead TSRMLS_CC); + + return stream->ops->read(stream, NULL, 0 TSRMLS_CC) == EOF ? 1 : 0; } PHPAPI int _php_stream_putc(php_stream *stream, int c TSRMLS_DC) @@ -234,68 +629,205 @@ return stream->ops->stat(stream, ssb TSRMLS_CC); } -PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRMLS_DC) +static char *php_stream_locate_eol(php_stream *stream TSRMLS_DC) { + size_t avail; + char *cr, *lf, *eol = NULL; + char *readptr; + + readptr = stream->readbuf + stream->readpos; + avail = stream->writepos - stream->readpos; - if (maxlen == 0) { - buf[0] = 0; - return buf; + /* Look for EOL */ + if (stream->flags & PHP_STREAM_FLAG_DETECT_EOL) { + cr = memchr(readptr, '\r', avail); + lf = memchr(readptr, '\n', avail); + + if (cr && lf != cr + 1) { + /* mac */ + stream->flags ^= PHP_STREAM_FLAG_DETECT_EOL; + stream->flags |= PHP_STREAM_FLAG_EOL_MAC; + eol = cr; + } else if ((cr && lf && cr == lf - 1) || (lf)) { + /* dos or unix endings */ + stream->flags ^= PHP_STREAM_FLAG_DETECT_EOL; + eol = lf; + } + } else if (stream->flags & PHP_STREAM_FLAG_EOL_MAC) { + eol = memchr(readptr, '\r', avail); + } else { + /* unix (and dos) line endings */ + eol = memchr(readptr, '\n', avail); } - if (stream->ops->gets) { - return stream->ops->gets(stream, buf, maxlen TSRMLS_CC); - } else if (stream->ops->read == NULL) { + return eol; +} + +PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRMLS_DC) +{ + size_t avail = 0; + int did_copy = 0; + + if (maxlen == 0) return NULL; - } else { - /* unbuffered fgets - poor performance ! */ - size_t n = 1; - char *c = buf; - - /* TODO: look at error returns? */ - - while(n < maxlen && stream->ops->read(stream, c, 1 TSRMLS_CC) > 0) { - n++; - if (*c == '\n') { - c++; + + /* + * If the underlying stream operations block when no new data is readable, + * we need to take extra precautions. + * + * If there is buffered data available, we check for a EOL. If it exists, + * we pass the data immediately back to the caller. This saves a call + * to the read implementation and will not block where blocking + * is not necessary at all. + * + * If the stream buffer contains more data than the caller requested, + * we can also avoid that costly step and simply return that data. + */ + + for (;;) { + avail = stream->writepos - stream->readpos; + + if (avail > 0) { + size_t cpysz = 0; + char *readptr; + char *eol; + int done = 0; + + readptr = stream->readbuf + stream->readpos; + eol = php_stream_locate_eol(stream TSRMLS_CC); + + if (eol) { + cpysz = eol - readptr + 1; + done = 1; + } else { + cpysz = avail; + } + + if (cpysz >= maxlen - 1) { + cpysz = maxlen - 1; + done = 1; + } + + memcpy(buf, readptr, cpysz); + + stream->position += cpysz; + stream->readpos += cpysz; + buf += cpysz; + maxlen -= cpysz; + + did_copy = 1; + if (done) { + break; + } + } else { + /* XXX: Should be fine to always read chunk_size */ + size_t toread = maxlen - 1; + if (toread > stream->chunk_size) + toread = stream->chunk_size; + + php_stream_fill_read_buffer(stream, toread TSRMLS_CC); + + if (stream->writepos - stream->readpos == 0) { break; } - c++; } - *c = 0; - return buf; } + + if (!did_copy) + return NULL; + + buf[0] = '\0'; + + return buf; } -PHPAPI int _php_stream_flush(php_stream *stream TSRMLS_DC) +PHPAPI int _php_stream_flush(php_stream *stream, int closing TSRMLS_DC) { + int ret = 0; + + if (stream->filterhead) + stream->filterhead->fops->flush(stream, stream->filterhead, closing TSRMLS_CC); + if (stream->ops->flush) { - return stream->ops->flush(stream TSRMLS_CC); + ret = stream->ops->flush(stream TSRMLS_CC); } - return 0; + + return ret; } PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) { + size_t didwrite; + assert(stream); if (buf == NULL || count == 0 || stream->ops->write == NULL) return 0; - return stream->ops->write(stream, buf, count TSRMLS_CC); + + if (stream->filterhead) { + didwrite = stream->filterhead->fops->write(stream, stream->filterhead, buf, count TSRMLS_CC); + } else { + didwrite = stream->ops->write(stream, buf, count TSRMLS_CC); + } + stream->position += didwrite; + return didwrite; } PHPAPI off_t _php_stream_tell(php_stream *stream TSRMLS_DC) { - off_t ret = -1; - - if (stream->ops->seek) { - ret = stream->ops->seek(stream, 0, SEEK_CUR TSRMLS_CC); - } - return ret; + return stream->position; } PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC) { - if (stream->ops->seek) { - return stream->ops->seek(stream, offset, whence TSRMLS_CC); + /* not moving anywhere */ + if ((offset == 0 && whence == SEEK_CUR) || (offset == stream->position && whence == SEEK_SET)) + return 0; + + /* handle the case where we are in the buffer */ + switch(whence) { + case SEEK_CUR: + if (offset > 0 && offset < stream->writepos - stream->readpos) { + stream->readpos += offset; + stream->position += offset; + stream->eof = 0; + return 0; + } + break; + case SEEK_SET: + if (offset > stream->position && + offset < stream->position + stream->writepos - stream->readpos) { + stream->readpos += offset - stream->position; + stream->position = offset; + stream->eof = 0; + return 0; + } + break; + } + + /* invalidate the buffer contents */ + stream->readpos = stream->writepos = 0; + + if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { + int ret; + + if (stream->filterhead) + stream->filterhead->fops->flush(stream, stream->filterhead, 0 TSRMLS_CC); + + switch(whence) { + case SEEK_CUR: + offset = stream->position + offset; + whence = SEEK_SET; + break; + } + ret = stream->ops->seek(stream, offset, whence, &stream->position TSRMLS_CC); + + if (((stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) || ret == 0) { + if (ret == 0) + stream->eof = 0; + return ret; + } + /* else the stream has decided that it can't support seeking after all; + * fall through to attempt emulation */ } /* emulate forward moving seeks with reads */ @@ -310,13 +842,48 @@ if (php_stream_read(stream, tmp, offset) == 0) return -1; } + stream->eof = 0; return 0; } - zend_error(E_WARNING, "streams of type %s do not support seeking", stream->ops->label); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream does not support seeking"); + return -1; } +PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +{ + int ret = PHP_STREAM_OPTION_RETURN_NOTIMPL; + + if (stream->ops->set_option) { + ret = stream->ops->set_option(stream, option, value, ptrparam TSRMLS_CC); + } + + if (ret == PHP_STREAM_OPTION_RETURN_NOTIMPL) { + switch(option) { + case PHP_STREAM_OPTION_SET_CHUNK_SIZE: + ret = stream->chunk_size; + stream->chunk_size = value; + return ret; + + case PHP_STREAM_OPTION_READ_BUFFER: + /* try to match the buffer mode as best we can */ + if (value == PHP_STREAM_BUFFER_NONE) { + stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; + } else { + stream->flags ^= PHP_STREAM_FLAG_NO_BUFFER; + } + ret = PHP_STREAM_OPTION_RETURN_OK; + break; + + default: + ret = PHP_STREAM_OPTION_RETURN_ERR; + } + } + + return ret; +} + PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC) { size_t bcount = 0; @@ -328,6 +895,7 @@ #ifdef HAVE_MMAP if (!php_stream_is(stream, PHP_STREAM_IS_SOCKET) + && stream->filterhead == NULL && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fd, 0)) { struct stat sbuf; @@ -391,6 +959,7 @@ * buffering layer. * */ if ( php_stream_is(src, PHP_STREAM_IS_STDIO) && + src->filterhead == NULL && php_stream_tell(src) == 0 && SUCCESS == php_stream_cast(src, PHP_STREAM_AS_FD, (void**)&srcfd, 0)) { @@ -400,7 +969,7 @@ void *srcfile; #if STREAM_DEBUG - fprintf(stderr, "mmap attempt: maxlen=%d filesize=%d\n", maxlen, sbuf.st_size); + fprintf(stderr, "mmap attempt: maxlen=%d filesize=%ld\n", maxlen, sbuf.st_size); #endif if (maxlen > sbuf.st_size || maxlen == 0) @@ -441,7 +1010,8 @@ } } if (len) { - *buf = perealloc_rel_orig(*buf, len, persistent); + *buf = perealloc_rel_orig(*buf, len + 1, persistent); + (*buf)[len] = '\0'; } else { pefree(*buf, persistent); *buf = NULL; @@ -471,6 +1041,7 @@ * buffering layer. * */ if ( php_stream_is(src, PHP_STREAM_IS_STDIO) && + src->filterhead == NULL && php_stream_tell(src) == 0 && SUCCESS == php_stream_cast(src, PHP_STREAM_AS_FD, (void**)&srcfd, 0)) { @@ -479,6 +1050,12 @@ if (fstat(srcfd, &sbuf) == 0) { void *srcfile; + /* in the event that the source file is 0 bytes, return 1 to indicate success + * because opening the file to write had already created a copy */ + + if(sbuf.st_size ==0) + return 1; + if (maxlen > sbuf.st_size || maxlen == 0) maxlen = sbuf.st_size; @@ -539,7 +1116,9 @@ typedef struct { FILE *file; - int is_pipe; /* use pclose */ + int fd; /* underlying file descriptor */ + int is_process_pipe; /* use pclose instead of fclose */ + int is_pipe; /* don't try and seek */ #if HAVE_FLUSHIO char last_op; #endif @@ -556,7 +1135,7 @@ } fclose(fp); - zend_error(E_WARNING, "%s(): unable to allocate stream", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate stream"); return NULL; } @@ -570,12 +1149,12 @@ fp = tmpfile(); if (fp == NULL) { - zend_error(E_WARNING, "tmpfile(): %s", strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "tmpfile(): %s", strerror(errno)); return NULL; } stream = php_stream_fopen_from_file_rel(fp, "r+"); if (stream == NULL) { - zend_error(E_WARNING, "tmpfile(): %s", strerror(errno)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "tmpfile(): %s", strerror(errno)); fclose(fp); return NULL; } @@ -587,10 +1166,22 @@ PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC TSRMLS_DC) { php_stdio_stream_data *self; - + self = emalloc_rel_orig(sizeof(*self)); self->file = file; self->is_pipe = 0; + self->is_process_pipe = 0; + + self->fd = fileno(file); + +#ifdef S_ISFIFO + /* detect if this is a pipe */ + if (self->fd >= 0) { + struct stat sb; + self->is_pipe = (fstat(self->fd, &sb) == 0 && S_ISFIFO(sb.st_mode)) ? 1 : 0; + } +#endif + return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode); } @@ -601,45 +1192,61 @@ self = emalloc_rel_orig(sizeof(*self)); self->file = file; self->is_pipe = 1; + self->is_process_pipe = 1; + self->fd = fileno(file); + return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode); } + static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; assert(data != NULL); + if (data->fd >= 0) { + + return write(data->fd, buf, count); + + } else { + #if HAVE_FLUSHIO - if (data->last_op == 'r') { - fseek(data->file, 0, SEEK_CUR); - } - data->last_op = 'w'; + if (!data->is_pipe && data->last_op == 'r') { + fseek(data->file, 0, SEEK_CUR); + } + data->last_op = 'w'; #endif - return fwrite(buf, 1, count, data->file); + return fwrite(buf, 1, count, data->file); + } } static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; + size_t ret; assert(data != NULL); - if (buf == NULL && count == 0) { - /* check for EOF condition */ - if (feof(data->file)) { - return EOF; - } - return 0; - } - + if (data->fd >= 0) { + ret = read(data->fd, buf, count); + + if (ret == 0 || (ret < 0 && errno != EWOULDBLOCK)) + stream->eof = 1; + + } else { #if HAVE_FLUSHIO - if (data->last_op == 'w') - fseek(data->file, 0, SEEK_CUR); - data->last_op = 'r'; + if (!data->is_pipe && data->last_op == 'w') + fseek(data->file, 0, SEEK_CUR); + data->last_op = 'r'; #endif - return fread(buf, 1, count, data->file); + ret = fread(buf, 1, count, data->file); + + if (ret == 0 && feof(data->file)) + stream->eof = 1; + } + return ret; } static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC) @@ -650,7 +1257,7 @@ assert(data != NULL); if (close_handle) { - if (data->is_pipe) { + if (data->is_process_pipe) { ret = pclose(data->file); } else { ret = fclose(data->file); @@ -671,50 +1278,64 @@ assert(data != NULL); - return fflush(data->file); + if (data->fd >= 0) { + return fsync(data->fd); + } else { + return fflush(data->file); + } } -static int php_stdiop_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC) +static int php_stdiop_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; + int ret; assert(data != NULL); - if (offset == 0 && whence == SEEK_CUR) - return ftell(data->file); - - return fseek(data->file, offset, whence); -} + if (data->is_pipe) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot seek on a pipe"); + return -1; + } -static char *php_stdiop_gets(php_stream *stream, char *buf, size_t size TSRMLS_DC) -{ - php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; + if (data->fd >= 0) { + off_t result; + + result = lseek(data->fd, offset, whence); + if (result == (off_t)-1) + return -1; - assert(data != NULL); -#if HAVE_FLUSHIO - if (data->last_op == 'w') { - fseek(data->file, 0, SEEK_CUR); + *newoffset = result; + return 0; + + } else { + ret = fseek(data->file, offset, whence); + *newoffset = ftell(data->file); + return ret; } - data->last_op = 'r'; -#endif - - return fgets(buf, size, data->file); } + static int php_stdiop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) { int fd; php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract; assert(data != NULL); + + /* as soon as someone touches the stdio layer, buffering may ensue, + * so we need to stop using the fd directly in that case */ switch (castas) { case PHP_STREAM_AS_STDIO: if (ret) { *ret = data->file; + data->fd = -1; } return SUCCESS; case PHP_STREAM_AS_FD: + /* fetch the fileno rather than using data->fd, since we may + * have zeroed that member if someone requested the FILE* + * first (see above case) */ fd = fileno(data->file); if (fd < 0) { return FAILURE; @@ -741,13 +1362,74 @@ return fstat(fd, &ssb->sb); } +static int php_stdiop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +{ + php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract; + size_t size; + int fd; +#ifdef O_NONBLOCK + /* FIXME: make this work for win32 */ + int flags; + int oldval; +#endif + + switch(option) { + case PHP_STREAM_OPTION_BLOCKING: + fd = fileno(data->file); + + if (fd == -1) + return -1; +#ifdef O_NONBLOCK + flags = fcntl(fd, F_GETFL, 0); + oldval = (flags & O_NONBLOCK) ? 0 : 1; + if (value) + flags ^= O_NONBLOCK; + else + flags |= O_NONBLOCK; + + if (-1 == fcntl(fd, F_SETFL, flags)) + return -1; + return oldval; +#else + return -1; /* not yet implemented */ +#endif + + case PHP_STREAM_OPTION_WRITE_BUFFER: + if (ptrparam) + size = *(size_t *)ptrparam; + else + size = BUFSIZ; + + switch(value) { + case PHP_STREAM_BUFFER_NONE: + stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; + return setvbuf(data->file, NULL, _IONBF, 0); + + case PHP_STREAM_BUFFER_LINE: + stream->flags ^= PHP_STREAM_FLAG_NO_BUFFER; + return setvbuf(data->file, NULL, _IOLBF, size); + + case PHP_STREAM_BUFFER_FULL: + stream->flags ^= PHP_STREAM_FLAG_NO_BUFFER; + return setvbuf(data->file, NULL, _IOFBF, size); + + default: + return -1; + } + break; + default: + return -1; + } +} + PHPAPI php_stream_ops php_stream_stdio_ops = { php_stdiop_write, php_stdiop_read, php_stdiop_close, php_stdiop_flush, "STDIO", php_stdiop_seek, - php_stdiop_gets, php_stdiop_cast, - php_stdiop_stat + php_stdiop_cast, + php_stdiop_stat, + php_stdiop_set_option }; /* }}} */ @@ -776,6 +1458,11 @@ /* Relative path open */ if (*filename == '.') { + + if (php_check_open_basedir(filename TSRMLS_CC)) { + return NULL; + } + if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) { return NULL; } @@ -789,6 +1476,11 @@ /* Absolute path open */ if (IS_ABSOLUTE_PATH(filename, filename_length)) { + + if (php_check_open_basedir(filename TSRMLS_CC)) { + return NULL; + } + if ((php_check_safe_mode_include_dir(filename TSRMLS_CC)) == 0) /* filename is in safe_mode_include_dir (or subdir) */ return php_stream_fopen_rel(filename, mode, opened_path); @@ -800,6 +1492,11 @@ } if (!path || (path && !*path)) { + + if (php_check_open_basedir(path TSRMLS_CC)) { + return NULL; + } + if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) { return NULL; } @@ -843,7 +1540,10 @@ if (PG(safe_mode)) { if (VCWD_STAT(trypath, &sb) == 0) { /* file exists ... check permission */ - if ((php_check_safe_mode_include_dir(trypath TSRMLS_CC) == 0) || + + if (php_check_open_basedir(trypath TSRMLS_CC)) { + stream = NULL; + } else if ((php_check_safe_mode_include_dir(trypath TSRMLS_CC) == 0) || php_checkuid(trypath, mode, CHECKUID_CHECK_MODE_PARAM)) { /* UID ok, or trypath is in safe_mode_include_dir */ stream = php_stream_fopen_rel(trypath, mode, opened_path); @@ -916,12 +1616,25 @@ return php_stream_write(((php_stream *)cookie), (char *)buffer, size); } +#ifdef COOKIE_SEEKER_USES_FPOS_T +static int stream_cookie_seeker(void *cookie, fpos_t *position, int whence) +{ + TSRMLS_FETCH(); + + *position = php_stream_seek((php_stream *)cookie, *position, whence); + + if (*position == -1) + return -1; + return 0; +} +#else static int stream_cookie_seeker(void *cookie, off_t position, int whence) { TSRMLS_FETCH(); return php_stream_seek((php_stream *)cookie, position, whence); } +#endif static int stream_cookie_closer(void *cookie) { @@ -949,6 +1662,19 @@ int flags = castas & PHP_STREAM_CAST_MASK; castas &= ~PHP_STREAM_CAST_MASK; + /* synchronize our buffer (if possible) */ + if (ret) { + php_stream_flush(stream); + if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { + off_t dummy; + + stream->ops->seek(stream, stream->position, SEEK_SET, &dummy TSRMLS_CC); + stream->readpos = stream->writepos = 0; + } + } + + /* filtered streams can only be cast as stdio, and only when fopencookie is present */ + if (castas == PHP_STREAM_AS_STDIO) { if (stream->stdiocast) { if (ret) { @@ -961,6 +1687,7 @@ * first, to avoid doubling up the layers of stdio with an fopencookie */ if (php_stream_is(stream, PHP_STREAM_IS_STDIO) && stream->ops->cast && + stream->filterhead == NULL && stream->ops->cast(stream, castas, ret TSRMLS_CC) == SUCCESS) { goto exit_success; @@ -992,11 +1719,17 @@ b) no memory -> lets bail */ - zend_error(E_ERROR, "%s(): fopencookie failed", get_active_function_name(TSRMLS_C)); + php_error_docref(NULL TSRMLS_CC, E_ERROR, "fopencookie failed"); return FAILURE; #endif } + + if (stream->filterhead) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot cast a filtered stream on this system"); + return FAILURE; + } + if (stream->ops->cast && stream->ops->cast(stream, castas, ret TSRMLS_CC) == SUCCESS) goto exit_success; @@ -1005,10 +1738,8 @@ static const char *cast_names[3] = { "STDIO FILE*", "File Descriptor", "Socket Descriptor" }; - TSRMLS_FETCH(); - zend_error(E_WARNING, "%s(): cannot represent a stream of type %s as a %s", - get_active_function_name(TSRMLS_C), + php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot represent a stream of type %s as a %s", stream->ops->label, cast_names[castas] ); @@ -1017,6 +1748,17 @@ return FAILURE; exit_success: + + if ((stream->writepos - stream->readpos) > 0 && stream->fclose_stdiocast != PHP_STREAM_FCLOSE_FOPENCOOKIE) { + /* the data we have buffered will be lost to the third party library that + * will be accessing the stream. Emit a warning so that the end-user will + * know that they should try something else */ + + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "%d bytes of buffered data lost during conversion to FILE*!", + stream->writepos - stream->readpos); + } + if (castas == PHP_STREAM_AS_STDIO && ret) stream->stdiocast = *ret; @@ -1039,22 +1781,41 @@ /* }}} */ /* {{{ wrapper init and registration */ -int php_init_stream_wrappers(TSRMLS_D) + +static void stream_resource_regular_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + php_stream *stream = (php_stream*)rsrc->ptr; + /* set the return value for pclose */ + FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); +} + +static void stream_resource_persistent_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) { - return zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1); + php_stream *stream = (php_stream*)rsrc->ptr; + FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); } -int php_shutdown_stream_wrappers(TSRMLS_D) +int php_init_stream_wrappers(int module_number TSRMLS_DC) +{ + le_stream = zend_register_list_destructors_ex(stream_resource_regular_dtor, NULL, "stream", module_number); + le_pstream = zend_register_list_destructors_ex(NULL, stream_resource_persistent_dtor, "persistent stream", module_number); + + return ( + zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS + && + zend_hash_init(&stream_filters_hash, 0, NULL, NULL, 1) == SUCCESS + ) ? SUCCESS : FAILURE; +} + +int php_shutdown_stream_wrappers(int module_number TSRMLS_DC) { zend_hash_destroy(&url_stream_wrappers_hash); + zend_hash_destroy(&stream_filters_hash); return SUCCESS; } PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) { - if (!PG(allow_url_fopen) && wrapper->is_url) - return FAILURE; - return zend_hash_add(&url_stream_wrappers_hash, protocol, strlen(protocol), wrapper, sizeof(*wrapper), NULL); } @@ -1089,7 +1850,7 @@ return closedir((DIR *)stream->abstract); } -static int php_plain_files_dirstream_rewind(php_stream *stream, off_t offset, int whence TSRMLS_DC) +static int php_plain_files_dirstream_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) { rewinddir((DIR *)stream->abstract); return 0; @@ -1100,8 +1861,9 @@ php_plain_files_dirstream_close, NULL, "dir", php_plain_files_dirstream_rewind, - NULL, NULL, - NULL + NULL, /* cast */ + NULL, /* stat */ + NULL /* set_option */ }; static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, char *path, char *mode, @@ -1144,6 +1906,10 @@ return php_stream_fopen_with_path_rel(path, mode, PG(include_path), opened_path); } + if (php_check_open_basedir(path TSRMLS_CC)) { + return NULL; + } + if ((options & ENFORCE_SAFE_MODE) && PG(safe_mode) && (!php_checkuid(path, mode, CHECKUID_CHECK_MODE_PARAM))) return NULL; @@ -1169,16 +1935,17 @@ 0 }; -static php_stream_wrapper *locate_url_wrapper(char *path, char **path_for_open, int options TSRMLS_DC) +PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char **path_for_open, int options TSRMLS_DC) { php_stream_wrapper *wrapper = NULL; const char *p, *protocol = NULL; int n = 0; - *path_for_open = path; + if (path_for_open) + *path_for_open = (char*)path; if (options & IGNORE_URL) - return &php_plain_files_wrapper; + return (options & STREAM_LOCATE_WRAPPERS_ONLY) ? NULL : &php_plain_files_wrapper; for (p = path; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { n++; @@ -1190,7 +1957,7 @@ /* BC with older php scripts and zlib wrapper */ protocol = "compress.zlib"; n = 13; - zend_error(E_WARNING, "Use of \"zlib:\" wrapper is deprecated; please use \"compress.zlib://\" instead."); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Use of \"zlib:\" wrapper is deprecated; please use \"compress.zlib://\" instead."); } if (protocol) { @@ -1201,27 +1968,30 @@ n = sizeof(wrapper_name) - 1; PHP_STRLCPY(wrapper_name, protocol, sizeof(wrapper_name), n); - zend_error(E_NOTICE, "Unable to find the wrapper \"%s\" - did you forget to enable it when you configured PHP?", + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unable to find the wrapper \"%s\" - did you forget to enable it when you configured PHP?", wrapper_name); wrapper = NULL; protocol = NULL; } } + /* TODO: curl based streams probably support file:// properly */ if (!protocol || !strncasecmp(protocol, "file", n)) { if (protocol && path[n+1] == '/' && path[n+2] == '/') { - zend_error(E_WARNING, "remote host file access not supported, %s", path); + if (options & REPORT_ERRORS) + php_error_docref(NULL TSRMLS_CC, E_WARNING, "remote host file access not supported, %s", path); return NULL; } - if (protocol) - *path_for_open = path + n + 1; + if (protocol && path_for_open) + *path_for_open = (char*)path + n + 1; /* fall back on regular file access */ - return &php_plain_files_wrapper; + return (options & STREAM_LOCATE_WRAPPERS_ONLY) ? NULL : &php_plain_files_wrapper; } if (wrapper && wrapper->is_url && !PG(allow_url_fopen)) { - zend_error(E_WARNING, "URL file-access is disabled in the server configuration"); + if (options & REPORT_ERRORS) + php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration"); return NULL; } @@ -1233,7 +2003,7 @@ php_stream_wrapper *wrapper = NULL; char *path_to_open = path; - wrapper = locate_url_wrapper(path, &path_to_open, ENFORCE_SAFE_MODE TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, ENFORCE_SAFE_MODE TSRMLS_CC); if (wrapper && wrapper->wops->url_stat) { return wrapper->wops->url_stat(wrapper, path_to_open, ssb TSRMLS_CC); } @@ -1253,42 +2023,58 @@ path_to_open = path; - wrapper = locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); if (wrapper && wrapper->wops->dir_opener) { stream = wrapper->wops->dir_opener(wrapper, - path_to_open, "r", options, NULL, + path_to_open, "r", options ^ REPORT_ERRORS, NULL, context STREAMS_REL_CC TSRMLS_CC); - if (stream) + if (stream) { stream->wrapper = wrapper; + stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; + } + } else if (wrapper) { + php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC, "not implemented"); } - if (stream == NULL && (options & REPORT_ERRORS)) { - char *tmp = estrdup(path); - char *msg; - - if (wrapper) - msg = strerror(errno); - else - msg = "no suitable wrapper could be found"; - - php_strip_url_passwd(tmp); - zend_error(E_WARNING, "%s(\"%s\") - %s", get_active_function_name(TSRMLS_C), tmp, msg); - efree(tmp); + display_wrapper_errors(wrapper, path, "failed to open dir" TSRMLS_CC); } + tidy_wrapper_error_log(wrapper TSRMLS_CC); + return stream; } /* }}} */ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent TSRMLS_DC) { + if (sizeof(php_stream_dirent) == php_stream_read(dirstream, (char*)ent, sizeof(php_stream_dirent))) return ent; return NULL; } +PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...) +{ + va_list args; + char *buffer = NULL; + + va_start(args, fmt); + vspprintf(&buffer, 0, fmt, args); + va_end(args); + + if (options & REPORT_ERRORS || wrapper == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, buffer); + efree(buffer); + } else { + /* append to stack */ + wrapper->err_stack = erealloc(wrapper->err_stack, (wrapper->err_count + 1) * sizeof(char *)); + if (wrapper->err_stack) + wrapper->err_stack[wrapper->err_count++] = buffer; + } +} + /* {{{ php_stream_open_wrapper_ex */ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) @@ -1296,6 +2082,10 @@ php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; char *path_to_open; +#if ZEND_DEBUG + char *copy_of_path = NULL; +#endif + if (opened_path) *opened_path = NULL; @@ -1305,23 +2095,40 @@ path_to_open = path; - wrapper = locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); if (wrapper) { + + /* prepare error stack */ + wrapper->err_count = 0; + wrapper->err_stack = NULL; + stream = wrapper->wops->stream_opener(wrapper, - path_to_open, mode, options, + path_to_open, mode, options ^ REPORT_ERRORS, opened_path, context STREAMS_REL_CC TSRMLS_CC); if (stream) stream->wrapper = wrapper; } +#if ZEND_DEBUG + if (stream) { + copy_of_path = estrdup(path); + stream->__orig_path = copy_of_path; + } +#endif + if (stream != NULL && (options & STREAM_MUST_SEEK)) { php_stream *newstream; - switch(php_stream_make_seekable_rel(stream, &newstream, PHP_STREAM_NO_PREFERENCE)) { + switch(php_stream_make_seekable_rel(stream, &newstream, + (options & STREAM_WILL_CAST) + ? PHP_STREAM_PREFER_STDIO : PHP_STREAM_NO_PREFERENCE)) { case PHP_STREAM_UNCHANGED: return stream; case PHP_STREAM_RELEASED: +#if ZEND_DEBUG + newstream->__orig_path = copy_of_path; +#endif return newstream; default: php_stream_close(stream); @@ -1329,8 +2136,8 @@ if (options & REPORT_ERRORS) { char *tmp = estrdup(path); php_strip_url_passwd(tmp); - zend_error(E_WARNING, "%s(\"%s\") - could not make seekable - %s", - get_active_function_name(TSRMLS_C), tmp, strerror(errno)); + php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "could not make seekable - %s", + tmp, strerror(errno)); efree(tmp); options ^= REPORT_ERRORS; @@ -1338,18 +2145,13 @@ } } if (stream == NULL && (options & REPORT_ERRORS)) { - char *tmp = estrdup(path); - char *msg; - - if (wrapper) - msg = strerror(errno); - else - msg = "no suitable wrapper could be found"; - - php_strip_url_passwd(tmp); - zend_error(E_WARNING, "%s(\"%s\") - %s", get_active_function_name(TSRMLS_C), tmp, msg); - efree(tmp); + display_wrapper_errors(wrapper, path, "failed to create stream" TSRMLS_CC); } + tidy_wrapper_error_log(wrapper TSRMLS_CC); +#if ZEND_DEBUG + if (stream == NULL && copy_of_path != NULL) + efree(copy_of_path); +#endif return stream; } /* }}} */ @@ -1364,7 +2166,7 @@ if (stream == NULL) return NULL; - + if (php_stream_cast(stream, PHP_STREAM_AS_STDIO|PHP_STREAM_CAST_TRY_HARD|PHP_STREAM_CAST_RELEASE, (void**)&fp, REPORT_ERRORS) == FAILURE) { @@ -1454,33 +2256,38 @@ } PHPAPI int php_stream_context_get_option(php_stream_context *context, - const char *wrappername, const char *optionname, zval **optionvalue) + const char *wrappername, const char *optionname, zval ***optionvalue) { zval **wrapperhash; if (FAILURE == zend_hash_find(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&wrapperhash)) return FAILURE; - - return zend_hash_find(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)&optionvalue); + return zend_hash_find(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)optionvalue); } PHPAPI int php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue) { zval **wrapperhash; + zval *category; if (FAILURE == zend_hash_find(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&wrapperhash)) { - MAKE_STD_ZVAL(*wrapperhash); - array_init(*wrapperhash); - if (FAILURE == zend_hash_update(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)wrapperhash, sizeof(zval *), NULL)) + MAKE_STD_ZVAL(category); + array_init(category); + if (FAILURE == zend_hash_update(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&category, sizeof(zval *), NULL)) return FAILURE; ZVAL_ADDREF(optionvalue); + wrapperhash = &category; } return zend_hash_update(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)&optionvalue, sizeof(zval *), NULL); } +PHPAPI HashTable *php_stream_get_url_stream_wrappers_hash() +{ + return &url_stream_wrappers_hash; +} /* * Local variables: 1.4 +468 -144 php4/main/user_streams.c Index: user_streams.c =================================================================== RCS file: /cvsroot/php-i18n/php4/main/user_streams.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- user_streams.c 9 May 2002 05:39:43 -0000 1.3 +++ user_streams.c 6 Oct 2002 21:54:34 -0000 1.4 @@ -17,10 +17,11 @@ +----------------------------------------------------------------------+ */ -/* $Id: user_streams.c,v 1.16 2002/05/04 17:42:58 sas Exp $ */ +/* $Id: user_streams.c,v 1.26 2002/10/05 10:35:13 wez Exp $ */ #include "php.h" #include "php_globals.h" +#include "ext/standard/file.h" static int le_protocols; @@ -32,12 +33,17 @@ }; static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +static int user_wrapper_stat_url(php_stream_wrapper *wrapper, char *url, php_stream_statbuf *ssb TSRMLS_DC); +static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, char *filename, char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); static php_stream_wrapper_ops user_stream_wops = { user_wrapper_opener, - NULL, - NULL, - NULL + NULL, /* close - the streams themselves know how */ + NULL, /* stat - the streams themselves know how */ + user_wrapper_stat_url, + user_wrapper_opendir, + "user-space" }; @@ -80,42 +86,89 @@ #define USERSTREAM_WRITE "stream_write" #define USERSTREAM_FLUSH "stream_flush" #define USERSTREAM_SEEK "stream_seek" -#define USERSTREAM_GETS "stream_gets" #define USERSTREAM_TELL "stream_tell" #define USERSTREAM_EOF "stream_eof" +#define USERSTREAM_STAT "stream_stat" +#define USERSTREAM_STATURL "url_stat" +#define USERSTREAM_DIR_OPEN "dir_opendir" +#define USERSTREAM_DIR_READ "dir_readdir" +#define USERSTREAM_DIR_REWIND "dir_rewinddir" +#define USERSTREAM_DIR_CLOSE "dir_closedir" -/* class should have methods like these: +/* {{{ class should have methods like these: -function stream_open($path, $mode, $options, &$opened_path) - { - return true/false; - } - function stream_read($count) - { - return false on error; - else return string; - } - function stream_write($data) - { - return false on error; - else return count written; - } - function stream_close() - { - } - function stream_flush() - { - } - function stream_seek($offset, $whence) - { - } - function stream_gets($size) - { - return false on error; - else return string; - } - - * */ + function stream_open($path, $mode, $options, &$opened_path) + { + return true/false; + } + + function stream_read($count) + { + return false on error; + else return string; + } + + function stream_write($data) + { + return false on error; + else return count written; + } + + function stream_close() + { + } + + function stream_flush() + { + return true/false; + } + + function stream_seek($offset, $whence) + { + return true/false; + } + + function stream_tell() + { + return (int)$position; + } + + function stream_eof() + { + return true/false; + } + + function stream_stat() + { + return array( just like that returned by fstat() ); + } + + function url_stat(string $url) + { + return array( just like that returned by stat() ); + } + + function dir_opendir(string $url, int $options) + { + return true / false; + } + + function dir_readdir() + { + return string next filename in dir ; + } + + function dir_closedir() + { + release dir related resources; + } + + function dir_rewinddir() + { + reset to start of dir list; + } + + }}} **/ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { @@ -126,6 +179,13 @@ int call_result; php_stream *stream = NULL; + /* Try to catch bad usage without preventing flexibility */ + if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "infinite recursion prevented"); + return NULL; + } + FG(user_stream_current_filename) = filename; + us = emalloc(sizeof(*us)); us->wrapper = uwrap; @@ -164,7 +224,7 @@ 4, args, 0, NULL TSRMLS_CC); - if (call_result == SUCCESS && zretval != NULL) { + if (call_result == SUCCESS && zretval != NULL && zval_is_true(zretval)) { /* the stream is now open! */ stream = php_stream_alloc_rel(&php_stream_userspace_ops, us, 0, mode); @@ -177,12 +237,15 @@ stream->wrapperdata = us->object; zval_add_ref(&stream->wrapperdata); } else { - /* destroy the object */ - zval_ptr_dtor(&us->object); - efree(us); + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "\"%s::" USERSTREAM_OPEN "\" call failed", + us->wrapper->classname); } /* destroy everything else */ + if (stream == NULL) { + zval_ptr_dtor(&us->object); + efree(us); + } if (zretval) zval_ptr_dtor(&zretval); @@ -192,12 +255,89 @@ zval_ptr_dtor(&zmode); zval_ptr_dtor(&zfilename); + FG(user_stream_current_filename) = NULL; + + return stream; +} + +static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, char *filename, char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) +{ + struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; + php_userstream_data_t *us; + zval *zfilename, *zoptions, *zretval = NULL, *zfuncname; + zval **args[2]; + int call_result; + php_stream *stream = NULL; + + /* Try to catch bad usage without preventing flexibility */ + if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "infinite recursion prevented"); + return NULL; + } + FG(user_stream_current_filename) = filename; + + us = emalloc(sizeof(*us)); + us->wrapper = uwrap; + + /* create an instance of our class */ + ALLOC_ZVAL(us->object); + object_init_ex(us->object, uwrap->ce); + ZVAL_REFCOUNT(us->object) = 1; + PZVAL_IS_REF(us->object) = 1; + + /* call it's dir_open method - set up params first */ + MAKE_STD_ZVAL(zfilename); + ZVAL_STRING(zfilename, filename, 1); + args[0] = &zfilename; + + MAKE_STD_ZVAL(zoptions); + ZVAL_LONG(zoptions, options); + args[1] = &zoptions; + + MAKE_STD_ZVAL(zfuncname); + ZVAL_STRING(zfuncname, USERSTREAM_DIR_OPEN, 1); + + call_result = call_user_function_ex(NULL, + &us->object, + zfuncname, + &zretval, + 2, args, + 0, NULL TSRMLS_CC); + + if (call_result == SUCCESS && zretval != NULL && zval_is_true(zretval)) { + /* the stream is now open! */ + stream = php_stream_alloc_rel(&php_stream_userspace_dir_ops, us, 0, mode); + + /* set wrapper data to be a reference to our object */ + stream->wrapperdata = us->object; + zval_add_ref(&stream->wrapperdata); + } else { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed", + us->wrapper->classname); + } + + /* destroy everything else */ + if (stream == NULL) { + zval_ptr_dtor(&us->object); + efree(us); + } + if (zretval) + zval_ptr_dtor(&zretval); + + zval_ptr_dtor(&zfuncname); + zval_ptr_dtor(&zoptions); + zval_ptr_dtor(&zfilename); + + FG(user_stream_current_filename) = NULL; + return stream; } -/* {{{ proto bool file_register_wrapper(string protocol, string classname) + +/* {{{ proto bool stream_register_wrapper(string protocol, string classname) Registers a custom URL protocol handler class */ -PHP_FUNCTION(file_register_wrapper) +PHP_FUNCTION(stream_register_wrapper) { char *protocol, *classname; int protocol_len, classname_len; @@ -207,11 +347,6 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &protocol, &protocol_len, &classname, &classname_len) == FAILURE) { RETURN_FALSE; } - - if (!PG(allow_url_fopen)) { - zend_error(E_WARNING, "%s(): fopen wrappers have been disabled", get_active_function_name(TSRMLS_C)); - RETURN_FALSE; - } uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap)); uwrap->protoname = estrndup(protocol, protocol_len); @@ -230,7 +365,7 @@ RETURN_TRUE; } } else { - zend_error(E_WARNING, "%s(): class '%s' is undefined", get_active_function_name(TSRMLS_C), + php_error_docref(NULL TSRMLS_CC, E_WARNING, "class '%s' is undefined", classname); } @@ -265,14 +400,18 @@ 1, args, 0, NULL TSRMLS_CC); - if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_LONG) + didwrite = 0; + if (call_result == SUCCESS && retval != NULL) { + convert_to_long(retval); didwrite = Z_LVAL_P(retval); - else - didwrite = 0; + } else if (call_result == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!", + us->wrapper->classname); + } /* don't allow strange buffer overruns due to bogus return */ if (didwrite > count) { - zend_error(E_WARNING, "%s::" USERSTREAM_WRITE " - wrote %d bytes more data than requested (%d written, %d max)", + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_WRITE " wrote %d bytes more data than requested (%d written, %d max)", us->wrapper->classname, didwrite - count, didwrite, count); didwrite = count; @@ -292,56 +431,61 @@ int call_result; size_t didread = 0; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; + zval *zcount; assert(us != NULL); - if (buf == NULL && count == 0) { - ZVAL_STRINGL(&func_name, USERSTREAM_EOF, sizeof(USERSTREAM_EOF)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_READ, sizeof(USERSTREAM_READ)-1, 0); - call_result = call_user_function_ex(NULL, + MAKE_STD_ZVAL(zcount); + ZVAL_LONG(zcount, count); + args[0] = &zcount; + + call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, - 0, NULL, 0, NULL TSRMLS_CC); + 1, args, + 0, NULL TSRMLS_CC); + + if (call_result == SUCCESS && retval != NULL) { + convert_to_string(retval); + didread = Z_STRLEN_P(retval); + if (didread > count) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_READ " - read %d bytes more data than requested (%d read, %d max) - excess data will be lost", + us->wrapper->classname, didread - count, didread, count); + didread = count; + } + if (didread > 0) + memcpy(buf, Z_STRVAL_P(retval), didread); + } else if (call_result == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_READ " is not implemented!", + us->wrapper->classname); + } + zval_ptr_dtor(&zcount); + + if (retval) + zval_ptr_dtor(&retval); - if (call_result == SUCCESS && retval != NULL && zval_is_true(retval)) - didread = 0; - else - didread = EOF; + /* since the user stream has no way of setting the eof flag directly, we need to ask it if we hit eof */ - } else { - zval *zcount; + ZVAL_STRINGL(&func_name, USERSTREAM_EOF, sizeof(USERSTREAM_EOF)-1, 0); - ZVAL_STRINGL(&func_name, USERSTREAM_READ, sizeof(USERSTREAM_READ)-1, 0); + call_result = call_user_function_ex(NULL, + &us->object, + &func_name, + &retval, + 0, NULL, 0, NULL TSRMLS_CC); - MAKE_STD_ZVAL(zcount); - ZVAL_LONG(zcount, count); - args[0] = &zcount; - - call_result = call_user_function_ex(NULL, - &us->object, - &func_name, - &retval, - 1, args, - 0, NULL TSRMLS_CC); - - if (retval && Z_TYPE_P(retval) == IS_STRING) { - didread = Z_STRLEN_P(retval); - if (didread > count) { - zend_error(E_WARNING, "%s::" USERSTREAM_READ " - read %d bytes more data than requested (%d read, %d max) - excess data will be lost", - us->wrapper->classname, didread - count, didread, count); - didread = count; - } - if (didread > 0) - memcpy(buf, Z_STRVAL_P(retval), didread); + if (!(call_result == SUCCESS && retval != NULL && zval_is_true(retval))) { + if (call_result == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_EOF " is not implemented! Assuming EOF", + us->wrapper->classname); } - zval_ptr_dtor(&zcount); + stream->eof = 1; } - - if (retval) - zval_ptr_dtor(&retval); - + return didread; } @@ -399,55 +543,65 @@ return call_result; } -static int php_userstreamop_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC) +static int php_userstreamop_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) { zval func_name; zval *retval = NULL; - int call_result; + int call_result, ret; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; + zval **args[2]; + zval *zoffs, *zwhence; assert(us != NULL); - if (offset == 0 && whence == SEEK_CUR) { - ZVAL_STRINGL(&func_name, USERSTREAM_TELL, sizeof(USERSTREAM_TELL)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_SEEK, sizeof(USERSTREAM_SEEK)-1, 0); - call_result = call_user_function_ex(NULL, + MAKE_STD_ZVAL(zoffs); + ZVAL_LONG(zoffs, offset); + args[0] = &zoffs; + + MAKE_STD_ZVAL(zwhence); + ZVAL_LONG(zwhence, whence); + args[1] = &zwhence; + + call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, - 0, NULL, 0, NULL TSRMLS_CC); + 2, args, + 0, NULL TSRMLS_CC); + zval_ptr_dtor(&zoffs); + zval_ptr_dtor(&zwhence); + if (call_result == FAILURE) { + /* stream_seek is not implemented, so disable seeks for this stream */ + stream->flags |= PHP_STREAM_FLAG_NO_SEEK; + /* there should be no retval to clean up */ + return -1; + } else if (call_result == SUCCESS && retval != NULL && zval_is_true(retval)) { + ret = 0; } else { - zval **args[2]; - zval *zoffs, *zwhence; - - ZVAL_STRINGL(&func_name, USERSTREAM_SEEK, sizeof(USERSTREAM_SEEK)-1, 0); + ret = -1; + } - MAKE_STD_ZVAL(zoffs); - ZVAL_LONG(zoffs, offset); - args[0] = &zoffs; - - MAKE_STD_ZVAL(zwhence); - ZVAL_LONG(zwhence, whence); - args[1] = &zwhence; - - call_result = call_user_function_ex(NULL, - &us->object, - &func_name, - &retval, - 2, args, - 0, NULL TSRMLS_CC); + if (retval) + zval_ptr_dtor(&retval); - zval_ptr_dtor(&zoffs); - zval_ptr_dtor(&zwhence); + /* now determine where we are */ + ZVAL_STRINGL(&func_name, USERSTREAM_TELL, sizeof(USERSTREAM_TELL)-1, 0); - } + call_result = call_user_function_ex(NULL, + &us->object, + &func_name, + &retval, + 0, NULL, 0, NULL TSRMLS_CC); if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_LONG) - call_result = Z_LVAL_P(retval); + *newoffs = Z_LVAL_P(retval); else - call_result = -1; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", + us->wrapper->classname); if (retval) zval_ptr_dtor(&retval); @@ -455,61 +609,231 @@ return 0; } -static char *php_userstreamop_gets(php_stream *stream, char *buf, size_t size TSRMLS_DC) + +/* parse the return value from one of the stat functions and store the + * relevant fields into the statbuf provided */ +static int statbuf_from_array(zval *array, php_stream_statbuf *ssb TSRMLS_DC) +{ + zval *elem; + +#define STAT_PROP_ENTRY(name) \ + if (SUCCESS == zend_hash_find(Z_ARRVAL_P(array), #name, sizeof(#name), (void**)&elem)) { \ + convert_to_long(elem); \ + ssb->sb.st_##name = Z_LVAL_P(elem); \ + } + + STAT_PROP_ENTRY(dev); + STAT_PROP_ENTRY(ino); + STAT_PROP_ENTRY(mode); + STAT_PROP_ENTRY(nlink); + STAT_PROP_ENTRY(uid); + STAT_PROP_ENTRY(gid); +#if HAVE_ST_RDEV + STAT_PROP_ENTRY(rdev); +#endif + STAT_PROP_ENTRY(size); + STAT_PROP_ENTRY(atime); + STAT_PROP_ENTRY(mtime); + STAT_PROP_ENTRY(ctime); +#ifdef HAVE_ST_BLKSIZE + STAT_PROP_ENTRY(blksize); +#endif +#ifdef HAVE_ST_BLOCKS + STAT_PROP_ENTRY(blocks); +#endif + +#undef STAT_PROP_ENTRY + return SUCCESS; +} + +static int php_userstreamop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) { zval func_name; zval *retval = NULL; - zval *zcount; - zval **args[2]; - size_t didread = 0; + int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; + int ret = -1; - assert(us != NULL); + ZVAL_STRINGL(&func_name, USERSTREAM_STAT, sizeof(USERSTREAM_STAT)-1, 0); + + call_result = call_user_function_ex(NULL, + &us->object, + &func_name, + &retval, + 0, NULL, 0, NULL TSRMLS_CC); - /* TODO: when the gets method is not available, fall back on emulated version using read */ + if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_ARRAY) { + if (SUCCESS == statbuf_from_array(retval, ssb TSRMLS_CC)) + ret = 0; + } else { + if (call_result == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_STAT " is not implemented!", + us->wrapper->classname); + } + } + return ret; +} + +static int user_wrapper_stat_url(php_stream_wrapper *wrapper, char *url, php_stream_statbuf *ssb TSRMLS_DC) +{ + struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; + zval *zfilename, *zfuncname, *zretval; + zval **args[1]; + int call_result; + zval *object; + int ret = -1; + + /* create an instance of our class */ + ALLOC_ZVAL(object); + object_init_ex(object, uwrap->ce); + ZVAL_REFCOUNT(object) = 1; + PZVAL_IS_REF(object) = 1; + + /* call the stat_url method */ - ZVAL_STRINGL(&func_name, USERSTREAM_GETS, sizeof(USERSTREAM_GETS)-1, 0); + /* call it's stream_open method - set up params first */ + MAKE_STD_ZVAL(zfilename); + ZVAL_STRING(zfilename, url, 1); + args[0] = &zfilename; - MAKE_STD_ZVAL(zcount); - ZVAL_LONG(zcount, size); - args[0] = &zcount; + MAKE_STD_ZVAL(zfuncname); + ZVAL_STRING(zfuncname, USERSTREAM_STATURL, 1); + + call_result = call_user_function_ex(NULL, + &object, + zfuncname, + &zretval, + 1, args, + 0, NULL TSRMLS_CC); + + if (call_result == SUCCESS && zretval != NULL && Z_TYPE_P(zretval) == IS_ARRAY) { + /* We got the info we needed */ + if (SUCCESS == statbuf_from_array(zretval, ssb TSRMLS_CC)) + ret = 0; + } else { + if (call_result == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_STATURL " is not implemented!", + uwrap->classname); + } + } + + /* clean up */ + zval_ptr_dtor(&object); + if (zretval) + zval_ptr_dtor(&zretval); + + zval_ptr_dtor(&zfuncname); + zval_ptr_dtor(&zfilename); + + return ret; - call_user_function_ex(NULL, +} + +static size_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t count TSRMLS_DC) +{ + zval func_name; + zval *retval = NULL; + int call_result; + size_t didread = 0; + php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; + php_stream_dirent *ent = (php_stream_dirent*)buf; + + /* avoid problems if someone mis-uses the stream */ + if (count != sizeof(php_stream_dirent)) + return 0; + + ZVAL_STRINGL(&func_name, USERSTREAM_DIR_READ, sizeof(USERSTREAM_DIR_READ)-1, 0); + + call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, - 1, args, + 0, NULL, 0, NULL TSRMLS_CC); - if (retval && Z_TYPE_P(retval) == IS_STRING) { - didread = Z_STRLEN_P(retval); - if (didread > size) { - zend_error(E_WARNING, "%s::" USERSTREAM_GETS " - read more data than requested; some data will be lost", - us->wrapper->classname); - didread = size; - } - if (didread > 0) - memcpy(buf, Z_STRVAL_P(retval), didread); + if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) != IS_BOOL) { + convert_to_string(retval); + PHP_STRLCPY(ent->d_name, Z_STRVAL_P(retval), sizeof(ent->d_name), Z_STRLEN_P(retval)); + + didread = sizeof(php_stream_dirent); + } else if (call_result == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_DIR_READ " is not implemented!", + us->wrapper->classname); + } + if (retval) zval_ptr_dtor(&retval); - } + + return didread; +} + +static int php_userstreamop_closedir(php_stream *stream, int close_handle TSRMLS_DC) +{ + zval func_name; + zval *retval = NULL; + php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; + + assert(us != NULL); + + ZVAL_STRINGL(&func_name, USERSTREAM_DIR_CLOSE, sizeof(USERSTREAM_DIR_CLOSE)-1, 0); + + call_user_function_ex(NULL, + &us->object, + &func_name, + &retval, + 0, NULL, 0, NULL TSRMLS_CC); if (retval) - zval_ptr_dtor(&zcount); + zval_ptr_dtor(&retval); + + zval_ptr_dtor(&us->object); + + efree(us); + + return 0; +} + +static int php_userstreamop_rewinddir(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) +{ + zval func_name; + zval *retval = NULL; + php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; - if (didread) - return buf; + ZVAL_STRINGL(&func_name, USERSTREAM_DIR_REWIND, sizeof(USERSTREAM_DIR_REWIND)-1, 0); + + call_user_function_ex(NULL, + &us->object, + &func_name, + &retval, + 0, NULL, 0, NULL TSRMLS_CC); + if (retval) + zval_ptr_dtor(&retval); + return 0; + } php_stream_ops php_stream_userspace_ops = { php_userstreamop_write, php_userstreamop_read, php_userstreamop_close, php_userstreamop_flush, "user-space", - php_userstreamop_seek, php_userstreamop_gets, + php_userstreamop_seek, + NULL, /* cast */ + php_userstreamop_stat, /* stat */ + NULL /* set_option */ +}; + +php_stream_ops php_stream_userspace_dir_ops = { + NULL, /* write */ + php_userstreamop_readdir, + php_userstreamop_closedir, + NULL, /* flush */ + "user-space-dir", + php_userstreamop_rewinddir, NULL, /* cast */ - NULL /* stat */ + NULL, /* stat */ + NULL /* set_option */ }; 1.3 +1 -1 php4/main/win95nt.h Index: win95nt.h =================================================================== RCS file: /cvsroot/php-i18n/php4/main/win95nt.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- win95nt.h 29 Apr 2002 02:33:38 -0000 1.2 +++ win95nt.h 6 Oct 2002 21:54:34 -0000 1.3 @@ -41,7 +41,7 @@ #define M_PI_4 0.78539816339744830962 #endif -#if !PHP_DEBUG +#if !defined(PHP_DEBUG) #ifdef inline #undef inline #endif 1.6 +62 -18 php4/sapi/cgi/cgi_main.c Index: cgi_main.c =================================================================== RCS file: /cvsroot/php-i18n/php4/sapi/cgi/cgi_main.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- cgi_main.c 2 Aug 2002 22:05:26 -0000 1.5 +++ cgi_main.c 6 Oct 2002 21:54:35 -0000 1.6 @@ -201,12 +201,35 @@ } -static void sapi_cgi_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC) +static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) { - if (sapi_header) { - PHPWRITE_H(sapi_header->header, sapi_header->header_len); + char buf[1024]; + int len; + sapi_header_struct *h; + zend_llist_position pos; + + len = sprintf(buf, "Status: %d\r\n", SG(sapi_headers).http_response_code); + PHPWRITE_H(buf, len); + + if (SG(sapi_headers).send_default_content_type) { + char *hd; + + hd = sapi_get_default_content_type(TSRMLS_C); + PHPWRITE_H("Content-type: ", sizeof("Content-type: ")-1); + PHPWRITE_H(hd, strlen(hd)); + PHPWRITE_H("\r\n", 2); + efree(hd); + } + + h = zend_llist_get_first_ex(&sapi_headers->headers, &pos); + while (h) { + PHPWRITE_H(h->header, h->header_len); + PHPWRITE_H("\r\n", 2); + h = zend_llist_get_next_ex(&sapi_headers->headers, &pos); } PHPWRITE_H("\r\n", 2); + + return SAPI_HEADER_SENT_SUCCESSFULLY; } @@ -273,6 +296,15 @@ } +static int php_cgi_startup(sapi_module_struct *sapi_module) +{ + if (php_module_startup(sapi_module, NULL, 0)==FAILURE) { + return FAILURE; + } + return SUCCESS; +} + + /* {{{ sapi_module_struct cgi_sapi_module */ static sapi_module_struct cgi_sapi_module = { @@ -283,7 +315,7 @@ "CGI", /* pretty name */ #endif - php_module_startup, /* startup */ + php_cgi_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ NULL, /* activate */ @@ -297,8 +329,8 @@ php_error, /* error handler */ NULL, /* header handler */ - NULL, /* send headers handler */ - sapi_cgi_send_header, /* send header handler */ + sapi_cgi_send_headers, /* send headers handler */ + NULL, /* send header handler */ sapi_cgi_read_post, /* read POST data */ sapi_cgi_read_cookies, /* read Cookies */ @@ -568,7 +600,7 @@ cgi_sapi_module.executable_location = argv[0]; /* startup after we get the above ini override se we get things right */ - if (php_module_startup(&cgi_sapi_module)==FAILURE) { + if (php_module_startup(&cgi_sapi_module, NULL, 0)==FAILURE) { #ifdef ZTS tsrm_shutdown(); #endif @@ -1020,11 +1052,8 @@ switch (behavior) { case PHP_MODE_STANDARD: - if (php_execute_script(&file_handle TSRMLS_CC)) { - exit_status = EG(exit_status); - } else { - exit_status = 255; - } + php_execute_script(&file_handle TSRMLS_CC); + exit_status = EG(exit_status); break; case PHP_MODE_LINT: PG(during_request_startup) = 0; @@ -1065,13 +1094,24 @@ #endif } - if (SG(request_info).path_translated) { - persist_alloc(SG(request_info).path_translated); - } - - php_request_shutdown((void *) 0); + { + char *path_translated; + + /* Go through this trouble so that the memory manager doesn't warn + * about SG(request_info).path_translated leaking + */ + if (SG(request_info).path_translated) { + path_translated = strdup(SG(request_info).path_translated); + STR_FREE(SG(request_info).path_translated); + SG(request_info).path_translated = path_translated; + } + + php_request_shutdown((void *) 0); - STR_FREE(SG(request_info).path_translated); + if (SG(request_info).path_translated) { + free(SG(request_info).path_translated); + } + } #ifdef PHP_FASTCGI if (!fastcgi) break; @@ -1103,6 +1143,10 @@ #ifdef ZTS tsrm_shutdown(); +#endif + +#if PHP_WIN32 && ZEND_DEBUG && 0 + _CrtDumpMemoryLeaks( ); #endif return exit_status; 1.3 +17 -3 php4/sapi/cli/config.m4 Index: config.m4 =================================================================== RCS file: /cvsroot/php-i18n/php4/sapi/cli/config.m4,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- config.m4 29 Apr 2002 02:33:45 -0000 1.2 +++ config.m4 6 Oct 2002 21:54:35 -0000 1.3 @@ -1,11 +1,12 @@ dnl -dnl $Id: config.m4,v 1.5 2002/04/14 03:57:59 sniper Exp $ +dnl $Id: config.m4,v 1.11 2002/09/29 16:22:48 sas Exp $ dnl AC_MSG_CHECKING(for CLI build) AC_ARG_ENABLE(cli, -[ --disable-cli Disable building CLI version of PHP.], +[ --disable-cli Disable building CLI version of PHP + (this forces --without-pear).], [ PHP_SAPI_CLI=$enableval ],[ @@ -13,7 +14,20 @@ ]) if test "$PHP_SAPI_CLI" != "no"; then - INSTALL_CLI="\$(INSTALL) -m 0755 sapi/cli/php \$(INSTALL_ROOT)\$(bindir)/php" + PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/cli/Makefile.frag) + SAPI_CLI_PATH=sapi/cli/php + PHP_SUBST(SAPI_CLI_PATH) + + case $host_alias in + *darwin*) + BUILD_CLI="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_CLI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + ;; + *) + BUILD_CLI="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_CLI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_CLI_PATH)" + ;; + esac + INSTALL_CLI="\$(INSTALL) -m 0755 \$(SAPI_CLI_PATH) \$(INSTALL_ROOT)\$(bindir)/php" + PHP_SUBST(BUILD_CLI) PHP_SUBST(INSTALL_CLI) else PHP_DISABLE_CLI 1.5 +106 -34 php4/sapi/cli/php_cli.c Index: php_cli.c =================================================================== RCS file: /cvsroot/php-i18n/php4/sapi/cli/php_cli.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- php_cli.c 2 Aug 2002 22:05:26 -0000 1.4 +++ php_cli.c 6 Oct 2002 21:54:35 -0000 1.5 @@ -148,6 +148,8 @@ } } +static char *php_self = ""; +static char *script_filename = ""; static void sapi_cli_register_variables(zval *track_vars_array TSRMLS_DC) { @@ -157,7 +159,13 @@ php_import_environment_variables(track_vars_array TSRMLS_CC); /* Build the special-case PHP_SELF variable for the CLI version */ - /* php_register_variable("PHP_SELF", SG(request_info).argv[0], track_vars_array TSRMLS_CC);*/ + php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC); + php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC); + /* filenames are empty for stdin */ + php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC); + php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC); + /* just make it available */ + php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC); } @@ -192,13 +200,23 @@ PHPWRITE_H("\r\n", 2); } + +static int php_cli_startup(sapi_module_struct *sapi_module) +{ + if (php_module_startup(sapi_module, NULL, 0)==FAILURE) { + return FAILURE; + } + return SUCCESS; +} + + /* {{{ sapi_module_struct cli_sapi_module */ static sapi_module_struct cli_sapi_module = { "cli", /* name */ "Command Line Interface", /* pretty name */ - php_module_startup, /* startup */ + php_cli_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ NULL, /* activate */ @@ -296,6 +314,55 @@ efree(*arg); } +static void cli_register_file_handles(TSRMLS_D) +{ + zval *zin, *zout, *zerr; + php_stream *s_in, *s_out, *s_err; + php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL; + zend_constant ic, oc, ec; + + MAKE_STD_ZVAL(zin); + MAKE_STD_ZVAL(zout); + MAKE_STD_ZVAL(zerr); + + s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in); + s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out); + s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err); + + if (s_in==NULL || s_out==NULL || s_err==NULL) { + return; + } + + php_stream_to_zval(s_in, zin); + php_stream_to_zval(s_out, zout); + php_stream_to_zval(s_err, zerr); + + ic.value = *zin; + zval_copy_ctor(&ic.value); + ic.flags = CONST_CS | CONST_PERSISTENT; + ic.name = zend_strndup("STDIN", 6); + ic.name_len = 6; + zend_register_constant(&ic TSRMLS_CC); + + oc.value = *zout; + zval_copy_ctor(&oc.value); + oc.flags = CONST_CS | CONST_PERSISTENT; + oc.name = zend_strndup("STDOUT", 7); + oc.name_len = 7; + zend_register_constant(&oc TSRMLS_CC); + + ec.value = *zerr; + zval_copy_ctor(&ec.value); + ec.flags = CONST_CS | CONST_PERSISTENT; + ec.name = zend_strndup("STDERR", 7); + ec.name_len = 7; + zend_register_constant(&ec TSRMLS_CC); + + FREE_ZVAL(zin); + FREE_ZVAL(zout); + FREE_ZVAL(zerr); +} + /* {{{ main */ int main(int argc, char *argv[]) @@ -364,7 +431,7 @@ cli_sapi_module.executable_location = argv[0]; /* startup after we get the above ini override se we get things right */ - if (php_module_startup(&cli_sapi_module)==FAILURE) { + if (php_module_startup(&cli_sapi_module, NULL, 0)==FAILURE) { return FAILURE; } @@ -402,6 +469,8 @@ zend_alter_ini_entry("implicit_flush", 15, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); + zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */ + while ((c = ap_php_getopt(argc, argv, OPTSTRING)) != -1) { switch (c) { @@ -561,39 +630,15 @@ script_file=argv[ap_php_optind]; ap_php_optind++; } - /* before registering argv to modulule exchange the *new* argv[0] */ - /* we can achieve this without allocating more memory */ - SG(request_info).argc=argc-ap_php_optind+1; - arg_excp = argv+ap_php_optind-1; - arg_free = argv[ap_php_optind-1]; - if (script_file) { - argv[ap_php_optind-1] = script_file; - } else { - argv[ap_php_optind-1] = "-"; /* should be stdin */ - } - SG(request_info).argv=argv+ap_php_optind-1; - - if (php_request_startup(TSRMLS_C)==FAILURE) { - php_module_shutdown(TSRMLS_C); - *arg_excp = arg_free; - return FAILURE; - } - *arg_excp = arg_free; /* reconstuct argv */ - if (no_headers) { - SG(headers_sent) = 1; - SG(request_info).no_headers = 1; - } if (script_file) { if (!(file_handle.handle.fp = VCWD_FOPEN(script_file, "rb"))) { SG(headers_sent) = 1; SG(request_info).no_headers = 1; PUTS("Could not open input file.\n"); - php_request_shutdown((void *) 0); - php_module_shutdown(TSRMLS_C); return FAILURE; } - php_register_variable("PHP_SELF", script_file, NULL TSRMLS_CC); file_handle.filename = script_file; + script_filename = script_file; /* #!php support */ c = fgetc(file_handle.handle.fp); if (c == '#') { @@ -605,13 +650,38 @@ rewind(file_handle.handle.fp); } } else { - php_register_variable("PHP_SELF", "-", NULL TSRMLS_CC); file_handle.filename = "-"; file_handle.handle.fp = stdin; } file_handle.type = ZEND_HANDLE_FP; file_handle.opened_path = NULL; file_handle.free_filename = 0; + php_self = file_handle.filename; + + /* before registering argv to modulule exchange the *new* argv[0] */ + /* we can achieve this without allocating more memory */ + SG(request_info).argc=argc-ap_php_optind+1; + arg_excp = argv+ap_php_optind-1; + arg_free = argv[ap_php_optind-1]; + SG(request_info).path_translated = file_handle.filename; + argv[ap_php_optind-1] = file_handle.filename; + SG(request_info).argv=argv+ap_php_optind-1; + + if (php_request_startup(TSRMLS_C)==FAILURE) { + *arg_excp = arg_free; + fclose(file_handle.handle.fp); + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + php_request_shutdown((void *) 0); + php_module_shutdown(TSRMLS_C); + PUTS("Could not startup.\n"); + return FAILURE; + } + *arg_excp = arg_free; /* reconstuct argv */ + if (no_headers) { + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + } /* This actually destructs the elements of the list - ugly hack */ zend_llist_apply(&global_vars, (llist_apply_func_t) php_register_command_line_global_vars TSRMLS_CC); @@ -619,11 +689,11 @@ switch (behavior) { case PHP_MODE_STANDARD: - if (php_execute_script(&file_handle TSRMLS_CC)) { - exit_status = EG(exit_status); - } else { - exit_status = 255; + if (strcmp(file_handle.filename, "-")) { + cli_register_file_handles(TSRMLS_C); } + php_execute_script(&file_handle TSRMLS_CC); + exit_status = EG(exit_status); break; case PHP_MODE_LINT: PG(during_request_startup) = 0; @@ -663,9 +733,11 @@ break; #endif case PHP_MODE_CLI_DIRECT: + cli_register_file_handles(TSRMLS_C); if (zend_eval_string(exec_direct, NULL, "Command line code" TSRMLS_CC) == FAILURE) { exit_status=254; } + break; } php_request_shutdown((void *) 0); @@ -675,7 +747,7 @@ } } zend_catch { - exit_status = 255; + exit_status = EG(exit_status); } zend_end_try(); php_module_shutdown(TSRMLS_C);