Do variable variables in PHP allow invalid variable names?

I found what appears to be a PHP language abuse bug. When creating variable variables, you can declare and handle a seemingly illegal variable as long as you continue to access it as a variable. Example:

${'0'} = 1;         //I am an illegal variable called $0
${'0'}++;           //I can be accessed and manipulated.
var_dump(${'0'});   //Output: int(2)

      

This behavior looks rather strange. The official documentation for SimpleXml briefly mentions a way to create hyphenated variable names, but my example shows that it can be abused pretty badly nonetheless.

I would like to know how is this possible and valid when parsing code?

+3


source to share


2 answers


Internally PHP stores variables ( zend_array* symbol_table

) in the same data structure that is used for arrays . This allows you to have variable names with the same restrictions as array keys.

Eg. The Zend API function zend_set_local_var

sets a value to the symbol table with zend_hash_update

, which is a function used to manipulate PHP array types.

However, we cannot resolve every character to variable names in PHP source code. This is because lexical analysis must distinguish labels from other tokens. Variable variables offer a workaround for this.

This is not a mistake, but a way of misusing something. That being said, the documentation states that all labels, including variables, must be in the form of a regular expression [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

, so I won't rely on with arbitrary characters in variable names.



What it really does ${'0'} = 1;

is it sets the value to 1 on the current scope symbol table in the key 0

. You can get this table with get_defined_vars

. Looking at the source code , we can see that the function simply copies the current symbol table and returns it to the caller.

The PHP extract

function ( src ) actually checks that the keys are in a valid label format (by calling php_valid_var_name

), so you cannot generate funky named variables using that.

Anyway, while it is possible to create variables of any name using the variable variable syntax (even an unnamed variable ${''}

), I think this is bad practice. It's even worse if the library expects or forces you to do so. To say that the workaround might be a bit overpriced. Perhaps this should be seen as an implementation detail and an undocumented feature.

+3


source


@Nadav I don't have a complete idea of ​​this, but I have a little idea,

Remember that curly braces ({}) literally mean "evaluate what's inside curly braces", so you can condense the variable creation as you did $ {'0'} = 1 from this http://php.net/manual/ en / language.variables.php # 73373

PHP stores the variable in array form, if you want to check then use $ GLOBALS (array) - this is a super global variable that has all the reference to the variables present in the script, it stores the variable name as a key and the value as a variable value, let's say below case:



<?php
    ${'0'} = 1; // here php stores it as 0th index in the array
    ${'1'} = 2; // here php stores it as 1th index in the array
    $b = "I am b"; // here php stores it as bth index in the array
    echo "<pre>";
    print_r($GLOBALS);

      

output:

Array
(
    [_GET] => Array
        (
        )

    [_POST] => Array
        (
        )

    [_COOKIE] => Array
        (
        )

    [_FILES] => Array
        (
        )

    [GLOBALS] => Array
 *RECURSION*
    [0] => 1
    [1] => 2
    [b] => I am b
)

      

0


source







All Articles