updated linebreaks

This commit is contained in:
bee-san 2023-12-27 12:44:38 +00:00
parent cc86650786
commit 963c58ed24
3 changed files with 150 additions and 150 deletions

View file

@ -1,88 +1,88 @@
/** /**
* *
* LZNT1 Decompress. * LZNT1 Decompress.
* *
* @author 0xThiebaut [thiebaut.dev] * @author 0xThiebaut [thiebaut.dev]
* @copyright Crown Copyright 2023 * @copyright Crown Copyright 2023
* @license Apache-2.0 * @license Apache-2.0
* *
* https://github.com/Velocidex/go-ntfs/blob/master/parser%2Flznt1.go * https://github.com/Velocidex/go-ntfs/blob/master/parser%2Flznt1.go
*/ */
import Utils from "../Utils.mjs"; import Utils from "../Utils.mjs";
import OperationError from "../errors/OperationError.mjs"; import OperationError from "../errors/OperationError.mjs";
const COMPRESSED_MASK = 1 << 15, const COMPRESSED_MASK = 1 << 15,
SIZE_MASK = (1 << 12) - 1; SIZE_MASK = (1 << 12) - 1;
/** /**
* @param {number} offset * @param {number} offset
* @returns {number} * @returns {number}
*/ */
function getDisplacement(offset) { function getDisplacement(offset) {
let result = 0; let result = 0;
while (offset >= 0x10) { while (offset >= 0x10) {
offset >>= 1; offset >>= 1;
result += 1; result += 1;
} }
return result; return result;
} }
/** /**
* @param {byteArray} compressed * @param {byteArray} compressed
* @returns {byteArray} * @returns {byteArray}
*/ */
export function decompress(compressed) { export function decompress(compressed) {
const decompressed = Array(); const decompressed = Array();
let coffset = 0; let coffset = 0;
while (coffset + 2 <= compressed.length) { while (coffset + 2 <= compressed.length) {
const doffset = decompressed.length; const doffset = decompressed.length;
const blockHeader = Utils.byteArrayToInt(compressed.slice(coffset, coffset + 2), "little"); const blockHeader = Utils.byteArrayToInt(compressed.slice(coffset, coffset + 2), "little");
coffset += 2; coffset += 2;
const size = blockHeader & SIZE_MASK; const size = blockHeader & SIZE_MASK;
const blockEnd = coffset + size + 1; const blockEnd = coffset + size + 1;
if (size === 0) { if (size === 0) {
break; break;
} else if (compressed.length < coffset + size) { } else if (compressed.length < coffset + size) {
throw new OperationError("Malformed LZNT1 stream: Block too small! Has the stream been truncated?"); throw new OperationError("Malformed LZNT1 stream: Block too small! Has the stream been truncated?");
} }
if ((blockHeader & COMPRESSED_MASK) !== 0) { if ((blockHeader & COMPRESSED_MASK) !== 0) {
while (coffset < blockEnd) { while (coffset < blockEnd) {
let header = compressed[coffset++]; let header = compressed[coffset++];
for (let i = 0; i < 8 && coffset < blockEnd; i++) { for (let i = 0; i < 8 && coffset < blockEnd; i++) {
if ((header & 1) === 0) { if ((header & 1) === 0) {
decompressed.push(compressed[coffset++]); decompressed.push(compressed[coffset++]);
} else { } else {
const pointer = Utils.byteArrayToInt(compressed.slice(coffset, coffset + 2), "little"); const pointer = Utils.byteArrayToInt(compressed.slice(coffset, coffset + 2), "little");
coffset += 2; coffset += 2;
const displacement = getDisplacement(decompressed.length - doffset - 1); const displacement = getDisplacement(decompressed.length - doffset - 1);
const symbolOffset = (pointer >> (12 - displacement)) + 1; const symbolOffset = (pointer >> (12 - displacement)) + 1;
const symbolLength = (pointer & (0xFFF >> displacement)) + 2; const symbolLength = (pointer & (0xFFF >> displacement)) + 2;
const shiftOffset = decompressed.length - symbolOffset; const shiftOffset = decompressed.length - symbolOffset;
for (let shiftDelta = 0; shiftDelta < symbolLength + 1; shiftDelta++) { for (let shiftDelta = 0; shiftDelta < symbolLength + 1; shiftDelta++) {
const shift = shiftOffset + shiftDelta; const shift = shiftOffset + shiftDelta;
if (shift < 0 || decompressed.length <= shift) { if (shift < 0 || decompressed.length <= shift) {
throw new OperationError("Malformed LZNT1 stream: Invalid shift!"); throw new OperationError("Malformed LZNT1 stream: Invalid shift!");
} }
decompressed.push(decompressed[shift]); decompressed.push(decompressed[shift]);
} }
} }
header >>= 1; header >>= 1;
} }
} }
} else { } else {
decompressed.push(...compressed.slice(coffset, coffset + size + 1)); decompressed.push(...compressed.slice(coffset, coffset + size + 1));
coffset += size + 1; coffset += size + 1;
} }
} }
return decompressed; return decompressed;
} }

