}
else {
t |= (*p & 0x7f) << shift;
+ p ++;
break;
}
rspamd_archive_process_rar (struct rspamd_task *task,
struct rspamd_mime_part *part)
{
- const guchar *p, *end;
+ const guchar *p, *end, *section_start;
const guchar rar_v5_magic[] = {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00},
rar_v4_magic[] = {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00};
const guint rar_encrypted_header = 4, rar_main_header = 1,
rar_file_header = 2;
- guint64 vint, sz, comp_sz = 0, uncomp_sz = 0;
+ guint64 vint, sz, comp_sz = 0, uncomp_sz = 0, flags = 0, type = 0;
struct rspamd_archive *arch;
struct rspamd_archive_file *f;
gint r;
/* Size */
RAR_READ_VINT_SKIP ();
sz = vint;
- /* Type (not skip) */
- RAR_READ_VINT ();
+ /* Type */
+ section_start = p;
+ RAR_READ_VINT_SKIP ();
+ type = vint;
+ /* Header flags */
+ RAR_READ_VINT_SKIP ();
+ flags = vint;
+
+ if (flags & 0x1) {
+ /* Have extra zone */
+ RAR_READ_VINT_SKIP ();
+ }
+ if (flags & 0x2) {
+ /* Data zone is presented */
+ RAR_READ_VINT_SKIP ();
+ sz += vint;
+ }
- if (vint == rar_encrypted_header) {
+ if (type == rar_encrypted_header) {
/* We can't read any further information as archive is encrypted */
arch->flags |= RSPAMD_ARCHIVE_ENCRYPTED;
goto end;
}
- else if (vint != rar_main_header) {
+ else if (type != rar_main_header) {
msg_debug_task ("rar archive is invalid (bad main header): %s",
part->filename);
}
/* Nothing useful in main header */
+ p = section_start;
RAR_SKIP_BYTES (sz);
while (p < end) {
return;
}
- /* Type (not skip) */
- RAR_READ_VINT ();
- if (vint != rar_file_header) {
+ section_start = p;
+ /* Type */
+ RAR_READ_VINT_SKIP ();
+ type = vint;
+ /* Header flags */
+ RAR_READ_VINT_SKIP ();
+ flags = vint;
+
+ if (flags & 0x1) {
+ /* Have extra zone */
+ RAR_READ_VINT_SKIP ();
+ }
+ if (flags & 0x2) {
+ /* Data zone is presented */
+ RAR_READ_VINT_SKIP ();
+ sz += vint;
+ comp_sz = vint;
+ }
+
+ if (type != rar_file_header) {
+ p = section_start;
RAR_SKIP_BYTES (sz);
}
else {
/* We have a file header, go forward */
- const guchar *section_type_start = p;
- guint64 flags, fname_len;
-
- p += r; /* Remain from type */
- /* Header flags */
- RAR_READ_VINT_SKIP ();
- flags = vint;
+ guint64 fname_len;
- /* Now we have two optional fields (fuck rar!) */
- if (flags & 0x1) {
- /* Extra flag */
- RAR_READ_VINT_SKIP ();
- }
- if (flags & 0x2) {
- /* Data size - compressed size */
- RAR_READ_VINT_SKIP ();
- comp_sz = vint;
- }
-
- /* File flags */
+ /* File header specific flags */
RAR_READ_VINT_SKIP ();
-
flags = vint;
/* Unpacked size */
f->compressed_size = comp_sz;
f->fname = g_string_new_len (p, fname_len);
g_ptr_array_add (arch->files, f);
+
/* Restore p to the beginning of the header */
- p = section_type_start;
+ p = section_start;
RAR_SKIP_BYTES (sz);
}
}