r110321 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r110320‎ | r110321 | r110322 >
Date:19:45, 30 January 2012
Author:krinkle
Status:reverted (Comments)
Tags:core 
Comment:
[Xml::encodeJsVar] Use FormatJson::encode / native json_encode instead
* Follows-up r110320
* XmlTest.php passes
Modified paths:
  • /trunk/phase3/includes/Xml.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Xml.php
@@ -607,52 +607,19 @@
608608 }
609609
610610 /**
611 - * Encode a variable of unknown type to JavaScript.
612 - * Arrays are converted to JS arrays, objects are converted to JS associative
613 - * arrays (objects). So cast your PHP associative arrays to objects before
614 - * passing them to here.
 611+ * Encode a variable of unknown type to JavaScript. If you're not dealing
 612+ * with potential instances of XmlJsCode (which bypass encoding), then
 613+ * FormatJson::encode should be used directly.
615614 *
616615 * @param $value
617616 *
618617 * @return string
619618 */
620619 public static function encodeJsVar( $value ) {
621 - if ( is_bool( $value ) ) {
622 - $s = $value ? 'true' : 'false';
623 - } elseif ( is_null( $value ) ) {
624 - $s = 'null';
625 - } elseif ( is_int( $value ) || is_float( $value ) ) {
626 - $s = strval($value);
627 - } elseif ( is_array( $value ) && // Make sure it's not associative.
628 - array_keys($value) === range( 0, count($value) - 1 ) ||
629 - count($value) == 0
630 - ) {
631 - $s = '[';
632 - foreach ( $value as $elt ) {
633 - if ( $s != '[' ) {
634 - $s .= ',';
635 - }
636 - $s .= self::encodeJsVar( $elt );
637 - }
638 - $s .= ']';
639 - } elseif ( $value instanceof XmlJsCode ) {
640 - $s = $value->value;
641 - } elseif ( is_object( $value ) || is_array( $value ) ) {
642 - // Objects and associative arrays
643 - $s = '{';
644 - foreach ( (array)$value as $name => $elt ) {
645 - if ( $s != '{' ) {
646 - $s .= ',';
647 - }
648 -
649 - $s .= '"' . self::escapeJsString( $name ) . '":' .
650 - self::encodeJsVar( $elt );
651 - }
652 - $s .= '}';
653 - } else {
654 - $s = '"' . self::escapeJsString( $value ) . '"';
 620+ if ( $value instanceof XmlJsCode ) {
 621+ return $value->value;
655622 }
656 - return $s;
 623+ return FormatJson::encode( $value );
657624 }
658625
659626 /**

Follow-up revisions

RevisionCommit summaryAuthorDate
r110900Revert r110321: introduces an XSS vulnerability because FormatJson::encode() ...tstarling00:03, 8 February 2012

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r110320[Xml::encodeJsVar] Change to match FormatJson::encode output...krinkle19:40, 30 January 2012

Comments

#Comment by Catrope (talk | contribs)   20:18, 2 February 2012

This isn't 100% equivalent, because people could pass in XmlJsCode objects hidden in a deeply nested structure (e.g. Xml::encodeJsVar( array( 'foo' => new XmlJsCode( '1 + 2' ) ) ). However, I've looked at the code that uses XmlJsCode (only three occurrences, all in ResourceLoader.php) and none of them use this kind of nesting, so this is fine.

Status & tagging log