Ar fixes (#8292)
This commit is contained in:
parent
7c24a96aa9
commit
7db09c8543
98
shlr/ar/ar.c
98
shlr/ar/ar.c
|
@ -7,6 +7,7 @@
|
|||
|
||||
const char *AR_MAGIC_HEADER = "!<arch>\n";
|
||||
const char *AR_FILE_HEADER_END = "`\n";
|
||||
const int AR_FILENAME_LEN = 16;
|
||||
|
||||
/* Used to lookup filename table */
|
||||
static int index_filename = -2;
|
||||
|
@ -34,25 +35,17 @@ R_API RBuffer *ar_open_file(const char *arname, const char *filename) {
|
|||
}
|
||||
files = r_list_new ();
|
||||
/* Parse archive */
|
||||
ar_read_file (b, buffer, BUF_SIZE, true, NULL, NULL);
|
||||
ar_read_file (b, buffer, true, NULL, NULL);
|
||||
ar_read_filename_table (b, buffer, files, filename);
|
||||
|
||||
/* If b->base is set, then we found the file root in the archive */
|
||||
while (r && !b->base) {
|
||||
ar_read (b, buffer, 2);
|
||||
/* Fix padding */
|
||||
if (*buffer == '\n') {
|
||||
buffer[0] = buffer[1];
|
||||
b->cur -= 1;
|
||||
ar_read (b, buffer, 2);
|
||||
}
|
||||
r = ar_read_file (b, buffer, BUF_SIZE, false, files, filename);
|
||||
r = ar_read_file (b, buffer, false, files, filename);
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
RListIter *iter;
|
||||
char *name;
|
||||
puts ("Available files:\n");
|
||||
r_list_foreach (files, iter, name) {
|
||||
printf ("%s\n", name);
|
||||
}
|
||||
|
@ -121,7 +114,7 @@ int ar_read_header(RBuffer *b, char *buffer) {
|
|||
return r;
|
||||
}
|
||||
|
||||
int ar_read_file(RBuffer *b, char *buffer, int bufsz, bool lookup, RList *files, const char *filename) {
|
||||
int ar_read_file(RBuffer *b, char *buffer, bool lookup, RList *files, const char *filename) {
|
||||
ut64 filesize = 0;
|
||||
char *tmp = NULL;
|
||||
char *curfile = NULL;
|
||||
|
@ -130,26 +123,35 @@ int ar_read_file(RBuffer *b, char *buffer, int bufsz, bool lookup, RList *files,
|
|||
|
||||
/* File identifier */
|
||||
if (lookup) {
|
||||
r = ar_read (b, buffer, bufsz);
|
||||
ar_read (b, buffer, AR_FILENAME_LEN);
|
||||
} else {
|
||||
r = ar_read (b, buffer + 2, bufsz - 1);
|
||||
ar_read (b, buffer, 2);
|
||||
/* Fix padding issues */
|
||||
if (*buffer == '\n') {
|
||||
buffer[0] = buffer[1];
|
||||
b->cur--;
|
||||
ar_read (b, buffer, 2);
|
||||
}
|
||||
ar_read (b, buffer + 2, AR_FILENAME_LEN - 2);
|
||||
}
|
||||
buffer[bufsz] = 0;
|
||||
buffer[AR_FILENAME_LEN] = '\0';
|
||||
/* Fix some padding issues */
|
||||
if (buffer[15] != '/' && buffer[15] != ' ') {
|
||||
if (buffer[AR_FILENAME_LEN - 1] != '/' && buffer[AR_FILENAME_LEN - 1] != ' ') {
|
||||
// Find padding offset
|
||||
tmp = (char *)r_str_lchr (buffer, ' ');
|
||||
if (!tmp) {
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
int dif = (int) (tmp - buffer);
|
||||
dif = 31 - dif;
|
||||
// Re-read the whole filename
|
||||
b->cur -= dif;
|
||||
r = ar_read (b, buffer, 16);
|
||||
r = ar_read (b, buffer, AR_FILENAME_LEN);
|
||||
}
|
||||
free (curfile);
|
||||
curfile = strdup (buffer);
|
||||
if (!curfile) {
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
/* If /XX then refer to filename table later */
|
||||
if (curfile[0] == '/' && curfile[1] >= '0' && curfile[1] <= '9') {
|
||||
|
@ -158,49 +160,29 @@ int ar_read_file(RBuffer *b, char *buffer, int bufsz, bool lookup, RList *files,
|
|||
/* Read filename */
|
||||
tmp = strchr (curfile, '/');
|
||||
if (!tmp) {
|
||||
return 0;
|
||||
goto fail;
|
||||
}
|
||||
*tmp = '\0';
|
||||
if (files) {
|
||||
r_list_append (files, strdup (curfile));
|
||||
}
|
||||
}
|
||||
/* File timestamp */
|
||||
r = ar_read (b, buffer, 12);
|
||||
if (r != 12) {
|
||||
free (curfile);
|
||||
return 0;
|
||||
}
|
||||
/* Owner id */
|
||||
r = ar_read (b, buffer, 6);
|
||||
if (r != 6) {
|
||||
free (curfile);
|
||||
return 0;
|
||||
}
|
||||
/* Group id */
|
||||
r = ar_read (b, buffer, 6);
|
||||
if (r != 6) {
|
||||
free (curfile);
|
||||
return 0;
|
||||
}
|
||||
/* File mode */
|
||||
r = ar_read (b, buffer, 8);
|
||||
if (r != 8) {
|
||||
free (curfile);
|
||||
return 0;
|
||||
}
|
||||
/* File size */
|
||||
r = ar_read (b, buffer, 10);
|
||||
filesize = strtoull (buffer, &tmp, 10);
|
||||
if (r != 10) {
|
||||
free (curfile);
|
||||
return 0;
|
||||
/* Timestamp 12
|
||||
* Owner ID 6
|
||||
* Group ID 6
|
||||
* File Mode 8
|
||||
* File Size 10
|
||||
* Header end 2 */
|
||||
r = ar_read (b, buffer, 44);
|
||||
if (r != 44) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
filesize = strtoull (buffer + 32, &tmp, 10);
|
||||
|
||||
/* Header end */
|
||||
r = ar_read (b, buffer, 2);
|
||||
if (strncmp (buffer, AR_FILE_HEADER_END, 2)) {
|
||||
free (curfile);
|
||||
return 0;
|
||||
if (strncmp (buffer + 42, AR_FILE_HEADER_END, 2)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* File content */
|
||||
|
@ -218,15 +200,19 @@ int ar_read_file(RBuffer *b, char *buffer, int bufsz, bool lookup, RList *files,
|
|||
b->cur += filesize - 1;
|
||||
free (curfile);
|
||||
return filesize;
|
||||
fail:
|
||||
free (curfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ar_read_filename_table(RBuffer *b, char *buffer, RList *files, const char *filename) {
|
||||
int r = ar_read (b, buffer, 16);
|
||||
if (r != 16) {
|
||||
int r = ar_read (b, buffer, AR_FILENAME_LEN);
|
||||
if (r != AR_FILENAME_LEN) {
|
||||
return 0;
|
||||
}
|
||||
if (strncmp (buffer, "//", 2)) {
|
||||
b->cur -= 16;
|
||||
// What we read was not a filename table, just go back
|
||||
b->cur -= AR_FILENAME_LEN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,6 @@ R_API int ar_write_at(RBuffer *b, ut64 off, void *buf, int count);
|
|||
int ar_read(RBuffer *b, void *dest, int len);
|
||||
int ar_read_until_slash(RBuffer *b, char *buffer, int limit);
|
||||
int ar_read_header(RBuffer *b, char *buffer);
|
||||
int ar_read_file(RBuffer *b, char *buffer, int bufsz, bool lookup, RList *files, const char *filename);
|
||||
int ar_read_file(RBuffer *b, char *buffer, bool lookup, RList *files, const char *filename);
|
||||
int ar_read_filename_table(RBuffer *b, char *buffer, RList *files, const char *filename);
|
||||
#endif // _AR_H
|
||||
|
|
Loading…
Reference in New Issue