# [PATCH] reserved words allowed as function/method names

- Thread: https://externals.io/message/32579
- Original archive: https://news-web.php.net/php.internals/32579
- Started by Gregory Beaver on 2007-10-03T02:49:56+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #32579 — Gregory Beaver — 2007-10-03T02:49:56+00:00

URL: https://externals.io/message/32579#32579

Hi,

I spent a while tonight tinkering with the parser to try to figure out
how to allow it to use T_IMPORT as well as `T_STRING` for method names,
and quickly came to the conclusion that this causes way more trouble
than it is worth.  However, in a moment of inspiration, I realized that
a minor change in the lexer would allow any reserved words for method
names.  The patch is attached.  This patch allows all kinds of odd
looking code that probably won't be used, but permanently guarantees
that code written for PHP now will never conflict with future reserved
words:

<?php
namespace testing;
class Test {
function array()
{
echo "array\n";
}
function class()
{
echo "class\n";
}
static function import()
{
echo "import\n";
}
function new()
{
echo "new\n";
}
$a = new Test;
$a->array();
$a->class();
$a->new();
Test::import();
testing::Test::import();
?>

The patch does not allow reserved names for class names, interface
names, functions, or for class constants.  This would be much harder to
implement in the lexer, and in my experience collisions with reserved
words most often happens with methods.

The patch only allows methods to use reserved words, not functions, and
causes a fatal error with this code:

<?php
function foreach($a)
{
}
?>

This prevents this wtf code, which would also produce a different (and
non-intuitive) fatal error:

<?php
foreach (foreach() as $foreach) {foreach();}
?>

The patch is against PHP 5.3, and PHP 6

Greg

---

## #32580 — Gregory Beaver — 2007-10-03T03:15:40+00:00

URL: https://externals.io/message/32579#32580 · In reply to: #32579

Gregory Beaver wrote:

> ===================================================================
> RCS file: /repository/php-src/run-tests.php,v
> retrieving revision 1.226.2.37.2.35
> diff -u -r1.226.2.37.2.35 run-tests.php
> --- run-tests.php	14 Sep 2007 15:28:03 -0000	1.226.2.37.2.35
> +++ run-tests.php	3 Oct 2007 02:40:57 -0000
> @@ -1328,12 +1328,15 @@
>  		$raw_lines = explode("\n", $post);
>  
>  		$request = '';
> +		$started = false;
>  		foreach ($raw_lines as $line) {
>  			if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) {
>  				$env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
>  				continue;
>  			}
> -			$request .= $line . "\n";
> +			if ($started) $request .= "\n";
> +			$started = true;
> +			$request .= $line;
>  		}
>  
>  		$env['CONTENT_LENGTH'] = strlen($request);

ignore this part, sorry.

Greg

---

## #32639 — Gregory Beaver — 2007-10-05T02:18:47+00:00

URL: https://externals.io/message/32579#32639 · In reply to: #32579

Patches added to http://bugs.php.net/28261, and I re-opened the bug.

Greg

