commit: fa7a501dc77a11a96d5c73ad9a69feecbe01a398
parent ca7c71ba82abfdfa5fa2fdf4632bf6d50d10148f
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Tue, 30 Sep 2025 22:23:35 +0200
Java JAR detection: Check for extra field properly and META-INF/*
Diffstat:
3 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
@@ -8,6 +8,12 @@ See the `deblob.1` manpage for more information.
Project permalink: <https://hacktivis.me/projects/deblob>
+## Tarballs
+- deblob: <https://distfiles.hacktivis.me/releases/deblob/>
+- deblob-test: <https://distfiles.hacktivis.me/releases/deblob-test/>
+
+Signify public keys at <https://distfiles.hacktivis.me/releases/signify/>
+
## Dependencies
### Common
- hare 0.24+
@@ -16,7 +22,7 @@ Project permalink: <https://hacktivis.me/projects/deblob>
### tests
- `ar`
- C Compiler
-- [deblob-test](https://hacktivis.me/git/deblob-test/) as submodule
+- [deblob-test](https://hacktivis.me/git/deblob-test/) either as submodule or tarball version 0.11
### linting
Those are only needed during development.
diff --git a/deblob.1 b/deblob.1
@@ -168,7 +168,7 @@ to hare as "deblob".
Generic formats and executables based on them:
.Bl -dash -compact
.It
-Generic Archives: Tarballs, Distro Packages, ZIP (including Java\~Jar), Cabinet (CAB), Microsoft Compound File (including MSI), …
+Generic Archives: Tarballs, Distro Packages, ZIP, Cabinet (CAB), Microsoft Compound File (including MSI), …
.It
Filesystems, disk dumps, databases
.El
diff --git a/main.ha b/main.ha
@@ -88,6 +88,7 @@ const racket: []u8 = ['r', 'a', 'c', 'k', 'e', 't'];
const zip: []u8 = ['P', 'K', 0x03, 0x04];
const jar: []u8 = [0xFE, 0xCA, 0, 0];
const shebang: []u8 = ['#', '!'];
+const meta_inf_: []u8 = ['M', 'E', 'T', 'A', '-', 'I', 'N', 'F', '/'];
let found: bool = false;
let json_out: io::handle = 0;
@@ -163,8 +164,26 @@ fn id_blob(filename: str) (void | str | fs::error | io::error) = {
};
if (bytes::hasprefix(buffer, zip)) {
- if(bytes::equal(jar, buffer[0x27..0x2B])) {
- return "Java JAR";
+ // Check first filename
+ // Optional in JAR and probably doesn't have to be the first filename
+ // but it's how it's usually done
+ //
+ // So far seen either META-INF/ and \xFE\xCA\x00\x00 in extra or just META-INF/MANIFEST.MF
+
+ const fname_len = endian::legetu16(buffer[0x1A..0x1C]);
+ if(fname_len < 256)
+ {
+ const fname_start = 0x1Eu16;
+ if(fname_len >= 9 && bytes::equal(meta_inf_, buffer[fname_start..fname_start+9])) {
+ return "Java JAR";
+ };
+
+ const extra_start = fname_start+fname_len;
+ const extra_len = endian::legetu16(buffer[0x1D..0x1E]);
+ if(extra_len == 4 && bytes::equal(jar, buffer[extra_start..extra_start+extra_len]))
+ {
+ return "Java JAR";
+ };
};
};
@@ -383,7 +402,12 @@ fn check_dir(dirname: str) (void | nomem | errors::invalid | io::error) = {
case nomem =>
fmt::fatal("deblob: error: os::readdir({}): Out of Memory", dirname);
};
- assert(len(files_before) == 61);
+
+ const files_before_exp = 63z;
+ if(len(files_before) != files_before_exp)
+ {
+ fmt::fatalf("deblob: expected {} in files_before, got {}\n", files_before_exp, len(files_before));
+ };
const ret = check_dir(dirname);
assert(ret is void);
@@ -396,7 +420,12 @@ fn check_dir(dirname: str) (void | nomem | errors::invalid | io::error) = {
case nomem =>
fmt::fatal("deblob: error: os::readdir({}): Out of Memory", dirname);
};
- assert(len(files_after) == 30);
+
+ const files_after_exp = 31z;
+ if(len(files_after) != files_after_exp)
+ {
+ fmt::fatalf("deblob: expected {} in files_before, got {}\n", files_after_exp, len(files_after));
+ };
};
export fn main() void = {