Bug report 13505 got me thinking about the behavior of define() - if 
you try to define a constant name that is a reserved word, or an 
existing function or class name, no warning is generated.

This could have  been a conscious decision - a case where it was 
decided that some safety could be traded for a bit of extra speed. If 
it wasn't, then here is a patch to check that the constant name does 
not clash with a reserved work, function name or class name.

I used an array of reserved words and a for loop to handle finding 
conflicting reserved words. Is there a better way to do this. AFAICT 
the other methods for handling reserved word conflicts are handled at 
the parser level. i.e. Trying to define 'function and (){}' generates a 
parser error.

Anyhoo, perhaps someone could take a look at the patch? :)

-- 
Zak Greant

PHP Quality Assurance Team
http://qa.php.net/

"We must be the change we wish to see." - M. K. Ghandi
Index: zend_builtin_functions.c
===================================================================
RCS file: /repository/Zend/zend_builtin_functions.c,v
retrieving revision 1.103
diff -u -r1.103 zend_builtin_functions.c
--- zend_builtin_functions.c    2001/08/11 15:57:07     1.103
+++ zend_builtin_functions.c    2001/10/02 07:06:21
@@ -380,7 +380,22 @@
 ZEND_FUNCTION(define)
 {
        zval **var, **val, **non_cs;
-       int case_sensitive;
+       char *lcname;
+       char *reserved_words[] = {
+               "and",          "isset",        "break",        "case",
+               "class",        "continue",     "default",      "die",
+               "do",           "echo",         "else",         "elseif",
+               "empty",        "endfor",       "endforeach",   "endif",
+               "endswitch",    "endwhile",     "exit",         "extends",
+               "for",          "foreach",      "function",     "global",
+               "if",           "include",      "include_once", "list",
+               "new",          "not",          "or",           "parent",
+               "print",        "require",      "require_once", "return",
+               "static",       "stdClass",     "switch",       "var",
+               "virtual",      "while",        "xor",          "__sleep",
+               "__wakeup",     "__file__",     "__line__",     ""
+       };
+       int case_sensitive, index;
        zend_constant c;

        switch(ZEND_NUM_ARGS()) {
@@ -420,8 +435,38 @@
                        break;
        }
        convert_to_string_ex(var);
+
+
+    /* Ensure that the constant will not conflict with existing function or class names */
+    lcname = estrndup((*var)->value.str.val, (*var)->value.str.len);
+    zend_str_tolower(lcname, (*var)->value.str.len);
+
+    if (zend_hash_exists(EG(function_table), lcname, (*var)->value.str.len+1)) {
+        efree(lcname);
+        zend_error(E_WARNING,"Constant names must not conflict with function names.");
+        RETURN_FALSE;
+    }
+
+    if (zend_hash_exists(EG(class_table), lcname, (*var)->value.str.len+1)) {
+        efree(lcname);
+        zend_error(E_WARNING,"Constant names must not conflict with class names.");
+        RETURN_FALSE;
+    }
+
+    for (index = 0; *reserved_words[index]; ++index) {
+        if (strcmp (reserved_words[index], lcname)) {
+            efree(lcname);
+            zend_error(E_WARNING, "Constant names must not conflict with reserved words");
+            RETURN_FALSE;
+        }
+    }
+
+
+        efree(lcname);

+
        c.value = **val;
+
        zval_copy_ctor(&c.value);
        c.flags = case_sensitive; /* non persistent */
        c.name = zend_strndup((*var)->value.str.val, (*var)->value.str.len);
-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to