]> granicus.if.org Git - php/commitdiff
Fixed #70157 parse_ini_string() segmentation fault with INI_SCANNER_TYPED
authorTjerk Meesters <datibbaw@php.net>
Sat, 15 Aug 2015 06:44:07 +0000 (14:44 +0800)
committerTjerk Meesters <datibbaw@php.net>
Sat, 15 Aug 2015 07:10:34 +0000 (15:10 +0800)
Zend/zend_ini_parser.y
ext/standard/basic_functions.c
ext/standard/tests/general_functions/bug70157.phpt [new file with mode: 0644]

index 952ef9c506475361aa3626b74fcbec409b8fae02..22b92db03340ede1a2ed0afd2c9481c51348932f 100644 (file)
@@ -108,7 +108,18 @@ static void zend_ini_init_string(zval *result)
 */
 static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
 {
-       int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
+       int length;
+
+       if (Z_TYPE_P(op1) != IS_STRING) {
+               zval copy;
+               MAKE_COPY_ZVAL(&op1, &copy);
+               convert_to_string(&copy);
+               Z_STRVAL_P(op1) = zend_strndup(Z_STRVAL(copy), Z_STRLEN(copy));
+               Z_STRLEN_P(op1) = Z_STRLEN(copy);
+               zval_dtor(&copy);
+       }
+
+       length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
 
        Z_STRVAL_P(result) = (char *) realloc(Z_STRVAL_P(op1), length+1);
        memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
@@ -213,7 +224,7 @@ ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_erro
        zend_file_handle_dtor(fh TSRMLS_CC);
 
        shutdown_ini_scanner(TSRMLS_C);
-       
+
        if (retval == 0) {
                return SUCCESS;
        } else {
@@ -303,7 +314,11 @@ statement:
 #endif
                        ZEND_INI_PARSER_CB(&$1, &$5, &$2, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
                        free(Z_STRVAL($1));
-                       free(Z_STRVAL($2));
+                       if (Z_TYPE($2) == IS_STRING) {
+                               free(Z_STRVAL($2));
+                       } else {
+                               zval_dtor(&$2);
+                       }
                        zval_internal_dtor(&$5);
                }
        |       TC_LABEL        { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); free(Z_STRVAL($1)); }
index 07348a23f74756c89bb5a08fdf4724890d0e100d..1abe3e60abbbfd96f3ccc0b891edbc5154ac73eb 100644 (file)
@@ -3515,7 +3515,7 @@ PHPAPI double php_get_inf(void) /* {{{ */
 
 #define BASIC_ADD_SUBMODULE(module) \
        zend_hash_add_empty_element(&basic_submodules, #module, strlen(#module));
-       
+
 #define BASIC_RINIT_SUBMODULE(module) \
        if (zend_hash_exists(&basic_submodules, #module, strlen(#module))) { \
                PHP_RINIT(module)(INIT_FUNC_ARGS_PASSTHRU); \
@@ -5903,10 +5903,11 @@ static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int cal
                        ALLOC_ZVAL(element);
                        MAKE_COPY_ZVAL(&arg2, element);
 
-                       if (arg3 && Z_STRLEN_P(arg3) > 0) {
-                               add_assoc_zval_ex(hash, Z_STRVAL_P(arg3), Z_STRLEN_P(arg3) + 1, element);
-                       } else {
+                       if (!arg3 || (Z_TYPE_P(arg3) == IS_STRING && Z_STRLEN_P(arg3) == 0)) {
                                add_next_index_zval(hash, element);
+                       } else {
+                               array_set_zval_key(Z_ARRVAL_P(hash), arg3, element);
+                               zval_ptr_dtor(&element);
                        }
                }
                break;
diff --git a/ext/standard/tests/general_functions/bug70157.phpt b/ext/standard/tests/general_functions/bug70157.phpt
new file mode 100644 (file)
index 0000000..f593682
--- /dev/null
@@ -0,0 +1,29 @@
+--TEST--
+parse_ini_string() crashes on values starting with number or unquoted strings
+--FILE--
+<?php
+
+$contents = <<<EOS
+[agatha.christie]
+title = 10 little indians
+foo[123] = E_ALL & ~E_DEPRECATED
+foo[456] = 123
+EOS;
+
+var_dump(parse_ini_string($contents, false, INI_SCANNER_TYPED));
+
+?>
+Done
+--EXPECTF--
+array(%d) {
+  ["title"]=>
+  string(%d) "10 little indians"
+  ["foo"]=>
+  array(%d) {
+    [123]=>
+    string(%d) "24575"
+    [456]=>
+    int(123)
+  }
+}
+Done