Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

The test has been enhanced, the feature has been slightly refactored.…

… A leading backslach in constant name will be skipped. (#41)
  • Loading branch information...
commit 80609ccbbefdc7d21d4d250209c5925bb55b13e0 1 parent ee02898
@zenovich authored
Showing with 106 additions and 45 deletions.
  1. +42 −41 runkit_constants.c
  2. +64 −4 tests/runkit_constant_remove_from_ns.phpt
View
83 runkit_constants.c
@@ -26,46 +26,47 @@
*/
static int php_runkit_fetch_const(char *cname, int cname_len, zend_constant **constant, char **found_cname TSRMLS_DC)
{
- int namespace_constant = 0;
+ char *lcase = NULL;
+ char *old_cname = cname;
+ int constant_name_len = cname_len;
+
+#if RUNKIT_ABOVE53
+ char *separator;
+
+ if (cname_len > 0 && cname[0] == '\\') {
+ ++cname;
+ --cname_len;
+ }
+ separator = (char *) zend_memrchr(cname, '\\', cname_len);
+ if (separator) {
+ int nsname_len = separator - cname;
+ char *constant_name = separator + 1;
+ constant_name_len = cname_len - nsname_len - 1;
+
+ lcase = emalloc(nsname_len + 1 + constant_name_len + 1);
+ memcpy(lcase, cname, nsname_len + 1);
+ memcpy(lcase + nsname_len + 1, constant_name, constant_name_len + 1);
+ zend_str_tolower(lcase, nsname_len);
+ cname = lcase;
+ }
+#endif
if (zend_hash_find(EG(zend_constants), cname, cname_len + 1, (void*)constant) == FAILURE) {
- char *lcase;
-
- lcase = zend_str_tolower_dup(cname, cname_len);
- if (zend_hash_find(EG(zend_constants), lcase, cname_len + 1, (void*)constant) == FAILURE) {
- char *separator;
-
- separator = zend_memrchr(cname, '\\', cname_len);
- if (separator) {
- int nsname_len = separator - cname;
- char *constant_name = separator + 1;
- int constant_name_len = cname_len - nsname_len - 1;
-
- lcase = erealloc(lcase, nsname_len + 1 + constant_name_len + 1);
- lcase[nsname_len] = '\\';
- memcpy(lcase + nsname_len + 1, constant_name, constant_name_len + 1);
-
- if (zend_hash_find(EG(zend_constants), lcase, cname_len + 1, (void*)constant) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Constant %s not found", cname);
- efree(lcase);
- return FAILURE;
- }
- namespace_constant = 1;
- } else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Constant %s not found", cname);
- efree(lcase);
- return FAILURE;
- }
+ if (!lcase) {
+ lcase = estrndup(cname, cname_len);
+ zend_str_tolower(lcase, cname_len);
+ } else {
+ zend_str_tolower(lcase + cname_len - constant_name_len, constant_name_len);
}
-
- if (!namespace_constant && (*constant)->flags & CONST_CS) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Constant %s not found", cname);
+ cname = lcase;
+ if (zend_hash_find(EG(zend_constants), cname, cname_len + 1, (void*)constant) == FAILURE || ((*constant)->flags & CONST_CS)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Constant %s not found", old_cname);
efree(lcase);
return FAILURE;
}
- *found_cname = lcase;
- } else {
- *found_cname = estrndup(cname, cname_len);
+ }
+ if (found_cname) {
+ *found_cname = lcase ? lcase : estrndup(cname, cname_len);
}
return SUCCESS;
@@ -117,7 +118,6 @@ int php_runkit_update_children_consts(RUNKIT_53_TSRMLS_ARG(void *pDest), int num
static int php_runkit_constant_remove(char *classname, int classname_len, char *constname, int constname_len TSRMLS_DC)
{
zend_constant *constant;
- char *lcase = NULL;
char *found_constname;
if (classname && (classname_len > 0)) {
@@ -166,16 +166,10 @@ static int php_runkit_constant_remove(char *classname, int classname_len, char *
if (zend_hash_del(EG(zend_constants), found_constname, constant->name_len) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to remove constant");
- if (lcase) {
- efree(lcase);
- }
efree(found_constname);
return FAILURE;
}
efree(found_constname);
- if (lcase) {
- efree(lcase);
- }
#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION > 5)
php_runkit_clear_all_functions_runtime_cache(TSRMLS_C);
@@ -210,6 +204,13 @@ static int php_runkit_constant_add(char *classname, int classname_len, char *con
if ((classname == NULL) || (classname_len == 0)) {
zend_constant c;
+#if RUNKIT_ABOVE53
+ if (constname_len > 0 && constname[0] == '\\') {
+ ++constname;
+ --constname_len;
+ }
+#endif
+
/* Traditional global constant */
c.value = *value;
zval_copy_ctor(&c.value);
View
68 tests/runkit_constant_remove_from_ns.phpt
@@ -1,22 +1,82 @@
--TEST--
-runkit_constant_remove() and namespaces
+runkit_constant_remove(), runkit_constant_add(), and namespaces
+--SKIPIF--
+<?php
+ if(!extension_loaded("runkit") || !RUNKIT_FEATURE_MANIPULATION) print "skip";
+ if(version_compare(PHP_VERSION, '5.3.0', '<')) print "skip";
+?>
--FILE--
<?php
namespace Mock\Constant\Command;
+class RunkitClass {const Test='test';}
-define('Mock\Constant\Command\Test', 'test1');
+define('Mock\Constant\Command\Test', 'test');
+var_dump(\Mock\Constant\Command\Test);
var_dump(runkit_constant_remove('Mock\Constant\Command\Test'));
+var_dump(defined('\Mock\Constant\Command\Test'));
var_dump(runkit_constant_add('Mock\Constant\Command\Test', 'test1'));
+var_dump(\Mock\Constant\Command\Test);
var_dump(runkit_constant_remove('Mock\Constant\Command\Test'));
-var_dump(runkit_constant_add('Mock\Constant\Command\Test', 'test1'));
+var_dump(defined('\Mock\Constant\Command\Test'));
+var_dump(runkit_constant_add('Mock\Constant\Command\Test', 'test2'));
+var_dump(\Mock\Constant\Command\Test);
-echo "==DONE==\n";
+echo "\n";
+
+var_dump(\Mock\Constant\Command\RunkitClass::Test);
+var_dump(runkit_constant_remove('Mock\Constant\Command\RunkitClass::Test'));
+var_dump(defined('\Mock\Constant\Command\RunkitClass::Test'));
+var_dump(runkit_constant_add('Mock\Constant\Command\RunkitClass::Test', 'test1'));
+var_dump(\Mock\Constant\Command\RunkitClass::Test);
+var_dump(runkit_constant_remove('Mock\Constant\Command\RunkitClass::Test'));
+var_dump(defined('\Mock\Constant\Command\RunkitClass::Test'));
+var_dump(runkit_constant_add('Mock\Constant\Command\RunkitClass::Test', 'test2'));
+var_dump(\Mock\Constant\Command\RunkitClass::Test);
+echo "\n";
+
+define('Test', 'test');
+var_dump(\Test);
+var_dump(runkit_constant_remove('\Test'));
+var_dump(defined('\Test'));
+var_dump(runkit_constant_add('\Test', 'test1'));
+var_dump(\Test);
+var_dump(runkit_constant_remove('\Test'));
+var_dump(defined('\Test'));
+var_dump(runkit_constant_add('\Test', 'test2'));
+var_dump(\Test);
+
+echo "==DONE==\n";
?>
--EXPECT--
+string(4) "test"
+bool(true)
+bool(false)
+bool(true)
+string(5) "test1"
+bool(true)
+bool(false)
+bool(true)
+string(5) "test2"
+
+string(4) "test"
+bool(true)
+bool(false)
+bool(true)
+string(5) "test1"
+bool(true)
+bool(false)
+bool(true)
+string(5) "test2"
+
+string(4) "test"
bool(true)
+bool(false)
bool(true)
+string(5) "test1"
bool(true)
+bool(false)
bool(true)
+string(5) "test2"
==DONE==
Please sign in to comment.
Something went wrong with that request. Please try again.