🚧 Improve .solidpkg reader
This commit is contained in:
parent
a382fe6e0f
commit
5b3a6c0dd7
3 changed files with 63 additions and 7 deletions
|
@ -1,6 +1,6 @@
|
|||
import getUrlContents from './getUrlContents';
|
||||
import { Product } from './interfaces/ISettings';
|
||||
import verifyProductName from './verifyProductName';
|
||||
import getUrlContents from '../getUrlContents';
|
||||
import { Product } from '../interfaces/ISettings';
|
||||
import verifyProductName from '../verifyProductName';
|
||||
|
||||
export default function getSolidpkg(product: Product, from: number, to: number): Promise<Buffer> {
|
||||
//Verify function arguments
|
23
src/ssn/modifyPassword.ts
Normal file
23
src/ssn/modifyPassword.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/** Takes a password as it is included in the extra field, and returns a password that can be used to decode the file. */
|
||||
export default function modifyPassword(passwordIn: Uint8Array) {
|
||||
const passwordLength = passwordIn.byteLength;
|
||||
const passwordOut = new Uint8Array(passwordLength);
|
||||
|
||||
for (let i = 0; i < passwordLength; i += 1) {
|
||||
if (passwordIn[i] === 0) { break; }
|
||||
let curChar = passwordIn[i] + (1 << (i % 32));
|
||||
if (curChar > 0x7E) {
|
||||
if (curChar === 0xFF || curChar === 0x7F) {
|
||||
curChar = 0x3F;
|
||||
} else {
|
||||
curChar = curChar & 0x7F;
|
||||
}
|
||||
}
|
||||
if (curChar < 0x21) {
|
||||
curChar = (curChar | (1 << ((curChar % 3) + 5))) + 1;
|
||||
}
|
||||
passwordOut[i] = curChar;
|
||||
}
|
||||
|
||||
return passwordOut;
|
||||
}
|
|
@ -1,9 +1,15 @@
|
|||
import { TextDecoder } from 'util';
|
||||
import modifyPassword from './modifyPassword';
|
||||
|
||||
const MAGIC_END_OF_CENTRAL_DIR = 0x06054b50;
|
||||
const MAGIC_CENTRAL_DIR = 0x02014b50;
|
||||
const COMPRESSION_DEFLATE = 8;
|
||||
|
||||
const Decoder = new TextDecoder('utf-8');
|
||||
|
||||
export default function readSolidpkg(buffer: Buffer) {
|
||||
const dv = new DataView(buffer.buffer);
|
||||
const arrayBuffer = buffer.buffer;
|
||||
const dv = new DataView(arrayBuffer);
|
||||
|
||||
//--------------- READ END OF CENTRAL DIR ---------------
|
||||
|
||||
|
@ -75,10 +81,37 @@ export default function readSolidpkg(buffer: Buffer) {
|
|||
const fileCommentLength = dv.getUint16(pos, true); pos += 2;
|
||||
pos += 8; //skip disk num start and file attributes
|
||||
const relOffset = dv.getUint32(pos, true); pos += 4;
|
||||
pos += fileNameLength; //skip file name
|
||||
//TODO: read password from extra field
|
||||
const fileName = Decoder.decode(new DataView(arrayBuffer, pos, fileNameLength)); pos += fileNameLength; //skip file name
|
||||
|
||||
//read password from extra field
|
||||
let encodedPassword: Uint8Array | undefined;
|
||||
while (pos + 4 <= extraFieldLength) {
|
||||
const fieldId = dv.getUint16(pos, true); pos += 2;
|
||||
const fieldLength = dv.getUint16(pos, true); pos += 2;
|
||||
switch (fieldId) {
|
||||
case 0x8810: { //password
|
||||
if (fieldLength > 120) {
|
||||
throw new Error(`Password is too long, it should be 120 characters at most but is ${fieldLength} characters long.`);
|
||||
}
|
||||
const passwordLength = fieldLength;
|
||||
encodedPassword = new Uint8Array(arrayBuffer, pos, fieldLength);
|
||||
break;
|
||||
}
|
||||
case 0x80AE: //unknown, some kind of hash or checksum, ignore it
|
||||
break;
|
||||
default:
|
||||
//unknown field, ignore it
|
||||
}
|
||||
pos += fieldLength;
|
||||
}
|
||||
if (typeof encodedPassword === 'undefined') {
|
||||
throw new Error('Could not find password in extra field.');
|
||||
}
|
||||
|
||||
const decodedPassword = modifyPassword(encodedPassword);
|
||||
|
||||
//TODO: read encrypted + compressed file
|
||||
//...
|
||||
|
||||
return { lastMod1, lastMod2, fileCrc, comprSize, uncomprSize, fileNameLength, extraFieldLength, fileCommentLength, relOffset };
|
||||
return { lastMod1, lastMod2, fileCrc, comprSize, uncomprSize, fileNameLength, extraFieldLength, fileCommentLength, relOffset, fileName, encodedPassword, decodedPassword };
|
||||
}
|
Loading…
Reference in a new issue