summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--Zend/zend_exceptions.c8
-rw-r--r--Zend/zend_exceptions.h8
-rw-r--r--ext/dba/dba.c25
-rw-r--r--ext/dba/tests/bug65708.phpt38
-rw-r--r--ext/opcache/ZendAccelerator.c16
-rw-r--r--ext/opcache/ZendAccelerator.h1
-rw-r--r--ext/opcache/zend_accelerator_module.c47
8 files changed, 132 insertions, 19 deletions
diff --git a/NEWS b/NEWS
index aa3f8d2125..bdc0cd5fb6 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,10 @@ PHP NEWS
. Fixed bug #65548 (Comparison for DateTimeImmutable doesn't work).
(Boro Sitnikovski)
+- DBA extension:
+ . Fixed bug #65708 (dba functions cast $key param to string in-place,
+ bypassing copy on write). (Adam)
+
- GD
. Ensure that the defined interpolation method is used with the generic
scaling methods. (Pierre)
@@ -22,9 +26,13 @@ PHP NEWS
imap). (ryotakatsuki at gmail dot com)
- OPcache:
+ . Added function opcache_compile_file() to load PHP scripts into cache
+ without execution. (Julien)
. Fixed bug #65665 (Exception not properly caught when opcache enabled).
(Laruence)
. Fixed bug #65510 (5.5.2 crashes in _get_zval_ptr_ptr_var). (Dmitry)
+ . Fixed issue #135 (segfault in interned strings if initial memory is too
+ low). (Julien)
- SPL:
. Fix bug #64782 (SplFileObject constructor make $context optional / give it
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index 14ae75e38d..c7f157c4d5 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -560,7 +560,7 @@ ZEND_METHOD(exception, getPrevious)
RETURN_ZVAL(previous, 1, 0);
}
-int zend_spprintf(char **message, int max_len, char *format, ...) /* {{{ */
+int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ */
{
va_list arg;
int len;
@@ -732,7 +732,7 @@ ZEND_API zend_class_entry *zend_get_error_exception(TSRMLS_D) /* {{{ */
}
/* }}} */
-ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC) /* {{{ */
+ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC) /* {{{ */
{
zval *ex;
@@ -760,7 +760,7 @@ ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, char *messa
}
/* }}} */
-ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...) /* {{{ */
+ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...) /* {{{ */
{
va_list arg;
char *message;
@@ -775,7 +775,7 @@ ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long cod
}
/* }}} */
-ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, char *message, long code, int severity TSRMLS_DC) /* {{{ */
+ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC) /* {{{ */
{
zval *ex = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
zend_update_property_long(default_exception_ce, ex, "severity", sizeof("severity")-1, severity TSRMLS_CC);
diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h
index 82633530d6..81c8a1f213 100644
--- a/Zend/zend_exceptions.h
+++ b/Zend/zend_exceptions.h
@@ -40,12 +40,12 @@ ZEND_API void zend_register_default_classes(TSRMLS_D);
/* exception_ce NULL or zend_exception_get_default() or a derived class
* message NULL or the message of the exception */
-ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC);
-ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...);
+ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC);
+ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...);
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC);
ZEND_API void zend_clear_exception(TSRMLS_D);
-ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, char *message, long code, int severity TSRMLS_DC);
+ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC);
extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
@@ -53,7 +53,7 @@ extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC);
/* do not export, in php it's available thru spprintf directly */
-int zend_spprintf(char **message, int max_len, char *format, ...);
+int zend_spprintf(char **message, int max_len, const char *format, ...);
END_EXTERN_C()
diff --git a/ext/dba/dba.c b/ext/dba/dba.c
index 8005101de3..50a94dd2ad 100644
--- a/ext/dba/dba.c
+++ b/ext/dba/dba.c
@@ -226,12 +226,17 @@ static size_t php_dba_make_key(zval *key, char **key_str, char **key_free TSRMLS
*key_free = *key_str;
return len;
} else {
- *key_free = NULL;
+ zval tmp = *key;
+ int len;
- convert_to_string(key);
- *key_str = Z_STRVAL_P(key);
+ zval_copy_ctor(&tmp);
+ convert_to_string(&tmp);
- return Z_STRLEN_P(key);
+ *key_free = *key_str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp));
+ len = Z_STRLEN(tmp);
+
+ zval_dtor(&tmp);
+ return len;
}
}
/* }}} */
@@ -297,6 +302,14 @@ static size_t php_dba_make_key(zval *key, char **key_str, char **key_free TSRMLS
RETURN_FALSE; \
}
+/* the same check, but with a call to DBA_ID_DONE before returning */
+#define DBA_WRITE_CHECK_WITH_ID \
+ if(info->mode != DBA_WRITER && info->mode != DBA_TRUNC && info->mode != DBA_CREAT) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "You cannot perform a modification to a database without proper access"); \
+ DBA_ID_DONE; \
+ RETURN_FALSE; \
+ }
+
/* }}} */
/* {{{ globals */
@@ -557,7 +570,7 @@ static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode)
DBA_FETCH_RESOURCE(info, &id);
- DBA_WRITE_CHECK;
+ DBA_WRITE_CHECK_WITH_ID;
if (info->hnd->update(info, key_str, key_len, val, val_len, mode TSRMLS_CC) == SUCCESS) {
DBA_ID_DONE;
@@ -1110,7 +1123,7 @@ PHP_FUNCTION(dba_delete)
{
DBA_ID_GET2;
- DBA_WRITE_CHECK;
+ DBA_WRITE_CHECK_WITH_ID;
if(info->hnd->delete(info, key_str, key_len TSRMLS_CC) == SUCCESS)
{
diff --git a/ext/dba/tests/bug65708.phpt b/ext/dba/tests/bug65708.phpt
new file mode 100644
index 0000000000..b77138f6ed
--- /dev/null
+++ b/ext/dba/tests/bug65708.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Bug #65708 (dba functions cast $key param to string in-place, bypassing copy on write)
+--SKIPIF--
+<?php
+ require_once(dirname(__FILE__) .'/skipif.inc');
+?>
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+require_once(dirname(__FILE__) .'/test.inc');
+
+$db = dba_popen($db_filename, 'c');
+
+$key = 1;
+$copy = $key;
+
+echo gettype($key)."\n";
+echo gettype($copy)."\n";
+
+dba_exists($key, $db);
+
+echo gettype($key)."\n";
+echo gettype($copy)."\n";
+
+dba_close($db);
+
+?>
+--CLEAN--
+<?php
+ require(dirname(__FILE__) .'/clean.inc');
+?>
+--EXPECT--
+integer
+integer
+integer
+integer
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 827f047cd4..72b5a1b9fe 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -1446,7 +1446,7 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han
}
/* zend_compile() replacement */
-static zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
+zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
{
zend_persistent_script *persistent_script = NULL;
char *key = NULL;
@@ -2407,14 +2407,14 @@ static inline int accel_find_sapi(TSRMLS_D)
return FAILURE;
}
-static void zend_accel_init_shm(TSRMLS_D)
+static int zend_accel_init_shm(TSRMLS_D)
{
zend_shared_alloc_lock(TSRMLS_C);
accel_shared_globals = zend_shared_alloc(sizeof(zend_accel_shared_globals));
if (!accel_shared_globals) {
zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
- return;
+ return FAILURE;
}
ZSMMG(app_shared_globals) = accel_shared_globals;
@@ -2429,7 +2429,8 @@ static void zend_accel_init_shm(TSRMLS_D)
ZCSG(interned_strings).arBuckets = zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(Bucket *));
ZCSG(interned_strings_start) = zend_shared_alloc((ZCG(accel_directives).interned_strings_buffer * 1024 * 1024));
if (!ZCSG(interned_strings).arBuckets || !ZCSG(interned_strings_start)) {
- zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " cannot allocate buffer for interned strings");
+ zend_accel_error(ACCEL_LOG_FATAL, ACCELERATOR_PRODUCT_NAME " cannot allocate buffer for interned strings");
+ return FAILURE;
}
ZCSG(interned_strings_end) = ZCSG(interned_strings_start) + (ZCG(accel_directives).interned_strings_buffer * 1024 * 1024);
ZCSG(interned_strings_top) = ZCSG(interned_strings_start);
@@ -2468,6 +2469,8 @@ static void zend_accel_init_shm(TSRMLS_D)
ZCSG(restart_in_progress) = 0;
zend_shared_alloc_unlock(TSRMLS_C);
+
+ return SUCCESS;
}
static void accel_globals_ctor(zend_accel_globals *accel_globals TSRMLS_DC)
@@ -2525,7 +2528,10 @@ static int accel_startup(zend_extension *extension)
/********************************************/
switch (zend_shared_alloc_startup(ZCG(accel_directives).memory_consumption)) {
case ALLOC_SUCCESS:
- zend_accel_init_shm(TSRMLS_C);
+ if (zend_accel_init_shm(TSRMLS_C) == FAILURE) {
+ accel_startup_ok = 0;
+ return FAILURE;
+ }
break;
case ALLOC_FAILURE:
accel_startup_ok = 0;
diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h
index 361b60b08f..f223f126e4 100644
--- a/ext/opcache/ZendAccelerator.h
+++ b/ext/opcache/ZendAccelerator.h
@@ -325,6 +325,7 @@ int accelerator_shm_read_lock(TSRMLS_D);
void accelerator_shm_read_unlock(TSRMLS_D);
char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_length, int *key_len TSRMLS_DC);
+zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
#if !defined(ZEND_DECLARE_INHERITED_CLASS_DELAYED)
# define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145
diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c
index f9ddaa98b8..dedb7215c1 100644
--- a/ext/opcache/zend_accelerator_module.c
+++ b/ext/opcache/zend_accelerator_module.c
@@ -48,6 +48,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_get_status, 0, 0, 0)
ZEND_ARG_INFO(0, fetch_scripts)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_compile_file, 0, 0, 1)
+ ZEND_ARG_INFO(0, file)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_invalidate, 0, 0, 1)
ZEND_ARG_INFO(0, script)
ZEND_ARG_INFO(0, force)
@@ -59,12 +63,14 @@ static ZEND_FUNCTION(opcache_invalidate);
/* Private functions */
static ZEND_FUNCTION(opcache_get_status);
+static ZEND_FUNCTION(opcache_compile_file);
static ZEND_FUNCTION(opcache_get_configuration);
static zend_function_entry accel_functions[] = {
/* User functions */
ZEND_FE(opcache_reset, arginfo_opcache_none)
ZEND_FE(opcache_invalidate, arginfo_opcache_invalidate)
+ ZEND_FE(opcache_compile_file, arginfo_opcache_compile_file)
/* Private functions */
ZEND_FE(opcache_get_configuration, arginfo_opcache_none)
ZEND_FE(opcache_get_status, arginfo_opcache_get_status)
@@ -709,3 +715,44 @@ static ZEND_FUNCTION(opcache_invalidate)
RETURN_FALSE;
}
}
+
+static ZEND_FUNCTION(opcache_compile_file)
+{
+ char *script_name;
+ int script_name_len;
+ zend_file_handle handle;
+ zend_op_array *op_array = NULL;
+ zend_execute_data *orig_execute_data = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &script_name, &script_name_len) == FAILURE) {
+ return;
+ }
+
+ if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled)) {
+ zend_error(E_NOTICE, ACCELERATOR_PRODUCT_NAME " seems to be disabled, can't compile file");
+ RETURN_FALSE;
+ }
+
+ handle.filename = script_name;
+ handle.free_filename = 0;
+ handle.opened_path = NULL;
+ handle.type = ZEND_HANDLE_FILENAME;
+
+ orig_execute_data = EG(current_execute_data);
+
+ zend_try {
+ op_array = persistent_compile_file(&handle, ZEND_INCLUDE TSRMLS_CC);
+ } zend_catch {
+ EG(current_execute_data) = orig_execute_data;
+ zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s" TSRMLS_CC, handle.filename);
+ } zend_end_try();
+
+ if(op_array != NULL) {
+ destroy_op_array(op_array TSRMLS_CC);
+ efree(op_array);
+ RETVAL_TRUE;
+ } else {
+ RETVAL_FALSE;
+ }
+ zend_destroy_file_handle(&handle TSRMLS_CC);
+}