subprojects/rzar: fix crash (#6516)

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
This commit is contained in:
NOT XVilka 2026-06-17 02:09:11 +08:00 committed by GitHub
parent 0421f03afe
commit c0945b0231
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 25 deletions

View file

@ -25,15 +25,15 @@ typedef struct Filetable {
ut64 offset; ut64 offset;
} filetable; } filetable;
static RzArFp *arfp_new(RzBuffer *b, bool shared_buf) { static RzArFp *arfp_new(RzBuffer *b) {
rz_return_val_if_fail(b, NULL); rz_return_val_if_fail(b, NULL);
RzArFp *f = RZ_NEW(RzArFp); RzArFp *f = RZ_NEW(RzArFp);
if (f) { if (f) {
f->name = NULL; f->name = NULL;
f->shared_buf = shared_buf; f->buf = rz_buf_ref(b);
f->buf = b;
f->start = 0; f->start = 0;
f->end = 0; f->end = 0;
f->st_mode = 0;
} }
return f; return f;
} }
@ -323,46 +323,39 @@ RZ_API RzList /*<RzArFp *>*/ *ar_open_all(const char *arname, int perm) {
filetable tbl = { NULL, 0, 0 }; filetable tbl = { NULL, 0, 0 };
int res = -1; int res = -1;
bool shared = false;
do { do {
shared = !rz_list_empty(files); RzArFp *arf = arfp_new(b);
RzArFp *arf = arfp_new(b, shared);
if (!arf) { if (!arf) {
rz_list_free(files); rz_list_free(files);
if (!shared) { files = NULL;
rz_buf_free(b); break;
}
return NULL;
} }
if ((res = ar_parse_entry(arf, &tbl, arsize)) <= 0) { if ((res = ar_parse_entry(arf, &tbl, arsize)) <= 0) {
// on error or when it has reached the EOF // on error or when it has reached the EOF
free(tbl.data);
ar_close(arf); ar_close(arf);
return files; break;
} }
// on linux the fmode is always 0, but arf->mode is non-zero // on linux the fmode is always 0, but arf->mode is non-zero
if (!arf->st_mode || if (!arf->st_mode ||
((fmode = (arf->st_mode & S_IFMT)) && fmode != S_IFREG) || ((fmode = (arf->st_mode & S_IFMT)) && fmode != S_IFREG) ||
arf->start >= arf->end) { arf->start >= arf->end) {
// open only regular files. // open only regular files.
// we do not need to close the buffer
arf->shared_buf = true;
ar_close(arf); ar_close(arf);
continue; continue;
} }
if (!rz_list_append(files, arf)) { if (!rz_list_append(files, arf)) {
free(tbl.data);
ar_close(arf); ar_close(arf);
rz_list_free(files); rz_list_free(files);
return NULL; files = NULL;
break;
} }
} while (res > 0); } while (res > 0);
// this portion should never be reached
free(tbl.data); free(tbl.data);
rz_buf_free(b);
return files; return files;
} }
@ -393,7 +386,7 @@ RZ_API RzArFp *ar_open_file(const char *arname, int perm, const char *filename)
return NULL; return NULL;
} }
RzArFp *arf = arfp_new(b, false); RzArFp *arf = arfp_new(b);
if (!arf) { if (!arf) {
rz_buf_free(b); rz_buf_free(b);
return NULL; return NULL;
@ -419,10 +412,11 @@ RZ_API RzArFp *ar_open_file(const char *arname, int perm, const char *filename)
if (r == 0 && filename) { if (r == 0 && filename) {
RZ_LOG_ERROR("ar: Cound not find file '%s' in archive '%s'\n", filename, arname); RZ_LOG_ERROR("ar: Cound not find file '%s' in archive '%s'\n", filename, arname);
} }
ar_close(arf); // results in buf being free'd ar_close(arf);
return NULL; arf = NULL;
} }
rz_buf_free(b);
return arf; return arf;
} }
@ -431,9 +425,7 @@ RZ_API void ar_close(RzArFp *f) {
return; return;
} }
free(f->name); free(f->name);
if (!f->shared_buf) { rz_buf_free(f->buf);
rz_buf_free(f->buf);
}
free(f); free(f);
} }
@ -456,5 +448,5 @@ RZ_API int ar_write_at(RzArFp *f, ut64 off, void *buf, int count) {
if (count + off > f->end) { if (count + off > f->end) {
count = f->end - off; count = f->end - off;
} }
return rz_buf_write_at(f->buf, off + f->start, buf, count); return rz_buf_write_at(f->buf, off, buf, count);
} }

View file

@ -10,7 +10,6 @@ typedef struct RZARFP {
ut64 start; ut64 start;
ut64 end; ut64 end;
RzBuffer *buf; RzBuffer *buf;
bool shared_buf;
ut32 st_mode; ut32 st_mode;
} RzArFp; } RzArFp;

View file

@ -325,3 +325,15 @@ EXPECT=<<EOF
3 * r-x 0x000000b4 d_/os/obj/x86fre/minkernel/crts/ucrt/src/appcrt/dll/osmode_debug_public/../not_callable_by_os/objfre/i386/clog10l.obj 3 * r-x 0x000000b4 d_/os/obj/x86fre/minkernel/crts/ucrt/src/appcrt/dll/osmode_debug_public/../not_callable_by_os/objfre/i386/clog10l.obj
EOF EOF
RUN RUN
NAME=ar reopen in write mode then seek (#6414)
FILE=ar://bins/ar/libgdbr.a
CMDS=<<EOF
oo+
s 0x08090af7
p8 16
EOF
EXPECT=<<EOF
554889e5534883ec2848897dd8488b45
EOF
RUN