feat: charset parsing & misc fixes

This commit is contained in:
Percs 2024-12-05 23:32:11 -06:00
parent d821554f57
commit 34bd4e5752
4 changed files with 73 additions and 95 deletions

View file

@ -240,7 +240,14 @@ export default function (client: ScramjetClient, self: typeof window) {
},
});
client.Trap("HTMLIFrameElement.prototype.contentWindow", {
client.Trap(
[
"HTMLIFrameElement.prototype.contentWindow",
"HTMLFrameElement.prototype.contentWindow",
"HTMLObjectElement.prototype.contentWindow",
"HTMLEmbedElement.prototype.contentWindow",
],
{
get(ctx) {
const realwin = ctx.get() as Window;
if (!realwin) return realwin;
@ -255,12 +262,22 @@ export default function (client: ScramjetClient, self: typeof window) {
return newclient.globalProxy;
}
},
});
}
);
client.Trap("HTMLIFrameElement.prototype.contentDocument", {
client.Trap(
[
"HTMLIFrameElement.prototype.contentDocument",
"HTMLFrameElement.prototype.contentDocument",
"HTMLObjectElement.prototype.contentDocument",
"HTMLEmbedElement.prototype.contentDocument",
],
{
get(ctx) {
const contentwindow =
client.descriptors["HTMLIFrameElement.prototype.contentWindow"].get;
client.descriptors[
`${ctx.this.constructor.name}.prototype.contentWindow`
].get;
const realwin = contentwindow.apply(ctx.this);
if (!realwin) return realwin;
@ -273,42 +290,8 @@ export default function (client: ScramjetClient, self: typeof window) {
return newclient.documentProxy;
}
},
});
client.Trap("HTMLFrameElement.prototype.contentWindow", {
get(ctx) {
const realwin = ctx.get() as Window;
if (!realwin) return realwin;
if (SCRAMJETCLIENT in realwin) {
return realwin[SCRAMJETCLIENT].globalProxy;
} else {
// hook the iframe
const newclient = new ScramjetClient(realwin);
newclient.hook();
return newclient.globalProxy;
}
},
});
client.Trap("HTMLFrameElement.prototype.contentDocument", {
get(ctx) {
const contentwindow =
client.descriptors["HTMLFrameElement.prototype.contentWindow"].get;
const realwin = contentwindow.apply(ctx.this);
if (!realwin) return realwin;
if (SCRAMJETCLIENT in realwin) {
return realwin[SCRAMJETCLIENT].documentProxy;
} else {
const newclient = new ScramjetClient(realwin);
newclient.hook();
return newclient.documentProxy;
}
},
});
);
client.Proxy(
[
@ -320,7 +303,7 @@ export default function (client: ScramjetClient, self: typeof window) {
apply(ctx) {
const doc = ctx.call();
if (doc) {
ctx.return(ctx.this.contentDocument);
return ctx.return(ctx.this.contentDocument);
}
},
}
@ -331,7 +314,7 @@ export default function (client: ScramjetClient, self: typeof window) {
return ctx.get();
},
set(ctx, value) {
if (value == client.documentProxy) {
if (value === client.documentProxy) {
return ctx.set(self.document);
}
@ -339,9 +322,19 @@ export default function (client: ScramjetClient, self: typeof window) {
},
});
client.Proxy("Document.prototype.open", {
apply(ctx) {
const doc = ctx.call() as Document;
const scram: ScramjetClient = doc[SCRAMJETCLIENT];
if (!scram) return ctx.return(doc); // ??
return ctx.return(scram.documentProxy);
},
});
client.Trap("Node.prototype.ownerDocument", {
get(ctx) {
// return client.documentProxy;
const doc = ctx.get() as Document | null;
if (!doc) return null;

View file

@ -2,26 +2,4 @@ export function getOwnPropertyDescriptorHandler(target, prop) {
const realDescriptor = Reflect.getOwnPropertyDescriptor(target, prop);
return realDescriptor;
// const d: PropertyDescriptor = {};
// if (realDescriptor.enumerable !== undefined)
// d.enumerable = realDescriptor.enumerable;
// if (realDescriptor.configurable !== undefined)
// d.configurable = realDescriptor.configurable;
// if (realDescriptor.writable !== undefined)
// d.writable = realDescriptor.writable;
// if (realDescriptor.get) {
// d.get = () => this.get(target, prop);
// }
// if (realDescriptor.set) {
// d.set = (value) => this.set(target, prop, value);
// }
// if (realDescriptor.value) {
// d.value = this.get(target, prop);
// }
// return d;
}

View file

@ -11,11 +11,6 @@ function rewriteFunction(ctx: ProxyCtx, client: ScramjetClient) {
export default function (client: ScramjetClient, _self: Self) {
const handler: Proxy = {
apply(ctx: ProxyCtx) {
if ((ctx.fn as any).alreadyProxied) {
debugger;
throw new Error("blah slop");
}
(ctx.fn as any).alreadyProxied = true;
rewriteFunction(ctx, client);
},
construct(ctx) {

View file

@ -319,7 +319,19 @@ async function rewriteBody(
case "iframe":
case "document":
if (response.headers.get("content-type")?.startsWith("text/html")) {
return rewriteHtml(await response.text(), cookieStore, meta, true);
// note from percs: i think this has the potential to be slow asf, but for right now its fine (we should probably look for a better solution)
const buf = await response.arrayBuffer();
const decode = new TextDecoder("utf-8").decode(buf);
const charsetHeader = response.headers.get("content-type");
const charset =
charsetHeader?.split("charset=")[1] ||
decode.match(/charset=([^"]+)/)?.[1] ||
"utf-8";
const htmlContent = charset
? new TextDecoder(charset).decode(buf)
: decode;
return rewriteHtml(htmlContent, cookieStore, meta, true);
} else {
return response.body;
}