CyberChef/src/js/operations/Compress.js

354 lines
8.8 KiB
JavaScript
Raw Normal View History

import Utils from '../core/Utils';
import Uint8Array from 'core-js/modules/es6.typed.uint8-array';
2016-11-29 02:08:20 +00:00
2016-11-28 10:42:58 +00:00
/**
* Compression operations.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*
* @namespace
*/
2016-11-29 00:22:34 +00:00
const Compress = {
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
COMPRESSION_TYPE: ['Dynamic Huffman Coding', 'Fixed Huffman Coding', 'None (Store)'],
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
INFLATE_BUFFER_TYPE: ['Adaptive', 'Block'],
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
COMPRESSION_METHOD: ['Deflate', 'None (Store)'],
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
OS: ['MSDOS', 'Unix', 'Macintosh'],
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
RAW_COMPRESSION_TYPE_LOOKUP: {
'Fixed Huffman Coding': Zlib.RawDeflate.CompressionType.FIXED,
'Dynamic Huffman Coding': Zlib.RawDeflate.CompressionType.DYNAMIC,
'None (Store)': Zlib.RawDeflate.CompressionType.NONE,
},
2016-11-28 10:42:58 +00:00
/**
* Raw Deflate operation.
*
* @param {byte_array} input
* @param {Object[]} args
* @returns {byte_array}
*/
2016-11-29 00:22:34 +00:00
run_raw_deflate(input, args) {
const deflate = new Zlib.RawDeflate(input, {
compressionType: Compress.RAW_COMPRESSION_TYPE_LOOKUP[args[0]],
});
return Array.prototype.slice.call(deflate.compress());
},
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
INFLATE_INDEX: 0,
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
INFLATE_BUFFER_SIZE: 0,
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
INFLATE_RESIZE: false,
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
INFLATE_VERIFY: false,
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
RAW_BUFFER_TYPE_LOOKUP: {
Adaptive: Zlib.RawInflate.BufferType.ADAPTIVE,
Block: Zlib.RawInflate.BufferType.BLOCK,
},
2016-11-28 10:42:58 +00:00
/**
* Raw Inflate operation.
*
* @param {byte_array} input
* @param {Object[]} args
* @returns {byte_array}
*/
2016-11-29 00:22:34 +00:00
run_raw_inflate(input, args) {
2016-11-28 10:42:58 +00:00
// Deal with character encoding issues
2016-11-29 00:22:34 +00:00
input = Utils.str_to_byte_array(Utils.byte_array_to_utf8(input));
let inflate = new Zlib.RawInflate(input, {
index: args[0],
bufferSize: args[1],
bufferType: Compress.RAW_BUFFER_TYPE_LOOKUP[args[2]],
resize: args[3],
verify: args[4],
}),
result = Array.prototype.slice.call(inflate.decompress());
2016-11-28 10:42:58 +00:00
// Raw Inflate somethimes messes up and returns nonsense like this:
// ]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]...
// e.g. Input data of [8b, 1d, dc, 44]
// Look for the first two square brackets:
2016-11-29 00:22:34 +00:00
if (result.length > 158 && result[0] == 93 && result[5] == 93) {
2016-11-28 10:42:58 +00:00
// If the first two square brackets are there, check that the others
// are also there. If they are, throw an error. If not, continue.
2016-11-29 00:22:34 +00:00
let valid = false;
for (let i = 0; i < 155; i += 5) {
if (result[i] != 93) {
valid = true;
2016-11-28 10:42:58 +00:00
}
2016-11-29 00:22:34 +00:00
}
if (!valid) {
throw 'Error: Unable to inflate data';
}
}
2016-11-28 10:42:58 +00:00
// Trust me, this is the easiest way...
2016-11-29 00:22:34 +00:00
return result;
},
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
ZLIB_COMPRESSION_TYPE_LOOKUP: {
'Fixed Huffman Coding': Zlib.Deflate.CompressionType.FIXED,
'Dynamic Huffman Coding': Zlib.Deflate.CompressionType.DYNAMIC,
'None (Store)': Zlib.Deflate.CompressionType.NONE,
},
2016-11-28 10:42:58 +00:00
/**
* Zlib Deflate operation.
*
* @param {byte_array} input
* @param {Object[]} args
* @returns {byte_array}
*/
2016-11-29 00:22:34 +00:00
run_zlib_deflate(input, args) {
const deflate = new Zlib.Deflate(input, {
compressionType: Compress.ZLIB_COMPRESSION_TYPE_LOOKUP[args[0]],
});
return Array.prototype.slice.call(deflate.compress());
},
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
ZLIB_BUFFER_TYPE_LOOKUP: {
Adaptive: Zlib.Inflate.BufferType.ADAPTIVE,
Block: Zlib.Inflate.BufferType.BLOCK,
},
2016-11-28 10:42:58 +00:00
/**
* Zlib Inflate operation.
*
* @param {byte_array} input
* @param {Object[]} args
* @returns {byte_array}
*/
2016-11-29 00:22:34 +00:00
run_zlib_inflate(input, args) {
2016-11-28 10:42:58 +00:00
// Deal with character encoding issues
2016-11-29 00:22:34 +00:00
input = Utils.str_to_byte_array(Utils.byte_array_to_utf8(input));
const inflate = new Zlib.Inflate(input, {
index: args[0],
bufferSize: args[1],
bufferType: Compress.ZLIB_BUFFER_TYPE_LOOKUP[args[2]],
resize: args[3],
verify: args[4],
});
return Array.prototype.slice.call(inflate.decompress());
},
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
GZIP_CHECKSUM: false,
2016-11-28 10:42:58 +00:00
/**
* Gzip operation.
*
* @param {byte_array} input
* @param {Object[]} args
* @returns {byte_array}
*/
2016-11-29 00:22:34 +00:00
run_gzip(input, args) {
let filename = args[1],
comment = args[2],
options = {
deflateOptions: {
compressionType: Compress.ZLIB_COMPRESSION_TYPE_LOOKUP[args[0]],
},
flags: {
fhcrc: args[3],
},
};
if (filename.length) {
options.flags.fname = true;
options.filename = filename;
}
if (comment.length) {
options.flags.fcommenct = true;
options.comment = comment;
}
const gzip = new Zlib.Gzip(input, options);
return Array.prototype.slice.call(gzip.compress());
},
2016-11-28 10:42:58 +00:00
/**
* Gunzip operation.
*
* @param {byte_array} input
* @param {Object[]} args
* @returns {byte_array}
*/
2016-11-29 00:22:34 +00:00
run_gunzip(input, args) {
2016-11-28 10:42:58 +00:00
// Deal with character encoding issues
2016-11-29 00:22:34 +00:00
input = Utils.str_to_byte_array(Utils.byte_array_to_utf8(input));
const gunzip = new Zlib.Gunzip(input);
return Array.prototype.slice.call(gunzip.decompress());
},
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
PKZIP_FILENAME: 'file.txt',
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
ZIP_COMPRESSION_METHOD_LOOKUP: {
Deflate: Zlib.Zip.CompressionMethod.DEFLATE,
'None (Store)': Zlib.Zip.CompressionMethod.STORE,
},
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
ZIP_OS_LOOKUP: {
MSDOS: Zlib.Zip.OperatingSystem.MSDOS,
Unix: Zlib.Zip.OperatingSystem.UNIX,
Macintosh: Zlib.Zip.OperatingSystem.MACINTOSH,
},
2016-11-28 10:42:58 +00:00
/**
* Zip operation.
*
* @param {byte_array} input
* @param {Object[]} args
* @returns {byte_array}
*/
2016-11-29 00:22:34 +00:00
run_pkzip(input, args) {
let password = Utils.str_to_byte_array(args[2]),
options = {
filename: Utils.str_to_byte_array(args[0]),
comment: Utils.str_to_byte_array(args[1]),
compressionMethod: Compress.ZIP_COMPRESSION_METHOD_LOOKUP[args[3]],
os: Compress.ZIP_OS_LOOKUP[args[4]],
deflateOption: {
compressionType: Compress.ZLIB_COMPRESSION_TYPE_LOOKUP[args[5]],
},
},
zip = new Zlib.Zip();
if (password.length) { zip.setPassword(password); }
zip.addFile(input, options);
return Array.prototype.slice.call(zip.compress());
},
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
PKUNZIP_VERIFY: false,
2016-11-28 10:42:58 +00:00
/**
* Unzip operation.
*
* @param {byte_array} input
* @param {Object[]} args
* @returns {string}
*/
2016-11-29 00:22:34 +00:00
run_pkunzip(input, args) {
let options = {
password: Utils.str_to_byte_array(args[0]),
verify: args[1],
},
file = '',
unzip = new Zlib.Unzip(input, options),
filenames = unzip.getFilenames(),
output = `<div style='padding: 5px;'>${filenames.length} file(s) found</div>\n`;
output += "<div class='panel-group' id='zip-accordion' role='tablist' aria-multiselectable='true'>";
window.uzip = unzip;
for (let i = 0; i < filenames.length; i++) {
file = Utils.byte_array_to_utf8(unzip.decompress(filenames[i]));
output += `${"<div class='panel panel-default'>" +
"<div class='panel-heading' role='tab' id='heading"}${i}'>` +
'<h4 class=\'panel-title\'>' +
`<a class='collapsed' role='button' data-toggle='collapse' data-parent='#zip-accordion' href='#collapse${i
}' aria-expanded='true' aria-controls='collapse${i}'>${
filenames[i]}<span class='pull-right'>${file.length.toLocaleString()} bytes</span></a></h4></div>` +
`<div id='collapse${i}' class='panel-collapse collapse' role='tabpanel' aria-labelledby='heading${i}'>` +
`<div class='panel-body'>${
Utils.escape_html(file)}</div></div></div>`;
}
return `${output}</div>`;
},
2016-11-28 10:42:58 +00:00
/**
* Bzip2 Decompress operation.
*
* @param {byte_array} input
* @param {Object[]} args
* @returns {string}
*/
2016-11-29 00:22:34 +00:00
run_bzip2_decompress(input, args) {
let compressed = new Uint8Array(input),
bzip2_reader,
plain = '';
bzip2_reader = bzip2.array(compressed);
plain = bzip2.simple(bzip2_reader);
return plain;
},
2016-11-28 10:42:58 +00:00
};
export default Compress;