WordPress.org

Make WordPress Core

Ticket #4005: gettext.php.2.diff

File gettext.php.2.diff, 1.6 KB (added by moeffju, 7 years ago)

Fix plural forms handling, revision 2 (better input sanitizing)

  • gettext.php

    old new  
    282282        $header = $this->cache_translations[""]; 
    283283      } else { 
    284284        $header = $this->get_translation_string(0); 
    285       } 
     285      } 
     286      $header .= "\n"; // make sure our regex matches 
    286287      if (eregi("plural-forms: ([^\n]*)\n", $header, $regs)) 
    287288        $expr = $regs[1]; 
    288289      else 
    289290        $expr = "nplurals=2; plural=n == 1 ? 0 : 1;"; 
    290       $this->pluralheader = $expr; 
     291 
     292      // sanitize 
     293      if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/', $expr, $matches)) { 
     294        $nplurals= preg_replace( '@[^0-9]@', '', $matches[1] ); 
     295        $plural= preg_replace( '@[^n0-9:\(\)\?\|\&=!<>+*/\%-]@', '', $matches[2] ); 
     296        $expr= 'nplurals='.$nplurals.';plural='.$plural; 
     297      } 
     298      else { 
     299        // malformed expression, use default ($expr is not overwritten) 
     300      } 
     301       
     302      // add parentheses 
     303      // important since PHP's ternary evaluates from left to right 
     304      $expr.= ';'; 
     305      $res= ''; 
     306      $p= 0; 
     307      for ($i= 0; $i < strlen($expr); $i++) { 
     308        $ch= $expr[$i]; 
     309        switch ($ch) { 
     310          case '?': 
     311            $res.= ' ? ('; 
     312            $p++; 
     313            break; 
     314          case ':': 
     315            $res.= ') : ('; 
     316            break; 
     317          case ';': 
     318            $res.= str_repeat( ')', $p) . ';'; 
     319            $p= 0; 
     320            break; 
     321          default: 
     322            $res.= $ch; 
     323        } 
     324      } 
     325 
     326      $this->pluralheader = $res; 
    291327    } 
    292328    return $this->pluralheader; 
    293329  }