diff --git a/README.md b/README.md index 8781974..3f593ea 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Please report any issue you have with those (only for mainstream browsers) Also, use this if you plan to use b4k's archive. - [Install 4chanX (recommended)](https://www.4chan-x.net/builds/4chan-X.user.js) -- Install the correct WebExtension for your Browser ([Firefox](https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.284.xpi) or Chrome-based (Down for "maintainance")) +- Install the correct WebExtension for your Browser ([Firefox](https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.285.xpi) or Chrome-based (Down for "maintainance")) For FF users, the extension is signed so you can just drag and drop it on your about:addons tab. diff --git a/chrome/dist/main.js b/chrome/dist/main.js index 5afca54..1c130ad 100644 --- a/chrome/dist/main.js +++ b/chrome/dist/main.js @@ -73,7 +73,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 284]; + define_BUILD_VERSION_default = [0, 285]; } }); @@ -14135,18 +14135,18 @@ constructor(reader, strict = true) { this.reader = reader; this.strict = strict; - this.stopped = false; this.req = 8; this.ptr = 8; + this.stopped = false; this.repr = import_buffer.Buffer.from([]); } async catchup() { while (this.repr.byteLength < this.req) { const chunk = await this.reader.read(); if (chunk.done) { - this.stopped = true; if (this.strict) throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + this.stopped = true; return; } this.repr = import_buffer.Buffer.concat([this.repr, chunk.value]); @@ -14162,18 +14162,22 @@ const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; this.req += length + 4; - const pos = this.ptr + length + 8; - await this.catchup(); + const pos = this.ptr; yield [ name, - this.repr.slice(this.ptr, this.ptr + length + 4), - this.repr.readUInt32BE(this.ptr + length + 4), + async () => { + await this.catchup(); + return this.repr.slice(pos, pos + length + 4); + }, + async () => { + await this.catchup(); + return this.repr.readUInt32BE(this.ptr + length + 4); + }, this.ptr ]; - this.ptr += length + 8; - await this.catchup(); if (this.stopped) break; + this.ptr += length + 8; if (name == "IEND") break; } @@ -14181,34 +14185,24 @@ async dtor() { } }; - var SyncBufferWriter = class { - constructor() { - this.cumul = []; - } - write(b) { - this.cumul.push(b); - } - getBuffer() { - return import_buffer.Buffer.concat(this.cumul); - } - }; var PNGEncoder = class { - constructor(writer) { - this.writer = writer; + constructor(bytes) { + this.writer = bytes.getWriter(); this.writer.write(import_buffer.Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])); } - insertchunk(chunk) { + async insertchunk(chunk) { let b = import_buffer.Buffer.alloc(4); - const buff = chunk[1]; + const buff = await chunk[1](); b.writeInt32BE(buff.length - 4, 0); - this.writer.write(b); - this.writer.write(buff); + await this.writer.write(b); + await this.writer.write(buff); b = import_buffer.Buffer.alloc(4); b.writeInt32BE((0, import_crc_32.buf)(buff), 0); - this.writer.write(b); - console.log("finished inserting"); + await this.writer.write(b); } async dtor() { + this.writer.releaseLock(); + await this.writer.close(); } }; var BufferWriteStream = () => { @@ -17964,7 +17958,7 @@ let buff; switch (name) { case "tEXt": - buff = chunk; + buff = await chunk(); if (buff.slice(4, 4 + CUM3.length).equals(CUM3)) { const k = await decodeCoom3Payload(buff.slice(4 + CUM3.length)); ret.push(...k.filter((e) => e).map((e) => e)); @@ -18008,7 +18002,7 @@ case "IDAT": if (ret.length) return ret; - buff = chunk; + buff = await chunk(); idats.push(buff.slice(4)); case "IEND": complete = true; @@ -18039,6 +18033,16 @@ data.copy(ret, 4); return ret; }; + var BufferWriteStream2 = () => { + let b = import_buffer3.Buffer.from([]); + const ret = new WritableStream({ + write(chunk) { + b = import_buffer3.Buffer.concat([b, chunk]); + console.log("finished appending"); + } + }); + return [ret, () => b]; + }; var embedInRawDeflate = (b, h) => { const src = new BitstreamReader2(); const hid = new BitstreamReader2(); @@ -18056,8 +18060,8 @@ throw new Error("Settings uninit"); if (csettings2.pmeth < 5) { let magic4 = false; - const bws2 = new SyncBufferWriter(); - const encoder = new PNGEncoder(bws2); + const [writestream2, extract8] = BufferWriteStream2(); + const encoder = new PNGEncoder(writestream2); const decoder = new PNGDecoder(container.stream().getReader()); for await (const [name, chunk, crc, offset] of decoder.chunks()) { if (magic4 && name != "IDAT") @@ -18066,20 +18070,20 @@ const passed = import_buffer3.Buffer.from(injb); switch (csettings2.pmeth) { case 0: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed]))), () => Promise.resolve(0), 0]); break; case 1: xor(passed, password); - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 2: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 3: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 4: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))]))), () => Promise.resolve(0), 0]); break; } magic4 = true; @@ -18088,23 +18092,23 @@ } encoder.insertchunk([ "IEND", - buildChunk("IEND", import_buffer3.Buffer.from([])), - 0, + () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), + () => Promise.resolve(0), 0 ]); - return bws2.getBuffer(); + return extract8(); } let pdec = new PNGDecoder(container.stream().getReader()); const concat = []; for await (const chk of pdec.chunks()) if (chk[0] == "IDAT") - concat.push(chk[1].slice(4)); + concat.push((await chk[1]()).slice(4)); const comp = import_buffer3.Buffer.concat(concat); const head = comp.slice(0, 2); const chksum = comp.slice(-4); const idatblk = embedInRawDeflate(comp.slice(2, -4), injb); - const bws = new SyncBufferWriter(); - const penc = new PNGEncoder(bws); + const [writestream, extract7] = BufferWriteStream2(); + const penc = new PNGEncoder(writestream); pdec = new PNGDecoder(container.stream().getReader()); let ins = false; for await (const chk of pdec.chunks()) { @@ -18112,14 +18116,14 @@ penc.insertchunk(chk); } else { if (!ins) { - penc.insertchunk(["IDAT", import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum]), 0, 0]); + penc.insertchunk(["IDAT", () => Promise.resolve(import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum])), () => Promise.resolve(0), 0]); ins = true; } } } await penc.dtor(); console.log("Finished writing"); - return bws.getBuffer(); + return extract7(); }; var inject = async (container, links) => { links = links.map((link) => { diff --git a/chrome/manifest.json b/chrome/manifest.json index 8e480c2..b5321a2 100644 --- a/chrome/manifest.json +++ b/chrome/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "PngExtraEmbedder", "description": "Discover embedded files on 4chan and archives!", - "version": "0.284", + "version": "0.285", "icons": { "64": "1449696017588.png" }, diff --git a/dist/main.js b/dist/main.js index 5eb22d5..9e4396e 100644 --- a/dist/main.js +++ b/dist/main.js @@ -73,7 +73,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 284]; + define_BUILD_VERSION_default = [0, 285]; } }); @@ -14135,18 +14135,18 @@ constructor(reader, strict = true) { this.reader = reader; this.strict = strict; - this.stopped = false; this.req = 8; this.ptr = 8; + this.stopped = false; this.repr = import_buffer.Buffer.from([]); } async catchup() { while (this.repr.byteLength < this.req) { const chunk = await this.reader.read(); if (chunk.done) { - this.stopped = true; if (this.strict) throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + this.stopped = true; return; } this.repr = import_buffer.Buffer.concat([this.repr, chunk.value]); @@ -14162,18 +14162,22 @@ const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; this.req += length + 4; - const pos = this.ptr + length + 8; - await this.catchup(); + const pos = this.ptr; yield [ name, - this.repr.slice(this.ptr, this.ptr + length + 4), - this.repr.readUInt32BE(this.ptr + length + 4), + async () => { + await this.catchup(); + return this.repr.slice(pos, pos + length + 4); + }, + async () => { + await this.catchup(); + return this.repr.readUInt32BE(this.ptr + length + 4); + }, this.ptr ]; - this.ptr += length + 8; - await this.catchup(); if (this.stopped) break; + this.ptr += length + 8; if (name == "IEND") break; } @@ -14181,34 +14185,24 @@ async dtor() { } }; - var SyncBufferWriter = class { - constructor() { - this.cumul = []; - } - write(b) { - this.cumul.push(b); - } - getBuffer() { - return import_buffer.Buffer.concat(this.cumul); - } - }; var PNGEncoder = class { - constructor(writer) { - this.writer = writer; + constructor(bytes) { + this.writer = bytes.getWriter(); this.writer.write(import_buffer.Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])); } - insertchunk(chunk) { + async insertchunk(chunk) { let b = import_buffer.Buffer.alloc(4); - const buff = chunk[1]; + const buff = await chunk[1](); b.writeInt32BE(buff.length - 4, 0); - this.writer.write(b); - this.writer.write(buff); + await this.writer.write(b); + await this.writer.write(buff); b = import_buffer.Buffer.alloc(4); b.writeInt32BE((0, import_crc_32.buf)(buff), 0); - this.writer.write(b); - console.log("finished inserting"); + await this.writer.write(b); } async dtor() { + this.writer.releaseLock(); + await this.writer.close(); } }; var BufferWriteStream = () => { @@ -17799,7 +17793,7 @@ let buff; switch (name) { case "tEXt": - buff = chunk; + buff = await chunk(); if (buff.slice(4, 4 + CUM3.length).equals(CUM3)) { const k = await decodeCoom3Payload(buff.slice(4 + CUM3.length)); ret.push(...k.filter((e) => e).map((e) => e)); @@ -17843,7 +17837,7 @@ case "IDAT": if (ret.length) return ret; - buff = chunk; + buff = await chunk(); idats.push(buff.slice(4)); case "IEND": complete = true; @@ -17874,6 +17868,16 @@ data.copy(ret, 4); return ret; }; + var BufferWriteStream2 = () => { + let b = import_buffer3.Buffer.from([]); + const ret = new WritableStream({ + write(chunk) { + b = import_buffer3.Buffer.concat([b, chunk]); + console.log("finished appending"); + } + }); + return [ret, () => b]; + }; var embedInRawDeflate = (b, h) => { const src = new BitstreamReader2(); const hid = new BitstreamReader2(); @@ -17891,8 +17895,8 @@ throw new Error("Settings uninit"); if (csettings2.pmeth < 5) { let magic4 = false; - const bws2 = new SyncBufferWriter(); - const encoder = new PNGEncoder(bws2); + const [writestream2, extract8] = BufferWriteStream2(); + const encoder = new PNGEncoder(writestream2); const decoder = new PNGDecoder(container.stream().getReader()); for await (const [name, chunk, crc, offset] of decoder.chunks()) { if (magic4 && name != "IDAT") @@ -17901,20 +17905,20 @@ const passed = import_buffer3.Buffer.from(injb); switch (csettings2.pmeth) { case 0: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed]))), () => Promise.resolve(0), 0]); break; case 1: xor(passed, password); - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 2: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 3: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 4: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))]))), () => Promise.resolve(0), 0]); break; } magic4 = true; @@ -17923,23 +17927,23 @@ } encoder.insertchunk([ "IEND", - buildChunk("IEND", import_buffer3.Buffer.from([])), - 0, + () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), + () => Promise.resolve(0), 0 ]); - return bws2.getBuffer(); + return extract8(); } let pdec = new PNGDecoder(container.stream().getReader()); const concat = []; for await (const chk of pdec.chunks()) if (chk[0] == "IDAT") - concat.push(chk[1].slice(4)); + concat.push((await chk[1]()).slice(4)); const comp = import_buffer3.Buffer.concat(concat); const head = comp.slice(0, 2); const chksum = comp.slice(-4); const idatblk = embedInRawDeflate(comp.slice(2, -4), injb); - const bws = new SyncBufferWriter(); - const penc = new PNGEncoder(bws); + const [writestream, extract7] = BufferWriteStream2(); + const penc = new PNGEncoder(writestream); pdec = new PNGDecoder(container.stream().getReader()); let ins = false; for await (const chk of pdec.chunks()) { @@ -17947,14 +17951,14 @@ penc.insertchunk(chk); } else { if (!ins) { - penc.insertchunk(["IDAT", import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum]), 0, 0]); + penc.insertchunk(["IDAT", () => Promise.resolve(import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum])), () => Promise.resolve(0), 0]); ins = true; } } } await penc.dtor(); console.log("Finished writing"); - return bws.getBuffer(); + return extract7(); }; var inject = async (container, links) => { links = links.map((link) => { diff --git a/efdb47d2f0e04144bbaa-0.284.xpi b/efdb47d2f0e04144bbaa-0.284.xpi new file mode 100644 index 0000000..59c1308 Binary files /dev/null and b/efdb47d2f0e04144bbaa-0.284.xpi differ diff --git a/efdb47d2f0e04144bbaa-0.285.xpi b/efdb47d2f0e04144bbaa-0.285.xpi new file mode 100644 index 0000000..3030bec Binary files /dev/null and b/efdb47d2f0e04144bbaa-0.285.xpi differ diff --git a/firefox/dist/main.js b/firefox/dist/main.js index a4b2dd8..c299aad 100644 --- a/firefox/dist/main.js +++ b/firefox/dist/main.js @@ -73,7 +73,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 284]; + define_BUILD_VERSION_default = [0, 285]; } }); @@ -14135,18 +14135,18 @@ constructor(reader, strict = true) { this.reader = reader; this.strict = strict; - this.stopped = false; this.req = 8; this.ptr = 8; + this.stopped = false; this.repr = import_buffer.Buffer.from([]); } async catchup() { while (this.repr.byteLength < this.req) { const chunk = await this.reader.read(); if (chunk.done) { - this.stopped = true; if (this.strict) throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + this.stopped = true; return; } this.repr = import_buffer.Buffer.concat([this.repr, chunk.value]); @@ -14162,18 +14162,22 @@ const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; this.req += length + 4; - const pos = this.ptr + length + 8; - await this.catchup(); + const pos = this.ptr; yield [ name, - this.repr.slice(this.ptr, this.ptr + length + 4), - this.repr.readUInt32BE(this.ptr + length + 4), + async () => { + await this.catchup(); + return this.repr.slice(pos, pos + length + 4); + }, + async () => { + await this.catchup(); + return this.repr.readUInt32BE(this.ptr + length + 4); + }, this.ptr ]; - this.ptr += length + 8; - await this.catchup(); if (this.stopped) break; + this.ptr += length + 8; if (name == "IEND") break; } @@ -14181,34 +14185,24 @@ async dtor() { } }; - var SyncBufferWriter = class { - constructor() { - this.cumul = []; - } - write(b) { - this.cumul.push(b); - } - getBuffer() { - return import_buffer.Buffer.concat(this.cumul); - } - }; var PNGEncoder = class { - constructor(writer) { - this.writer = writer; + constructor(bytes) { + this.writer = bytes.getWriter(); this.writer.write(import_buffer.Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])); } - insertchunk(chunk) { + async insertchunk(chunk) { let b = import_buffer.Buffer.alloc(4); - const buff = chunk[1]; + const buff = await chunk[1](); b.writeInt32BE(buff.length - 4, 0); - this.writer.write(b); - this.writer.write(buff); + await this.writer.write(b); + await this.writer.write(buff); b = import_buffer.Buffer.alloc(4); b.writeInt32BE((0, import_crc_32.buf)(buff), 0); - this.writer.write(b); - console.log("finished inserting"); + await this.writer.write(b); } async dtor() { + this.writer.releaseLock(); + await this.writer.close(); } }; var BufferWriteStream = () => { @@ -17941,7 +17935,7 @@ let buff; switch (name) { case "tEXt": - buff = chunk; + buff = await chunk(); if (buff.slice(4, 4 + CUM3.length).equals(CUM3)) { const k = await decodeCoom3Payload(buff.slice(4 + CUM3.length)); ret.push(...k.filter((e) => e).map((e) => e)); @@ -17985,7 +17979,7 @@ case "IDAT": if (ret.length) return ret; - buff = chunk; + buff = await chunk(); idats.push(buff.slice(4)); case "IEND": complete = true; @@ -18016,6 +18010,16 @@ data.copy(ret, 4); return ret; }; + var BufferWriteStream2 = () => { + let b = import_buffer3.Buffer.from([]); + const ret = new WritableStream({ + write(chunk) { + b = import_buffer3.Buffer.concat([b, chunk]); + console.log("finished appending"); + } + }); + return [ret, () => b]; + }; var embedInRawDeflate = (b, h) => { const src = new BitstreamReader2(); const hid = new BitstreamReader2(); @@ -18033,8 +18037,8 @@ throw new Error("Settings uninit"); if (csettings2.pmeth < 5) { let magic4 = false; - const bws2 = new SyncBufferWriter(); - const encoder = new PNGEncoder(bws2); + const [writestream2, extract8] = BufferWriteStream2(); + const encoder = new PNGEncoder(writestream2); const decoder = new PNGDecoder(container.stream().getReader()); for await (const [name, chunk, crc, offset] of decoder.chunks()) { if (magic4 && name != "IDAT") @@ -18043,20 +18047,20 @@ const passed = import_buffer3.Buffer.from(injb); switch (csettings2.pmeth) { case 0: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed]))), () => Promise.resolve(0), 0]); break; case 1: xor(passed, password); - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 2: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 3: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 4: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))]))), () => Promise.resolve(0), 0]); break; } magic4 = true; @@ -18065,23 +18069,23 @@ } encoder.insertchunk([ "IEND", - buildChunk("IEND", import_buffer3.Buffer.from([])), - 0, + () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), + () => Promise.resolve(0), 0 ]); - return bws2.getBuffer(); + return extract8(); } let pdec = new PNGDecoder(container.stream().getReader()); const concat = []; for await (const chk of pdec.chunks()) if (chk[0] == "IDAT") - concat.push(chk[1].slice(4)); + concat.push((await chk[1]()).slice(4)); const comp = import_buffer3.Buffer.concat(concat); const head = comp.slice(0, 2); const chksum = comp.slice(-4); const idatblk = embedInRawDeflate(comp.slice(2, -4), injb); - const bws = new SyncBufferWriter(); - const penc = new PNGEncoder(bws); + const [writestream, extract7] = BufferWriteStream2(); + const penc = new PNGEncoder(writestream); pdec = new PNGDecoder(container.stream().getReader()); let ins = false; for await (const chk of pdec.chunks()) { @@ -18089,14 +18093,14 @@ penc.insertchunk(chk); } else { if (!ins) { - penc.insertchunk(["IDAT", import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum]), 0, 0]); + penc.insertchunk(["IDAT", () => Promise.resolve(import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum])), () => Promise.resolve(0), 0]); ins = true; } } } await penc.dtor(); console.log("Finished writing"); - return bws.getBuffer(); + return extract7(); }; var inject = async (container, links) => { links = links.map((link) => { diff --git a/firefox/manifest.json b/firefox/manifest.json index 676252c..2eacac9 100644 --- a/firefox/manifest.json +++ b/firefox/manifest.json @@ -7,7 +7,7 @@ }, "name": "PngExtraEmbedder", "description": "Discover embedded files on 4chan and archives!", - "version": "0.284", + "version": "0.285", "icons": { "64": "1449696017588.png" }, diff --git a/firefox_update.json b/firefox_update.json index 4bf21c2..0aa09d7 100644 --- a/firefox_update.json +++ b/firefox_update.json @@ -1 +1 @@ -{"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.284","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.284.xpi"}]}}} \ No newline at end of file +{"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.285","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.285.xpi"}]}}} \ No newline at end of file diff --git a/main.meta.js b/main.meta.js index 18d23fb..97b6cd9 100644 --- a/main.meta.js +++ b/main.meta.js @@ -1,7 +1,7 @@ // ==UserScript== // @name PNGExtraEmbed // @namespace https://coom.tech/ -// @version 0.284 +// @version 0.285 // @description uhh // @author You // @match https://boards.4channel.org/* diff --git a/main.user.js b/main.user.js index b0458df..c084ec0 100644 --- a/main.user.js +++ b/main.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name PNGExtraEmbed // @namespace https://coom.tech/ -// @version 0.284 +// @version 0.285 // @description uhh // @author You // @match https://boards.4channel.org/* @@ -109,7 +109,7 @@ const _DOMParser = DOMParser; var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 284]; + define_BUILD_VERSION_default = [0, 285]; } }); @@ -14171,18 +14171,18 @@ const _DOMParser = DOMParser; constructor(reader, strict = true) { this.reader = reader; this.strict = strict; - this.stopped = false; this.req = 8; this.ptr = 8; + this.stopped = false; this.repr = import_buffer.Buffer.from([]); } async catchup() { while (this.repr.byteLength < this.req) { const chunk = await this.reader.read(); if (chunk.done) { - this.stopped = true; if (this.strict) throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + this.stopped = true; return; } this.repr = import_buffer.Buffer.concat([this.repr, chunk.value]); @@ -14198,18 +14198,22 @@ const _DOMParser = DOMParser; const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; this.req += length + 4; - const pos = this.ptr + length + 8; - await this.catchup(); + const pos = this.ptr; yield [ name, - this.repr.slice(this.ptr, this.ptr + length + 4), - this.repr.readUInt32BE(this.ptr + length + 4), + async () => { + await this.catchup(); + return this.repr.slice(pos, pos + length + 4); + }, + async () => { + await this.catchup(); + return this.repr.readUInt32BE(this.ptr + length + 4); + }, this.ptr ]; - this.ptr += length + 8; - await this.catchup(); if (this.stopped) break; + this.ptr += length + 8; if (name == "IEND") break; } @@ -14217,34 +14221,24 @@ const _DOMParser = DOMParser; async dtor() { } }; - var SyncBufferWriter = class { - constructor() { - this.cumul = []; - } - write(b) { - this.cumul.push(b); - } - getBuffer() { - return import_buffer.Buffer.concat(this.cumul); - } - }; var PNGEncoder = class { - constructor(writer) { - this.writer = writer; + constructor(bytes) { + this.writer = bytes.getWriter(); this.writer.write(import_buffer.Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])); } - insertchunk(chunk) { + async insertchunk(chunk) { let b = import_buffer.Buffer.alloc(4); - const buff = chunk[1]; + const buff = await chunk[1](); b.writeInt32BE(buff.length - 4, 0); - this.writer.write(b); - this.writer.write(buff); + await this.writer.write(b); + await this.writer.write(buff); b = import_buffer.Buffer.alloc(4); b.writeInt32BE((0, import_crc_32.buf)(buff), 0); - this.writer.write(b); - console.log("finished inserting"); + await this.writer.write(b); } async dtor() { + this.writer.releaseLock(); + await this.writer.close(); } }; var BufferWriteStream = () => { @@ -17835,7 +17829,7 @@ const _DOMParser = DOMParser; let buff; switch (name) { case "tEXt": - buff = chunk; + buff = await chunk(); if (buff.slice(4, 4 + CUM3.length).equals(CUM3)) { const k = await decodeCoom3Payload(buff.slice(4 + CUM3.length)); ret.push(...k.filter((e) => e).map((e) => e)); @@ -17879,7 +17873,7 @@ const _DOMParser = DOMParser; case "IDAT": if (ret.length) return ret; - buff = chunk; + buff = await chunk(); idats.push(buff.slice(4)); case "IEND": complete = true; @@ -17910,6 +17904,16 @@ const _DOMParser = DOMParser; data.copy(ret, 4); return ret; }; + var BufferWriteStream2 = () => { + let b = import_buffer3.Buffer.from([]); + const ret = new WritableStream({ + write(chunk) { + b = import_buffer3.Buffer.concat([b, chunk]); + console.log("finished appending"); + } + }); + return [ret, () => b]; + }; var embedInRawDeflate = (b, h) => { const src = new BitstreamReader2(); const hid = new BitstreamReader2(); @@ -17927,8 +17931,8 @@ const _DOMParser = DOMParser; throw new Error("Settings uninit"); if (csettings2.pmeth < 5) { let magic4 = false; - const bws2 = new SyncBufferWriter(); - const encoder = new PNGEncoder(bws2); + const [writestream2, extract8] = BufferWriteStream2(); + const encoder = new PNGEncoder(writestream2); const decoder = new PNGDecoder(container.stream().getReader()); for await (const [name, chunk, crc, offset] of decoder.chunks()) { if (magic4 && name != "IDAT") @@ -17937,20 +17941,20 @@ const _DOMParser = DOMParser; const passed = import_buffer3.Buffer.from(injb); switch (csettings2.pmeth) { case 0: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM3, passed]))), () => Promise.resolve(0), 0]); break; case 1: xor(passed, password); - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM4, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 2: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM5, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 3: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM6, import_buffer3.Buffer.from(import_buffer3.Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 4: - encoder.insertchunk(["tEXt", buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", import_buffer3.Buffer.concat([CUM7, import_buffer3.Buffer.from(bs58.encode(passed))]))), () => Promise.resolve(0), 0]); break; } magic4 = true; @@ -17959,23 +17963,23 @@ const _DOMParser = DOMParser; } encoder.insertchunk([ "IEND", - buildChunk("IEND", import_buffer3.Buffer.from([])), - 0, + () => Promise.resolve(buildChunk("IEND", import_buffer3.Buffer.from([]))), + () => Promise.resolve(0), 0 ]); - return bws2.getBuffer(); + return extract8(); } let pdec = new PNGDecoder(container.stream().getReader()); const concat = []; for await (const chk of pdec.chunks()) if (chk[0] == "IDAT") - concat.push(chk[1].slice(4)); + concat.push((await chk[1]()).slice(4)); const comp = import_buffer3.Buffer.concat(concat); const head = comp.slice(0, 2); const chksum = comp.slice(-4); const idatblk = embedInRawDeflate(comp.slice(2, -4), injb); - const bws = new SyncBufferWriter(); - const penc = new PNGEncoder(bws); + const [writestream, extract7] = BufferWriteStream2(); + const penc = new PNGEncoder(writestream); pdec = new PNGDecoder(container.stream().getReader()); let ins = false; for await (const chk of pdec.chunks()) { @@ -17983,14 +17987,14 @@ const _DOMParser = DOMParser; penc.insertchunk(chk); } else { if (!ins) { - penc.insertchunk(["IDAT", import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum]), 0, 0]); + penc.insertchunk(["IDAT", () => Promise.resolve(import_buffer3.Buffer.concat([import_buffer3.Buffer.from("IDAT"), head, idatblk, chksum])), () => Promise.resolve(0), 0]); ins = true; } } } await penc.dtor(); console.log("Finished writing"); - return bws.getBuffer(); + return extract7(); }; var inject = async (container, links) => { links = links.map((link) => { diff --git a/pngextraembedder-0.285.xpi b/pngextraembedder-0.285.xpi new file mode 100644 index 0000000..3030bec Binary files /dev/null and b/pngextraembedder-0.285.xpi differ diff --git a/src/png.ts b/src/png.ts index 58b959d..e42cf4d 100644 --- a/src/png.ts +++ b/src/png.ts @@ -4,13 +4,11 @@ import type { ImageProcessor } from "./main"; export type PNGChunk = [ string, // name - Buffer, // data - number, // crc + () => Promise, // data + () => Promise, // crc number];// offset export class PNGDecoder { - stopped = false; - repr: Buffer; req = 8; @@ -21,13 +19,15 @@ export class PNGDecoder { this.repr = Buffer.from([]); } + stopped = false; + async catchup() { while (this.repr.byteLength < this.req) { const chunk = await this.reader.read(); if (chunk.done) { - this.stopped = true; if (this.strict) throw new Error(`Unexpected EOF, got ${this.repr.byteLength}, required ${this.req}, ${chunk.value}`); + this.stopped = true; return; } this.repr = Buffer.concat([this.repr, chunk.value]); @@ -38,23 +38,25 @@ export class PNGDecoder { while (true) { this.req += 8; // req length and name await this.catchup(); - if (this.stopped) - break; + if (this.stopped) break; const length = this.repr.readUInt32BE(this.ptr); const name = this.repr.slice(this.ptr + 4, this.ptr + 8).toString(); this.ptr += 4; this.req += length + 4; // crc //await this.catchup(); - const pos = this.ptr + length + 8; - await this.catchup(); + const pos = this.ptr; yield [name, - this.repr.slice(this.ptr, this.ptr + length + 4), - this.repr.readUInt32BE(this.ptr + length + 4), + async () => { + await this.catchup(); + return this.repr.slice(pos, pos + length + 4); + }, + async () => { + await this.catchup(); + return this.repr.readUInt32BE(this.ptr + length + 4); + }, this.ptr] as PNGChunk; + if (this.stopped) break; this.ptr += length + 8; - await this.catchup(); - if (this.stopped) - break; if (name == 'IEND') break; } @@ -65,40 +67,28 @@ export class PNGDecoder { } } -export class SyncBufferWriter { - cumul: Buffer[] = []; - - write(b: Buffer) { - this.cumul.push(b); - } - - getBuffer() { - return Buffer.concat(this.cumul); - } -} - export class PNGEncoder { - // writer: WritableStreamDefaultWriter; + writer: WritableStreamDefaultWriter; - constructor(private writer: SyncBufferWriter) { + constructor(bytes: WritableStream) { + this.writer = bytes.getWriter(); this.writer.write(Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])); } - insertchunk(chunk: PNGChunk) { + async insertchunk(chunk: PNGChunk) { let b = Buffer.alloc(4); - const buff = chunk[1]; + const buff = await chunk[1](); b.writeInt32BE(buff.length - 4, 0); - this.writer.write(b); // write length - this.writer.write(buff); // chunk includes chunkname + await this.writer.write(b); // write length + await this.writer.write(buff); // chunk includes chunkname b = Buffer.alloc(4); b.writeInt32BE(buf(buff), 0); - this.writer.write(b); - console.log("finished inserting"); + await this.writer.write(b); } async dtor() { - //this.writer.releaseLock(); - //await this.writer.close(); + this.writer.releaseLock(); + await this.writer.close(); } } diff --git a/src/pngv3.ts b/src/pngv3.ts index 5c7f732..8f91665 100644 --- a/src/pngv3.ts +++ b/src/pngv3.ts @@ -1,6 +1,6 @@ import { Buffer } from "buffer"; import type { EmbeddedFile, ImageProcessor } from "./main"; -import { PNGDecoder, PNGEncoder, SyncBufferWriter } from "./png"; +import { PNGDecoder, PNGEncoder } from "./png"; import { decodeCoom3Payload } from "./utils"; import { settings } from "./stores"; import { filehosts } from "./filehosts"; @@ -157,7 +157,7 @@ const extract = async (png: Buffer) => { switch (name) { // should exist at the beginning of file to signal decoders if the file indeed has an embedded chunk case 'tEXt': - buff = chunk; + buff = await chunk(); if (buff.slice(4, 4 + CUM3.length).equals(CUM3)) { const k = await decodeCoom3Payload(buff.slice(4 + CUM3.length)); ret.push(...k.filter(e => e).map(e => e as EmbeddedFile)); @@ -206,7 +206,7 @@ const extract = async (png: Buffer) => { case 'IDAT': if (ret.length) return ret; - buff = chunk; + buff = await chunk(); idats.push(buff.slice(4)); // eslint-disable-next-line no-fallthrough @@ -274,9 +274,8 @@ export const inject_data = async (container: File, injb: Buffer) => { throw new Error("Settings uninit"); if (csettings.pmeth < 5) { let magic = false; - //const [writestream, extract] = BufferWriteStream(); - const bws = new SyncBufferWriter(); - const encoder = new PNGEncoder(bws); + const [writestream, extract] = BufferWriteStream(); + const encoder = new PNGEncoder(writestream); const decoder = new PNGDecoder(container.stream().getReader()); for await (const [name, chunk, crc, offset] of decoder.chunks()) { @@ -286,20 +285,20 @@ export const inject_data = async (container: File, injb: Buffer) => { const passed = Buffer.from(injb); switch (csettings.pmeth) { case 0: - encoder.insertchunk(["tEXt", buildChunk("tEXt", Buffer.concat([CUM3, passed])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", Buffer.concat([CUM3, passed]))), () => Promise.resolve(0), 0]); break; case 1: xor(passed, password); - encoder.insertchunk(["tEXt", buildChunk("tEXt", Buffer.concat([CUM4, Buffer.from(Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", Buffer.concat([CUM4, Buffer.from(Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 2: - encoder.insertchunk(["tEXt", buildChunk("tEXt", Buffer.concat([CUM5, Buffer.from(Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", Buffer.concat([CUM5, Buffer.from(Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 3: - encoder.insertchunk(["tEXt", buildChunk("tEXt", Buffer.concat([CUM6, Buffer.from(Buffer.from(passed).toString("base64"))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", Buffer.concat([CUM6, Buffer.from(Buffer.from(passed).toString("base64"))]))), () => Promise.resolve(0), 0]); break; case 4: - encoder.insertchunk(["tEXt", buildChunk("tEXt", Buffer.concat([CUM7, Buffer.from(bs58.encode(passed))])), 0, 0]); + encoder.insertchunk(["tEXt", () => Promise.resolve(buildChunk("tEXt", Buffer.concat([CUM7, Buffer.from(bs58.encode(passed))]))), () => Promise.resolve(0), 0]); break; } magic = true; @@ -307,23 +306,23 @@ export const inject_data = async (container: File, injb: Buffer) => { encoder.insertchunk([name, chunk, crc, offset]); } encoder.insertchunk(["IEND", - buildChunk("IEND", Buffer.from([])), - 0, + () => Promise.resolve(buildChunk("IEND", Buffer.from([]))), + () => Promise.resolve(0), 0]); - return bws.getBuffer(); + return extract(); } let pdec = new PNGDecoder(container.stream().getReader()); const concat: Buffer[] = []; for await (const chk of pdec.chunks()) if (chk[0] == "IDAT") - concat.push((chk[1]).slice(4)); + concat.push((await chk[1]()).slice(4)); const comp = Buffer.concat(concat); const head = comp.slice(0, 2); // keep the header the same const chksum = comp.slice(-4); // checksum is over the uncompressed data, so no need to recalculate const idatblk = embedInRawDeflate(comp.slice(2, -4), injb); - const bws = new SyncBufferWriter(); - const penc = new PNGEncoder(bws); + const [writestream, extract] = BufferWriteStream(); + const penc = new PNGEncoder(writestream); pdec = new PNGDecoder(container.stream().getReader()); // restart again let ins = false; for await (const chk of pdec.chunks()) { @@ -331,14 +330,14 @@ export const inject_data = async (container: File, injb: Buffer) => { penc.insertchunk(chk); } else { if (!ins) { - penc.insertchunk(["IDAT", Buffer.concat([Buffer.from('IDAT'), head, idatblk, chksum]), 0, 0]); + penc.insertchunk(["IDAT", () => Promise.resolve(Buffer.concat([Buffer.from('IDAT'), head, idatblk, chksum])), () => Promise.resolve(0), 0]); ins = true; } } } await penc.dtor(); console.log("Finished writing"); - return bws.getBuffer(); + return extract(); }; const inject = async (container: File, links: string[]) => {