Skip to content

Commit 44b1006

Browse files
authored
Merge pull request #515 from 5saviahv/updates
Keep local extra data
2 parents 696646c + 86bae22 commit 44b1006

File tree

8 files changed

+235
-96
lines changed

8 files changed

+235
-96
lines changed

.github/workflows/codeql.yml

+37-37
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ name: "CodeQL"
1313

1414
on:
1515
push:
16-
branches: [ "master" ]
16+
branches: ["master"]
1717
pull_request:
18-
branches: [ "master" ]
18+
branches: ["master"]
1919
schedule:
20-
- cron: '41 3 * * 5'
20+
- cron: "41 3 * * 5"
2121

2222
jobs:
2323
analyze:
@@ -44,8 +44,8 @@ jobs:
4444
fail-fast: false
4545
matrix:
4646
include:
47-
- language: javascript-typescript
48-
build-mode: none
47+
- language: javascript-typescript
48+
build-mode: none
4949
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
5050
# Use `c-cpp` to analyze code written in C, C++ or both
5151
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
@@ -55,39 +55,39 @@ jobs:
5555
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
5656
# 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
5757
steps:
58-
- name: Checkout repository
59-
uses: actions/checkout@v4
58+
- name: Checkout repository
59+
uses: actions/checkout@v4
6060

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

71-
# 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
72-
# queries: security-extended,security-and-quality
71+
# 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
72+
# queries: security-extended,security-and-quality
7373

74-
# If the analyze step fails for one of the languages you are analyzing with
75-
# "We were unable to automatically build your code", modify the matrix above
76-
# to set the build mode to "manual" for that language. Then modify this step
77-
# to build your code.
78-
# ℹ️ Command-line programs to run using the OS shell.
79-
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
80-
- if: matrix.build-mode == 'manual'
81-
shell: bash
82-
run: |
83-
echo 'If you are using a "manual" build mode for one or more of the' \
84-
'languages you are analyzing, replace this with the commands to build' \
85-
'your code, for example:'
86-
echo ' make bootstrap'
87-
echo ' make release'
88-
exit 1
74+
# If the analyze step fails for one of the languages you are analyzing with
75+
# "We were unable to automatically build your code", modify the matrix above
76+
# to set the build mode to "manual" for that language. Then modify this step
77+
# to build your code.
78+
# ℹ️ Command-line programs to run using the OS shell.
79+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
80+
- if: matrix.build-mode == 'manual'
81+
shell: bash
82+
run: |
83+
echo 'If you are using a "manual" build mode for one or more of the' \
84+
'languages you are analyzing, replace this with the commands to build' \
85+
'your code, for example:'
86+
echo ' make bootstrap'
87+
echo ' make release'
88+
exit 1
8989
90-
- name: Perform CodeQL Analysis
91-
uses: github/codeql-action/analyze@v3
92-
with:
93-
category: "/language:${{matrix.language}}"
90+
- name: Perform CodeQL Analysis
91+
uses: github/codeql-action/analyze@v3
92+
with:
93+
category: "/language:${{matrix.language}}"

adm-zip.js

+28-1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,18 @@ module.exports = function (/**String*/ input, /** object */ options) {
123123
return (item && item.getData(pass)) || null;
124124
},
125125

