j4k0xb / webcrack

Deobfuscate obfuscator.io, unminify and unpack bundled javascript
https://webcrack.netlify.app
MIT License
647 stars 73 forks source link

prettify html and css strings in tagged template literals #65

Closed milahu closed 4 months ago

milahu commented 4 months ago

currently, only the javascript code is pretty printed it would be nice to also pretty print html-in-javascript and css-in-javascript strings

im afraid this would require dynamic analysis of the template tag functions

a cheap fix would be guessing string type from string content = try to parse html, try to parse css, use what works

see also Template literals # Tagged templates

actual result: html and css strings are ugly long lines

class SomeElement extends HTMLElement {
  static #htmlNode = htmlNodeOfString` <template> <div id="container"> ... </div> </template> `;
  static #cssSheet = cssSheetOfString` :host { display: block; width: 100%; }`;
}

expected result: pretty print html and css strings

class SomeElement extends HTMLElement {
  static #htmlNode = htmlNodeOfString`
    <template>
      <div id="container">
        ...
      </div>
    </template>
  `;
  static #cssSheet= cssSheetOfString`
    :host {
      display: block;
      width: 100%;
    }
  `;
}
htmlNodeOfString is a html parser ```js let pn = document.createElement("template"); let htmlNodeOfString = (aC, ...aD) => { // build the string aF let aE = []; for (let aH = 0; aH < aC.length; aH += 1) { aE.push(aC[aH]); if (aD[aH] !== undefined) { aE.push(aD[aH]); } } let aF = aE.join(""); // parse the string aF pn.innerHTML = aF; // return html node let aG = document.importNode(pn.content, true); if (aG.children.length === 1) { return aG.firstElementChild; } else { return aG; } }; ```
cssSheetOfString is a css parser ```js let cssSheetOfString = (aC, ...aD) => { // build the string aF let aE = []; for (let aH = 0; aH < aC.length; aH += 1) { aE.push(aC[aH]); if (aD[aH] !== undefined) { aE.push(aD[aH]); } } let aF = aE.join(""); // parse the string aF let aG = new CSSStyleSheet(); aG.replaceSync(aF); // return css stylesheet return aG; }; ```
workaround: grep and prettier: prettify html strings ```sh #!/usr/bin/env bash for js_path in elements/*/*.js; do echo "patching $js_path" js_code=$(<"$js_path") while read line; do html_code=$(echo "$line" | cut -d'`' -f2) html_code_start=${html_code:0:50} echo " prettying ${html_code_start}..." html_code_new=$( echo echo "$html_code" | prettier --print-width 9999999999 --stdin-filepath x.html | sed 's/^/ /' echo ) js_code=${js_code/"$html_code"/"$html_code_new"} done < <(echo "$js_code" | grep -E ' = htmlNodeOfString`.') echo -n "$js_code" >"$js_path" done ```
workaround: grep and prettier: prettify css strings ```sh #!/usr/bin/env bash for js_path in elements/*/*.js; do echo "patching $js_path" js_code=$(<"$js_path") while read line; do css_code=$(echo "$line" | cut -d'`' -f2) css_code_start=${css_code:0:50} echo " prettying ${css_code_start}..." css_code_new=$( echo echo "$css_code" | prettier --print-width 9999999999 --stdin-filepath x.css | sed 's/^/ /' echo ) js_code=${js_code/"$css_code"/"$css_code_new"} done < <(echo "$js_code" | grep -E ' = cssSheetOfString`.') echo -n "$js_code" >"$js_path" done ```
workaround breaks on nested strings because `'...'` and `"..."` quotes cannot have multi-line strings ```js class SomeElement extends HTMLElement { static #htmlNode = htmlNodeOfString` `; ```
j4k0xb commented 4 months ago

the parser is from https://github.com/jarek-foksa/xel/blob/b68391d2787c76ec574948d649ab6e77ecb554d9/utils/template.js, including all elements: https://github.com/jarek-foksa/xel/blob/master/elements/x-tag.js so it doesn't make too much sense to develop some sophisticated guessing and prettifying when the source code is available another issue is that modifying the spaces and newlines can affect the formatting (e.g. in a <pre> element)

if you still wanna do it, I suggest renaming the functions to html and css, then letting prettier handle it: playground

milahu commented 4 months ago

renaming the functions to html and css

thanks! : )

#!/usr/bin/env bash

s=""

mangled_html="un"
mangled_css="xn"

# rename tagged template literals to html`...` and css`...`
# so prettier can prettify the string contents
# \b = word boundary   
s+='s/\b'$mangled_html'`/html`/g;'
s+='s/\b'$mangled_css'`/css`/g;'

# rename the tag functions to html and css
s+='s/let '$mangled_html' =/let html =/g;'
s+='s/let '$mangled_css' =/let css =/g;'

# replace html`${'str'}` with html`str`
# \b = word boundary
s+="s/\bhtml\`\\\$\{'([^'\`]*)'\}\`;/html\`\1\`;/g;"

sed -i -E "$s" elements/apps/bx-progressivewebapp.js

prettier -w \
  elements/apps/bx-progressivewebapp.js \