Gregory Beaver wrote:
> Hi,
> 
> I spent a while tonight tinkering with the parser to try to figure out
> how to allow it to use T_IMPORT as well as `T_STRING` for method names,
> and quickly came to the conclusion that this causes way more trouble
> than it is worth.  However, in a moment of inspiration, I realized that
> a minor change in the lexer would allow any reserved words for method
> names.  The patch is attached.  This patch allows all kinds of odd
> looking code that probably won't be used, but permanently guarantees
> that code written for PHP now will never conflict with future reserved
> words:
> 
> <?php
> namespace testing;
> class Test {
> function array()
> {
> echo "array\n";
> }
> function class()
> {
> echo "class\n";
> }
> static function import()
> {
> echo "import\n";
> }
> function new()
> {
> echo "new\n";
> }
> $a = new Test;
> $a->array();
> $a->class();
> $a->new();
> Test::import();
> testing::Test::import();
> ?>
> 
> The patch does not allow reserved names for class names, interface
> names, functions, or for class constants.  This would be much harder to
> implement in the lexer, and in my experience collisions with reserved
> words most often happens with methods.
> 
> The patch only allows methods to use reserved words, not functions, and
> causes a fatal error with this code:
> 
> <?php
> function foreach($a)
> {
> }
> ?>
> 
> This prevents this wtf code, which would also produce a different (and
> non-intuitive) fatal error:
> 
> <?php
> foreach (foreach() as $foreach) {foreach();}
> ?>
> 
> The patch is against PHP 5.3, and PHP 6
> 
> Greg
> 
> 
> ------------------------------------------------------------------------
> 
> ? better_halt.patch.txt
> ? config.cli
> ? config.nice.nodebug
> ? err
> ? install-pear-nozlib.phar
> ? run-tests.oops.patch.txt
> ? smarter_lexer.patch.txt
> ? test-phar.sh
> ? test.phar
> ? testme.php
> ? zlib.patch
> ? Zend/tests/zend_function_name.phpt
> ? ext/gd/run-tests.php
> ? ext/gettext/run-tests.php
> ? ext/mysqli/run-tests.php
> ? ext/zip/run-tests.php
> ? ext/zlib/zlib_filter.c.2
> ? pear/scripts
> ? tests/lang/halt_compiler1.phpt
> ? tests/lang/halt_compiler2.phpt
> ? tests/lang/halt_compiler3.phpt
> ? tests/lang/halt_compiler4.phpt
> Index: run-tests.php
> ===================================================================
> RCS file: /repository/php-src/run-tests.php,v
> retrieving revision 1.226.2.37.2.35
> diff -u -r1.226.2.37.2.35 run-tests.php
> --- run-tests.php	14 Sep 2007 15:28:03 -0000	1.226.2.37.2.35
> +++ run-tests.php	3 Oct 2007 02:40:57 -0000
> @@ -1328,12 +1328,15 @@
>  		$raw_lines = explode("\n", $post);
>  
>  		$request = '';
> +		$started = false;
>  		foreach ($raw_lines as $line) {
>  			if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) {
>  				$env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
>  				continue;
>  			}
> -			$request .= $line . "\n";
> +			if ($started) $request .= "\n";
> +			$started = true;
> +			$request .= $line;
>  		}
>  
>  		$env['CONTENT_LENGTH'] = strlen($request);
> Index: Zend/zend_language_scanner.l
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_language_scanner.l,v
> retrieving revision 1.131.2.11.2.13.2.1
> diff -u -r1.131.2.11.2.13.2.1 zend_language_scanner.l
> --- Zend/zend_language_scanner.l	28 Sep 2007 19:52:50 -0000	1.131.2.11.2.13.2.1
> +++ Zend/zend_language_scanner.l	3 Oct 2007 02:41:02 -0000
> @@ -978,6 +978,9 @@
>  }
>  
>  <ST_IN_SCRIPTING>"function" {
> +	if (CG(active_class_entry)) {
> +		yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
> +	}
>  	return T_FUNCTION;
>  }
>  
> @@ -1118,6 +1121,14 @@
>  	return T_OBJECT_OPERATOR;
>  }
>  
> +<ST_LOOKING_FOR_PROPERTY>{WHITESPACE} {
> +	zendlval->value.str.val = yytext; /* no copying - intentional */
> +	zendlval->value.str.len = yyleng;
> +	zendlval->type = IS_STRING;
> +	HANDLE_NEWLINES(yytext, yyleng);
> +	return T_WHITESPACE;
> +}
> +
>  <ST_LOOKING_FOR_PROPERTY>{LABEL} {
>  	yy_pop_state(TSRMLS_C);
>  	zend_copy_value(zendlval, yytext, yyleng);
> @@ -1131,6 +1142,7 @@
>  }
>  
>  <ST_IN_SCRIPTING>"::" {
> +	yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
>  	return T_PAAMAYIM_NEKUDOTAYIM;
>  }
>  
> 
> 
> ------------------------------------------------------------------------
> 
> Index: Zend/zend_language_scanner.l
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_language_scanner.l,v
> retrieving revision 1.170
> diff -u -r1.170 zend_language_scanner.l
> --- Zend/zend_language_scanner.l	9 Sep 2007 22:49:31 -0000	1.170
> +++ Zend/zend_language_scanner.l	3 Oct 2007 02:42:31 -0000
> @@ -1483,6 +1483,9 @@
>  }
>  
>  <ST_IN_SCRIPTING>"function" {
> +	if (CG(active_class_entry)) {
> +		yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
> +	}
>  	return T_FUNCTION;
>  }
>  
> @@ -1627,6 +1630,14 @@
>  	return T_OBJECT_OPERATOR;
>  }
>  
> +<ST_LOOKING_FOR_PROPERTY>{WHITESPACE} {
> +	Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
> +	Z_STRLEN_P(zendlval) = yyleng;
> +	Z_TYPE_P(zendlval) = IS_STRING;
> +	HANDLE_NEWLINES(yytext, yyleng);
> +	return T_WHITESPACE;
> +}
> +
>  <ST_LOOKING_FOR_PROPERTY>{LABEL} {
>  	yy_pop_state(TSRMLS_C);
>  	if (!zend_copy_scanner_string(zendlval, yytext, yyleng, UG(unicode)?IS_UNICODE:IS_STRING, SCNG(output_conv) TSRMLS_CC)) {
> @@ -1644,6 +1655,7 @@
>  }
>  
>  <ST_IN_SCRIPTING>"::" {
> +	yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
>  	return T_PAAMAYIM_NEKUDOTAYIM;
>  }