126+
/**
127+
* Returns how many child elements has on entry (directories) on files it is always 0
128+
* @param {ZipEntry|string} entry ZipEntry object or String with the full path of the entry
129+
* @returns {integer}
130+
*/
131+
childCount: function (entry) {
132+
const item = getEntry(entry);
133+
if (item) {
134+
return _zip.getChildCount(item);
135+
}
136+
},
137+
126138
/**
127139
* Asynchronous readFile
128140
* @param {ZipEntry|string} entry ZipEntry object or String with the full path of the entry
@@ -188,11 +200,26 @@ module.exports = function (/**String*/ input, /** object */ options) {
188200
/**
189201
* Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory
190202
*
191-
* @param {ZipEntry} entry
203+
* @param {ZipEntry|string} entry
204+
* @returns {void}
192205
*/
193206
deleteFile: function (entry) {
194207
// @TODO: test deleteFile
195208
var item = getEntry(entry);
209+
if (item) {
210+
_zip.deleteFile(item.entryName);
211+
}
212+
},
213+
214+
/**
215+
* Remove the entry from the file or directory without affecting any nested entries
216+
*
217+
* @param {ZipEntry|string} entry
218+
* @returns {void}
219+
*/
220+
deleteEntry: function (entry) {
221+
// @TODO: test deleteEntry
222+
var item = getEntry(entry);
196223
if (item) {
197224
_zip.deleteEntry(item.entryName);
198225
}

headers/entryHeader.js

+35-22
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ module.exports = function () {
2525
// Without it file names may be corrupted for other apps when file names use unicode chars
2626
_flags |= Constants.FLG_EFS;
2727

28-
var _localHeader = {};
28+
const _localHeader = {
29+
extraLen: 0
30+
};
2931

3032
function setTime(val) {
3133
val = new Date(val);
@@ -143,6 +145,13 @@ module.exports = function () {
143145
_extraLen = val;
144146
},
145147

148+
get extraLocalLength() {
149+
return _localHeader.extraLen;
150+
},
151+
set extraLocalLength(val) {
152+
_localHeader.extraLen = val;
153+
},
154+
146155
get commentLength() {
147156
return _comLen;
148157
},
@@ -205,26 +214,30 @@ module.exports = function () {
205214
if (data.readUInt32LE(0) !== Constants.LOCSIG) {
206215
throw new Error(Utils.Errors.INVALID_LOC);
207216
}
208-
_localHeader = {
209-
// version needed to extract
210-
version: data.readUInt16LE(Constants.LOCVER),
211-
// general purpose bit flag
212-
flags: data.readUInt16LE(Constants.LOCFLG),
213-
// compression method
214-
method: data.readUInt16LE(Constants.LOCHOW),
215-
// modification time (2 bytes time, 2 bytes date)
216-
time: data.readUInt32LE(Constants.LOCTIM),
217-
// uncompressed file crc-32 value
218-
crc: data.readUInt32LE(Constants.LOCCRC),
219-
// compressed size
220-
compressedSize: data.readUInt32LE(Constants.LOCSIZ),
221-
// uncompressed size
222-
size: data.readUInt32LE(Constants.LOCLEN),
223-
// filename length
224-
fnameLen: data.readUInt16LE(Constants.LOCNAM),
225-
// extra field length
226-
extraLen: data.readUInt16LE(Constants.LOCEXT)
227-
};
217+
218+
// version needed to extract
219+
_localHeader.version = data.readUInt16LE(Constants.LOCVER);
220+
// general purpose bit flag
221+
_localHeader.flags = data.readUInt16LE(Constants.LOCFLG);
222+
// compression method
223+
_localHeader.method = data.readUInt16LE(Constants.LOCHOW);
224+
// modification time (2 bytes time, 2 bytes date)
225+
_localHeader.time = data.readUInt32LE(Constants.LOCTIM);
226+
// uncompressed file crc-32 valu
227+
_localHeader.crc = data.readUInt32LE(Constants.LOCCRC);
228+
// compressed size
229+
_localHeader.compressedSize = data.readUInt32LE(Constants.LOCSIZ);
230+
// uncompressed size
231+
_localHeader.size = data.readUInt32LE(Constants.LOCLEN);
232+
// filename length
233+
_localHeader.fnameLen = data.readUInt16LE(Constants.LOCNAM);
234+
// extra field length
235+
_localHeader.extraLen = data.readUInt16LE(Constants.LOCEXT);
236+
237+
// read extra data
238+
const extraStart = _offset + Constants.LOCHDR + _localHeader.fnameLen;
239+
const extraEnd = extraStart + _localHeader.extraLen;
240+
return input.slice(extraStart, extraEnd);
228241
},
229242

230243
loadFromBinary: function (/*Buffer*/ data) {
@@ -286,7 +299,7 @@ module.exports = function () {
286299
// filename length
287300
data.writeUInt16LE(_fnameLen, Constants.LOCNAM);
288301
// extra field length
289-
data.writeUInt16LE(_extraLen, Constants.LOCEXT);
302+
data.writeUInt16LE(_localHeader.extraLen, Constants.LOCEXT);
290303
return data;
291304
},
292305

test/assets/maximum3.zip

3.54 KB
Binary file not shown.

test/assets/ultra.zip

-360 Bytes
Binary file not shown.

test/methods/methods.test.js

+54
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ describe("adm-zip.js - methods handling local files", () => {
121121
});
122122

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

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

150152
expect(files.sort()).to.deep.equal(ultrazip.sort());
151153
});
154+
155+
it("zip.extractEntryTo(entry, destination, false, true) - [ extract folder from file where folders exists ]", () => {
156+
const zip = new Zip("./test/assets/maximum.zip");
157+
158+
zip.extractEntryTo("./attributes_test/New folder/", destination, false, true);
159+
160+
const files = walk(destination);
161+
const maximumzip = ["hidden.txt", "hidden_readonly.txt", "readonly.txt", "somefile.txt"].map(wrapList);
162+
163+
expect(files.sort()).to.deep.equal(maximumzip.sort());
164+
});
165+
166+
it("zip.extractEntryTo(entry, destination, false, true) - [ extract folder from file where folders does not exists ]", () => {
167+
const zip = new Zip("./test/assets/maximum3.zip");
168+
169+
zip.extractEntryTo("./attributes_test/New folder/", destination, false, true);
170+
171+
const files = walk(destination);
172+
const maximumzip = ["hidden.txt", "hidden_readonly.txt", "readonly.txt", "somefile.txt"].map(wrapList);
173+
174+
expect(files.sort()).to.deep.equal(maximumzip.sort());
175+
});
176+
177+
it("zip.extractEntryTo(entry, destination, true, true) - [ extract folder from file where folders exists ]", () => {
178+
const zip = new Zip("./test/assets/maximum.zip");
179+
180+
zip.extractEntryTo("./attributes_test/New folder/", destination, true, true);
181+
182+
const files = walk(destination);
183+
const maximumzip = [
184+
"./attributes_test/New folder/hidden.txt",
185+
"./attributes_test/New folder/hidden_readonly.txt",
186+
"./attributes_test/New folder/readonly.txt",
187+
"./attributes_test/New folder/somefile.txt"
188+
].map(wrapList);
189+
expect(files.sort()).to.deep.equal(maximumzip.sort());
190+
});
191+
192+
it("zip.extractEntryTo(entry, destination, true, true) - [ extract folder from file where folders does not exists ]", () => {
193+
const zip = new Zip("./test/assets/maximum3.zip");
194+
195+
zip.extractEntryTo("./attributes_test/New folder/", destination, true, true);
196+
197+
const files = walk(destination);
198+
const maximumzip = [
199+
"./attributes_test/New folder/hidden.txt",
200+
"./attributes_test/New folder/hidden_readonly.txt",
201+
"./attributes_test/New folder/readonly.txt",
202+
"./attributes_test/New folder/somefile.txt"
203+
].map(wrapList);
204+
expect(files.sort()).to.deep.equal(maximumzip.sort());
205+
});
152206
});
153207

154208
describe(".addLocalFolder() - sync", () => {

zipEntry.js

+10-11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module.exports = function (/** object */ options, /*Buffer*/ input) {
1010
_isDirectory = false,
1111
uncompressedData = null,
1212
_extra = Buffer.alloc(0),
13+
_extralocal = Buffer.alloc(0),
1314
_efs = true;
1415

1516
// assign options
@@ -23,7 +24,7 @@ module.exports = function (/** object */ options, /*Buffer*/ input) {
2324
if (!input || !(input instanceof Uint8Array)) {
2425
return Buffer.alloc(0);
2526
}
26-
_centralHeader.loadLocalHeaderFromBinary(input);
27+
_extralocal = _centralHeader.loadLocalHeaderFromBinary(input);
2728
return input.slice(_centralHeader.realDataOffset, _centralHeader.realDataOffset + _centralHeader.compressedSize);
2829
}
2930

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

341342
packCentralHeader: function () {
342343
_centralHeader.flags_efs = this.efs;
344+
_centralHeader.extraLength = _extra.length;
343345
// 1. create header (buffer)
344346
var header = _centralHeader.centralHeaderToBinary();
345347
var addpos = Utils.Constants.CENHDR;
346348
// 2. add file name
347349
_entryName.copy(header, addpos);
348350
addpos += _entryName.length;
349351
// 3. add extra data
350-
if (_centralHeader.extraLength) {
351-
_extra.copy(header, addpos);
352-
addpos += _centralHeader.extraLength;
353-
}
352+
_extra.copy(header, addpos);
353+
addpos += _centralHeader.extraLength;
354354
// 4. add file comment
355-
if (_centralHeader.commentLength) {
356-
_comment.copy(header, addpos);
357-
}
355+
_comment.copy(header, addpos);
358356
return header;
359357
},
360358

361359
packLocalHeader: function () {
362360
let addpos = 0;
363361
_centralHeader.flags_efs = this.efs;
362+
_centralHeader.extraLocalLength = _extralocal.length;
364363
// 1. construct local header Buffer
365364
const localHeaderBuf = _centralHeader.localHeaderToBinary();
366365
// 2. localHeader - crate header buffer
367-
const localHeader = Buffer.alloc(localHeaderBuf.length + _entryName.length + _extra.length);
366+
const localHeader = Buffer.alloc(localHeaderBuf.length + _entryName.length + _centralHeader.extraLocalLength);
368367
// 2.1 add localheader
369368
localHeaderBuf.copy(localHeader, addpos);
370369
addpos += localHeaderBuf.length;
371370
// 2.2 add file name
372371
_entryName.copy(localHeader, addpos);
373372
addpos += _entryName.length;
374373
// 2.3 add extra field
375-
_extra.copy(localHeader, addpos);
376-
addpos += _extra.length;
374+
_extralocal.copy(localHeader, addpos);
375+
addpos += _extralocal.length;
377376

378377
return localHeader;
379378
},

0 commit comments

Comments
 (0)