uploads.test.js
4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Unit tests for the upload pipeline building blocks (dev-plan.md T2).
// Run: node --test uploads.test.js
const test = require("node:test");
const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");
const {
parseMultipart,
boundaryFromContentType,
sniffImageType,
stripMetadataAndSave,
UPLOADS_DIR,
} = require("./uploads.js");
test("sniffImageType recognizes real magic bytes and rejects a zip disguised as .jpg", () => {
const jpeg = Buffer.from([0xff, 0xd8, 0xff, 0xe0, 0, 0, 0, 0]);
const png = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0, 0]);
const webp = Buffer.concat([Buffer.from("RIFF"), Buffer.from([0, 0, 0, 0]), Buffer.from("WEBP")]);
const zipDisguisedAsJpg = Buffer.from([0x50, 0x4b, 0x03, 0x04, 0, 0, 0, 0]); // PK.. local file header
assert.equal(sniffImageType(jpeg).type, "image/jpeg");
assert.equal(sniffImageType(png).type, "image/png");
assert.equal(sniffImageType(webp).type, "image/webp");
assert.equal(sniffImageType(zipDisguisedAsJpg), null);
});
test("parseMultipart extracts a file part from a real multipart body (built via the platform's own FormData/Response)", async () => {
const fd = new FormData();
fd.append("file", new Blob([Buffer.from([1, 2, 3, 4])], { type: "image/png" }), "photo.png");
const encoded = new Response(fd);
const body = Buffer.from(await encoded.arrayBuffer());
const boundary = boundaryFromContentType(encoded.headers.get("content-type"));
const parts = parseMultipart(body, boundary);
assert.equal(parts.length, 1);
assert.equal(parts[0].name, "file");
assert.equal(parts[0].filename, "photo.png");
assert.deepEqual([...parts[0].data], [1, 2, 3, 4]);
});
// Walks a JPEG's APP1 "Exif\0\0" TIFF block (if any) and reports whether
// IFD0 has a GPS IFD pointer (tag 0x8825) — i.e. whether the file carries
// GPS EXIF data. Dependency-free stand-in for what the original acceptance
// criteria describes as "exiftool sees no GPS" (no exiftool on this
// machine, see uploads.js's module comment).
function hasGpsExifTag(jpegBuffer) {
let offset = 2; // skip SOI (0xFFD8)
while (offset < jpegBuffer.length - 4) {
if (jpegBuffer[offset] !== 0xff) break;
const marker = jpegBuffer[offset + 1];
if (marker === 0xd8 || marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7)) {
offset += 2;
continue;
}
if (marker === 0xda) break; // start of scan — no more markers to read
const segmentLength = jpegBuffer.readUInt16BE(offset + 2);
if (marker === 0xe1 && jpegBuffer.toString("latin1", offset + 4, offset + 10) === "Exif\0\0") {
const tiffStart = offset + 10;
const littleEndian = jpegBuffer.toString("latin1", tiffStart, tiffStart + 2) === "II";
const readU16 = (p) => (littleEndian ? jpegBuffer.readUInt16LE(p) : jpegBuffer.readUInt16BE(p));
const readU32 = (p) => (littleEndian ? jpegBuffer.readUInt32LE(p) : jpegBuffer.readUInt32BE(p));
const ifd0Offset = tiffStart + readU32(tiffStart + 4);
const entryCount = readU16(ifd0Offset);
for (let i = 0; i < entryCount; i++) {
const entryOffset = ifd0Offset + 2 + i * 12;
if (readU16(entryOffset) === 0x8825) return true; // GPS IFD pointer tag
}
return false;
}
offset += 2 + segmentLength;
}
return false;
}
test("stripMetadataAndSave strips embedded GPS EXIF from a real photo and preserves pixel dimensions", () => {
const fixture = fs.readFileSync(path.join(__dirname, "test-fixtures", "with-gps.jpg"));
assert.equal(hasGpsExifTag(fixture), true, "test fixture should actually carry GPS EXIF");
const sniffed = sniffImageType(fixture);
assert.equal(sniffed.type, "image/jpeg");
const { absPath, relPath, ext } = stripMetadataAndSave(fixture, sniffed);
try {
assert.equal(ext, "jpg");
assert.match(relPath, /^\/uploads\/\d{6}\/[0-9a-f-]+\.jpg$/);
const out = fs.readFileSync(absPath);
assert.equal(hasGpsExifTag(out), false, "expected GPS EXIF to be gone after stripMetadataAndSave");
} finally {
fs.rmSync(absPath);
}
});
test.after(() => {
// stripMetadataAndSave writes into the real uploads/ tree (mirrors
// production layout); clean up the yyyymm dir if the test left it empty.
const yyyymm = new Date().toISOString().slice(0, 7).replace("-", "");
const dir = path.join(UPLOADS_DIR, yyyymm);
try {
if (fs.readdirSync(dir).length === 0) fs.rmdirSync(dir);
if (fs.readdirSync(UPLOADS_DIR).length === 0) fs.rmdirSync(UPLOADS_DIR);
} catch {
// already clean
}
});