/* Copyright (C) 2012-present by fent * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ const jsVarStr = '[a-zA-Z_\\$][a-zA-Z_0-9]*'; const jsSingleQuoteStr = `'[^'\\\\]*(:?\\\\[\\s\\S][^'\\\\]*)*'`; const jsDoubleQuoteStr = `"[^"\\\\]*(:?\\\\[\\s\\S][^"\\\\]*)*"`; const jsQuoteStr = `(?:${jsSingleQuoteStr}|${jsDoubleQuoteStr})`; const jsKeyStr = `(?:${jsVarStr}|${jsQuoteStr})`; const jsPropStr = `(?:\\.${jsVarStr}|\\[${jsQuoteStr}\\])`; const jsEmptyStr = `(?:''|"")`; const reverseStr = ':function\\(a\\)\\{' + '(?:return )?a\\.reverse\\(\\)' + '\\}'; const sliceStr = ':function\\(a,b\\)\\{' + 'return a\\.slice\\(b\\)' + '\\}'; const spliceStr = ':function\\(a,b\\)\\{' + 'a\\.splice\\(0,b\\)' + '\\}'; const swapStr = ':function\\(a,b\\)\\{' + 'var c=a\\[0\\];a\\[0\\]=a\\[b(?:%a\\.length)?\\];a\\[b(?:%a\\.length)?\\]=c(?:;return a)?' + '\\}'; const actionsObjRegexp = new RegExp( `var (${jsVarStr})=\\{((?:(?:${ jsKeyStr}${reverseStr}|${ jsKeyStr}${sliceStr}|${ jsKeyStr}${spliceStr}|${ jsKeyStr}${swapStr }),?\\r?\\n?)+)\\};`); const actionsFuncRegexp = new RegExp(`${`function(?: ${jsVarStr})?\\(a\\)\\{` + `a=a\\.split\\(${jsEmptyStr}\\);\\s*` + `((?:(?:a=)?${jsVarStr}`}${ jsPropStr }\\(a,\\d+\\);)+)` + `return a\\.join\\(${jsEmptyStr}\\)` + `\\}`); const reverseRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${reverseStr}`, 'm'); const sliceRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${sliceStr}`, 'm'); const spliceRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${spliceStr}`, 'm'); const swapRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${swapStr}`, 'm'); const swapHeadAndPosition = (arr, position) => { const first = arr[0]; arr[0] = arr[position % arr.length]; arr[position] = first; return arr; } function decipher(sig, tokens) { sig = sig.split(''); tokens = tokens.split(','); for(let i = 0, len = tokens.length; i < len; i++) { let token = tokens[i], pos; switch (token[0]) { case 'r': sig = sig.reverse(); break; case 'w': pos = ~~token.slice(1); sig = swapHeadAndPosition(sig, pos); break; case 's': pos = ~~token.slice(1); sig = sig.slice(pos); break; case 'p': pos = ~~token.slice(1); sig.splice(0, pos); break; } } return sig.join(''); }; function extractActions(body) { const objResult = actionsObjRegexp.exec(body); const funcResult = actionsFuncRegexp.exec(body); if(!objResult || !funcResult) return null; const obj = objResult[1].replace(/\$/g, '\\$'); const objBody = objResult[2].replace(/\$/g, '\\$'); const funcBody = funcResult[1].replace(/\$/g, '\\$'); let result = reverseRegexp.exec(objBody); const reverseKey = result && result[1] .replace(/\$/g, '\\$') .replace(/\$|^'|^"|'$|"$/g, ''); result = sliceRegexp.exec(objBody); const sliceKey = result && result[1] .replace(/\$/g, '\\$') .replace(/\$|^'|^"|'$|"$/g, ''); result = spliceRegexp.exec(objBody); const spliceKey = result && result[1] .replace(/\$/g, '\\$') .replace(/\$|^'|^"|'$|"$/g, ''); result = swapRegexp.exec(objBody); const swapKey = result && result[1] .replace(/\$/g, '\\$') .replace(/\$|^'|^"|'$|"$/g, ''); const keys = `(${[reverseKey, sliceKey, spliceKey, swapKey].join('|')})`; const myreg = `(?:a=)?${obj }(?:\\.${keys}|\\['${keys}'\\]|\\["${keys}"\\])` + `\\(a,(\\d+)\\)`; const tokenizeRegexp = new RegExp(myreg, 'g'); const tokens = []; while((result = tokenizeRegexp.exec(funcBody)) !== null) { const key = result[1] || result[2] || result[3]; const pos = result[4]; switch (key) { case swapKey: tokens.push(`w${result[4]}`); break; case reverseKey: tokens.push('r'); break; case sliceKey: tokens.push(`s${result[4]}`); break; case spliceKey: tokens.push(`p${result[4]}`); break; } } return tokens.join(','); }