r52011 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r52010‎ | r52011 | r52012 >
Date:22:56, 16 June 2009
Author:catrope
Status:reverted (Comments)
Tags:
Comment:
Adding wfParsePHP() to GlobalFunctions.php for use in the LocalisationUpdate extension (will update tomorrow).
Modified paths:
  • /trunk/phase3/includes/GlobalFunctions.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/GlobalFunctions.php
@@ -3156,3 +3156,143 @@
31573157
31583158 return $array;
31593159 }
 3160+
 3161+/**
 3162+ * Safe equivalent of eval() that parses a statement of the form
 3163+ * $varname = array( 'constant' => 'constant', ... ); or
 3164+ * $varname = 'constant'; or
 3165+ * $varname = 123;
 3166+ * and refuses to execute anything.
 3167+ *
 3168+ * @return True on success ($varname set globally), false on failue
 3169+ */
 3170+function wfParsePHP( $php ) {
 3171+ $tokens = token_get_all( "<?php $php" );
 3172+ array_shift( $tokens ); // Discard <?php token
 3173+ $token = array_shift( $tokens ); // $varname token
 3174+ if ( @$token[0] == T_WHITESPACE )
 3175+ $varToken = array_shift( $tokens ); // discard whitespace
 3176+ if ( @$token[0] != T_VARIABLE )
 3177+ return false;
 3178+ $varname = substr( $token[1], 1 ); // discard leading $
 3179+
 3180+ $token = array_shift( $tokens );
 3181+ if ( @$token[0] == T_WHITESPACE )
 3182+ $token = array_shift( $tokens ); // discard whitespace
 3183+ if ( $token[0] != '=' )
 3184+ return false;
 3185+
 3186+ $isGood = true;
 3187+ $varvalue = wfParsePHP_recursive( $tokens, $isGood );
 3188+ if ( $isGood )
 3189+ $GLOBALS[$varname] = $varvalue;
 3190+ return $isGood;
 3191+}
 3192+
 3193+function wfParsePHP_recursive( &$tokens, &$isGood ) {
 3194+ $isGood = true;
 3195+ $varvalue = null;
 3196+ $token = array_shift( $tokens );
 3197+ if ( @$token[0] == T_WHITESPACE )
 3198+ $token = array_shift( $tokens ); // discard whitespace
 3199+ if ( @$token[0] == T_ARRAY )
 3200+ $vartype = 'array';
 3201+ else if ( @$token[0] == T_CONSTANT_ENCAPSED_STRING )
 3202+ $vartype = 'string';
 3203+ else if ( @$token[0] == T_LNUMBER )
 3204+ $vartype = 'integer';
 3205+ else if ( @$token[0] == T_DNUMBER )
 3206+ $vartype = 'float';
 3207+ else if ( @$token[0] == T_STRING )
 3208+ $vartype = 'other';
 3209+ else
 3210+ return $isGood = false;
 3211+
 3212+ switch ( $vartype ) {
 3213+ case 'string':
 3214+ $varvalue = stripslashes( substr( $token[1], 1, -1 ) );
 3215+ break;
 3216+ case 'integer':
 3217+ $base = 10;
 3218+ if ( $token[1][0] == '0' ) {
 3219+ if ( $token[1][1] == 'x' )
 3220+ $base = 16;
 3221+ else
 3222+ $base = 8;
 3223+ }
 3224+ $varvalue = intval( $token[1], $base );
 3225+ break;
 3226+ case 'float':
 3227+ $varvalue = (float)$token[1];
 3228+ break;
 3229+ case 'other':
 3230+ if ( strcasecmp( $token[1], 'true' ) == 0 )
 3231+ $varvalue = true;
 3232+ else if ( strcasecmp( $token[1], 'false' ) == 0 )
 3233+ $varvalue = false;
 3234+ else if ( strcasecmp( $token[1], 'null' ) == 0 )
 3235+ $varvalue = null;
 3236+ else
 3237+ return $isGood = false;
 3238+ break;
 3239+ case 'array':
 3240+ $varvalue = array();
 3241+ $token = array_shift( $tokens );
 3242+ if ( @$token[0] == T_WHITESPACE )
 3243+ $token = array_shift( $tokens ); // discard whitespace
 3244+ if ( @$token != '(' )
 3245+ return $isGood = false;
 3246+
 3247+ $first = true;
 3248+ while( true ) {
 3249+ $token = array_shift( $tokens );
 3250+ //if(!$first) { var_dump($token);var_dump($tokens);die(); }
 3251+ if ( @$token[0] == T_WHITESPACE )
 3252+ $token = array_shift( $tokens ); // discard whitespace
 3253+ array_unshift( $tokens, $token );
 3254+ //if(!$first) { var_dump($token);var_dump($tokens);die(); }
 3255+ $recGood = true;
 3256+ $key = null;
 3257+ $val = wfParsePHP_recursive( $tokens, $recGood );
 3258+ if ( !$recGood )
 3259+ return $isGood = false;
 3260+ //var_dump($key);var_dump($tokens);die();
 3261+ $token = array_shift( $tokens );
 3262+ if ( @$token[0] == T_WHITESPACE )
 3263+ $token = array_shift( $tokens ); // discard whitespace
 3264+ if ( @$token[0] == T_DOUBLE_ARROW ) {
 3265+ $key = $val;
 3266+ //die("2");
 3267+ $token = array_shift( $tokens ); // discard =>
 3268+ if ( @$token[0] == T_WHITESPACE )
 3269+ $token = array_shift( $tokens );
 3270+ //die("3");
 3271+ array_unshift( $tokens, $token );
 3272+ //var_dump($tokens);die();
 3273+ $val = wfParsePHP_recursive( $tokens, $recGood );
 3274+ //var_dump($val);var_dump($tokens);die();
 3275+ if ( !$recGood )
 3276+ return $isGood = false;
 3277+ $token = array_shift( $tokens );
 3278+ }
 3279+
 3280+ if ( is_null( $key ) )
 3281+ $varvalue[] = $val;
 3282+ else
 3283+ $varvalue[$key] = $val;
 3284+
 3285+ if ( @$token[0] == T_WHITESPACE )
 3286+ $token = array_shift( $tokens ); // discard whitespace
 3287+ //var_dump($token);var_dump($tokens);die();
 3288+ if ( $token == ')' )
 3289+ break;
 3290+ else if ( $token != ',' )
 3291+ return $isGood = false;
 3292+ $first = false;
 3293+ }
 3294+ break;
 3295+ default:
 3296+ return $isGood = false;
 3297+ }
 3298+ return $varvalue;
 3299+}

Follow-up revisions

RevisionCommit summaryAuthorDate
r52043Self-revert r52011 per CR commentscatrope11:01, 17 June 2009
r52332Merge from trunk (r52011-r52330)demon23:20, 23 June 2009

Comments

#Comment by Tim Starling (talk | contribs)   08:47, 17 June 2009

You're kidding, right? Move it to its own module, we don't need this kind of bloat in GlobalFunctions.php. And get rid of the unlimited recursion, it sucks. I implemented a recursion-free parser for token_get_all() in /tools/switch-master/ConfEditor.php. It can parse the core localisation files already and could easily parse the extension files too with a slight change. It has error reporting and doesn't have debugging code scattered through it. You could use the parser from that.

#Comment by Catrope (talk | contribs)   08:53, 17 June 2009

I know the location is bad. but I needed sleep after writing it :)

I'll look at your parser; come to think of it, mine can't parse extension files without large changes.

Status & tagging log