[evince/wip/hadess/cbr-rarv5: 6/7] unarr: Add error reporting to open function




commit b9d9e821de2adaf5828b7bd6d0249372e3c2279c
Author: Bastien Nocera <hadess hadess net>
Date:   Sun Feb 21 17:11:08 2021 +0100

    unarr: Add error reporting to open function
    
    Add a new open function that reports the error encountered, so that it's
    possible to detect RAR v5 archives.

 cut-n-paste/unarr/rar/rar.c | 31 +++++++++++++++++++++++++++++++
 cut-n-paste/unarr/unarr.h   |  9 +++++++++
 2 files changed, 40 insertions(+)
---
diff --git a/cut-n-paste/unarr/rar/rar.c b/cut-n-paste/unarr/rar/rar.c
index 40cafcfc..d03b2da4 100644
--- a/cut-n-paste/unarr/rar/rar.c
+++ b/cut-n-paste/unarr/rar/rar.c
@@ -221,3 +221,34 @@ ar_archive *ar_open_rar_archive(ar_stream *stream)
 
     return ar_open_archive(stream, sizeof(ar_archive_rar), rar_close, rar_parse_entry, rar_get_name, 
rar_uncompress, NULL, FILE_SIGNATURE_SIZE);
 }
+
+ar_archive *ar_open_rar_archive_with_error(ar_stream *stream,
+                                          ArArchiveError *error_code)
+{
+    char signature[FILE_SIGNATURE_SIZE];
+    ar_archive *ret;
+
+    if (!ar_seek(stream, 0, SEEK_SET)) {
+        *error_code = AR_ARCHIVE_ERROR_UNKNOWN;
+        return NULL;
+    }
+    if (ar_read(stream, signature, sizeof(signature)) != sizeof(signature)) {
+        *error_code = AR_ARCHIVE_ERROR_UNKNOWN;
+        return NULL;
+    }
+    if (memcmp(signature, "Rar!\x1A\x07\x00", sizeof(signature)) != 0) {
+        if (memcmp(signature, "Rar!\x1A\x07\x01", sizeof(signature)) == 0)
+            *error_code = AR_ARCHIVE_ERROR_RAR5;
+        else if (memcmp(signature, "RE~^", 4) == 0)
+            *error_code = AR_ARCHIVE_ERROR_OLDRAR;
+        else if (memcmp(signature, "MZ", 2) == 0 || memcmp(signature, "\x7F\x45LF", 4) == 0)
+            *error_code = AR_ARCHIVE_ERROR_SFX;
+        return NULL;
+    }
+
+
+    ret = ar_open_archive(stream, sizeof(ar_archive_rar), rar_close, rar_parse_entry, rar_get_name, 
rar_uncompress, NULL, FILE_SIGNATURE_SIZE);
+    if (!ret)
+        *error_code = AR_ARCHIVE_ERROR_UNKNOWN;
+    return ret;
+}
diff --git a/cut-n-paste/unarr/unarr.h b/cut-n-paste/unarr/unarr.h
index 5ef7447c..cf3538d8 100644
--- a/cut-n-paste/unarr/unarr.h
+++ b/cut-n-paste/unarr/unarr.h
@@ -12,6 +12,14 @@ typedef int64_t time64_t;
 
 #define UNARR_API_VERSION 100
 
+typedef enum {
+  AR_ARCHIVE_ERROR_NONE,
+  AR_ARCHIVE_ERROR_UNKNOWN,
+  AR_ARCHIVE_ERROR_RAR5,
+  AR_ARCHIVE_ERROR_OLDRAR,
+  AR_ARCHIVE_ERROR_SFX
+} ArArchiveError;
+
 /***** common/stream *****/
 
 typedef struct ar_stream_s ar_stream;
@@ -74,6 +82,7 @@ size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count);
 
 /* checks whether 'stream' could contain RAR data and prepares for archive listing/extraction; returns NULL 
on failure */
 ar_archive *ar_open_rar_archive(ar_stream *stream);
+ar_archive *ar_open_rar_archive_with_error(ar_stream *stream, ArArchiveError *error_code);
 
 /***** tar/tar *****/
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]