diff --git a/.gitignore b/.gitignore index 0e4389c..3c9aa04 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ static/bare-mux-worker.js meta.json rewriter/target rewriter/out +static/wasm.js diff --git a/rewriter/src/rewrite.rs b/rewriter/src/rewrite.rs index e16b54d..ad1ebdd 100644 --- a/rewriter/src/rewrite.rs +++ b/rewriter/src/rewrite.rs @@ -62,11 +62,13 @@ impl<'a> Visit<'a> for Rewriter { if UNSAFE_GLOBALS.contains(&s.name.to_string().as_str()) { self.jschanges.push(JsChange::GenericChange { span: s.span, - text: format!("$s({})", s.name), + text: format!("(globalThis.$s({}))", s.name), }); } } - _ => {} + _ => { + walk::walk_assignment_expression(self, expr); + } } } fn visit_variable_declarator(&mut self, it: &oxc_ast::ast::VariableDeclarator<'a>) { @@ -75,27 +77,17 @@ impl<'a> Visit<'a> for Rewriter { if UNSAFE_GLOBALS.contains(&s.name.to_string().as_str()) { self.jschanges.push(JsChange::GenericChange { span: s.span, - text: format!("$s({})", s.name), + text: format!("(globalThis.$s({}))", s.name), }); } } - _ => {} + _ => { + walk::walk_variable_declarator(self, it); + } } } fn visit_member_expression(&mut self, it: &MemberExpression<'a>) { self.trace_member(it); - // match it { - // MemberExpression::StaticMemberExpression(s) => { - // dbg!(s); - // if s.property.name.to_string() == "location" { - // self.jschanges.push(JsChange::GenericChange { - // span: s.property.span, - // text: "$s(location)".to_string(), - // }); - // } - // } - // _ => {} - // } } } @@ -119,14 +111,14 @@ impl Rewriter { if UNSAFE_GLOBALS.contains(&obj.name.to_string().as_str()) { self.jschanges.push(JsChange::GenericChange { span: obj.span, - text: format!("$s({})", obj.name), + text: format!("(globalThis.$s({}))", obj.name), }); } } Expression::ThisExpression(obj) => { self.jschanges.push(JsChange::GenericChange { span: obj.span, - text: "$s(this)".to_string(), + text: "(globalThis.$s(this))".to_string(), }); } _ => { @@ -140,14 +132,14 @@ impl Rewriter { if UNSAFE_GLOBALS.contains(&obj.name.to_string().as_str()) { self.jschanges.push(JsChange::GenericChange { span: obj.span, - text: format!("$s({})", obj.name), + text: format!("(globalThis.$s({}))", obj.name), }); } } Expression::ThisExpression(obj) => { self.jschanges.push(JsChange::GenericChange { span: obj.span, - text: "$s(this)".to_string(), + text: "(globalThis.$s(this))".to_string(), }); } _ => { diff --git a/src/client/index.ts b/src/client/index.ts index e7ee693..9fe11f1 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -13,6 +13,7 @@ import "./css.ts"; import "./history.ts"; import "./worker.ts"; import "./beacon.ts" +import "./origin.ts"; declare global { interface Window { diff --git a/src/client/origin.ts b/src/client/origin.ts new file mode 100644 index 0000000..35b4e76 --- /dev/null +++ b/src/client/origin.ts @@ -0,0 +1,42 @@ +import { decodeUrl } from "../shared/rewriters/url"; + + +// const descriptor = Object.getOwnPropertyDescriptor(window, "origin"); +delete window.origin; + +Object.defineProperty(window, "origin", { + get() { + return new URL(decodeUrl(location.href)).origin; + }, + set() { + return false; + }, +}); + + +Object.defineProperty(document, "URL", { + get() { + return decodeUrl(location.href); + }, + set() { + return false; + } +}) + +Object.defineProperty(document, "baseURI", { + get() { + return decodeUrl(location.href); + }, + set() { + return false; + } +}) + +Object.defineProperty(document, "domain", { + get() { + return new URL(decodeUrl(location.href)).hostname; + }, + set() { + return false; + } +}) diff --git a/src/client/requests/websocket.ts b/src/client/requests/websocket.ts index 5255ee5..990e961 100644 --- a/src/client/requests/websocket.ts +++ b/src/client/requests/websocket.ts @@ -1,3 +1,4 @@ +import { decodeUrl } from "../../shared/rewriters/url"; import { BareClient } from "../shared"; const client = new BareClient(); @@ -9,6 +10,7 @@ WebSocket = new Proxy(WebSocket, { target, { "User-Agent": navigator.userAgent, + "Origin": new URL(decodeUrl(location.href)).origin, }, ArrayBuffer.prototype ); diff --git a/src/client/scope.ts b/src/client/scope.ts index 4fe24c8..92a3d67 100644 --- a/src/client/scope.ts +++ b/src/client/scope.ts @@ -1,11 +1,13 @@ import { locationProxy } from "./location"; -import { windowProxy } from "./window"; +import { documentProxy, windowProxy } from "./window"; function scope(identifier: any) { if (identifier instanceof Window) { return windowProxy; } else if (identifier instanceof Location) { return locationProxy; + } else if (identifier instanceof Document) { + return documentProxy; } return identifier; diff --git a/src/client/window.ts b/src/client/window.ts index 7bfce26..a9db441 100644 --- a/src/client/window.ts +++ b/src/client/window.ts @@ -24,7 +24,9 @@ export const windowProxy = new Proxy(window, { const value = Reflect.get(target, prop); - if (typeof value === "function") { + + // this is bad! i don't know what the right thing to do is + if (typeof value === "function" && value != Object) { return value.bind(target); } @@ -45,3 +47,22 @@ export const windowProxy = new Proxy(window, { return Reflect.set(target, prop, newValue); }, }); + + +export const documentProxy = new Proxy(document, { + get(target, prop) { + const propIsString = typeof prop === "string"; + + if (propIsString && prop === "location") { + return locationProxy; + } + + const value = Reflect.get(target, prop); + + if (typeof value === "function") { + return value.bind(target); + } + + return value; + } +}); diff --git a/src/shared/rewriters/js.ts b/src/shared/rewriters/js.ts index d17852d..26a0b62 100644 --- a/src/shared/rewriters/js.ts +++ b/src/shared/rewriters/js.ts @@ -1,8 +1,8 @@ -// import { parseModule } from "meriyah"; -// import { generate } from "astring"; -// import { makeTraveler } from "astravel"; -// import { encodeUrl } from "./url"; -// import * as ESTree from "estree"; +import { parseModule } from "meriyah"; +import { generate } from "astring"; +import { makeTraveler } from "astravel"; +import { encodeUrl } from "./url"; +import * as ESTree from "estree"; // i am a cat. i like to be petted. i like to be fed. i like to be @@ -16,108 +16,114 @@ // top // parent -import init, { rewrite_js } from "../../../rewriter/out/rewriter.js"; -init("/rewriter_bg.wasm"); +import { initSync, rewrite_js } from "../../../rewriter/out/rewriter.js"; +import "../../../static/wasm.js"; + +initSync(new WebAssembly.Module( + Uint8Array.from(atob(WASM), c => c.charCodeAt(0)) +)) -// Also can take in origin?: URL export function rewriteJs(js: string) { const f = rewrite_js(js); - console.log(f) return f + + // console.log(f) + // + // return f + // try { + // const ast = parseModule(js, { + // module: true, + // webcompat: true, + // }); + // + // const identifierList = [ + // "window", + // "self", + // "globalThis", + // "this", + // "parent", + // "top", + // "location", + // ]; + // + // const customTraveler = makeTraveler({ + // ImportDeclaration: (node: ESTree.ImportDeclaration) => { + // node.source.value = encodeUrl(node.source.value as string, origin); + // }, + // + // ImportExpression: (node: ESTree.ImportExpression) => { + // if (node.source.type === "Literal") { + // node.source.value = encodeUrl(node.source.value as string, origin); + // } else if (node.source.type === "Identifier") { + // // this is for things that import something like + // // const moduleName = "name"; + // // await import(moduleName); + // node.source.name = `__wrapImport(${node.source.name})`; + // } + // }, + // + // ExportAllDeclaration: (node: ESTree.ExportAllDeclaration) => { + // node.source.value = encodeUrl(node.source.value as string, origin); + // }, + // + // ExportNamedDeclaration: (node: ESTree.ExportNamedDeclaration) => { + // // strings are Literals in ESTree syntax but these will always be strings + // if (node.source) + // node.source.value = encodeUrl(node.source.value as string, origin); + // }, + // + // MemberExpression: (node: ESTree.MemberExpression) => { + // if ( + // node.object.type === "Identifier" && + // identifierList.includes(node.object.name) + // ) { + // node.object.name = `globalThis.$s(${node.object.name})`; + // } + // }, + // + // AssignmentExpression: (node: ESTree.AssignmentExpression, more) => { + // if ( + // node.left.type === "Identifier" && + // identifierList.includes(node.left.name) + // ) { + // node.left.name = `globalThis.$s(${node.left.name})`; + // } + // + // if ( + // node.right.type === "Identifier" && + // identifierList.includes(node.right.name) + // ) { + // node.right.name = `globalThis.$s(${node.right.name})`; + // } + // }, + // ArrayExpression: (node: ESTree.ArrayExpression) => { + // node.elements.forEach((element) => { + // if (element.type === "Identifier" && identifierList.includes(element.name)) { + // element.name = `globalThis.$s(${element.name})`; + // } + // }); + // }, + // + // VariableDeclarator: (node: ESTree.VariableDeclarator) => { + // if ( + // node.init && + // node.init.type === "Identifier" && + // identifierList.includes(node.init.name) + // ) { + // node.init.name = `globalThis.$s(${node.init.name})`; + // } + // }, + // }); + // + // customTraveler.go(ast); + // + // return generate(ast); + // } catch (e) { + // console.error(e); + // console.log(js); + // + // return js; + // } } -// try { -// const ast = parseModule(js, { -// module: true, -// webcompat: true, -// }); -// -// const identifierList = [ -// "window", -// "self", -// "globalThis", -// "this", -// "parent", -// "top", -// "location", -// ]; -// -// const customTraveler = makeTraveler({ -// ImportDeclaration: (node: ESTree.ImportDeclaration) => { -// node.source.value = encodeUrl(node.source.value as string, origin); -// }, -// -// ImportExpression: (node: ESTree.ImportExpression) => { -// if (node.source.type === "Literal") { -// node.source.value = encodeUrl(node.source.value as string, origin); -// } else if (node.source.type === "Identifier") { -// // this is for things that import something like -// // const moduleName = "name"; -// // await import(moduleName); -// node.source.name = `__wrapImport(${node.source.name})`; -// } -// }, -// -// ExportAllDeclaration: (node: ESTree.ExportAllDeclaration) => { -// node.source.value = encodeUrl(node.source.value as string, origin); -// }, -// -// ExportNamedDeclaration: (node: ESTree.ExportNamedDeclaration) => { -// // strings are Literals in ESTree syntax but these will always be strings -// if (node.source) -// node.source.value = encodeUrl(node.source.value as string, origin); -// }, -// -// MemberExpression: (node: ESTree.MemberExpression) => { -// if ( -// node.object.type === "Identifier" && -// identifierList.includes(node.object.name) -// ) { -// node.object.name = `globalThis.$s(${node.object.name})`; -// } -// }, -// -// AssignmentExpression: (node: ESTree.AssignmentExpression, more) => { -// console.log(node, more); -// if ( -// node.left.type === "Identifier" && -// identifierList.includes(node.left.name) -// ) { -// node.left.name = `globalThis.$s(${node.left.name})`; -// } -// -// if ( -// node.right.type === "Identifier" && -// identifierList.includes(node.right.name) -// ) { -// node.right.name = `globalThis.$s(${node.right.name})`; -// } -// }, -// ArrayExpression: (node: ESTree.ArrayExpression) => { -// node.elements.forEach((element) => { -// if (element.type === "Identifier" && identifierList.includes(element.name)) { -// element.name = `globalThis.$s(${element.name})`; -// } -// }); -// }, -// -// VariableDeclarator: (node: ESTree.VariableDeclarator) => { -// if ( -// node.init && -// node.init.type === "Identifier" && -// identifierList.includes(node.init.name) -// ) { -// node.init.name = `globalThis.$s(${node.init.name})`; -// } -// }, -// }); -// -// customTraveler.go(ast); -// -// return generate(ast); -// } catch (e) { -// console.error(e); -// console.log(js); -// -// return js; -// } + diff --git a/src/shared/rewriters/url.ts b/src/shared/rewriters/url.ts index 74cd1ea..ee5bc1f 100644 --- a/src/shared/rewriters/url.ts +++ b/src/shared/rewriters/url.ts @@ -1,4 +1,4 @@ -;import { rewriteJs } from "./js"; +import { rewriteJs } from "./js"; function canParseUrl(url: string, origin?: URL) { try { diff --git a/src/worker/index.ts b/src/worker/index.ts index 1b91538..5d5a301 100644 --- a/src/worker/index.ts +++ b/src/worker/index.ts @@ -187,6 +187,7 @@ self.ScramjetServiceWorker = class ScramjetServiceWorker { if (!["document", "iframe"].includes(request.destination)) return new Response(undefined, { status: 500 }); + console.log("FOUND ERROR"); console.error(err); return renderError(err, decodeUrl(request.url)); @@ -200,8 +201,8 @@ function errorTemplate(trace: string, fetchedURL: string) { errorTrace.value = ${JSON.stringify(trace)}; fetchedURL.textContent = ${JSON.stringify(fetchedURL)}; for (const node of document.querySelectorAll("#hostname")) node.textContent = ${JSON.stringify( - location.hostname - )}; + location.hostname + )}; reload.addEventListener("click", () => location.reload()); version.textContent = "0.0.1"; `; @@ -238,9 +239,8 @@ function errorTemplate(trace: string, fetchedURL: string) {
Scramjet v
- +