View file

@ -1,41 +1,41 @@
/** /**
* @author 0xThiebaut [thiebaut.dev] * @author 0xThiebaut [thiebaut.dev]
* @copyright Crown Copyright 2023 * @copyright Crown Copyright 2023
* @license Apache-2.0 * @license Apache-2.0
*/ */
import Operation from "../Operation.mjs"; import Operation from "../Operation.mjs";
import {decompress} from "../lib/LZNT1.mjs"; import {decompress} from "../lib/LZNT1.mjs";
/** /**
* LZNT1 Decompress operation * LZNT1 Decompress operation
*/ */
class LZNT1Decompress extends Operation { class LZNT1Decompress extends Operation {
/** /**
* LZNT1 Decompress constructor * LZNT1 Decompress constructor
*/ */
constructor() { constructor() {
super(); super();
this.name = "LZNT1 Decompress"; this.name = "LZNT1 Decompress";
this.module = "Compression"; this.module = "Compression";
this.description = "Decompresses data using the LZNT1 algorithm.<br><br>Similar to the Windows API <code>RtlDecompressBuffer</code>."; this.description = "Decompresses data using the LZNT1 algorithm.<br><br>Similar to the Windows API <code>RtlDecompressBuffer</code>.";
this.infoURL = "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-xca/5655f4a3-6ba4-489b-959f-e1f407c52f15"; this.infoURL = "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-xca/5655f4a3-6ba4-489b-959f-e1f407c52f15";
this.inputType = "byteArray"; this.inputType = "byteArray";
this.outputType = "byteArray"; this.outputType = "byteArray";
this.args = []; this.args = [];
} }
/** /**
* @param {byteArray} input * @param {byteArray} input
* @param {Object[]} args * @param {Object[]} args
* @returns {byteArray} * @returns {byteArray}
*/ */
run(input, args) { run(input, args) {
return decompress(input); return decompress(input);
} }
} }
export default LZNT1Decompress; export default LZNT1Decompress;

View file

@ -1,22 +1,22 @@
/** /**
* LZNT1 Decompress tests. * LZNT1 Decompress tests.
* *
* @author 0xThiebaut [thiebaut.dev] * @author 0xThiebaut [thiebaut.dev]
* @copyright Crown Copyright 2023 * @copyright Crown Copyright 2023
* @license Apache-2.0 * @license Apache-2.0
*/ */
import TestRegister from "../../lib/TestRegister.mjs"; import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([ TestRegister.addTests([
{ {
name: "LZNT1 Decompress", name: "LZNT1 Decompress",
input: "\x1a\xb0\x00compress\x00edtestda\x04ta\x07\x88alot", input: "\x1a\xb0\x00compress\x00edtestda\x04ta\x07\x88alot",
expectedOutput: "compressedtestdatacompressedalot", expectedOutput: "compressedtestdatacompressedalot",
recipeConfig: [ recipeConfig: [
{ {
op: "LZNT1 Decompress", op: "LZNT1 Decompress",
args: [] args: []
} }
], ],
} }
]); ]);