WordPress.org

Make WordPress Core

Ticket #4005: gettext.php.2.diff

File gettext.php.2.diff, 1.6 KB (added by moeffju, 11 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  }