diff options
author | Colomban Wendling <[email protected]> | 2024-01-24 21:37:17 +0100 |
---|---|---|
committer | raveit65 <[email protected]> | 2024-01-31 23:36:40 +0100 |
commit | daf682c202c9edbeeb94963224930387796e469b (patch) | |
tree | 1d4d182467c4453424d5e70318e9526658bc85b4 | |
parent | ed5d540bf64fafbf9266b28f1156ce3ce2ba3038 (diff) | |
download | engrampa-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.c | 43 |
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)) { |