Browse Source

Revert png encoder/decoders

pull/46/head
coomdev 2 years ago
parent
commit
63b0e67756
  1. 2
      README.md
  2. 94
      chrome/dist/main.js
  3. 2
      chrome/manifest.json
  4. 94
      dist/main.js
  5. BIN
      efdb47d2f0e04144bbaa-0.284.xpi
  6. BIN
      efdb47d2f0e04144bbaa-0.285.xpi
  7. 94
      firefox/dist/main.js
  8. 2
      firefox/manifest.json
  9. 2
      firefox_update.json
  10. 2
      main.meta.js
  11. 96
      main.user.js
  12. BIN
      pngextraembedder-0.285.xpi
  13. 62
      src/png.ts
  14. 37
      src/pngv3.ts

2
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.

94
chrome/dist/main.js

@ -73,7 +73,7 @@
var define_BUILD_VERSION_default;
var init_define_BUILD_VERSION = __esm({
"<define:BUILD_VERSION>"() {
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) => {

2
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"
},

94
dist/main.js

@ -73,7 +73,7 @@
var define_BUILD_VERSION_default;
var init_define_BUILD_VERSION = __esm({
"<define:BUILD_VERSION>"() {
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) => {

BIN
efdb47d2f0e04144bbaa-0.284.xpi

Binary file not shown.

BIN
efdb47d2f0e04144bbaa-0.285.xpi

Binary file not shown.

94
firefox/dist/main.js

@ -73,7 +73,7 @@
var define_BUILD_VERSION_default;
var init_define_BUILD_VERSION = __esm({
"<define:BUILD_VERSION>"() {
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) => {

2
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"
},

2
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"}]}}}
{"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"}]}}}

2
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/*

96
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>"() {
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) => {

BIN
pngextraembedder-0.285.xpi

Binary file not shown.

62
src/png.ts

@ -4,13 +4,11 @@ import type { ImageProcessor } from "./main";
export type PNGChunk = [
string, // name
Buffer, // data
number, // crc
() => Promise<Buffer>, // data
() => Promise<number>, // 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<Buffer>;
writer: WritableStreamDefaultWriter<Buffer>;
constructor(private writer: SyncBufferWriter) {
constructor(bytes: WritableStream<Buffer>) {
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();
}
}

37
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[]) => {

Loading…
Cancel
Save