Skip to content

Commit 657ba6c

Browse files
authored
Merge branch 'libarchive:master' into 7zip-symlinks-unicode
2 parents 4ee385d + 586a964 commit 657ba6c

21 files changed

+360
-63
lines changed

Diff for: Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,7 @@ libarchive_test_EXTRA_DIST=\
926926
libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \
927927
libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \
928928
libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu \
929+
libarchive/test/test_read_format_rar5_data_ready_pointer_leak.rar.uu \
929930
libarchive/test/test_read_format_raw.bufr.uu \
930931
libarchive/test/test_read_format_raw.data.gz.uu \
931932
libarchive/test/test_read_format_raw.data.Z.uu \

Diff for: build/ci/github_actions/macos.sh

+6-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
#!/bin/sh
22
if [ "$1" = "prepare" ]
33
then
4-
set -x
5-
brew uninstall [email protected] > /dev/null
6-
brew uninstall [email protected] > /dev/null
7-
brew untap local/openssl > /dev/null
8-
brew untap local/python2 > /dev/null
9-
brew update > /dev/null
10-
brew upgrade > /dev/null
114
set -x -e
12-
for pkg in \
5+
#Uncommenting these adds a full minute to the CI time
6+
#brew update > /dev/null
7+
#brew upgrade > /dev/null
8+
9+
# This does an upgrade if the package is already installed
10+
brew install \
1311
autoconf \
1412
automake \
1513
libtool \
@@ -20,7 +18,4 @@ then
2018
zstd \
2119
libxml2 \
2220
openssl
23-
do
24-
brew list $pkg > /dev/null && brew upgrade $pkg || brew install $pkg
25-
done
2621
fi

Diff for: libarchive/archive_entry.c

