aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libarchive/libarchive/archive_read_support_format_rar.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libarchive/libarchive/archive_read_support_format_rar.c')
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_rar.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar.c b/contrib/libarchive/libarchive/archive_read_support_format_rar.c
index 1b3ea0e774f0..ce406278d130 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_rar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_rar.c
@@ -151,6 +151,9 @@
#undef minimum
#define minimum(a, b) ((a)<(b)?(a):(b))
+/* Stack overflow check */
+#define MAX_COMPRESS_DEPTH 1024
+
/* Fields common to all headers */
struct rar_header
{
@@ -339,7 +342,7 @@ static int read_symlink_stored(struct archive_read *, struct archive_entry *,
static int read_data_stored(struct archive_read *, const void **, size_t *,
int64_t *);
static int read_data_compressed(struct archive_read *, const void **, size_t *,
- int64_t *);
+ int64_t *, size_t);
static int rar_br_preparation(struct archive_read *, struct rar_br *);
static int parse_codes(struct archive_read *);
static void free_codes(struct archive_read *);
@@ -1025,7 +1028,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
case COMPRESS_METHOD_NORMAL:
case COMPRESS_METHOD_GOOD:
case COMPRESS_METHOD_BEST:
- ret = read_data_compressed(a, buff, size, offset);
+ ret = read_data_compressed(a, buff, size, offset, 0);
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
rar->start_new_table = 1;
@@ -1876,8 +1879,11 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
static int
read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
- int64_t *offset)
+ int64_t *offset, size_t looper)
{
+ if (looper++ > MAX_COMPRESS_DEPTH)
+ return (ARCHIVE_FATAL);
+
struct rar *rar;
int64_t start, end, actualend;
size_t bs;
@@ -1975,7 +1981,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
{
case 0:
rar->start_new_table = 1;
- return read_data_compressed(a, buff, size, offset);
+ return read_data_compressed(a, buff, size, offset, looper);
case 2:
rar->ppmd_eod = 1;/* End Of ppmd Data. */