7zip-native 0.0.14 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/binding.gyp +8 -8
- package/native/addon.cpp +108 -30
- package/package.json +13 -2
- package/prebuilds/darwin-arm64/7zip_native.node +0 -0
- package/prebuilds/darwin-x64/7zip_native.node +0 -0
- package/prebuilds/linux-arm/7zip_native.node +0 -0
- package/prebuilds/linux-arm64/7zip_native.node +0 -0
- package/prebuilds/linux-ia32/7zip_native.node +0 -0
- package/prebuilds/linux-x64/7zip_native.node +0 -0
- package/prebuilds/win32-arm64/7z.dll +0 -0
- package/prebuilds/win32-arm64/7zip_native.node +0 -0
- package/prebuilds/win32-x64/7z.dll +0 -0
- package/prebuilds/win32-x64/7zip_native.node +0 -0
package/README.md
CHANGED
|
@@ -294,7 +294,7 @@ Windows x86 (ia32) is not supported by the published prebuilt binaries.
|
|
|
294
294
|
|
|
295
295
|
## Electron
|
|
296
296
|
|
|
297
|
-
The addon uses Node-API, but the addon and 7-Zip engine still need to match the Electron application's operating system and architecture. Use a matching package prebuild when available, or rebuild for the Electron version and target architecture using your Electron build tooling.
|
|
297
|
+
The addon uses Node-API, but the addon and 7-Zip engine still need to match the Electron application's operating system and architecture. Use a matching package prebuild when available, or rebuild for the Electron version and target architecture using your Electron build tooling. The engine is loaded at runtime rather than linked into the addon, so ensure the matching engine library is included alongside the addon.
|
|
298
298
|
|
|
299
299
|
When packaging with ASAR, ensure both `7zip_native.node` and the matching engine library (`7z.dll`, `7z.so`, or `lib7z.dylib`) are physically unpacked and that the runtime paths resolve to those unpacked files. For `electron-builder`, an `asarUnpack` configuration can include:
|
|
300
300
|
|
package/binding.gyp
CHANGED
|
@@ -15,20 +15,20 @@
|
|
|
15
15
|
"cflags_cc!": ["-fno-exceptions"],
|
|
16
16
|
"conditions": [
|
|
17
17
|
["OS=='linux'", {
|
|
18
|
+
"sources": [
|
|
19
|
+
"vendor/7zip/CPP/Common/MyWindows.cpp",
|
|
20
|
+
"vendor/7zip/CPP/Windows/PropVariant.cpp"
|
|
21
|
+
],
|
|
18
22
|
"cflags_cc": ["-pthread"],
|
|
19
23
|
"libraries": [
|
|
20
24
|
"-pthread",
|
|
21
|
-
"-ldl"
|
|
22
|
-
"-L<(module_root_dir)/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o",
|
|
23
|
-
"-l:7z.so",
|
|
24
|
-
"-Wl,-rpath,'$$ORIGIN'"
|
|
25
|
+
"-ldl"
|
|
25
26
|
]
|
|
26
27
|
}],
|
|
27
28
|
["OS=='mac'", {
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"-Wl,-rpath,@loader_path"
|
|
29
|
+
"sources": [
|
|
30
|
+
"vendor/7zip/CPP/Common/MyWindows.cpp",
|
|
31
|
+
"vendor/7zip/CPP/Windows/PropVariant.cpp"
|
|
32
32
|
],
|
|
33
33
|
"xcode_settings": {
|
|
34
34
|
"CLANG_CXX_LANGUAGE_STANDARD": "c++17",
|
package/native/addon.cpp
CHANGED
|
@@ -2160,12 +2160,12 @@ public:
|
|
|
2160
2160
|
GUID classId;
|
|
2161
2161
|
std::string name;
|
|
2162
2162
|
bool extensionMatch;
|
|
2163
|
-
bool
|
|
2164
|
-
|
|
2163
|
+
bool contentMatch;
|
|
2164
|
+
unsigned probePriority;
|
|
2165
2165
|
};
|
|
2166
2166
|
std::vector<Format> formats;
|
|
2167
2167
|
formats.reserve(formatCount);
|
|
2168
|
-
std::vector<Byte> header(
|
|
2168
|
+
std::vector<Byte> header(1 << 20);
|
|
2169
2169
|
auto *probeFile = new FileInStream();
|
|
2170
2170
|
CMyComPtr<IInStream> probe = probeFile;
|
|
2171
2171
|
if (!probeFile->Open(path)) {
|
|
@@ -2178,6 +2178,8 @@ public:
|
|
|
2178
2178
|
if (headerSize == 0) {
|
|
2179
2179
|
throw std::runtime_error("Archive file is empty");
|
|
2180
2180
|
}
|
|
2181
|
+
const bool endOfFile = headerSize < header.size()
|
|
2182
|
+
|| GetFileStamp(path).size <= headerSize;
|
|
2181
2183
|
for (UInt32 i = 0; i < formatCount; ++i) {
|
|
2182
2184
|
NWindows::NCOM::CPropVariant classIdValue;
|
|
2183
2185
|
if (g_getHandlerProperty(i, NArchive::NHandlerPropID::kClassID, &classIdValue) != S_OK
|
|
@@ -2207,38 +2209,95 @@ public:
|
|
|
2207
2209
|
}
|
|
2208
2210
|
Func_IsArc isArchive = nullptr;
|
|
2209
2211
|
const bool hasSignatureFunction = g_getIsArc(i, &isArchive) == S_OK && isArchive != nullptr;
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2212
|
+
constexpr UInt32 kStartOpenFlags =
|
|
2213
|
+
NArcInfoFlags::kStartOpen
|
|
2214
|
+
| NArcInfoFlags::kPureStartOpen
|
|
2215
|
+
| NArcInfoFlags::kBackwardOpen;
|
|
2216
|
+
NWindows::NCOM::CPropVariant flagsValue;
|
|
2217
|
+
const bool hasFlags = g_getHandlerProperty(
|
|
2218
|
+
i, NArchive::NHandlerPropID::kFlags, &flagsValue) == S_OK
|
|
2219
|
+
&& flagsValue.vt == VT_UI4;
|
|
2220
|
+
const UInt32 flags = hasFlags ? flagsValue.ulVal : 0;
|
|
2221
|
+
if (!match && (flags & NArcInfoFlags::kByExtOnlyOpen) != 0) {
|
|
2222
|
+
continue;
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
bool contentMatch = false;
|
|
2226
|
+
unsigned probePriority = match ? 0 : 2;
|
|
2227
|
+
if (hasSignatureFunction) {
|
|
2228
|
+
const auto result = isArchive(header.data(), headerSize);
|
|
2229
|
+
contentMatch = result == k_IsArc_Res_YES
|
|
2230
|
+
|| (result == k_IsArc_Res_NEED_MORE && !endOfFile);
|
|
2231
|
+
if (!match && contentMatch) {
|
|
2232
|
+
probePriority = 1;
|
|
2233
|
+
} else if (!match && !contentMatch) {
|
|
2234
|
+
continue;
|
|
2235
|
+
}
|
|
2236
|
+
} else {
|
|
2237
|
+
NWindows::NCOM::CPropVariant signatureOffsetValue;
|
|
2238
|
+
UInt32 signatureOffset = 0;
|
|
2239
|
+
if (g_getHandlerProperty(
|
|
2240
|
+
i, NArchive::NHandlerPropID::kSignatureOffset, &signatureOffsetValue) == S_OK
|
|
2241
|
+
&& signatureOffsetValue.vt == VT_UI4) {
|
|
2242
|
+
signatureOffset = signatureOffsetValue.ulVal;
|
|
2243
|
+
}
|
|
2244
|
+
std::vector<std::vector<Byte>> signatures;
|
|
2245
|
+
NWindows::NCOM::CPropVariant signatureValue;
|
|
2246
|
+
if (g_getHandlerProperty(i, NArchive::NHandlerPropID::kSignature, &signatureValue) == S_OK
|
|
2247
|
+
&& signatureValue.vt == VT_BSTR
|
|
2248
|
+
&& ::SysStringByteLen(signatureValue.bstrVal) != 0) {
|
|
2249
|
+
const auto *data = reinterpret_cast<const Byte *>(signatureValue.bstrVal);
|
|
2250
|
+
const auto size = ::SysStringByteLen(signatureValue.bstrVal);
|
|
2251
|
+
signatures.emplace_back(data, data + size);
|
|
2252
|
+
} else {
|
|
2253
|
+
NWindows::NCOM::CPropVariant multiSignatureValue;
|
|
2254
|
+
if (g_getHandlerProperty(
|
|
2255
|
+
i, NArchive::NHandlerPropID::kMultiSignature, &multiSignatureValue) == S_OK
|
|
2256
|
+
&& multiSignatureValue.vt == VT_BSTR) {
|
|
2257
|
+
const auto *data = reinterpret_cast<const Byte *>(multiSignatureValue.bstrVal);
|
|
2258
|
+
const auto size = ::SysStringByteLen(multiSignatureValue.bstrVal);
|
|
2259
|
+
for (UINT offset = 0; offset < size;) {
|
|
2260
|
+
const auto signatureSize = data[offset++];
|
|
2261
|
+
if (signatureSize > size - offset) {
|
|
2262
|
+
signatures.clear();
|
|
2263
|
+
break;
|
|
2264
|
+
}
|
|
2265
|
+
signatures.emplace_back(data + offset, data + offset + signatureSize);
|
|
2266
|
+
offset += signatureSize;
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
bool signatureMatch = false;
|
|
2272
|
+
bool needCheck = !hasFlags || signatures.empty()
|
|
2273
|
+
|| (flags & kStartOpenFlags) != 0 || signatureOffset != 0;
|
|
2274
|
+
const auto signatureOffsetSize = static_cast<std::size_t>(signatureOffset);
|
|
2275
|
+
for (const auto& signature : signatures) {
|
|
2276
|
+
if (signatureOffsetSize > headerSize
|
|
2277
|
+
|| signature.size() > headerSize - signatureOffsetSize) {
|
|
2278
|
+
if (!endOfFile) {
|
|
2279
|
+
needCheck = true;
|
|
2280
|
+
}
|
|
2281
|
+
} else if (std::memcmp(
|
|
2282
|
+
header.data() + signatureOffsetSize, signature.data(), signature.size()) == 0) {
|
|
2283
|
+
signatureMatch = true;
|
|
2284
|
+
break;
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
contentMatch = signatureMatch;
|
|
2288
|
+
if (!match && signatureMatch) {
|
|
2289
|
+
probePriority = 1;
|
|
2290
|
+
} else if (!match && !needCheck) {
|
|
2291
|
+
continue;
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
formats.push_back({i, classId, std::move(name), match, contentMatch, probePriority});
|
|
2236
2295
|
}
|
|
2237
2296
|
if (formats.empty()) {
|
|
2238
2297
|
throw std::runtime_error("No registered 7-Zip handler recognizes this archive");
|
|
2239
2298
|
}
|
|
2240
2299
|
std::stable_sort(formats.begin(), formats.end(), [](const Format& left, const Format& right) {
|
|
2241
|
-
return left.
|
|
2300
|
+
return left.probePriority < right.probePriority;
|
|
2242
2301
|
});
|
|
2243
2302
|
|
|
2244
2303
|
bool passwordRequested = false;
|
|
@@ -2269,6 +2328,11 @@ public:
|
|
|
2269
2328
|
candidate->Close();
|
|
2270
2329
|
continue;
|
|
2271
2330
|
}
|
|
2331
|
+
if (!HasValidEntryPaths(candidate) && !format.contentMatch
|
|
2332
|
+
&& LowerAscii(format.name) != "gzip") {
|
|
2333
|
+
candidate->Close();
|
|
2334
|
+
continue;
|
|
2335
|
+
}
|
|
2272
2336
|
auto context = std::make_unique<ArchiveContext>();
|
|
2273
2337
|
context->archive = candidate;
|
|
2274
2338
|
context->stream = input;
|
|
@@ -2636,6 +2700,20 @@ public:
|
|
|
2636
2700
|
}
|
|
2637
2701
|
|
|
2638
2702
|
private:
|
|
2703
|
+
bool HasValidEntryPaths(IInArchive *archive) const
|
|
2704
|
+
{
|
|
2705
|
+
UInt32 count = 0;
|
|
2706
|
+
if (archive->GetNumberOfItems(&count) != S_OK || count > kMaxEntries) {
|
|
2707
|
+
return false;
|
|
2708
|
+
}
|
|
2709
|
+
for (UInt32 i = 0; i < count; ++i) {
|
|
2710
|
+
if (GetPropString(archive, i, kpidPath).empty()) {
|
|
2711
|
+
return false;
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
return true;
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2639
2717
|
ContextLease AcquireContext()
|
|
2640
2718
|
{
|
|
2641
2719
|
std::unique_lock<std::mutex> lock(contextMutex_);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "7zip-native",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "Native 7zip bindings for Node.js",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"type": "module",
|
|
@@ -65,9 +65,20 @@
|
|
|
65
65
|
},
|
|
66
66
|
"keywords": [
|
|
67
67
|
"7zip",
|
|
68
|
+
"7-zip",
|
|
69
|
+
"archive",
|
|
68
70
|
"nodejs",
|
|
69
71
|
"bindings",
|
|
70
|
-
"native"
|
|
72
|
+
"native",
|
|
73
|
+
"node-api",
|
|
74
|
+
"napi",
|
|
75
|
+
"zip",
|
|
76
|
+
"rar",
|
|
77
|
+
"tar",
|
|
78
|
+
"wim",
|
|
79
|
+
"compression",
|
|
80
|
+
"decompression",
|
|
81
|
+
"extraction"
|
|
71
82
|
],
|
|
72
83
|
"devDependencies": {
|
|
73
84
|
"@eslint/js": "^10.0.1",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|