summaryrefslogtreecommitdiff
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
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
-rw-r--r--include/file.h12
-rw-r--r--include/value.h2
-rw-r--r--zend/file.cpp22
-rw-r--r--zend/opcodes.cpp9
4 files changed, 34 insertions, 11 deletions
diff --git a/include/file.h b/include/file.h
index 093431e..6e24516 100644
--- a/include/file.h
+++ b/include/file.h
@@ -38,6 +38,18 @@ public:
File(const char *name) : File(name, ::strlen(name)) {}
/**
+ * Alternative constructor with a string object
+ * @param name the filename
+ */
+ File(const std::string &name) : File(name.c_str(), name.size()) {}
+
+ /**
+ * Alternative constructor with a Value object
+ * @param name the filename
+ */
+ File(const Value &value) : File(value.stringValue()) {}
+
+ /**
* Destructor
*/
virtual ~File();
diff --git a/include/value.h b/include/value.h
index 9447fc8..363779d 100644
--- a/include/value.h
+++ b/include/value.h
@@ -405,7 +405,7 @@ public:
char *reserve(size_t size);
/**
- * Get access to the raw buffer for read operationrs.
+ * Get access to the raw buffer for read operations.
* @return const char *
*/
const char *rawValue() const;
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;
}
/**