Adding wfParsePHP() to GlobalFunctions.php for use in the LocalisationUpdate extensio...
authorRoan Kattouw <catrope@users.mediawiki.org>
Tue, 16 Jun 2009 22:56:06 +0000 (22:56 +0000)
committerRoan Kattouw <catrope@users.mediawiki.org>
Tue, 16 Jun 2009 22:56:06 +0000 (22:56 +0000)
includes/GlobalFunctions.php

index 0505f0e..427543f 100644 (file)
@@ -3156,3 +3156,143 @@ function wfObjectToArray( $object, $recursive = true ) {
        
        return $array;
 }
+
+/**
+ * Safe equivalent of eval() that parses a statement of the form
+ * $varname = array( 'constant' => 'constant', ... ); or
+ * $varname = 'constant'; or
+ * $varname = 123;
+ * and refuses to execute anything.
+ *
+ * @return True on success ($varname set globally), false on failue
+ */
+function wfParsePHP( $php ) {
+       $tokens = token_get_all( "<?php $php" );
+       array_shift( $tokens ); // Discard <?php token
+       $token = array_shift( $tokens ); // $varname token
+       if ( @$token[0] == T_WHITESPACE )
+               $varToken = array_shift( $tokens ); // discard whitespace
+       if ( @$token[0] != T_VARIABLE )
+               return false;
+       $varname = substr( $token[1], 1 ); // discard leading $
+       
+       $token = array_shift( $tokens );
+       if ( @$token[0] == T_WHITESPACE )
+               $token = array_shift( $tokens ); // discard whitespace
+       if ( $token[0] != '=' )
+               return false;
+       
+       $isGood = true;
+       $varvalue = wfParsePHP_recursive( $tokens, $isGood );
+       if ( $isGood )
+               $GLOBALS[$varname] = $varvalue;
+       return $isGood;
+}
+
+function wfParsePHP_recursive( &$tokens, &$isGood ) {
+       $isGood = true;
+       $varvalue = null;
+       $token = array_shift( $tokens );
+       if ( @$token[0] == T_WHITESPACE )
+               $token = array_shift( $tokens ); // discard whitespace
+       if ( @$token[0] == T_ARRAY )
+               $vartype = 'array';
+       else if ( @$token[0] == T_CONSTANT_ENCAPSED_STRING )
+               $vartype = 'string';
+       else if ( @$token[0] == T_LNUMBER )
+               $vartype = 'integer';
+       else if ( @$token[0] == T_DNUMBER )
+               $vartype = 'float';
+       else if ( @$token[0] == T_STRING )
+               $vartype = 'other';
+       else
+               return $isGood = false;
+       
+       switch ( $vartype ) {
+               case 'string':
+                       $varvalue = stripslashes( substr( $token[1], 1, -1 ) );
+               break;
+               case 'integer':
+                       $base = 10;
+                       if ( $token[1][0] == '0' ) {
+                               if ( $token[1][1] == 'x' )
+                                       $base = 16;
+                               else
+                                       $base = 8;
+                       }
+                       $varvalue = intval( $token[1], $base );
+               break;
+               case 'float':
+                       $varvalue = (float)$token[1];
+               break;
+               case 'other':
+                       if ( strcasecmp( $token[1], 'true' ) == 0 )
+                               $varvalue = true;
+                       else if ( strcasecmp( $token[1], 'false' ) == 0 )
+                               $varvalue = false;
+                       else if ( strcasecmp( $token[1], 'null' ) == 0 )
+                               $varvalue = null;
+                       else
+                               return $isGood = false;
+               break;
+               case 'array':
+                       $varvalue = array();
+                       $token = array_shift( $tokens );
+                       if ( @$token[0] == T_WHITESPACE )
+                               $token = array_shift( $tokens ); // discard whitespace
+                       if ( @$token != '(' )
+                               return $isGood = false;
+                       
+                       $first = true;
+                       while( true ) {
+                               $token = array_shift( $tokens );
+                               //if(!$first) { var_dump($token);var_dump($tokens);die(); }
+                               if ( @$token[0] == T_WHITESPACE )
+                                       $token = array_shift( $tokens ); // discard whitespace
+                               array_unshift( $tokens, $token );
+                               //if(!$first) { var_dump($token);var_dump($tokens);die(); }
+                               $recGood = true;
+                               $key = null;
+                               $val = wfParsePHP_recursive( $tokens, $recGood );
+                               if ( !$recGood )
+                                       return $isGood = false;
+                               //var_dump($key);var_dump($tokens);die();
+                               $token = array_shift( $tokens );
+                               if ( @$token[0] == T_WHITESPACE )
+                                       $token = array_shift( $tokens ); // discard whitespace
+                               if ( @$token[0] == T_DOUBLE_ARROW ) {
+                                       $key = $val;
+                                       //die("2");
+                                       $token = array_shift( $tokens ); // discard =>
+                                       if ( @$token[0] == T_WHITESPACE )
+                                               $token = array_shift( $tokens );
+                                       //die("3");
+                                       array_unshift( $tokens, $token );
+                                       //var_dump($tokens);die();
+                                       $val = wfParsePHP_recursive( $tokens, $recGood );
+                                       //var_dump($val);var_dump($tokens);die();
+                                       if ( !$recGood )
+                                               return $isGood = false;
+                                       $token = array_shift( $tokens );
+                               }
+                               
+                               if ( is_null( $key ) )
+                                       $varvalue[] = $val;
+                               else
+                                       $varvalue[$key] = $val;
+                               
+                               if ( @$token[0] == T_WHITESPACE )
+                                       $token = array_shift( $tokens ); // discard whitespace
+                               //var_dump($token);var_dump($tokens);die();
+                               if ( $token == ')' )
+                                       break;
+                               else if ( $token != ',' )
+                                       return $isGood = false;
+                               $first = false;
+                       }
+               break;
+               default:
+                       return $isGood = false;
+       }
+       return $varvalue;
+}