X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=archival%2Flibunarchive%2Fget_header_ar.c;h=59fd34c732965a03af23e040602bc5ee80db0f00;hb=82604e973085f91f1b99cacea08963d0d1468084;hp=7f8c81ca0449b59c32d3a7d4c82e004cc6d83e6b;hpb=d9e15f206840219bb0f39c912a42fdcf8cbcaed6;p=oweals%2Fbusybox.git diff --git a/archival/libunarchive/get_header_ar.c b/archival/libunarchive/get_header_ar.c index 7f8c81ca0..59fd34c73 100644 --- a/archival/libunarchive/get_header_ar.c +++ b/archival/libunarchive/get_header_ar.c @@ -7,8 +7,9 @@ #include "libbb.h" #include "unarchive.h" -char get_header_ar(archive_handle_t *archive_handle) +char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) { + int err; file_header_t *typed = archive_handle->file_header; union { char raw[60]; @@ -22,9 +23,9 @@ char get_header_ar(archive_handle_t *archive_handle) char magic[2]; } formatted; } ar; -#ifdef CONFIG_FEATURE_AR_LONG_FILENAMES +#if ENABLE_FEATURE_AR_LONG_FILENAMES static char *ar_long_names; - static unsigned int ar_long_name_size; + static unsigned ar_long_name_size; #endif /* dont use xread as we want to handle the error ourself */ @@ -45,19 +46,29 @@ char get_header_ar(archive_handle_t *archive_handle) archive_handle->offset += 60; /* align the headers based on the header magic */ - if ((ar.formatted.magic[0] != '`') || (ar.formatted.magic[1] != '\n')) { + if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n') bb_error_msg_and_die("invalid ar header"); - } - typed->mode = xstrtoul(ar.formatted.mode, 8); - typed->mtime = xatou(ar.formatted.date); - typed->uid = xatou(ar.formatted.uid); - typed->gid = xatou(ar.formatted.gid); - typed->size = xatoul(ar.formatted.size); + /* FIXME: more thorough routine would be in order here */ + /* (we have something like that in tar) */ + /* but for now we are lax. This code works because */ + /* on misformatted numbers bb_strtou returns all-ones */ + typed->mode = err = bb_strtou(ar.formatted.mode, NULL, 8); + if (err == -1) bb_error_msg_and_die("invalid ar header"); + typed->mtime = err = bb_strtou(ar.formatted.date, NULL, 10); + if (err == -1) bb_error_msg_and_die("invalid ar header"); + typed->uid = err = bb_strtou(ar.formatted.uid, NULL, 10); + if (err == -1) bb_error_msg_and_die("invalid ar header"); + typed->gid = err = bb_strtou(ar.formatted.gid, NULL, 10); + if (err == -1) bb_error_msg_and_die("invalid ar header"); + typed->size = err = bb_strtou(ar.formatted.size, NULL, 10); + if (err == -1) bb_error_msg_and_die("invalid ar header"); /* long filenames have '/' as the first character */ if (ar.formatted.name[0] == '/') { -#ifdef CONFIG_FEATURE_AR_LONG_FILENAMES +#if ENABLE_FEATURE_AR_LONG_FILENAMES + unsigned long_offset; + if (ar.formatted.name[1] == '/') { /* If the second char is a '/' then this entries data section * stores long filename for multiple entries, they are stored @@ -69,20 +80,22 @@ char get_header_ar(archive_handle_t *archive_handle) /* This ar entries data section only contained filenames for other records * they are stored in the static ar_long_names for future reference */ return get_header_ar(archive_handle); /* Return next header */ - } else if (ar.formatted.name[1] == ' ') { + } + + if (ar.formatted.name[1] == ' ') { /* This is the index of symbols in the file for compilers */ data_skip(archive_handle); archive_handle->offset += typed->size; return get_header_ar(archive_handle); /* Return next header */ - } else { - /* The number after the '/' indicates the offset in the ar data section - (saved in variable long_name) that conatains the real filename */ - const unsigned int long_offset = atoi(&ar.formatted.name[1]); - if (long_offset >= ar_long_name_size) { - bb_error_msg_and_die("can't resolve long filename"); - } - typed->name = xstrdup(ar_long_names + long_offset); } + + /* The number after the '/' indicates the offset in the ar data section + * (saved in variable long_name) that conatains the real filename */ + long_offset = atoi(&ar.formatted.name[1]); + if (long_offset >= ar_long_name_size) { + bb_error_msg_and_die("can't resolve long filename"); + } + typed->name = xstrdup(ar_long_names + long_offset); #else bb_error_msg_and_die("long filenames not supported"); #endif @@ -96,7 +109,8 @@ char get_header_ar(archive_handle_t *archive_handle) if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { archive_handle->action_header(typed); if (archive_handle->sub_archive) { - while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS); + while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS) + continue; } else { archive_handle->action_data(archive_handle); }