//config: bool "unzip (24 kb)"
//config: default y
//config: help
-//config: unzip will list or extract files from a ZIP archive,
-//config: commonly found on DOS/WIN systems. The default behavior
-//config: (with no options) is to extract the archive into the
-//config: current directory.
+//config: unzip will list or extract files from a ZIP archive,
+//config: commonly found on DOS/WIN systems. The default behavior
+//config: (with no options) is to extract the archive into the
+//config: current directory.
//config:
//config:config FEATURE_UNZIP_CDF
//config: bool "Read and use Central Directory data"
//config: default y
//config: depends on UNZIP
//config: help
-//config: If you know that you only need to deal with simple
-//config: ZIP files without deleted/updated files, SFX archives etc,
-//config: you can reduce code size by unselecting this option.
-//config: To support less trivial ZIPs, say Y.
+//config: If you know that you only need to deal with simple
+//config: ZIP files without deleted/updated files, SFX archives etc,
+//config: you can reduce code size by unselecting this option.
+//config: To support less trivial ZIPs, say Y.
//config:
//config:config FEATURE_UNZIP_BZIP2
//config: bool "Support compression method 12 (bzip2)"
#define FIX_ENDIANNESS_ZIP(zip) \
do { if (BB_BIG_ENDIAN) { \
+ (zip).fmt.method = SWAP_LE16((zip).fmt.method ); \
(zip).fmt.crc32 = SWAP_LE32((zip).fmt.crc32 ); \
(zip).fmt.cmpsize = SWAP_LE32((zip).fmt.cmpsize ); \
(zip).fmt.ucmpsize = SWAP_LE32((zip).fmt.ucmpsize ); \
};
#endif
+static void die_if_bad_fnamesize(unsigned sz)
+{
+ if (sz > 0xfff) /* more than 4k?! no funny business please */
+ bb_error_msg_and_die("bad archive");
+}
+
static void unzip_skip(off_t skip)
{
if (skip != 0)
{
char *target;
- if (zip->fmt.ucmpsize > 0xfff) /* no funny business please */
- bb_error_msg_and_die("bad archive");
+ die_if_bad_fnamesize(zip->fmt.ucmpsize);
if (zip->fmt.method == 0) {
/* Method 0 - stored (not compressed) */
target[xstate.mem_output_size] = '\0';
#endif
}
+ if (!unsafe_symlink_target(target)) {
//TODO: libbb candidate
- if (symlink(target, dst_fn))
- bb_perror_msg_and_die("can't create symlink '%s'", dst_fn);
+ if (symlink(target, dst_fn)) {
+ /* shared message */
+ bb_perror_msg_and_die("can't create %slink '%s' to '%s'",
+ "sym", dst_fn, target
+ );
+ }
+ }
free(target);
}
#endif
/* Read filename */
free(dst_fn);
+ die_if_bad_fnamesize(zip.fmt.filename_len);
dst_fn = xzalloc(zip.fmt.filename_len + 1);
xread(zip_fd, dst_fn, zip.fmt.filename_len);
/* Skip extra header bytes */