Skip to content

Commit

Permalink
WIP - resurrecting runkit import and property manipulation
Browse files Browse the repository at this point in the history
TODO: tests/runkit_add_old_style_ctor_by_importing.inc segfaults

Work on getting runkit_import.c to compile, add runkit_import to
functions declared by runkit
  • Loading branch information
TysonAndre authored and TysonAndre-tmg committed Aug 17, 2017
1 parent 7f34657 commit ffcb3bc
Show file tree
Hide file tree
Showing 7 changed files with 364 additions and 44 deletions.
1 change: 1 addition & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ if test "$PHP_RUNKIT" != "no"; then
AC_DEFINE(PHP_RUNKIT_SPL_OBJECT_ID, 1, [Whether to define spl_object_id in php <= 7.1])
fi
PHP_NEW_EXTENSION(runkit, runkit.c runkit_functions.c runkit_methods.c \
runkit_import.c \
runkit_constants.c \
runkit_object_id.c \
runkit_common.c \
Expand Down
3 changes: 2 additions & 1 deletion config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ if (PHP_RUNKIT != "no") {
AC_DEFINE("PHP_RUNKIT_FEATURE_MODIFY", PHP_RUNKIT_MODIFY == "yes", "Runkit Manipulation");
AC_DEFINE("PHP_RUNKIT_FEATURE_SUPER", PHP_RUNKIT_SUPER == "yes", "Runkit Superglobals");
AC_DEFINE("PHP_RUNKIT_SPL_OBJECT_ID", PHP_RUNKIT_SPL_OBJECT_ID == "yes", "Runkit spl_object_id substitute");
EXTENSION("runkit", "runkit.c runkit_functions.c runkit_methods.c runkit_constants.c runkit_object_id.c runkit_common.c runkit_zend_execute_API.c");

EXTENSION("runkit", "runkit.c runkit_functions.c runkit_methods.c runkit_import.c runkit_constants.c runkit_object_id.c runkit_common.c runkit_zend_execute_API.c");
}
19 changes: 17 additions & 2 deletions php_runkit.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ static inline void* _debug_emalloc(void* data, int bytes, char* file, int line)

#ifdef PHP_RUNKIT_FEATURE_MODIFY
#define PHP_RUNKIT_MANIPULATION
// TODO: Enable these macros once the corresponding functions/files compile and pass some of the tests.
// TODO: Clean up these macros once the corresponding functions/files are 100% correct.
#define PHP_RUNKIT_MANIPULATION_IMPORT
// #define PHP_RUNKIT_MANIPULATION_PROPERTIES
// #define PHP_RUNKIT_MANIPULATION_CLASSES
#endif

#ifdef PHP_RUNKIT_MANIPULATION
Expand Down Expand Up @@ -146,6 +151,14 @@ PHP_FUNCTION(runkit_constant_add);
// PHP_FUNCTION(runkit_class_adopt);
#endif
// PHP_FUNCTION(runkit_import);
#ifdef PHP_RUNKIT_MANIPULATION_PROPERTIES
PHP_FUNCTION(runkit_default_property_add);
PHP_FUNCTION(runkit_default_property_remove);
#endif
// TODO
#ifdef PHP_RUNKIT_MANIPULATION_IMPORT
PHP_FUNCTION(runkit_import);
#endif /* PHP_RUNKIT_MANIPULATION_IMPORT */
#endif /* PHP_RUNKIT_MANIPULATION */

#ifdef PHP_RUNKIT_MANIPULATION
Expand Down Expand Up @@ -429,6 +442,7 @@ inline static zend_bool php_runkit_is_valid_return_type(const zend_string *retur
if (it >= end) {
return 0;
}
// The format of a valid class identifier is documented at https://secure.php.net/manual/en/language.oop5.basic.php
while (1) {
unsigned char c = *it;
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c >= 128) {
Expand All @@ -453,7 +467,6 @@ inline static zend_bool php_runkit_is_valid_return_type(const zend_string *retur
}
return 0;
}
// The format of a valid class identifier is documented at https://secure.php.net/manual/en/language.oop5.basic.php
}
/* }}} */

Expand Down Expand Up @@ -546,7 +559,9 @@ inline static zend_string* zend_string_to_interned(zend_string* original) {
/* {{{ zend_bool php_runkit_parse_function_arg */
/** Parses either multiple strings (1. function args, 2. body 3. (optional) return type), or a Closure. */
inline static zend_bool php_runkit_parse_function_arg(int argc, zval *args, int arg_pos, zend_function **fe, zend_string** arguments, zend_string** phpcode, long *opt_arg_pos, char *type TSRMLS_DC) {
// TODO: Does this do the right thing?
// If is successful, it returns true, advances opt_arg_pos. There are two was this could succeed
// 1. *fe = zend_function extracted from a closure.
// 2. *arguments, *phpcode = strings extracted from arguments
if (Z_TYPE(args[arg_pos]) == IS_OBJECT && Z_OBJCE(args[arg_pos]) == zend_ce_closure) {
*fe = (zend_function *) zend_get_closure_method_def(&(args[arg_pos]) TSRMLS_CC);
} else if (Z_TYPE(args[arg_pos]) == IS_STRING) {
Expand Down
28 changes: 18 additions & 10 deletions runkit.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
| http://www.opensource.org/licenses/BSD-3-Clause |
| If you did not receive a copy of the license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Sara Golemon <[email protected]> |
| Modified by Dmitry Zenovich <[email protected]> |
Expand Down Expand Up @@ -203,11 +203,9 @@ zend_function_entry runkit_functions[] = {
#endif

#ifdef PHP_RUNKIT_MANIPULATION
#ifdef PHP_RUNKIT_MANIPULATION_CLASSES
// PHP_FE(runkit_class_emancipate, NULL)
// PHP_FE(runkit_class_adopt, NULL)
#ifdef PHP_RUNKIT_MANIPULATION_IMPORT
PHP_FE(runkit_import, NULL)
#endif
// PHP_FE(runkit_import, NULL)

PHP_FE(runkit_function_add, arginfo_runkit_function_add)
PHP_FE(runkit_function_remove, arginfo_runkit_function_remove)
Expand All @@ -227,16 +225,25 @@ zend_function_entry runkit_functions[] = {
PHP_FALIAS(classkit_method_remove, runkit_method_remove, arginfo_runkit_method_remove)
PHP_FALIAS(classkit_method_rename, runkit_method_rename, arginfo_runkit_method_rename)
PHP_FALIAS(classkit_method_copy, runkit_method_copy, arginfo_runkit_method_copy)
PHP_FALIAS(classkit_import, runkit_import, arginfo_runkit_import)
#endif

PHP_FE(runkit_constant_redefine, arginfo_runkit_constant_redefine)
PHP_FE(runkit_constant_remove, arginfo_runkit_constant_remove)
PHP_FE(runkit_constant_add, arginfo_runkit_constant_add)

// PHP_FE(runkit_default_property_add, NULL)
// PHP_FE(runkit_default_property_remove, NULL)
#ifdef PHP_RUNKIT_MANIPULATION_PROPERTIES
PHP_FE(runkit_default_property_add, NULL)
PHP_FE(runkit_default_property_remove, NULL)
#endif
#endif /* PHP_RUNKIT_MANIPULATION */

#ifdef PHP_RUNKIT_SANDBOX
PHP_FE(runkit_sandbox_output_handler, NULL)
PHP_FE(runkit_lint, NULL)
PHP_FE(runkit_lint_file, NULL)
#endif

{NULL, NULL, NULL}
};
/* }}} */
Expand Down Expand Up @@ -433,7 +440,8 @@ static void php_runkit_register_auto_global(char *s, int len TSRMLS_DC)
ALLOC_HASHTABLE(RUNKIT_G(superglobals));
zend_hash_init(RUNKIT_G(superglobals), 2, NULL, NULL, 0);
}
// Insert a different but equivalent zend_string into the map for function runkit_superglobals(),
// Insert a different but equivalent zend_string (superglobal name)
// into the list for function runkit_superglobals(),
// to make reasoning about reference tracking easier.
ZVAL_NEW_STR(&z, zend_string_init(s, len, 1));
zend_hash_next_index_insert(RUNKIT_G(superglobals), &z);
Expand Down Expand Up @@ -508,9 +516,9 @@ static int php_runkit_superglobal_dtor(zval *zv TSRMLS_DC)
*/
PHP_RSHUTDOWN_FUNCTION(runkit)
{
#ifdef PHP_RUNKIT_MANIPULATION
// #ifdef PHP_RUNKIT_MANIPULATION
// php_runkit_default_class_members_list_element *el;
#endif
// #endif

#ifdef PHP_RUNKIT_SUPERGLOBALS
if (RUNKIT_G(superglobals)) {
Expand Down
2 changes: 2 additions & 0 deletions runkit_classes.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ runkit_property_modify() may be implemented in the future.
#include "php_runkit_zval.h"

#ifdef PHP_RUNKIT_MANIPULATION
#ifdef PHP_RUNKIT_MANIPULATION_CLASSES
/* {{{ php_runkit_remove_inherited_methods_foreach */
// Remove methods that were inherited from class ce from the function_table.
static int php_runkit_remove_inherited_methods(zval *pDest, void *argument TSRMLS_DC); // forward declare.
Expand Down Expand Up @@ -295,6 +296,7 @@ PHP_FUNCTION(runkit_class_adopt)
}
/* }}} */

#endif /* PHP_RUNKIT_MANIPULATION_CLASSES */
#endif /* PHP_RUNKIT_MANIPULATION */
/*
* Local variables:
Expand Down
77 changes: 48 additions & 29 deletions runkit_import.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,33 +171,52 @@ static int php_runkit_import_class_methods(zend_class_entry *dce, zend_class_ent
static int php_runkit_import_class_consts(zend_class_entry *dce, zend_class_entry *ce, int override TSRMLS_DC)
{
zend_string *key;
zval c;

ZEND_HASH_FOREACH_STR_KEY(&ce->constants_table, key) {
#if PHP_VERSION_ID >= 70100
zend_class_constant *c;
#endif
zval *c_zval;

#if PHP_VERSION_ID >= 70100
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { /* } */
#else
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c_zval) {
#endif
long action = HASH_ADD;
#if PHP_VERSION_ID >= 70100
zend_long access_type;
c_zval = &c->value;
#endif

if (key != NULL) {
if (zend_hash_exists(&dce->constants_table, key)) {
if (override) {
action = HASH_UPDATE;
} else {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s::%s already exists, not importing", ZSTR_VAL(dce->name), ZSTR_VAL(key));
continue;
}
}

php_runkit_zval_resolve_class_constant(&c, dce TSRMLS_CC);
Z_TRY_ADDREF(c);

if (zend_hash_add_or_update(&dce->constants_table, key, &c, action) == NULL) {
Z_TRY_DELREF(c);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to import %s::%s", ZSTR_VAL(dce->name), ZSTR_VAL(key));
}

php_runkit_update_children_consts_foreach(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), dce, &c, key);
} else {
if (key == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Constant has invalid key name");
continue;
}
if (zend_hash_exists(&dce->constants_table, key)) {
if (override) {
action = HASH_UPDATE;
} else {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s::%s already exists, not importing", ZSTR_VAL(dce->name), ZSTR_VAL(key));
continue;
}
}
#if PHP_VERSION_ID >= 70100
access_type = Z_ACCESS_FLAGS(*c_zval);
#endif

php_runkit_zval_resolve_class_constant(c_zval, dce TSRMLS_CC);
Z_TRY_ADDREF_P(c_zval);

// TODO: Does this need to create copies of the zend_class_constant?
#if PHP_VERSION_ID >= 70100
if (runkit_zend_hash_add_or_update_ptr(&dce->constants_table, key, c, action) == NULL) { /* } */
#else
if (zend_hash_add_or_update(&dce->constants_table, key, c_zval, action) == NULL) {
#endif
Z_TRY_DELREF_P(c_zval);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to import %s::%s", ZSTR_VAL(dce->name), ZSTR_VAL(key));
}

php_runkit_update_children_consts_foreach(EG(class_table), dce, c_zval, key RUNKIT_CONST_FLAGS_CC(access_type));
} ZEND_HASH_FOREACH_END();
return SUCCESS;
}
Expand Down Expand Up @@ -461,6 +480,10 @@ PHP_FUNCTION(runkit_import)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &filename, &flags) == FAILURE) {
RETURN_FALSE;
}
if (flags & PHP_RUNKIT_IMPORT_OVERRIDE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "support for PHP_RUNKIT_IMPORT_OVERRIDE is not implemented yet.");
RETURN_FALSE;
}
convert_to_string(filename);

if (compile_file != zend_compile_file) {
Expand Down Expand Up @@ -533,15 +556,11 @@ PHP_FUNCTION(runkit_import)
efree(new_op_array);

if (flags & PHP_RUNKIT_IMPORT_FUNCTIONS) {
php_runkit_import_functions(tmp_function_table, flags
, &clear_cache
TSRMLS_CC);
php_runkit_import_functions(tmp_function_table, flags, &clear_cache TSRMLS_CC);
}

if (flags & PHP_RUNKIT_IMPORT_CLASSES) {
php_runkit_import_classes(tmp_class_table, flags
, &clear_cache
TSRMLS_CC);
php_runkit_import_classes(tmp_class_table, flags, &clear_cache TSRMLS_CC);
}

zend_hash_destroy(tmp_class_table);
Expand Down
Loading

0 comments on commit ffcb3bc

Please sign in to comment.