diff options
author | Thomas BrĂ¼derli | 2012-03-30 16:19:49 +0000 |
---|---|---|
committer | Thomas BrĂ¼derli | 2012-03-30 16:19:49 +0000 |
commit | 9c39a2a23c81da0d36070a8cb030ed076cf69bec (patch) | |
tree | 75eaa1dc4717746f4696cb1663c5c9c1fdcb0d10 | |
parent | 3242f516a6c3e89fa898d96927746447e15d7750 (diff) | |
download | itools-9c39a2a23c81da0d36070a8cb030ed076cf69bec.tar.gz itools-9c39a2a23c81da0d36070a8cb030ed076cf69bec.tar.bz2 itools-9c39a2a23c81da0d36070a8cb030ed076cf69bec.zip |
Make javascript delivery unicode-safe
-rw-r--r-- | itjs.class | 23 | ||||
-rw-r--r-- | itjs.php | 10 |
2 files changed, 21 insertions, 12 deletions
@@ -23,12 +23,18 @@ class itjs { +static $charset; /** * Send HTTP headers (content-type) to transmit javascript code */ -function send_headers($charset = 'iso-8859-1') +function send_headers($charset = null) { + if (!$charset) + $charset = ini_get('default_charset') ?: 'iso-8859-1'; + + self::$charset = $charset; + if (!preg_match('/Opera/', $_SERVER['HTTP_USER_AGENT']) && !$_REQUEST['itjs_iframe']) # text/plain breaks Opera 8.51/Linux and IFrame fallback header("Content-Type: text/plain; charset=$charset"); # Berni reported some Firewalls to require this @@ -67,16 +73,17 @@ function serialize($values, $envelope = false) */ function encode($values) { - $texts = ($values === array_values($values)) ? "[]0 " : "{}1\n"; # Numerical or associative array static $jskeyword = array("abstract" => 1, "boolean" => 1, "break" => 1, "byte" => 1, "case" => 1, "catch" => 1, "char" => 1, "class" => 1, "const" => 1, "continue" => 1, "debugger" => 1, "default" => 1, "delete" => 1, "do" => 1, "double" => 1, "each" => 1, "else" => 1, "enum" => 1, "export" => 1, "extends" => 1, "false" => 1, "final" => 1, "finally" => 1, "float" => 1, "for" => 1, "function" => 1, "goto" => 1, "if" => 1, "implements" => 1, "import" => 1, "in" => 1, "instanceof" => 1, "int" => 1, "interface" => 1, "long" => 1, "namespace" => 1, "native" => 1, "new" => 1, "null" => 1, "package" => 1, "private" => 1, "protected" => 1, "public" => 1, "return" => 1, "short" => 1, "static" => 1, "super" => 1, "switch" => 1, "synchronized" => 1, "this" => 1, "throw" => 1, "throws" => 1, "transient" => 1, "true" => 1, "try" => 1, "typeof" => 1, "var" => 1, "void" => 1, "volatile" => 1, "while" => 1, "with" => 1, "xml" => 1); - $result = $texts{0}; + $charset = self::$charset ?: ini_get('default_charset'); + $texts = ($values === array_values($values)) ? "[]0 " : "{}1\n"; # Numerical or associative array + $result = $texts[0]; foreach ($values as $key => $value) { $result .= $separator; - if ($texts{2}) + if ($texts[2]) { if ($jskeyword[$key] || !preg_match('/^[a-z_]\w*$/i', $key)) $key = "'$key'"; @@ -91,17 +98,19 @@ function encode($values) else if (!is_array($value)) { $quote = (strval(intval($value)) === strval($value)) ? "" : '"'; - $string = strtr($value, array("\0" => '\\0', "\x84" => '\\"', "\x93" => '\\"',"\x94" => '\\"', '"' => '\\"', "</"=>"<\\/", "\n" => '\\n', "\r" => '\\r', "\t" => '\\t', "\\" => '\\\\')); + if (strtolower($charset) != "utf-8") + $value = strtr($value, array("\x84" => '"', "\x93" => '"', "\x94" => '"')); + $string = strtr($value, array("\0" => '\\0', '"' => '\\"', "</"=>"<\\/", "\n" => '\\n', "\r" => '\\r', "\t" => '\\t', "\\" => '\\\\')); $string = $GLOBALS['itjs_defaultconfig']['latin2unicode'] ? preg_replace_callback('/([\xa0-\xff])/', function($m) { return sprintf("\\u%04x", ord($m[1])); }, $string) : $string; $result .= $quote . $string . $quote; } else $result .= itjs::encode($value); - $separator = "," . $texts{3}; + $separator = "," . $texts[3]; } - $result .= $texts{1}; + $result .= $texts[1]; return $result; } @@ -33,7 +33,7 @@ foreach ($files as $file) { ob_start(); # Needs to capture inside loop to guarantee file order if (!(it::match('W3C_CSS_Validator', $_SERVER['HTTP_USER_AGENT']) && it::match('jquery-ui\.css', $file))) - $data .= it::replace(array('^1$' => ""), @include($file)); + $data .= it::replace(array('^1$' => ""), @include($file), array('utf8' => false)); $data .= ob_get_clean(); } @@ -50,9 +50,8 @@ else if (it::match('\.css', $_SERVER['PHP_SELF'])) $data .= "\n#it_boot_dom { display:none }\n"; # Append magic style for it_boot if (!it::match('^devel', $GLOBALS['ULTRASERVERTYPE'])) $data = it::replace(array('[ \t]*([{};])[ \t]*' => '$1', '/\*.*?\*/' => ""), $data); - if (it::match('W3C_CSS_Validator', $_SERVER['HTTP_USER_AGENT']) || EDC('w3c')) { + if (it::match('W3C_CSS_Validator', $_SERVER['HTTP_USER_AGENT']) || EDC('w3c')) $data = it::replace(array('@-.*' => "", 'background[^;}]*(gradient|rgba)[^;}]*;?' => "", '(filter:\s*(progid|none)|text-overflow:|zoom:|-webkit-|display:-moz-|-moz-|-o-|cursor:|border-radius:|behavior:|\w+:expression)[^;}]*;?' => "", 'html\.ie6.*' => "", '([^/])\*(\w)' => '$1$2'), $data); - } } else if (it::match('\.htc$', $file)) { @@ -64,7 +63,8 @@ else if (!it::match('\.html$', $file)) if ($_REQUEST['boot'] && !$_REQUEST['retry']) ob_start('ob_gzhandler'); - header("Content-Type: application/x-javascript; charset=iso-8859-1"); + $charset = ini_get('default_charset') ?: 'iso-8859-1'; + header("Content-Type: application/x-javascript; charset=$charset"); } @header("Etag: $checksum"); @@ -80,7 +80,7 @@ if ($checksum != $_SERVER['HTTP_IF_NONE_MATCH']) { $data .= "window.it_boot_init();\n"; if (!$_REQUEST['script']) - $data = sprintf("/*sln:%d*/\n%s/*eln:%d*/", strlen($data), strtr($data, array('%' => "%25", '.' => "%2e", 'e' => "%65", 'i' => "%69")), strlen($data)); # Protect from Firewalls/Proxies altering Javascript source code + $data = sprintf("/*sln:%d*/\n%s/*eln:%d*/", grapheme_strlen($data), strtr($data, array('%' => "%25", '.' => "%2e", 'e' => "%65", 'i' => "%69")), grapheme_strlen($data)); # Protect from Firewalls/Proxies altering Javascript source code } echo it_untaint($data); |