Skip to content

Commit

Permalink
Merge pull request #515 from 5saviahv/updates
Browse files Browse the repository at this point in the history
Keep local extra data
  • Loading branch information
5saviahv authored Jun 25, 2024
2 parents 696646c + 86bae22 commit 44b1006
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 96 deletions.
74 changes: 37 additions & 37 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ name: "CodeQL"

on:
push:
branches: [ "master" ]
branches: ["master"]
pull_request:
branches: [ "master" ]
branches: ["master"]
schedule:
- cron: '41 3 * * 5'
- cron: "41 3 * * 5"

jobs:
analyze:
Expand All @@ -44,8 +44,8 @@ jobs:
fail-fast: false
matrix:
include:
- language: javascript-typescript
build-mode: none
- language: javascript-typescript
build-mode: none
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
Expand All @@ -55,39 +55,39 @@ jobs:
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout repository
uses: actions/checkout@v4

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality

# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
29 changes: 28 additions & 1 deletion adm-zip.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ module.exports = function (/**String*/ input, /** object */ options) {
return (item && item.getData(pass)) || null;
},

/**
* Returns how many child elements has on entry (directories) on files it is always 0
* @param {ZipEntry|string} entry ZipEntry object or String with the full path of the entry
* @returns {integer}
*/
childCount: function (entry) {
const item = getEntry(entry);
if (item) {
return _zip.getChildCount(item);
}
},

