This commit is contained in:
xarkes 2017-08-24 13:37:20 +02:00 committed by radare
parent 7c24a96aa9
commit 7db09c8543
2 changed files with 43 additions and 57 deletions

View File

@ -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;
}

View File

@ -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