/resources/compiler/cJSCompiler.php
PHP | 324 lines | 213 code | 61 blank | 50 comment | 32 complexity | 8d649717610a23201c857bb071c2158e MD5 | raw file
Possible License(s): GPL-2.0
- <?php
- class cJSCompiler
- {
- var $output = "";
- var $aStrings = array();
-
- var $keyword = "munged";
- var $debug = false;
-
- function cJSCompiler() {
-
- }
-
- function readFromString($sString) {
- $this->output = $sString;
- }
-
- function readFromFile($sFileName) {
- $this->output = $this->output . join("", file($sFileName));
- }
-
- function getOutput() {
- return $this->output;
- }
-
- function addOmmitArray($aOmmit) {
- for ($nIndex = 0; $nIndex < count($aOmmit); $nIndex++)
- $this->addOmmitString($aOmmit[$nIndex]);
- }
-
- function addOmmitString($sString) {
- if (!in_array($sString, $this->aStrings))
- array_push($this->aStrings, $sString);
- }
-
- function stripComments() {
- $sData = $this->output;
-
- // Strip '//' comments
- $sData = str_replace('://', '?????', $sData);
- $sData = preg_replace('/\/\/.*(\r?\n)/', "", $sData);
- $sData = str_replace('?????', '://', $sData);
-
- // Strip '/* comment */' comments
- $sData = preg_replace('/\/\*.+\*\//Us', "", $sData);
-
- $this->output = $sData;
- }
-
- function stripSpaces() {
- $sData = $this->output;
-
- // replace tabs with spaces
- $sData = str_replace(" ", " ", $sData);
-
- // Strip ' : ' spaces around
- $sData = preg_replace('/\s*([=\+\-\*\/\?\:\|\&\^\!<>\{\},%;\(\)])\s*/', '\\1', $sData);
- //
- $sData = preg_replace('/\s*(if|for|with|do|while|try|catch)\s+/', '\\1', $sData);
-
- // strip carriage returns
- $sData = preg_replace("/\r\n|\r|\n/", "", $sData);
- // strip all more than one spaces
- $sData = preg_replace("/\s\s+/", "", $sData);
-
- // correct the bug produced above
- $sData = str_replace("else", "else ", $sData);
- $sData = str_replace("else {", "else{", $sData);
- $sData = str_replace(";}", "}", $sData);
-
- $this->output = $sData;
- }
-
- /*
- * Obfuscates variables (starting with any known variable prefix)
- *
- */
- function obfuscateVariables() {
- $sData = $this->output;
-
- preg_match_all('/[^a-zA-Z]([a-z][A-Z][a-zA-Z0-9_]+)/', $sData, $aTemp);
-
- $aValues = array_unique($aTemp[1]);
- sort($aValues);
- reset($aValues);
-
- // $aValues = $this->_normalizeArray($aTemp[1]);
-
- // Debug
- if ($this->debug)
- echo "Processing local variables:\n";
-
- for ($nIndex = count($aValues)-1; $nIndex >= 0; $nIndex--) {
- $sReplace = /*$nIndex < 26 ? chr(97 + $nIndex) :*/ $this->createToken($nIndex);
-
- $sData = str_replace($aValues[$nIndex], $sReplace, $sData);
- // $sData = preg_replace('/(\W)' . $aValues[$nIndex] . '(\W)/', '$1' . $sReplace . '$2', $sData);
-
- // Debug
- if ($this->debug)
- echo $aValues[$nIndex] . " [" . count(array_intersect($aTemp[1], array($aValues[$nIndex]))). "] -> " . $sReplace . "\n";
- }
- // Debug
- if ($this->debug)
- echo "\n";
-
- $this->output = $sData;
- }
-
- /*
- * Obfuscates private properties (starting with "_" prefix)
- *
- */
- function obfuscatePrivates() {
- $sData = $this->output;
-
- preg_match_all('/(\._[a-z_]+)/i', $sData, $aTemp);
- $aValues = array_unique($aTemp[1]);
- sort($aValues);
- reset($aValues);
-
- // Debug
- if ($this->debug)
- echo "Processing private members:\n";
-
- for ($nIndex = count($aValues)-1; $nIndex >= 0; $nIndex--) {
- $sReplace = "." . $this->createToken($nIndex);
- $sData = str_replace($aValues[$nIndex], $sReplace, $sData);
-
- // Debug
- if ($this->debug)
- echo $aValues[$nIndex] . " [" . count(array_intersect($aTemp[1], array($aValues[$nIndex]))). "] -> " . $sReplace . "\n";
- }
- // Debug
- if ($this->debug)
- echo "\n";
-
- $this->output = $sData;
- }
-
- function obfuscateStrings() {
- $sData = $this->output;
- $sDataTemp = $sData;
- if (count($this->aStrings))
- $sDataTemp = str_replace($this->aStrings, array_fill(0, count($this->aStrings), ""), $sDataTemp);
-
- // find "values"
- preg_match_all('/\"([a-z0-9_\-+\#\:\;\/\.]{2,})\"/i', $sDataTemp, $aTempValues);
-
- // find .properties
- preg_match_all('/\.(\$?[a-z][a-z0-9_]{2,})/i', $sDataTemp, $aTempProperties);
- /*
- $this->aStrings = array_unique(array_merge($this->aStrings, $aTempValues[1], $aTempProperties[1]));
- sort($this->aStrings);
- reset($this->aStrings);
- */
- $this->aStrings = $this->_normalizeArray(array_merge($this->aStrings, $aTempValues[1], $aTempProperties[1]));
-
- // Debug
- if ($this->debug)
- echo "Processing public properties and string values:\n";
-
- // manually replace most used property "prototype"
- $sData = str_replace(".prototype", "[$]", $sData);
-
- // Strings
- for ($nIndex = count($this->aStrings)-1; $nIndex >= 0; $nIndex--)
- $sData = str_replace( '"' . $this->aStrings[$nIndex] . '"', "_[" . $nIndex . ']', $sData);
-
- // Properties
- for ($nIndex = count($this->aStrings)-1; $nIndex >= 0; $nIndex--) {
- /*
- $sData = str_replace( '.' . $this->aStrings[$nIndex], "[_[" . $nIndex . ']]', $sData);
- */
- $sData = preg_replace( '/\.' .
- str_replace(
- array('/', '.', '$'),
- array('\/', '\.', '\$'),
- $this->aStrings[$nIndex]
- ). '(?!\w)/', "[_[" . $nIndex . ']]', $sData);
-
- // Debug
- if ($this->debug)
- echo $this->aStrings[$nIndex] . " [" . count(array_intersect(array_merge($aTempValues[1], $aTempProperties[1]), array($this->aStrings[$nIndex]))). "]\n";
- }
-
- // Debug
- if ($this->debug)
- echo "\n";
-
- $this->output = $sData;
- }
-
- function obfuscate() {
- // get or create obfuscated properties
- $nWString = array_search("String", $this->aStrings);
- if (!$nWString)
- $nWString = array_push($this->aStrings, "String") - 1;
- $nWMath = array_search("Math", $this->aStrings);
- if (!$nWMath)
- $nWMath = array_push($this->aStrings, "Math") - 1;
- $nWRegExp = array_search("RegExp", $this->aStrings);
- if (!$nWRegExp)
- $nWRegExp = array_push($this->aStrings, "RegExp") - 1;
- $nWFunction = array_search("Function", $this->aStrings);
- if (!$nWFunction)
- $nWFunction = array_push($this->aStrings, "Function") - 1;
- $nWlength = array_search("length", $this->aStrings);
- if (!$nWlength)
- $nWlength = array_push($this->aStrings, "length") - 1;
- $nWreplace = array_search("replace", $this->aStrings);
- if (!$nWreplace)
- $nWreplace = array_push($this->aStrings, "replace") - 1;
- $nWsplit = array_search("split", $this->aStrings);
- if (!$nWsplit)
- $nWsplit = array_push($this->aStrings, "split") - 1;
- $nWfromCharCode = array_search("fromCharCode", $this->aStrings);
- if (!$nWfromCharCode)
- $nWfromCharCode = array_push($this->aStrings, "fromCharCode") - 1;
- $nWcharCodeAt = array_search("charCodeAt", $this->aStrings);
- if (!$nWcharCodeAt)
- $nWcharCodeAt = array_push($this->aStrings, "charCodeAt") - 1;
- $nWfloor = array_search("floor", $this->aStrings);
- if (!$nWfloor)
- $nWfloor = array_push($this->aStrings, "floor") - 1;
-
- $output = $this->output;
- $sKeyWords = "";
- $nShift = 1;
-
- if (true) {
- $aKeyWords = array();
- $aKeyWords = array_merge($aKeyWords, array("in", "break", "case", "catch", "continue", "default", "delete", "else", "for", "function", "if", "instanceof", "new", "return", "throw", "typeof", "switch", "try", "var", "while", "with"));
- $aKeyWords = array_merge($aKeyWords, array("false", "null", "true"));
- $aKeyWords = array_merge($aKeyWords, array("arguments", "this", "window"));
- $aKeyWords = array_merge($aKeyWords, array("[_[", "]]", "[$]"));
- $aKeyWords = array_merge($aKeyWords, array("[]", "{}", "()", "&&", "||", "===", "==", "!!", "!==", "!=", "+=", "-=", "++", "--", "<=", ">="));
-
- // replace js keywords
- for ($nIndex = count($aKeyWords) - 1; $nIndex >= 0; $nIndex--)
- $output = str_replace($aKeyWords[$nIndex], ($nIndex % 10) . chr(122 - floor($nIndex/10)), $output);
-
- // encode keywords
- $sKeyWords = join(" ", $aKeyWords);
- $sKeyWords2 = "";
- for ($nIndex = strlen($sKeyWords) - 1; $nIndex >= 0; $nIndex--)
- $sKeyWords2 .= chr(ord(substr($sKeyWords, $nIndex, 1)) + $nShift);
- $sKeyWords = $sKeyWords2;
- }
-
- $m = $this->keyword[0];
- $u = $this->keyword[1];
- $n = $this->keyword[2];
- $g = $this->keyword[3];
- $e = $this->keyword[4];
- $d = $this->keyword[5];
-
- // create JS wrapper
- $sData = "(function({$m},{$u},{$n},{$g},{$e},{$d}){";
- if (true) {
- // decode js keywords
- $sData.= "for({$g}={$u}[{$d}[$nWlength]]-1;{$g}>=0;{$g}--)".
- "{$n}+={$e}[{$d}[$nWString]][{$d}[$nWfromCharCode]]({$u}[{$d}[$nWcharCodeAt]]({$g})-$nShift);";
- // restore js source
- $sData.= "{$u}={$n}[{$d}[$nWsplit]](' ');".
- "for({$g}={$u}[{$d}[$nWlength]]-1;{$g}>=0;{$g}--)".
- "{$m}={$m}[{$d}[$nWreplace]]({$e}[{$d}[$nWRegExp]]({$g}%10+({$e}[{$d}[$nWString]][{$d}[$nWfromCharCode]](122-{$e}[{$d}[$nWMath]][{$d}[$nWfloor]]({$g}/10))),'g'),{$u}[{$g}]);";
- }
-
- // execute source
- $sData .= "{$e}[{$d}[$nWFunction]]('_','$',{$m})({$d},{$d}[" . array_search("prototype", $this->aStrings) . "])";
-
- $sData .= "})(".
- "\"" . str_replace("\'", "'", addslashes($output)) . "\"," .
- "\"" . addslashes($sKeyWords) ."\",".
- "''," .
- "0," .
- "this,".
- "'" . join(" ", $this->aStrings) . "'.split(' ')".
- ")";
-
- $this->output = $sData;
- }
-
- function obfuscate2() {
- $output = $this->output;
-
- // Restore prototype to proper reference
- // $output = str_replace("[$]", "[_[0]]", $output);
-
- $sData = "(function($,_,_\$){"
- . str_replace("window", "_\$", $output)
- . "})('prototype','" . join(" ", $this->aStrings) . "'.split(' '),window)";
-
- $this->output = $sData;
- }
-
- function _normalizeArray($aTemp) {
- $aValuesTemp = array();
- for ($nIndex = count($aTemp) - 1; $nIndex >= 0; $nIndex--) {
- if (array_key_exists($aTemp[$nIndex], $aValuesTemp))
- $aValuesTemp[$aTemp[$nIndex]]++;
- else
- $aValuesTemp[$aTemp[$nIndex]] = 1;
- }
- arsort($aValuesTemp);
- // print_r($aValuesTemp);
- $aValues = array_keys($aValuesTemp);
- return $aValues;
- }
-
- var $reservedTokens = array("as", "do", "if", "in", "is", "for"/*, "let"*/, "var");
- var $alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
- function createToken($nIndex) {
- $sToken = $nIndex < 52
- ? substr($this->alphabet, $nIndex, 1)
- : substr($this->alphabet, (int) ($nIndex / 52), 1) . substr($this->alphabet, $nIndex % 62, 1);
- $nPosition = array_search($sToken, $this->reservedTokens);
-
- return $nPosition ? "_" . chr(97 + $nPosition % 62) : $sToken;
- }
- }
- ?>