+15
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,9 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry,
930930
void
931931
archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
932932
{
933+
if (g < 0) {
934+
g = 0;
935+
}
933936
entry->stat_valid = 0;
934937
entry->ae_stat.aest_gid = g;
935938
entry->ae_set |= AE_SET_GID;
@@ -980,6 +983,9 @@ _archive_entry_copy_gname_l(struct archive_entry *entry,
980983
void
981984
archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
982985
{
986+
if (ino < 0) {
987+
ino = 0;
988+
}
983989
entry->stat_valid = 0;
984990
entry->ae_set |= AE_SET_INO;
985991
entry->ae_stat.aest_ino = ino;
@@ -988,6 +994,9 @@ archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
988994
void
989995
archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
990996
{
997+
if (ino < 0) {
998+
ino = 0;
999+
}
9911000
entry->stat_valid = 0;
9921001
entry->ae_set |= AE_SET_INO;
9931002
entry->ae_stat.aest_ino = ino;
@@ -1343,6 +1352,9 @@ archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
13431352
void
13441353
archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
13451354
{
1355+
if (s < 0) {
1356+
s = 0;
1357+
}
13461358
entry->stat_valid = 0;
13471359
entry->ae_stat.aest_size = s;
13481360
entry->ae_set |= AE_SET_SIZE;
@@ -1464,6 +1476,9 @@ _archive_entry_copy_symlink_l(struct archive_entry *entry,
14641476
void
14651477
archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
14661478
{
1479+
if (u < 0) {
1480+
u = 0;
1481+
}
14671482
entry->stat_valid = 0;
14681483
entry->ae_stat.aest_uid = u;
14691484
entry->ae_set |= AE_SET_UID;

Diff for: libarchive/archive_entry_perms.3

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ character strings at the same time.
150150
.Fn archive_entry_set_XXX
151151
is an alias for
152152
.Fn archive_entry_copy_XXX .
153+
The strings are copied, and don't need to outlive the call.
153154
.Ss File Flags
154155
File flags are transparently converted between a bitmap
155156
representation and a textual format.

Diff for: libarchive/archive_ppmd8.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
671671
upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0)));
672672
}
673673

674-
do
674+
while (numPs != 0)
675675
{
676676
/* Create Child */
677677
CTX_PTR c1; /* = AllocContext(p); */
@@ -692,8 +692,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
692692
SetSuccessor(ps[--numPs], REF(c1));
693693
c = c1;
694694
}
695-
while (numPs != 0);
696-
695+
697696
return c;
698697
}
699698

Diff for: libarchive/archive_read_append_filter.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ archive_read_append_filter(struct archive *_a, int code)
111111
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
112112

113113
bidder = a->bidders;
114-
for (i = 0; i < number_bidders; i++, bidder++)
114+
for (i = 1; i < number_bidders; i++, bidder++)
115115
{
116116
if (!bidder->name || !strcmp(bidder->name, str))
117117
break;

Diff for: libarchive/archive_read_disk_entry_from_file.c

+1
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ setup_xattr(struct archive_read_disk *a,
520520
if (size == -1) {
521521
archive_set_error(&a->archive, errno,
522522
"Couldn't read extended attribute");
523+
free(value);
523524
return (ARCHIVE_WARN);
524525
}
525526

Diff for: libarchive/archive_read_support_format_cpio.c

+19-9
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,7 @@ static int
834834
header_afiol(struct archive_read *a, struct cpio *cpio,
835835
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
836836
{
837+
int64_t t;
837838
const void *h;
838839
const char *header;
839840

@@ -850,7 +851,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
850851

851852
archive_entry_set_dev(entry,
852853
(dev_t)atol16(header + afiol_dev_offset, afiol_dev_size));
853-
archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size));
854+
t = atol16(header + afiol_ino_offset, afiol_ino_size);
855+
if (t < 0) {
856+
archive_set_error(&a->archive, 0, "Nonsensical ino value");
857+
return (ARCHIVE_FATAL);
858+
}
859+
archive_entry_set_ino(entry, t);
854860
archive_entry_set_mode(entry,
855861
(mode_t)atol8(header + afiol_mode_offset, afiol_mode_size));
856862
archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size));
@@ -863,8 +869,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
863869
*namelength = (size_t)atol16(header + afiol_namesize_offset, afiol_namesize_size);
864870
*name_pad = 0; /* No padding of filename. */
865871

866-
cpio->entry_bytes_remaining =
867-
atol16(header + afiol_filesize_offset, afiol_filesize_size);
872+
t = atol16(header + afiol_filesize_offset, afiol_filesize_size);
873+
if (t < 0) {
874+
archive_set_error(&a->archive, 0, "Nonsensical file size");
875+
return (ARCHIVE_FATAL);
876+
}
877+
cpio->entry_bytes_remaining = t;
868878
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
869879
cpio->entry_padding = 0;
870880
__archive_read_consume(a, afiol_header_size);
@@ -1002,26 +1012,26 @@ be4(const unsigned char *p)
10021012
static int64_t
10031013
atol8(const char *p, unsigned char_cnt)
10041014
{
1005-
int64_t l;
1015+
uint64_t l;
10061016
int digit;
10071017

10081018
l = 0;
10091019
while (char_cnt-- > 0) {
10101020
if (*p >= '0' && *p <= '7')
10111021
digit = *p - '0';
10121022
else
1013-
return (l);
1023+
return ((int64_t)l);
10141024
p++;
10151025
l <<= 3;
10161026
l |= digit;
10171027
}
1018-
return (l);
1028+
return ((int64_t)l);
10191029
}
10201030

10211031
static int64_t
10221032
atol16(const char *p, unsigned char_cnt)
10231033
{
1024-
int64_t l;
1034+
uint64_t l;
10251035
int digit;
10261036

10271037
l = 0;
@@ -1033,12 +1043,12 @@ atol16(const char *p, unsigned char_cnt)
10331043
else if (*p >= '0' && *p <= '9')
10341044
digit = *p - '0';
10351045
else
1036-
return (l);
1046+
return ((int64_t)l);
10371047
p++;
10381048
l <<= 4;
10391049
l |= digit;
10401050
}
1041-
return (l);
1051+
return ((int64_t)l);
10421052
}
10431053

10441054
static int

Diff for: libarchive/archive_read_support_format_iso9660.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3263,7 +3263,7 @@ isodate17(const unsigned char *v)
32633263
tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
32643264
+ (v[2] - '0') * 10 + (v[3] - '0')
32653265
- 1900;
3266-
tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0');
3266+
tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0') - 1;
32673267
tm.tm_mday = (v[6] - '0') * 10 + (v[7] - '0');
32683268
tm.tm_hour = (v[8] - '0') * 10 + (v[9] - '0');
32693269
tm.tm_min = (v[10] - '0') * 10 + (v[11] - '0');

Diff for: libarchive/archive_read_support_format_rar.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -2983,7 +2983,7 @@ expand(struct archive_read *a, int64_t *end)
29832983

29842984
if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
29852985
goto bad_data;
2986-
if (lensymbol > lengthb_min)
2986+
if (lensymbol >= lengthb_min)
29872987
goto bad_data;
29882988
len = lengthbases[lensymbol] + 2;
29892989
if (lengthbits[lensymbol] > 0) {
@@ -3015,7 +3015,7 @@ expand(struct archive_read *a, int64_t *end)
30153015
}
30163016
else
30173017
{
3018-
if (symbol-271 > lengthb_min)
3018+
if (symbol-271 >= lengthb_min)
30193019
goto bad_data;
30203020
len = lengthbases[symbol-271]+3;
30213021
if(lengthbits[symbol-271] > 0) {
@@ -3027,7 +3027,7 @@ expand(struct archive_read *a, int64_t *end)
30273027

30283028
if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
30293029
goto bad_data;
3030-
if (offssymbol > offsetb_min)
3030+
if (offssymbol >= offsetb_min)
30313031
goto bad_data;
30323032
offs = offsetbases[offssymbol]+1;
30333033
if(offsetbits[offssymbol] > 0)
@@ -3361,7 +3361,10 @@ create_filter(struct rar_program_code *prog, const uint8_t *globaldata, uint32_t
33613361
filter->globaldatalen = globaldatalen > PROGRAM_SYSTEM_GLOBAL_SIZE ? globaldatalen : PROGRAM_SYSTEM_GLOBAL_SIZE;
33623362
filter->globaldata = calloc(1, filter->globaldatalen);
33633363
if (!filter->globaldata)
3364+
{
3365+
free(filter);
33643366
return NULL;
3367+
}
33653368
if (globaldata)
33663369
memcpy(filter->globaldata, globaldata, globaldatalen);
33673370
if (registers)

Diff for: libarchive/archive_read_support_format_rar5.c

+22-6
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ static int verify_global_checksums(struct archive_read* a);
361361
static int rar5_read_data_skip(struct archive_read *a);
362362
static int push_data_ready(struct archive_read* a, struct rar5* rar,
363363
const uint8_t* buf, size_t size, int64_t offset);
364+
static void clear_data_ready_stack(struct rar5* rar);
364365

365366
/* CDE_xxx = Circular Double Ended (Queue) return values. */
366367
enum CDE_RETURN_VALUES {
@@ -652,6 +653,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
652653
int ret;
653654
struct rar5* rar = get_context(a);
654655

656+
clear_data_ready_stack(rar);
655657
free(rar->cstate.filtered_buf);
656658

657659
rar->cstate.filtered_buf = malloc(flt->block_length);
@@ -1448,9 +1450,6 @@ static int parse_file_extra_redir(struct archive_read* a,
14481450
return ARCHIVE_EOF;
14491451
*extra_data_size -= target_size + 1;
14501452

1451-
if(!read_ahead(a, target_size, &p))
1452-
return ARCHIVE_EOF;
1453-
14541453
if(target_size > (MAX_NAME_IN_CHARS - 1)) {
14551454
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
14561455
"Link target is too long");
@@ -1463,6 +1462,9 @@ static int parse_file_extra_redir(struct archive_read* a,
14631462
return ARCHIVE_FATAL;
14641463
}
14651464

1465+
if(!read_ahead(a, target_size, &p))
1466+
return ARCHIVE_EOF;
1467+
14661468
memcpy(target_utf8_buf, p, target_size);
14671469
target_utf8_buf[target_size] = 0;
14681470

@@ -1780,6 +1782,13 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
17801782
if(rar->cstate.window_size < (ssize_t) window_size &&
17811783
rar->cstate.window_buf)
17821784
{
1785+
/* The `data_ready` stack contains pointers to the `window_buf` or
1786+
* `filtered_buf` buffers. Since we're about to reallocate the first
1787+
* buffer, some of those pointers could become invalid. Therefore, we
1788+
* need to dispose of all entries from the stack before attempting the
1789+
* realloc. */
1790+
clear_data_ready_stack(rar);
1791+
17831792
/* If window_buf has been allocated before, reallocate it, so
17841793
* that its size will match new window_size. */
17851794

@@ -1876,9 +1885,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
18761885
if(!read_var_sized(a, &name_size, NULL))
18771886
return ARCHIVE_EOF;
18781887

1879-
if(!read_ahead(a, name_size, &p))
1880-
return ARCHIVE_EOF;
1881-
18821888
if(name_size > (MAX_NAME_IN_CHARS - 1)) {
18831889
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
18841890
"Filename is too long");
@@ -1893,6 +1899,9 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
18931899
return ARCHIVE_FATAL;
18941900
}
18951901

1902+
if(!read_ahead(a, name_size, &p))
1903+
return ARCHIVE_EOF;
1904+
18961905
memcpy(name_utf8_buf, p, name_size);
18971906
name_utf8_buf[name_size] = 0;
18981907
if(ARCHIVE_OK != consume(a, name_size)) {
@@ -2455,6 +2464,8 @@ static void init_unpack(struct rar5* rar) {
24552464
rar->cstate.filtered_buf = NULL;
24562465
}
24572466

2467+
clear_data_ready_stack(rar);
2468+
24582469
rar->cstate.write_ptr = 0;
24592470
rar->cstate.last_write_ptr = 0;
24602471

@@ -3629,6 +3640,10 @@ static int use_data(struct rar5* rar, const void** buf, size_t* size,
36293640
return ARCHIVE_RETRY;
36303641
}
36313642

3643+
static void clear_data_ready_stack(struct rar5* rar) {
3644+
memset(&rar->cstate.dready, 0, sizeof(rar->cstate.dready));
3645+
}
3646+
36323647
/* Pushes the `buf`, `size` and `offset` arguments to the rar->cstate.dready
36333648
* FIFO stack. Those values will be popped from this stack by the `use_data`
36343649
* function. */
@@ -4187,6 +4202,7 @@ static int rar5_cleanup(struct archive_read *a) {
41874202

41884203
free(rar->cstate.window_buf);
41894204
free(rar->cstate.filtered_buf);
4205+
clear_data_ready_stack(rar);
41904206

41914207
free(rar->vol.push_buf);
41924208

0 commit comments

Comments
 (0)