/**
* Asynchronous readFile
* @param {ZipEntry|string} entry ZipEntry object or String with the full path of the entry
Expand Down Expand Up @@ -188,11 +200,26 @@ module.exports = function (/**String*/ input, /** object */ options) {
/**
* Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory
*
* @param {ZipEntry} entry
* @param {ZipEntry|string} entry
* @returns {void}
*/
deleteFile: function (entry) {
// @TODO: test deleteFile
var item = getEntry(entry);
if (item) {
_zip.deleteFile(item.entryName);
}
},

/**
* Remove the entry from the file or directory without affecting any nested entries
*
* @param {ZipEntry|string} entry
* @returns {void}
*/
deleteEntry: function (entry) {
// @TODO: test deleteEntry
var item = getEntry(entry);
if (item) {
_zip.deleteEntry(item.entryName);
}
Expand Down
57 changes: 35 additions & 22 deletions headers/entryHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ module.exports = function () {
// Without it file names may be corrupted for other apps when file names use unicode chars
_flags |= Constants.FLG_EFS;

var _localHeader = {};
const _localHeader = {
extraLen: 0
};

function setTime(val) {
val = new Date(val);
Expand Down Expand Up @@ -143,6 +145,13 @@ module.exports = function () {
_extraLen = val;
},

get extraLocalLength() {
return _localHeader.extraLen;
},
set extraLocalLength(val) {
_localHeader.extraLen = val;
},

get commentLength() {
return _comLen;
},
Expand Down Expand Up @@ -205,26 +214,30 @@ module.exports = function () {
if (data.readUInt32LE(0) !== Constants.LOCSIG) {
throw new Error(Utils.Errors.INVALID_LOC);
}
_localHeader = {
// version needed to extract
version: data.readUInt16LE(Constants.LOCVER),
// general purpose bit flag
flags: data.readUInt16LE(Constants.LOCFLG),
// compression method
method: data.readUInt16LE(Constants.LOCHOW),
// modification time (2 bytes time, 2 bytes date)
time: data.readUInt32LE(Constants.LOCTIM),
// uncompressed file crc-32 value
crc: data.readUInt32LE(Constants.LOCCRC),
// compressed size
compressedSize: data.readUInt32LE(Constants.LOCSIZ),
// uncompressed size
size: data.readUInt32LE(Constants.LOCLEN),
// filename length
fnameLen: data.readUInt16LE(Constants.LOCNAM),
// extra field length
extraLen: data.readUInt16LE(Constants.LOCEXT)
};

// version needed to extract
_localHeader.version = data.readUInt16LE(Constants.LOCVER);
// general purpose bit flag
_localHeader.flags = data.readUInt16LE(Constants.LOCFLG);
// compression method
_localHeader.method = data.readUInt16LE(Constants.LOCHOW);
// modification time (2 bytes time, 2 bytes date)
_localHeader.time = data.readUInt32LE(Constants.LOCTIM);
// uncompressed file crc-32 valu
_localHeader.crc = data.readUInt32LE(Constants.LOCCRC);
// compressed size
_localHeader.compressedSize = data.readUInt32LE(Constants.LOCSIZ);
// uncompressed size
_localHeader.size = data.readUInt32LE(Constants.LOCLEN);
// filename length
_localHeader.fnameLen = data.readUInt16LE(Constants.LOCNAM);
// extra field length
_localHeader.extraLen = data.readUInt16LE(Constants.LOCEXT);

// read extra data
const extraStart = _offset + Constants.LOCHDR + _localHeader.fnameLen;
const extraEnd = extraStart + _localHeader.extraLen;
return input.slice(extraStart, extraEnd);
},

loadFromBinary: function (/*Buffer*/ data) {
Expand Down Expand Up @@ -286,7 +299,7 @@ module.exports = function () {
// filename length
data.writeUInt16LE(_fnameLen, Constants.LOCNAM);
// extra field length
data.writeUInt16LE(_extraLen, Constants.LOCEXT);
data.writeUInt16LE(_localHeader.extraLen, Constants.LOCEXT);
return data;
},

Expand Down
Binary file added test/assets/maximum3.zip
Binary file not shown.
Binary file modified test/assets/ultra.zip
Binary file not shown.
54 changes: 54 additions & 0 deletions test/methods/methods.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ describe("adm-zip.js - methods handling local files", () => {
});

describe(".extractEntryTo() - sync", () => {
// each entry one by one
it("zip.extractEntryTo(entry, destination, false, true)", () => {
const zip = new Zip("./test/assets/ultra.zip");
var zipEntries = zip.getEntries();
Expand All @@ -132,6 +133,7 @@ describe("adm-zip.js - methods handling local files", () => {
expect(files.sort()).to.deep.equal(ultrazip.sort());
});

// each entry one by one
it("zip.extractEntryTo(entry, destination, true, true)", () => {
const zip = new Zip("./test/assets/ultra.zip");
var zipEntries = zip.getEntries();
Expand All @@ -149,6 +151,58 @@ describe("adm-zip.js - methods handling local files", () => {

expect(files.sort()).to.deep.equal(ultrazip.sort());
});

it("zip.extractEntryTo(entry, destination, false, true) - [ extract folder from file where folders exists ]", () => {
const zip = new Zip("./test/assets/maximum.zip");

zip.extractEntryTo("./attributes_test/New folder/", destination, false, true);

const files = walk(destination);
const maximumzip = ["hidden.txt", "hidden_readonly.txt", "readonly.txt", "somefile.txt"].map(wrapList);

expect(files.sort()).to.deep.equal(maximumzip.sort());
});

it("zip.extractEntryTo(entry, destination, false, true) - [ extract folder from file where folders does not exists ]", () => {
const zip = new Zip("./test/assets/maximum3.zip");

zip.extractEntryTo("./attributes_test/New folder/", destination, false, true);

const files = walk(destination);
const maximumzip = ["hidden.txt", "hidden_readonly.txt", "readonly.txt", "somefile.txt"].map(wrapList);

expect(files.sort()).to.deep.equal(maximumzip.sort());
});

it("zip.extractEntryTo(entry, destination, true, true) - [ extract folder from file where folders exists ]", () => {
const zip = new Zip("./test/assets/maximum.zip");

zip.extractEntryTo("./attributes_test/New folder/", destination, true, true);

const files = walk(destination);
const maximumzip = [
"./attributes_test/New folder/hidden.txt",
"./attributes_test/New folder/hidden_readonly.txt",
"./attributes_test/New folder/readonly.txt",
"./attributes_test/New folder/somefile.txt"
].map(wrapList);
expect(files.sort()).to.deep.equal(maximumzip.sort());
});

it("zip.extractEntryTo(entry, destination, true, true) - [ extract folder from file where folders does not exists ]", () => {
const zip = new Zip("./test/assets/maximum3.zip");

zip.extractEntryTo("./attributes_test/New folder/", destination, true, true);

const files = walk(destination);
const maximumzip = [
"./attributes_test/New folder/hidden.txt",
"./attributes_test/New folder/hidden_readonly.txt",
"./attributes_test/New folder/readonly.txt",
"./attributes_test/New folder/somefile.txt"
].map(wrapList);
expect(files.sort()).to.deep.equal(maximumzip.sort());
});
});

describe(".addLocalFolder() - sync", () => {
Expand Down
21 changes: 10 additions & 11 deletions zipEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = function (/** object */ options, /*Buffer*/ input) {
_isDirectory = false,
uncompressedData = null,
_extra = Buffer.alloc(0),
_extralocal = Buffer.alloc(0),
_efs = true;

// assign options
Expand All @@ -23,7 +24,7 @@ module.exports = function (/** object */ options, /*Buffer*/ input) {
if (!input || !(input instanceof Uint8Array)) {
return Buffer.alloc(0);
}
_centralHeader.loadLocalHeaderFromBinary(input);
_extralocal = _centralHeader.loadLocalHeaderFromBinary(input);
return input.slice(_centralHeader.realDataOffset, _centralHeader.realDataOffset + _centralHeader.compressedSize);
}

Expand Down Expand Up @@ -340,40 +341,38 @@ module.exports = function (/** object */ options, /*Buffer*/ input) {

packCentralHeader: function () {
_centralHeader.flags_efs = this.efs;
_centralHeader.extraLength = _extra.length;
// 1. create header (buffer)
var header = _centralHeader.centralHeaderToBinary();
var addpos = Utils.Constants.CENHDR;
// 2. add file name
_entryName.copy(header, addpos);
addpos += _entryName.length;
// 3. add extra data
if (_centralHeader.extraLength) {
_extra.copy(header, addpos);
addpos += _centralHeader.extraLength;
}
_extra.copy(header, addpos);
addpos += _centralHeader.extraLength;
// 4. add file comment
if (_centralHeader.commentLength) {
_comment.copy(header, addpos);
}
_comment.copy(header, addpos);
return header;
},

packLocalHeader: function () {
let addpos = 0;
_centralHeader.flags_efs = this.efs;
_centralHeader.extraLocalLength = _extralocal.length;
// 1. construct local header Buffer
const localHeaderBuf = _centralHeader.localHeaderToBinary();
// 2. localHeader - crate header buffer
const localHeader = Buffer.alloc(localHeaderBuf.length + _entryName.length + _extra.length);
const localHeader = Buffer.alloc(localHeaderBuf.length + _entryName.length + _centralHeader.extraLocalLength);
// 2.1 add localheader
localHeaderBuf.copy(localHeader, addpos);
addpos += localHeaderBuf.length;
// 2.2 add file name
_entryName.copy(localHeader, addpos);
addpos += _entryName.length;
// 2.3 add extra field
_extra.copy(localHeader, addpos);
addpos += _extra.length;
_extralocal.copy(localHeader, addpos);
addpos += _extralocal.length;

return localHeader;
},
Expand Down
Loading

0 comments on commit 44b1006

Please sign in to comment.