Skip to content

Commit 52426bc

Browse files
authored
Merge branch 'master' into feature-http-request
2 parents cbab995 + 45a9da5 commit 52426bc

File tree

4 files changed

+229
-2
lines changed

4 files changed

+229
-2
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cyberchef",
3-
"version": "5.7.3",
3+
"version": "5.8.0",
44
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
55
"author": "n1474335 <[email protected]>",
66
"homepage": "https://gchq.github.io/CyberChef",

src/core/lib/remove-exif.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/* piexifjs
2+
The MIT License (MIT)
3+
Copyright (c) 2014, 2015 hMatoba(https://github.com/hMatoba)
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18+
SOFTWARE.
19+
*/
20+
21+
import Utils from "../Utils.js";
22+
23+
// Param jpeg should be a binaryArray
24+
function removeEXIF(jpeg) {
25+
// Convert binaryArray to char string
26+
jpeg = Utils.byteArrayToChars(jpeg);
27+
if (jpeg.slice(0, 2) != "\xff\xd8") {
28+
throw ("Given data is not jpeg.");
29+
}
30+
31+
var segments = splitIntoSegments(jpeg);
32+
if (segments[1].slice(0, 2) == "\xff\xe1" &&
33+
segments[1].slice(4, 10) == "Exif\x00\x00") {
34+
segments = [segments[0]].concat(segments.slice(2));
35+
} else if (segments[2].slice(0, 2) == "\xff\xe1" &&
36+
segments[2].slice(4, 10) == "Exif\x00\x00") {
37+
segments = segments.slice(0, 2).concat(segments.slice(3));
38+
} else {
39+
throw ("Exif not found.");
40+
}
41+
42+
var new_data = segments.join("");
43+
44+
// Convert back to binaryArray
45+
new_data = Utils.strToCharcode(new_data);
46+
47+
return new_data;
48+
};
49+
50+
function splitIntoSegments(data) {
51+
if (data.slice(0, 2) != "\xff\xd8") {
52+
throw ("Given data isn't JPEG.");
53+
}
54+
55+
var head = 2;
56+
var segments = ["\xff\xd8"];
57+
while (true) {
58+
if (data.slice(head, head + 2) == "\xff\xda") {
59+
segments.push(data.slice(head));
60+
break;
61+
} else {
62+
var length = unpack(">H", data.slice(head + 2, head + 4))[0];
63+
var endPoint = head + length + 2;
64+
segments.push(data.slice(head, endPoint));
65+
head = endPoint;
66+
}
67+
68+
if (head >= data.length) {
69+
throw ("Wrong JPEG data.");
70+
}
71+
}
72+
return segments;
73+
}
74+
75+
function unpack(mark, str) {
76+
if (typeof(str) != "string") {
77+
throw ("'unpack' error. Got invalid type argument.");
78+
}
79+
var l = 0;
80+
for (var markPointer = 1; markPointer < mark.length; markPointer++) {
81+
if (mark[markPointer].toLowerCase() == "b") {
82+
l += 1;
83+
} else if (mark[markPointer].toLowerCase() == "h") {
84+
l += 2;
85+
} else if (mark[markPointer].toLowerCase() == "l") {
86+
l += 4;
87+
} else {
88+
throw ("'unpack' error. Got invalid mark.");
89+
}
90+
}
91+
92+
if (l != str.length) {
93+
throw ("'unpack' error. Mismatch between symbol and string length. " + l + ":" + str.length);
94+
}
95+
96+
var littleEndian;
97+
if (mark[0] == "<") {
98+
littleEndian = true;
99+
} else if (mark[0] == ">") {
100+
littleEndian = false;
101+
} else {
102+
throw ("'unpack' error.");
103+
}
104+
var unpacked = [];
105+
var strPointer = 0;
106+
var p = 1;
107+
var val = null;
108+
var c = null;
109+
var length = null;
110+
var sliced = "";
111+
112+
while (c = mark[p]) {
113+
if (c.toLowerCase() == "b") {
114+
length = 1;
115+
sliced = str.slice(strPointer, strPointer + length);
116+
val = sliced.charCodeAt(0);
117+
if ((c == "b") && (val >= 0x80)) {
118+
val -= 0x100;
119+
}
120+
} else if (c == "H") {
121+
length = 2;
122+
sliced = str.slice(strPointer, strPointer + length);
123+
if (littleEndian) {
124+
sliced = sliced.split("").reverse().join("");
125+
}
126+
val = sliced.charCodeAt(0) * 0x100 +
127+
sliced.charCodeAt(1);
128+
} else if (c.toLowerCase() == "l") {
129+
length = 4;
130+
sliced = str.slice(strPointer, strPointer + length);
131+
if (littleEndian) {
132+
sliced = sliced.split("").reverse().join("");
133+
}
134+
val = sliced.charCodeAt(0) * 0x1000000 +
135+
sliced.charCodeAt(1) * 0x10000 +
136+
sliced.charCodeAt(2) * 0x100 +
137+
sliced.charCodeAt(3);
138+
if ((c == "l") && (val >= 0x80000000)) {
139+
val -= 0x100000000;
140+
}
141+
} else {
142+
throw ("'unpack' error. " + c);
143+
}
144+
145+
unpacked.push(val);
146+
strPointer += length;
147+
p += 1;
148+
}
149+
150+
return unpacked;
151+
}
152+
153+
export default removeEXIF;

src/core/operations/Image.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as ExifParser from "exif-parser";
2+
import removeEXIF from "../lib/remove-exif.js";
23
import Utils from "../Utils.js";
34
import FileType from "./FileType.js";
45

@@ -23,7 +24,7 @@ const Image = {
2324
* @param {Object[]} args
2425
* @returns {string}
2526
*/
26-
runEXIF(input, args) {
27+
runExtractEXIF(input, args) {
2728
try {
2829
const bytes = Uint8Array.from(input);
2930
const parser = ExifParser.create(bytes.buffer);
@@ -44,6 +45,30 @@ const Image = {
4445
},
4546

4647

48+
/**
49+
* Remove EXIF operation.
50+
*
51+
* Removes EXIF data from a byteArray, representing a JPG.
52+
*
53+
* @author David Moodie [[email protected]]
54+
* @param {byteArray} input
55+
* @param {Object[]} args
56+
* @returns {string}
57+
*/
58+
runRemoveEXIF(input, args) {
59+
// Do nothing if input is empty
60+
if (input.length === 0) return input;
61+
62+
try {
63+
return removeEXIF(input);
64+
} catch (err) {
65+
// Simply return input if no EXIF data is found
66+
if (err === "Exif not found.") return input;
67+
throw "Could not remove EXIF data from image: " + err;
68+
}
69+
},
70+
71+
4772
/**
4873
* @constant
4974
* @default

test/tests/operations/Image.js

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)