summaryrefslogtreecommitdiff
path: root/zend
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-01-11 13:00:02 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-01-11 13:00:02 +0100
commit1c663ea116121469e37ad2cb9480387c16c0236b (patch)
tree06bf80d81f47d0c81b9cbdbccf7da9db61490022 /zend
parent1efade1a7667e4e1a34265fb3cf310faf8c80bb6 (diff)
fixed memory leak when executing php code using the Opcodes class, fixed possible double-free when path passed to File class was absolute, added extra constructors to the File class
Diffstat (limited to 'zend')
-rw-r--r--zend/file.cpp22
-rw-r--r--zend/opcodes.cpp9
2 files changed, 21 insertions, 10 deletions
diff --git a/zend/file.cpp b/zend/file.cpp
index 3ba53c9..98c1441 100644
--- a/zend/file.cpp
+++ b/zend/file.cpp
@@ -33,6 +33,13 @@ File::File(const char *name, size_t size)
// resolve the path
_path = zend_resolve_path(name, size TSRMLS_CC);
+
+ // the resolve-path function sometimes returns the original pointer, we
+ // do not want that because we may have to store the pathname in this object
+ if (_path != name) return;
+
+ // make a full copy of the pathname
+ _path = estrndup(name, size);
}
/**
@@ -78,7 +85,10 @@ Value File::execute()
_opcodes = new Opcodes(zend_compile_file(&fileHandle, ZEND_INCLUDE TSRMLS_CC));
// close the file handle
- zend_file_handle_dtor(&fileHandle TSRMLS_CC);
+ zend_destroy_file_handle(&fileHandle TSRMLS_CC);
+
+ // add the entry to the list of included files
+ zend_hash_add_empty_element(&EG(included_files), _path, ::strlen(_path) + 1);
// execute the opcodes
return _opcodes->execute();
@@ -91,18 +101,12 @@ Value File::execute()
Value File::once()
{
// skip if the opcodes are already known (then we know for sure that the
- // file was already executed)
- if (_opcodes) return nullptr;
-
- // also leap out if the filename was not even valid
- if (!_path) return nullptr;
+ // file was already executed), also leap out if the filename was not even valid
+ if (_opcodes || !_path) return nullptr;
// check if this file was already included
if (zend_hash_exists(&EG(included_files), _path, ::strlen(_path) + 1)) return nullptr;
- // add the entry to the list of included files
- if (zend_hash_add_empty_element(&EG(included_files), _path, ::strlen(_path) + 1) == FAILURE) return nullptr;
-
// execute the file
return execute();
}
diff --git a/zend/opcodes.cpp b/zend/opcodes.cpp
index 0603d9b..61d8a75 100644
--- a/zend/opcodes.cpp
+++ b/zend/opcodes.cpp
@@ -136,8 +136,15 @@ Value Opcodes::execute() const
// we're ready if there is no return value
if (!retval_ptr) return nullptr;
+ // wrap the return value
+ Value result(retval_ptr);
+
+ // destruct the zval (this function will decrement the reference counter,
+ // and only destruct if there are no other references left)
+ zval_ptr_dtor(&retval_ptr);
+
// copy the pointer into a value object, and return that
- return retval_ptr;
+ return result;
}
/**