summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColomban Wendling <[email protected]>2024-01-24 21:37:17 +0100
committerraveit65 <[email protected]>2024-01-31 23:36:40 +0100
commitdaf682c202c9edbeeb94963224930387796e469b (patch)
tree1d4d182467c4453424d5e70318e9526658bc85b4
parented5d540bf64fafbf9266b28f1156ce3ce2ba3038 (diff)
downloadengrampa-daf682c202c9edbeeb94963224930387796e469b.tar.bz2
engrampa-daf682c202c9edbeeb94963224930387796e469b.tar.xz
rar: Fix out of bounds read on malformed output
Check the fields count before retrieving it not to go out of bounds. This also slightly revise the logic to require the proper number of fields in the RAR5 `attribute_field_with_space()` case.
-rw-r--r--src/fr-command-rar.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/src/fr-command-rar.c b/src/fr-command-rar.c
index 7e69fd9..da9a523 100644
--- a/src/fr-command-rar.c
+++ b/src/fr-command-rar.c
@@ -229,29 +229,19 @@ process_line (char *line,
if (! rar_comm->rar4_odd_line) {
FileData *fdata;
const char *size_field, *ratio_field, *date_field, *time_field, *attr_field;
+ int n_fields;
+
+ if (rar_comm->rar5)
+ n_fields = 6 + (attribute_field_with_space (line) != 0);
+ else
+ n_fields = 6;
fdata = rar_comm->fdata;
/* read file info. */
- fields = split_line (line, attribute_field_with_space (line) ? 7 : 6);
- if (rar_comm->rar5) {
- int offset = attribute_field_with_space (line) ? 1 : 0;
-
- size_field = fields[1+offset];
- ratio_field = fields[3+offset];
- date_field = fields[4+offset];
- time_field = fields[5+offset];
- attr_field = fields[0+offset];
- }
- else {
- size_field = fields[0];
- ratio_field = fields[2];
- date_field = fields[3];
- time_field = fields[4];
- attr_field = fields[5];
- }
- if (g_strv_length (fields) < 6) {
+ fields = split_line (line, n_fields);
+ if (g_strv_length (fields) < (guint) n_fields) {
/* wrong line format, treat this line as a filename line */
g_strfreev (fields);
file_data_free (rar_comm->fdata);
@@ -260,6 +250,23 @@ process_line (char *line,
parse_name_field (line, rar_comm);
}
else {
+ if (rar_comm->rar5) {
+ int offset = attribute_field_with_space (line) ? 1 : 0;
+
+ size_field = fields[1+offset];
+ ratio_field = fields[3+offset];
+ date_field = fields[4+offset];
+ time_field = fields[5+offset];
+ attr_field = fields[0+offset];
+ }
+ else {
+ size_field = fields[0];
+ ratio_field = fields[2];
+ date_field = fields[3];
+ time_field = fields[4];
+ attr_field = fields[5];
+ }
+
if ((strcmp (ratio_field, "<->") == 0)
|| (strcmp (ratio_field, "<--") == 0))
{