mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[cmp] update Bled to latest
* Also try to fix the fallthrough Coverity warning in format_ext.c
This commit is contained in:
		
							parent
							
								
									2cf183e9f1
								
							
						
					
					
						commit
						07d1fdcc2f
					
				
					 15 changed files with 485 additions and 267 deletions
				
			
		|  | @ -64,6 +64,9 @@ typedef struct archive_handle_t { | |||
| 	/* Currently processed file's header */ | ||||
| 	file_header_t *file_header; | ||||
| 
 | ||||
| 	/* List of link placeholders */ | ||||
| 	llist_t *link_placeholders; | ||||
| 
 | ||||
| 	/* Process the header component, e.g. tar -t */ | ||||
| 	void FAST_FUNC (*action_header)(const file_header_t *); | ||||
| 
 | ||||
|  | @ -77,6 +80,9 @@ typedef struct archive_handle_t { | |||
| 	off_t offset; | ||||
| 
 | ||||
| 	/* Archiver specific. Can make it a union if it ever gets big */ | ||||
| #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||||
| 	unsigned tar__strip_components; | ||||
| #endif | ||||
| #define PAX_NEXT_FILE 0 | ||||
| #define PAX_GLOBAL    1 | ||||
| #if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB | ||||
|  | @ -95,6 +101,7 @@ typedef struct archive_handle_t { | |||
| #endif | ||||
| #if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM | ||||
| 	uoff_t cpio__blocks; | ||||
| 	struct bb_uidgid_t cpio__owner; | ||||
| 	struct hardlinks_t *cpio__hardlinks_to_create; | ||||
| 	struct hardlinks_t *cpio__created_hardlinks; | ||||
| #endif | ||||
|  | @ -110,20 +117,23 @@ typedef struct archive_handle_t { | |||
| 	const char *ar__name; | ||||
| 	struct archive_handle_t *ar__out; | ||||
| #endif | ||||
| #if ENABLE_FEATURE_AR_LONG_FILENAMES | ||||
| 	char *ar__long_names; | ||||
| 	unsigned ar__long_name_size; | ||||
| #endif | ||||
| } archive_handle_t; | ||||
| /* bits in ah_flags */ | ||||
| #define ARCHIVE_RESTORE_DATE        (1 << 0) | ||||
| #define ARCHIVE_CREATE_LEADING_DIRS (1 << 1) | ||||
| #define ARCHIVE_UNLINK_OLD          (1 << 2) | ||||
| #define ARCHIVE_EXTRACT_QUIET       (1 << 3) | ||||
| #define ARCHIVE_EXTRACT_NEWER       (1 << 4) | ||||
| #define ARCHIVE_DONT_RESTORE_OWNER  (1 << 5) | ||||
| #define ARCHIVE_DONT_RESTORE_PERM   (1 << 6) | ||||
| #define ARCHIVE_NUMERIC_OWNER       (1 << 7) | ||||
| #define ARCHIVE_O_TRUNC             (1 << 8) | ||||
| #define ARCHIVE_REMEMBER_NAMES      (1 << 9) | ||||
| #define ARCHIVE_EXTRACT_NEWER       (1 << 3) | ||||
| #define ARCHIVE_DONT_RESTORE_OWNER  (1 << 4) | ||||
| #define ARCHIVE_DONT_RESTORE_PERM   (1 << 5) | ||||
| #define ARCHIVE_NUMERIC_OWNER       (1 << 6) | ||||
| #define ARCHIVE_O_TRUNC             (1 << 7) | ||||
| #define ARCHIVE_REMEMBER_NAMES      (1 << 8) | ||||
| #if ENABLE_RPM | ||||
| #define ARCHIVE_REPLACE_VIA_RENAME  (1 << 10) | ||||
| #define ARCHIVE_REPLACE_VIA_RENAME  (1 << 9) | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
|  | @ -157,6 +167,11 @@ typedef struct tar_header_t {     /* byte offset */ | |||
| struct BUG_tar_header { | ||||
| 	char c[sizeof(tar_header_t) == TAR_BLOCK_SIZE ? 1 : -1]; | ||||
| }; | ||||
| void chksum_and_xwrite_tar_header(int fd, struct tar_header_t *hp) FAST_FUNC; | ||||
| 
 | ||||
| 
 | ||||
| extern const char cpio_TRAILER[]; | ||||
| 
 | ||||
| 
 | ||||
| archive_handle_t *init_handle(void) FAST_FUNC; | ||||
| 
 | ||||
|  | @ -188,22 +203,22 @@ void seek_by_jump(int fd, off_t amount) FAST_FUNC; | |||
| void seek_by_read(int fd, off_t amount) FAST_FUNC; | ||||
| 
 | ||||
| const char *strip_unsafe_prefix(const char *str) FAST_FUNC; | ||||
| void create_or_remember_link(llist_t **link_placeholders, | ||||
| 		const char *target, | ||||
| 		const char *linkname, | ||||
| 		int hard_link) FAST_FUNC; | ||||
| void create_links_from_list(llist_t *list) FAST_FUNC; | ||||
| 
 | ||||
| void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC; | ||||
| const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC; | ||||
| const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC; | ||||
| 
 | ||||
| /* A bit of bunzip2 internals are exposed for compressed help support: */ | ||||
| typedef struct bunzip_data bunzip_data; | ||||
| int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC; | ||||
| /* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes
 | ||||
|  * in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */ | ||||
| int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; | ||||
| void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; | ||||
| char *unpack_bz2_data(const char *packed, int packed_len, int unpacked_len) FAST_FUNC; | ||||
| 
 | ||||
| /* Meaning and direction (input/output) of the fields are transformer-specific */ | ||||
| typedef struct transformer_state_t { | ||||
| 	int8_t      check_signature;        /* most often referenced member */ | ||||
| 	int8_t   signature_skipped; /* most often referenced member */ | ||||
| 
 | ||||
| 	IF_DESKTOP(long long) int FAST_FUNC (*xformer)(struct transformer_state_t *xstate); | ||||
| 	USE_FOR_NOMMU(const char *xformer_prog;) | ||||
|  | @ -223,6 +238,12 @@ typedef struct transformer_state_t { | |||
| 	uint64_t bytes_in;  /* used in unzip code only: needs to know packed size */ | ||||
| 	uint32_t crc32; | ||||
| 	time_t   mtime;     /* gunzip code may set this on exit */ | ||||
| 
 | ||||
| 	union {             /* if we read magic, it's saved here */ | ||||
| 		uint8_t b[8]; | ||||
| 		uint16_t b16[4]; | ||||
| 		uint32_t b32[2]; | ||||
| 	} magic; | ||||
| } transformer_state_t; | ||||
| 
 | ||||
| void init_transformer_state(transformer_state_t *xstate) FAST_FUNC; | ||||
|  | @ -278,11 +299,11 @@ int bbunpack(char **argv, | |||
| void check_errors_in_children(int signo); | ||||
| #if BB_MMU | ||||
| void fork_transformer(int fd, | ||||
| 	int check_signature, | ||||
| 	int signature_skipped, | ||||
| 	IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate) | ||||
| ) FAST_FUNC; | ||||
| #define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), 1, (transformer)) | ||||
| #define fork_transformer_with_no_sig(fd, transformer)              fork_transformer((fd), 0, (transformer)) | ||||
| #define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), 0, (transformer)) | ||||
| #define fork_transformer_with_no_sig(fd, transformer)              fork_transformer((fd), 1, (transformer)) | ||||
| #else | ||||
| void fork_transformer(int fd, const char *transform_prog) FAST_FUNC; | ||||
| #define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), (transform_prog)) | ||||
|  |  | |||
|  | @ -65,7 +65,6 @@ int64_t bled_uncompress(const char* src, const char* dst, int type) | |||
| 	init_transformer_state(&xstate); | ||||
| 	xstate.src_fd = -1; | ||||
| 	xstate.dst_fd = -1; | ||||
| 	xstate.check_signature = 1; | ||||
| 
 | ||||
| 	xstate.src_fd = _openU(src, _O_RDONLY | _O_BINARY, 0); | ||||
| 	if (xstate.src_fd < 0) { | ||||
|  | @ -113,7 +112,6 @@ int64_t bled_uncompress_with_handles(HANDLE hSrc, HANDLE hDst, int type) | |||
| 	init_transformer_state(&xstate); | ||||
| 	xstate.src_fd = -1; | ||||
| 	xstate.dst_fd = -1; | ||||
| 	xstate.check_signature = 1; | ||||
| 
 | ||||
| 	xstate.src_fd = _open_osfhandle((intptr_t)hSrc, _O_RDONLY); | ||||
| 	if (xstate.src_fd < 0) { | ||||
|  | @ -157,7 +155,6 @@ int64_t bled_uncompress_to_buffer(const char* src, char* buf, size_t size, int t | |||
| 	init_transformer_state(&xstate); | ||||
| 	xstate.src_fd = -1; | ||||
| 	xstate.dst_fd = -1; | ||||
| 	xstate.check_signature = 1; | ||||
| 
 | ||||
| 	if (src[0] == 0) { | ||||
| 		xstate.src_fd = bb_virtual_fd; | ||||
|  | @ -206,7 +203,6 @@ int64_t bled_uncompress_to_dir(const char* src, const char* dir, int type) | |||
| 	init_transformer_state(&xstate); | ||||
| 	xstate.src_fd = -1; | ||||
| 	xstate.dst_fd = -1; | ||||
| 	xstate.check_signature = 1; | ||||
| 
 | ||||
| 	xstate.src_fd = _openU(src, _O_RDONLY | _O_BINARY, 0); | ||||
| 	if (xstate.src_fd < 0) { | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ | |||
| /*
 | ||||
|  * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||||
|  */ | ||||
| 
 | ||||
| #include "libbb.h" | ||||
| #include "bb_archive.h" | ||||
| 
 | ||||
|  | @ -11,6 +10,12 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 	file_header_t *file_header = archive_handle->file_header; | ||||
| 	int dst_fd; | ||||
| 	int res; | ||||
| 	char *hard_link; | ||||
| #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||||
| 	char *dst_name; | ||||
| #else | ||||
| # define dst_name (file_header->name) | ||||
| #endif | ||||
| 
 | ||||
| #if ENABLE_FEATURE_TAR_SELINUX | ||||
| 	char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; | ||||
|  | @ -23,11 +28,49 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	/* Hard links are encoded as regular files of size 0
 | ||||
| 	 * with a nonempty link field */ | ||||
| 	hard_link = NULL; | ||||
| 	if (S_ISREG(file_header->mode) && file_header->size == 0) | ||||
| 		hard_link = file_header->link_target; | ||||
| 
 | ||||
| #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||||
| 	dst_name = file_header->name; | ||||
| 	if (archive_handle->tar__strip_components) { | ||||
| 		unsigned n = archive_handle->tar__strip_components; | ||||
| 		do { | ||||
| 			dst_name = strchr(dst_name, '/'); | ||||
| 			if (!dst_name || dst_name[1] == '\0') { | ||||
| 				data_skip(archive_handle); | ||||
| 				goto ret; | ||||
| 			} | ||||
| 			dst_name++; | ||||
| 			/*
 | ||||
| 			 * Link target is shortened only for hardlinks: | ||||
| 			 * softlinks restored unchanged. | ||||
| 			 */ | ||||
| 			if (hard_link) { | ||||
| // GNU tar 1.26 does not check that we reached end of link name:
 | ||||
| // if "dir/hardlink" is hardlinked to "file",
 | ||||
| // tar xvf a.tar --strip-components=1 says:
 | ||||
| //  tar: hardlink: Cannot hard link to '': No such file or directory
 | ||||
| // and continues processing. We silently skip such entries.
 | ||||
| 				hard_link = strchr(hard_link, '/'); | ||||
| 				if (!hard_link || hard_link[1] == '\0') { | ||||
| 					data_skip(archive_handle); | ||||
| 					goto ret; | ||||
| 				} | ||||
| 				hard_link++; | ||||
| 			} | ||||
| 		} while (--n != 0); | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { | ||||
| 		char *slash = strrchr(file_header->name, '/'); | ||||
| 		char *slash = strrchr(dst_name, '/'); | ||||
| 		if (slash) { | ||||
| 			*slash = '\0'; | ||||
| 			bb_make_directory(file_header->name, -1, FILEUTILS_RECUR); | ||||
| 			bb_make_directory(dst_name, -1, FILEUTILS_RECUR); | ||||
| 			*slash = '/'; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -35,12 +78,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 	if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { | ||||
| 		/* Remove the entry if it exists */ | ||||
| 		if (!S_ISDIR(file_header->mode)) { | ||||
| 			/* Is it hardlink?
 | ||||
| 			 * We encode hard links as regular files of size 0 with a symlink */ | ||||
| 			if (S_ISREG(file_header->mode) | ||||
| 			 && file_header->link_target | ||||
| 			 && file_header->size == 0 | ||||
| 			) { | ||||
| 			if (hard_link) { | ||||
| 				/* Ugly special case:
 | ||||
| 				 * tar cf t.tar hardlink1 hardlink2 hardlink1 | ||||
| 				 * results in this tarball structure: | ||||
|  | @ -48,56 +86,46 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 				 * hardlink2 -> hardlink1 | ||||
| 				 * hardlink1 -> hardlink1 <== !!! | ||||
| 				 */ | ||||
| 				if (strcmp(file_header->link_target, file_header->name) == 0) | ||||
| 				if (strcmp(hard_link, dst_name) == 0) | ||||
| 					goto ret; | ||||
| 			} | ||||
| 			/* Proceed with deleting */ | ||||
| 			if (_unlink(file_header->name) == -1 | ||||
| 			if (_unlink(dst_name) == -1 | ||||
| 			 && errno != ENOENT | ||||
| 			) { | ||||
| 				bb_perror_msg_and_die("can't remove old file %s", | ||||
| 						file_header->name); | ||||
| 						dst_name); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) { | ||||
| 		/* Remove the existing entry if its older than the extracted entry */ | ||||
| 		struct stat existing_sb; | ||||
| 		if (lstat(file_header->name, &existing_sb) == -1) { | ||||
| 		if (lstat(dst_name, &existing_sb) == -1) { | ||||
| 			if (errno != ENOENT) { | ||||
| 				bb_perror_msg_and_die("can't stat old file"); | ||||
| 				bb_simple_perror_msg_and_die("can't stat old file"); | ||||
| 			} | ||||
| 		} | ||||
| 		else if (existing_sb.st_mtime >= file_header->mtime) { | ||||
| 			if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | ||||
| 			 && !S_ISDIR(file_header->mode) | ||||
| 			) { | ||||
| 			if (!S_ISDIR(file_header->mode)) { | ||||
| 				bb_error_msg("%s not created: newer or " | ||||
| 					"same age file exists", file_header->name); | ||||
| 					"same age file exists", dst_name); | ||||
| 			} | ||||
| 			data_skip(archive_handle); | ||||
| 			goto ret; | ||||
| 		} | ||||
| 		else if ((_unlink(file_header->name) == -1) && (errno != EISDIR)) { | ||||
| 		else if ((_unlink(dst_name) == -1) && (errno != EISDIR)) { | ||||
| 			bb_perror_msg_and_die("can't remove old file %s", | ||||
| 					file_header->name); | ||||
| 					dst_name); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Handle hard links separately
 | ||||
| 	 * We encode hard links as regular files of size 0 with a symlink */ | ||||
| 	if (S_ISREG(file_header->mode) | ||||
| 	 && file_header->link_target | ||||
| 	 && file_header->size == 0 | ||||
| 	) { | ||||
| 		/* hard link */ | ||||
| 		res = link(file_header->link_target, file_header->name); | ||||
| 		if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { | ||||
| 			bb_perror_msg("can't create %slink " | ||||
| 					"from %s to %s", "hard", | ||||
| 					file_header->name, | ||||
| 					file_header->link_target); | ||||
| 		} | ||||
| 	/* Handle hard links separately */ | ||||
| 	if (hard_link) { | ||||
| 		create_or_remember_link(&archive_handle->link_placeholders, | ||||
| 				hard_link, | ||||
| 				dst_name, | ||||
| 				1); | ||||
| 		/* Hardlinks have no separate mode/ownership, skip chown/chmod */ | ||||
| 		goto ret; | ||||
| 	} | ||||
|  | @ -106,15 +134,17 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 	switch (file_header->mode & S_IFMT) { | ||||
| 	case S_IFREG: { | ||||
| 		/* Regular file */ | ||||
| 		char *dst_name; | ||||
| #ifdef ARCHIVE_REPLACE_VIA_RENAME | ||||
| 		char *dst_nameN; | ||||
| #endif | ||||
| 		int flags = O_WRONLY | O_CREAT | O_EXCL; | ||||
| 		if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) | ||||
| 			flags = O_WRONLY | O_CREAT | O_TRUNC; | ||||
| 		dst_name = file_header->name; | ||||
| #ifdef ARCHIVE_REPLACE_VIA_RENAME | ||||
| 		dst_nameN = dst_name; | ||||
| 		if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) | ||||
| 			/* rpm-style temp file name */ | ||||
| 			dst_name = xasprintf("%s;%x", dst_name, (int)getpid()); | ||||
| 			dst_nameN = xasprintf("%s;%x", dst_name, (int)getpid()); | ||||
| #endif | ||||
| 		if (_sopen_s(&dst_fd, dst_name, flags, _SH_DENYNO, file_header->mode) != 0) { | ||||
| 			bb_perror_msg_and_die("can't open file %s", dst_name); | ||||
|  | @ -123,48 +153,66 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 		_close(dst_fd); | ||||
| #ifdef ARCHIVE_REPLACE_VIA_RENAME | ||||
| 		if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { | ||||
| 			xrename(dst_name, file_header->name); | ||||
| 			free(dst_name); | ||||
| 			xrename(dst_nameN, dst_name); | ||||
| 			free(dst_nameN); | ||||
| 		} | ||||
| #endif | ||||
| 		break; | ||||
| 	} | ||||
| 	case S_IFDIR: | ||||
| 		res = mkdir(file_header->name, file_header->mode); | ||||
| 		if ((res == -1) | ||||
| //TODO: this causes problems if tarball contains a r-xr-xr-x directory:
 | ||||
| // we create this directory, and then fail to create files inside it
 | ||||
| // (if tar xf isn't run as root).
 | ||||
| // GNU tar works around this by chmod-ing directories *after* all files are extracted.
 | ||||
| 		res = mkdir(dst_name, file_header->mode); | ||||
| 		if ((res != 0) | ||||
| 		 && (errno != EISDIR) /* btw, Linux doesn't return this */ | ||||
| 		 && (errno != EEXIST) | ||||
| 		 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | ||||
| 		) { | ||||
| 			bb_perror_msg("can't make dir %s", file_header->name); | ||||
| 			bb_perror_msg("can't make dir %s", dst_name); | ||||
| 		} | ||||
| 		break; | ||||
| 	case S_IFLNK: | ||||
| 		/* Symlink */ | ||||
| //TODO: what if file_header->link_target == NULL (say, corrupted tarball?)
 | ||||
| 		res = symlink(file_header->link_target, file_header->name); | ||||
| 		if ((res == -1) | ||||
| 		 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | ||||
| 		) { | ||||
| 			bb_perror_msg("can't create %slink " | ||||
| 				"from %s to %s", "sym", | ||||
| 				file_header->name, | ||||
| 				file_header->link_target); | ||||
| 		} | ||||
| 
 | ||||
| 		/* To avoid a directory traversal attack via symlinks,
 | ||||
| 		 * do not restore symlinks with ".." components | ||||
| 		 * or symlinks starting with "/", unless a magic | ||||
| 		 * envvar is set. | ||||
| 		 * | ||||
| 		 * For example, consider a .tar created via: | ||||
| 		 *  $ tar cvf bug.tar anything.txt | ||||
| 		 *  $ ln -s /tmp symlink | ||||
| 		 *  $ tar --append -f bug.tar symlink | ||||
| 		 *  $ rm symlink | ||||
| 		 *  $ mkdir symlink | ||||
| 		 *  $ tar --append -f bug.tar symlink/evil.py | ||||
| 		 * | ||||
| 		 * This will result in an archive that contains: | ||||
| 		 *  $ tar --list -f bug.tar | ||||
| 		 *  anything.txt | ||||
| 		 *  symlink [-> /tmp] | ||||
| 		 *  symlink/evil.py | ||||
| 		 * | ||||
| 		 * Untarring bug.tar would otherwise place evil.py in '/tmp'. | ||||
| 		 */ | ||||
| 		create_or_remember_link(&archive_handle->link_placeholders, | ||||
| 				file_header->link_target, | ||||
| 				dst_name, | ||||
| 				0); | ||||
| 		break; | ||||
| 	case S_IFSOCK: | ||||
| 	case S_IFBLK: | ||||
| 	case S_IFCHR: | ||||
| 	case S_IFIFO: | ||||
| 		res = mknod(file_header->name, file_header->mode, file_header->device); | ||||
| 		if ((res == -1) | ||||
| 		 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | ||||
| 		) { | ||||
| 			bb_perror_msg("can't create node %s", file_header->name); | ||||
| 		res = mknod(dst_name, file_header->mode, file_header->device); | ||||
| 		if (res != 0) { | ||||
| 			bb_perror_msg("can't create node %s", dst_name); | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		bb_error_msg_and_die("unrecognized file type"); | ||||
| 		bb_simple_error_msg_and_die("unrecognized file type"); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!S_ISLNK(file_header->mode)) { | ||||
|  | @ -199,7 +247,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
| 
 | ||||
| 			t[1].tv_sec = t[0].tv_sec = file_header->mtime; | ||||
| 			t[1].tv_usec = t[0].tv_usec = 0; | ||||
| 			utimes64(file_header->name, t); | ||||
| 			utimes64(dst_name, t); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,14 +1,14 @@ | |||
| /* vi: set sw=4 ts=4: */ | ||||
| /* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net).
 | ||||
| 
 | ||||
|    Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), | ||||
|    which also acknowledges contributions by Mike Burrows, David Wheeler, | ||||
|    Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, | ||||
|    Robert Sedgewick, and Jon L. Bentley. | ||||
| 
 | ||||
|    Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||||
| /*
 | ||||
|  * Small bzip2 deflate implementation, by Rob Landley (rob@landley.net). | ||||
|  * | ||||
|  * Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), | ||||
|  * which also acknowledges contributions by Mike Burrows, David Wheeler, | ||||
|  * Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, | ||||
|  * Robert Sedgewick, and Jon L. Bentley. | ||||
|  * | ||||
|  * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
| 	Size and speed optimizations by Manuel Novoa III  (mjn3@codepoet.org). | ||||
| 
 | ||||
|  | @ -38,7 +38,6 @@ | |||
| 
 | ||||
| 	Manuel | ||||
|  */ | ||||
| 
 | ||||
| #include "libbb.h" | ||||
| #include "bb_archive.h" | ||||
| 
 | ||||
|  | @ -101,14 +100,14 @@ struct bunzip_data { | |||
| 	unsigned dbufSize; | ||||
| 
 | ||||
| 	/* For I/O error handling */ | ||||
| 	jmp_buf jmpbuf; | ||||
| 	jmp_buf *jmpbuf; | ||||
| 
 | ||||
| 	/* Big things go last (register-relative addressing can be larger for big offsets) */ | ||||
| 	uint32_t crc32Table[256]; | ||||
| 	uint8_t selectors[32768];  /* nSelectors=15 bits */ | ||||
| 	struct group_data groups[MAX_GROUPS];  /* Huffman coding tables */ | ||||
| }; | ||||
| /* typedef struct bunzip_data bunzip_data; -- done in .h file */ | ||||
| typedef struct bunzip_data bunzip_data; | ||||
| 
 | ||||
| 
 | ||||
| /* Return the next nnn bits of input.  All reads from the compressed input
 | ||||
|  | @ -128,14 +127,15 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |||
| 			/* if "no input fd" case: in_fd == -1, read fails, we jump */ | ||||
| 			bd->inbufCount = safe_read(bd->in_fd, bd->inbuf, IOBUF_SIZE); | ||||
| 			if (bd->inbufCount <= 0) | ||||
| 				longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF); | ||||
| 				longjmp(*bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF); | ||||
| 			bd->inbufPos = 0; | ||||
| 		} | ||||
| 
 | ||||
| 		/* Avoid 32-bit overflow (dump bit buffer to top of output) */ | ||||
| 		if (bit_count >= 24) { | ||||
| 			bits = bd->inbufBits & ((1 << bit_count) - 1); | ||||
| 			bits = bd->inbufBits & ((1U << bit_count) - 1); | ||||
| 			bits_wanted -= bit_count; | ||||
| 			// coverity[negative_shift]
 | ||||
| 			bits <<= bits_wanted; | ||||
| 			bit_count = 0; | ||||
| 		} | ||||
|  | @ -152,20 +152,20 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |||
| 
 | ||||
| 	return bits; | ||||
| } | ||||
| //#define get_bits(bd, n) (dbg("%d:get_bits()", __LINE__), get_bits(bd, n))
 | ||||
| 
 | ||||
| /* Unpacks the next block and sets up for the inverse Burrows-Wheeler step. */ | ||||
| static int get_next_block(bunzip_data *bd) | ||||
| { | ||||
| 	struct group_data *hufGroup; | ||||
| 	int dbufCount, dbufSize, groupCount, *base, *limit, selector, | ||||
| 		i, j, t, runPos, symCount, symTotal, nSelectors, byteCount[256]; | ||||
| 	int runCnt; | ||||
| 	int groupCount, selector, | ||||
| 		i, j, symCount, symTotal, nSelectors, byteCount[256]; | ||||
| 	uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; | ||||
| 	uint32_t *dbuf; | ||||
| 	unsigned origPtr; | ||||
| 	unsigned origPtr, t; | ||||
| 	unsigned dbufCount, runPos; | ||||
| 	unsigned runCnt = 0; // runCnt; /* for compiler */
 | ||||
| 
 | ||||
| 	dbuf = bd->dbuf; | ||||
| 	dbufSize = bd->dbufSize; | ||||
| 	selectors = bd->selectors; | ||||
| 
 | ||||
| /* In bbox, we are ok with aborting through setjmp which is set up in start_bunzip */ | ||||
|  | @ -180,15 +180,19 @@ static int get_next_block(bunzip_data *bd) | |||
| 	i = get_bits(bd, 24); | ||||
| 	j = get_bits(bd, 24); | ||||
| 	bd->headerCRC = get_bits(bd, 32); | ||||
| 	if ((i == 0x177245) && (j == 0x385090)) return RETVAL_LAST_BLOCK; | ||||
| 	if ((i != 0x314159) || (j != 0x265359)) return RETVAL_NOT_BZIP_DATA; | ||||
| 	if ((i == 0x177245) && (j == 0x385090)) | ||||
| 		return RETVAL_LAST_BLOCK; | ||||
| 	if ((i != 0x314159) || (j != 0x265359)) | ||||
| 		return RETVAL_NOT_BZIP_DATA; | ||||
| 
 | ||||
| 	/* We can add support for blockRandomised if anybody complains.  There was
 | ||||
| 	   some code for this in busybox 1.0.0-pre3, but nobody ever noticed that | ||||
| 	   it didn't actually work. */ | ||||
| 	if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT; | ||||
| 	if (get_bits(bd, 1)) | ||||
| 		return RETVAL_OBSOLETE_INPUT; | ||||
| 	origPtr = get_bits(bd, 24); | ||||
| 	if ((int)origPtr > dbufSize) return RETVAL_DATA_ERROR; | ||||
| 	if (origPtr > bd->dbufSize) | ||||
| 		return RETVAL_DATA_ERROR; | ||||
| 
 | ||||
| 	/* mapping table: if some byte values are never used (encoding things
 | ||||
| 	   like ascii text), the compression code removes the gaps to have fewer | ||||
|  | @ -232,8 +236,9 @@ static int get_next_block(bunzip_data *bd) | |||
| 		/* Get next value */ | ||||
| 		int n = 0; | ||||
| 		while (get_bits(bd, 1)) { | ||||
| 			if (n >= groupCount) return RETVAL_DATA_ERROR; | ||||
| 			n++; | ||||
| 			if (n >= groupCount) | ||||
| 				return RETVAL_DATA_ERROR; | ||||
| 		} | ||||
| 		/* Decode MTF to get the next selector */ | ||||
| 		tmp_byte = mtfSymbol[n]; | ||||
|  | @ -249,6 +254,8 @@ static int get_next_block(bunzip_data *bd) | |||
| 		uint8_t length[MAX_SYMBOLS]; | ||||
| 		/* 8 bits is ALMOST enough for temp[], see below */ | ||||
| 		unsigned temp[MAX_HUFCODE_BITS+1]; | ||||
| 		struct group_data *hufGroup; | ||||
| 		int *base, *limit; | ||||
| 		int minLen, maxLen, pp, len_m1; | ||||
| 
 | ||||
| 		/* Read Huffman code lengths for each symbol.  They're stored in
 | ||||
|  | @ -284,8 +291,10 @@ static int get_next_block(bunzip_data *bd) | |||
| 		/* Find largest and smallest lengths in this group */ | ||||
| 		minLen = maxLen = length[0]; | ||||
| 		for (i = 1; i < symCount; i++) { | ||||
| 			if (length[i] > maxLen) maxLen = length[i]; | ||||
| 			else if (length[i] < minLen) minLen = length[i]; | ||||
| 			if (length[i] > maxLen) | ||||
| 				maxLen = length[i]; | ||||
| 			else if (length[i] < minLen) | ||||
| 				minLen = length[i]; | ||||
| 		} | ||||
| 
 | ||||
| 		/* Calculate permute[], base[], and limit[] tables from length[].
 | ||||
|  | @ -308,7 +317,7 @@ static int get_next_block(bunzip_data *bd) | |||
| 		base = hufGroup->base - 1; | ||||
| 		limit = hufGroup->limit - 1; | ||||
| 
 | ||||
| 		/* Calculate permute[].  Concurently, initialize temp[] and limit[]. */ | ||||
| 		/* Calculate permute[].  Concurrently, initialize temp[] and limit[]. */ | ||||
| 		pp = 0; | ||||
| 		for (i = minLen; i <= maxLen; i++) { | ||||
| 			int k; | ||||
|  | @ -321,7 +330,8 @@ static int get_next_block(bunzip_data *bd) | |||
| 		/* Count symbols coded for at each bit length */ | ||||
| 		/* NB: in pathological cases, temp[8] can end ip being 256.
 | ||||
| 		 * That's why uint8_t is too small for temp[]. */ | ||||
| 		for (i = 0; i < symCount; i++) temp[length[i]]++; | ||||
| 		for (i = 0; i < symCount; i++) | ||||
| 			temp[length[i]]++; | ||||
| 
 | ||||
| 		/* Calculate limit[] (the largest symbol-coding value at each bit
 | ||||
| 		 * length, which is (previous limit<<1)+symbols at this level), and | ||||
|  | @ -364,12 +374,22 @@ static int get_next_block(bunzip_data *bd) | |||
| 
 | ||||
| 	runPos = dbufCount = selector = 0; | ||||
| 	for (;;) { | ||||
| 		struct group_data *hufGroup; | ||||
| 		int *base, *limit; | ||||
| 		int nextSym; | ||||
| 		uint8_t ngrp; | ||||
| 
 | ||||
| 		/* Fetch next Huffman coding group from list. */ | ||||
| 		symCount = GROUP_SIZE - 1; | ||||
| 		if (selector >= nSelectors) return RETVAL_DATA_ERROR; | ||||
| 		hufGroup = bd->groups + selectors[selector++]; | ||||
| 		if (selector >= nSelectors) | ||||
| 			return RETVAL_DATA_ERROR; | ||||
| 		ngrp = selectors[selector++]; | ||||
| 		if (ngrp >= groupCount) { | ||||
| 			dbg("%d selectors[%d]:%d groupCount:%d", | ||||
| 				__LINE__, selector-1, ngrp, groupCount); | ||||
| 			return RETVAL_DATA_ERROR; | ||||
| 		} | ||||
| 		hufGroup = bd->groups + ngrp; | ||||
| 		base = hufGroup->base - 1; | ||||
| 		limit = hufGroup->limit - 1; | ||||
| 
 | ||||
|  | @ -404,7 +424,8 @@ static int get_next_block(bunzip_data *bd) | |||
| 		} | ||||
| 		/* Figure how many bits are in next symbol and unget extras */ | ||||
| 		i = hufGroup->minLen; | ||||
| 		while (nextSym > limit[i]) ++i; | ||||
| 		while (nextSym > limit[i]) | ||||
| 			++i; | ||||
| 		j = hufGroup->maxLen - i; | ||||
| 		if (j < 0) | ||||
| 			return RETVAL_DATA_ERROR; | ||||
|  | @ -436,7 +457,7 @@ static int get_next_block(bunzip_data *bd) | |||
| 			   symbols, but a run of length 0 doesn't mean anything in this | ||||
| 			   context).  Thus space is saved. */ | ||||
| 			runCnt += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */ | ||||
| 			if (runPos < dbufSize) runPos <<= 1; | ||||
| 			if (runPos < bd->dbufSize) runPos <<= 1; | ||||
| 			goto end_of_huffman_loop; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -446,14 +467,15 @@ static int get_next_block(bunzip_data *bd) | |||
| 		   literal used is the one at the head of the mtfSymbol array.) */ | ||||
| 		if (runPos != 0) { | ||||
| 			uint8_t tmp_byte; | ||||
| 			if (dbufCount + runCnt > dbufSize) { | ||||
| 				dbg("dbufCount:%d+runCnt:%d %d > dbufSize:%d RETVAL_DATA_ERROR", | ||||
| 						dbufCount, runCnt, dbufCount + runCnt, dbufSize); | ||||
| 			if (dbufCount + runCnt > bd->dbufSize) { | ||||
| 				dbg("dbufCount:%u+runCnt:%u %u > dbufSize:%u RETVAL_DATA_ERROR", | ||||
| 						dbufCount, runCnt, dbufCount + runCnt, bd->dbufSize); | ||||
| 				return RETVAL_DATA_ERROR; | ||||
| 			} | ||||
| 			tmp_byte = symToByte[mtfSymbol[0]]; | ||||
| 			byteCount[tmp_byte] += runCnt; | ||||
| 			while (--runCnt >= 0) dbuf[dbufCount++] = (uint32_t)tmp_byte; | ||||
| 			while ((int)--runCnt >= 0) | ||||
| 				dbuf[dbufCount++] = (uint32_t)tmp_byte; | ||||
| 			runPos = 0; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -467,7 +489,7 @@ static int get_next_block(bunzip_data *bd) | |||
| 		   first symbol in the mtf array, position 0, would have been handled | ||||
| 		   as part of a run above.  Therefore 1 unused mtf position minus | ||||
| 		   2 non-literal nextSym values equals -1.) */ | ||||
| 		if (dbufCount >= dbufSize) return RETVAL_DATA_ERROR; | ||||
| 		if (dbufCount >= bd->dbufSize) return RETVAL_DATA_ERROR; | ||||
| 		i = nextSym - 1; | ||||
| 		uc = mtfSymbol[i]; | ||||
| 
 | ||||
|  | @ -507,7 +529,7 @@ static int get_next_block(bunzip_data *bd) | |||
| 	} | ||||
| 
 | ||||
| 	/* Figure out what order dbuf would be in if we sorted it. */ | ||||
| 	for (i = 0; i < dbufCount; i++) { | ||||
| 	for (i = 0; i < (int)dbufCount; i++) { | ||||
| 		uint8_t tmp_byte = (uint8_t)dbuf[i]; | ||||
| 		int tmp_count = byteCount[tmp_byte]; | ||||
| 		dbuf[tmp_count] |= (i << 8); | ||||
|  | @ -540,7 +562,7 @@ static int get_next_block(bunzip_data *bd) | |||
|    in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0. | ||||
|    (Why? This allows to get rid of one local variable) | ||||
| */ | ||||
| int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | ||||
| static int read_bunzip(bunzip_data *bd, char *outbuf, int len) | ||||
| { | ||||
| 	const uint32_t *dbuf; | ||||
| 	int pos, current, previous; | ||||
|  | @ -664,7 +686,10 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
| /* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
 | ||||
|    should work for NOFORK applets too, we must be extremely careful to not leak | ||||
|    any allocations! */ | ||||
| int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | ||||
| static int FAST_FUNC start_bunzip( | ||||
| 		void *jmpbuf, | ||||
| 		bunzip_data **bdp, | ||||
| 		int in_fd, | ||||
| 		const void *inbuf, int len) | ||||
| { | ||||
| 	bunzip_data *bd; | ||||
|  | @ -676,13 +701,16 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | |||
| 
 | ||||
| 	/* Figure out how much data to allocate */ | ||||
| 	i = sizeof(bunzip_data); | ||||
| 	if (in_fd != -1) i += IOBUF_SIZE; | ||||
| 	if (in_fd != -1) | ||||
| 		i += IOBUF_SIZE; | ||||
| 
 | ||||
| 	/* Allocate bunzip_data.  Most fields initialize to zero. */ | ||||
| 	bd = *bdp = xzalloc(i); | ||||
| 	if (bd == NULL) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	bd->jmpbuf = jmpbuf; | ||||
| 
 | ||||
| 	/* Setup input buffer */ | ||||
| 	bd->in_fd = in_fd; | ||||
| 	if (-1 == in_fd) { | ||||
|  | @ -697,10 +725,6 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | |||
| 	/* Init the CRC32 table (big endian) */ | ||||
| 	crc32_filltable(bd->crc32Table, 1); | ||||
| 
 | ||||
| 	/* Setup for I/O error handling via longjmp */ | ||||
| 	i = setjmp(bd->jmpbuf); | ||||
| 	if (i) return i; | ||||
| 
 | ||||
| 	/* Ensure that file starts with "BZh['1'-'9']." */ | ||||
| 	/* Update: now caller verifies 1st two bytes, makes .gz/.bz2
 | ||||
| 	 * integration easier */ | ||||
|  | @ -724,7 +748,7 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | |||
| 	return RETVAL_OK; | ||||
| } | ||||
| 
 | ||||
| void FAST_FUNC dealloc_bunzip(bunzip_data *bd) | ||||
| static void FAST_FUNC dealloc_bunzip(bunzip_data *bd) | ||||
| { | ||||
| 	free(bd->dbuf); | ||||
| 	free(bd); | ||||
|  | @ -749,8 +773,12 @@ unpack_bz2_stream(transformer_state_t *xstate) | |||
| 		return -1; | ||||
| 	len = 0; | ||||
| 	while (1) { /* "Process one BZ... stream" loop */ | ||||
| 		jmp_buf jmpbuf; | ||||
| 
 | ||||
| 		i = start_bunzip(&bd, xstate->src_fd, outbuf + 2, len); | ||||
| 		/* Setup for I/O error handling via longjmp */ | ||||
| 		i = setjmp(jmpbuf); | ||||
| 		if (i == 0) | ||||
| 			i = start_bunzip(&jmpbuf, &bd, xstate->src_fd, outbuf + 2, len); | ||||
| 
 | ||||
| 		if (i == 0) { | ||||
| 			while (1) { /* "Produce some output bytes" loop */ | ||||
|  | @ -781,7 +809,7 @@ unpack_bz2_stream(transformer_state_t *xstate) | |||
| 			break; | ||||
| 		} | ||||
| 		if (bd->headerCRC != bd->totalCRC) { | ||||
| 			bb_error_msg("CRC error"); | ||||
| 			bb_simple_error_msg("CRC error"); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -811,6 +839,36 @@ unpack_bz2_stream(transformer_state_t *xstate) | |||
| 	return i ? i : IF_DESKTOP(total_written) + 0; | ||||
| } | ||||
| 
 | ||||
| char* FAST_FUNC | ||||
| unpack_bz2_data(const char *packed, int packed_len, int unpacked_len) | ||||
| { | ||||
| 	char *outbuf = NULL; | ||||
| 	bunzip_data *bd; | ||||
| 	int i; | ||||
| 	jmp_buf jmpbuf; | ||||
| 
 | ||||
| 	/* Setup for I/O error handling via longjmp */ | ||||
| 	i = setjmp(jmpbuf); | ||||
| 	if (i == 0) { | ||||
| 		i = start_bunzip(&jmpbuf, | ||||
| 			&bd, | ||||
| 			/* src_fd: */ -1, | ||||
| 			/* inbuf:  */ packed, | ||||
| 			/* len:    */ packed_len | ||||
| 		); | ||||
| 	} | ||||
| 	/* read_bunzip can longjmp and end up here with i != 0
 | ||||
| 	 * on read data errors! Not trivial */ | ||||
| 	if (i == 0) { | ||||
| 		/* Cannot use xmalloc: will leak bd in NOFORK case! */ | ||||
| 		outbuf = malloc_or_warn(unpacked_len); | ||||
| 		if (outbuf) | ||||
| 			read_bunzip(bd, outbuf, unpacked_len); | ||||
| 	} | ||||
| 	dealloc_bunzip(bd); | ||||
| 	return outbuf; | ||||
| } | ||||
| 
 | ||||
| #ifdef TESTING | ||||
| 
 | ||||
| static char *const bunzip_errors[] = { | ||||
|  |  | |||
|  | @ -32,8 +32,6 @@ | |||
|  * | ||||
|  * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||||
|  */ | ||||
| 
 | ||||
| #include <setjmp.h> | ||||
| #include "libbb.h" | ||||
| #include "bb_archive.h" | ||||
| 
 | ||||
|  | @ -41,7 +39,8 @@ typedef struct huft_t { | |||
| 	unsigned char e;	/* number of extra bits or operation */ | ||||
| 	unsigned char b;	/* number of bits in this code or subcode */ | ||||
| 	union { | ||||
| 		unsigned short n;	/* literal, length base, or distance base */ | ||||
| 		unsigned n;	/* literal, length base, or distance base */ | ||||
| 		/* ^^^^^ was "unsigned short", but that results in larger code */ | ||||
| 		struct huft_t *t;	/* pointer to next level of table */ | ||||
| 	} v; | ||||
| } huft_t; | ||||
|  | @ -128,6 +127,8 @@ typedef struct state_t { | |||
| #define gunzip_bb           (S()gunzip_bb          ) | ||||
| #define gunzip_bk           (S()gunzip_bk          ) | ||||
| #define to_read             (S()to_read            ) | ||||
| // #define bytebuffer_max   (S()bytebuffer_max     )
 | ||||
| // Both gunzip and unzip can use constant buffer size now (16k):
 | ||||
| #define bytebuffer_max      BB_BUFSIZE | ||||
| #define bytebuffer          (S()bytebuffer         ) | ||||
| #define bytebuffer_offset   (S()bytebuffer_offset  ) | ||||
|  | @ -184,29 +185,26 @@ static const uint16_t mask_bits[] ALIGN2 = { | |||
| 	0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff | ||||
| }; | ||||
| 
 | ||||
| /* Copy lengths for literal codes 257..285 */ | ||||
| static const uint16_t cplens[] ALIGN2 = { | ||||
| 	3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, | ||||
| 	67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 | ||||
| /* Put lengths/offsets and extra bits in a struct of arrays
 | ||||
|  * to make calls to huft_build() have one fewer parameter. | ||||
|  */ | ||||
| struct cp_ext { | ||||
| 	uint16_t cp[31]; | ||||
| 	uint8_t ext[31]; | ||||
| }; | ||||
| 
 | ||||
| /* Copy lengths and extra bits for literal codes 257..285 */ | ||||
| /* note: see note #13 above about the 258 in this list. */ | ||||
| /* Extra bits for literal codes 257..285 */ | ||||
| static const uint8_t cplext[] ALIGN1 = { | ||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, | ||||
| 	5, 5, 5, 0, 99, 99 | ||||
| }; /* 99 == invalid */ | ||||
| 
 | ||||
| /* Copy offsets for distance codes 0..29 */ | ||||
| static const uint16_t cpdist[] ALIGN2 = { | ||||
| 	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, | ||||
| 	769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 | ||||
| static const struct cp_ext lit ALIGN2 = { | ||||
| 	/*257 258 259 260 261 262 263 264 265 266 267 268 269 270 271  272  273  274  275  276   277   278   279   280   281   282   283    284    285 */ | ||||
| 	/*0   1   2   3   4   5   6   7   8   9   10  11  12  13   14   15   16   17   18   19    20    21    22    23    24    25    26     27     28     29  30 */ | ||||
| 	{ 3,  4,  5,  6,  7,  8,  9,  10, 11, 13, 15, 17, 19, 23,  27,  31,  35,  43,  51,  59,   67,   83,   99,  115,  131,  163,  195,   227,   258,     0, 0  }, | ||||
| 	{ 0,  0,  0,  0,  0,  0,  0,   0,  1,  1,  1,  1,  2,  2,   2,   2,   3,   3,   3,   3,    4,    4,    4,    4,    5,    5,    5,     5,     0,    99, 99 } /* 99 == invalid */ | ||||
| }; | ||||
| 
 | ||||
| /* Extra bits for distance codes */ | ||||
| static const uint8_t cpdext[] ALIGN1 = { | ||||
| 	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, | ||||
| 	11, 11, 12, 12, 13, 13 | ||||
| /* Copy offsets and extra bits for distance codes 0..29 */ | ||||
| static const struct cp_ext dist ALIGN2 = { | ||||
| 	/*0   1   2   3   4   5   6   7   8   9   10  11  12  13   14   15   16   17   18   19    20    21    22    23    24    25    26     27     28     29 */ | ||||
| 	{ 1,  2,  3,  4,  5,  7,  9,  13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 }, | ||||
| 	{ 0,  0,  0,  0,  1,  1,  2,   2,  3,  3,  4,  4,  5,  5,   6,   6,   7,   7,   8,   8,    9,    9,   10,   10,   11,   11,   12,    12,    13,    13 } | ||||
| }; | ||||
| 
 | ||||
| /* Tables for deflate from PKZIP's appnote.txt. */ | ||||
|  | @ -222,10 +220,19 @@ static const uint8_t border[] ALIGN1 = { | |||
|  * each table. | ||||
|  * t: table to free | ||||
|  */ | ||||
| #define BAD_HUFT(p) ((uintptr_t)(p) & 1) | ||||
| #define ERR_RET     ((huft_t*)(uintptr_t)1) | ||||
| static void huft_free(huft_t *p) | ||||
| { | ||||
| 	huft_t *q; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If 'p' has the error bit set we have to clear it, otherwise we might run | ||||
| 	 * into a segmentation fault or an invalid pointer to free(p) | ||||
| 	 */ | ||||
| 	//if (BAD_HUFT(p)) // commented out, since bit clearing has effect only if condition is true
 | ||||
| 		p = (huft_t*)((uintptr_t)p & ~(uintptr_t)ERR_RET); | ||||
| 
 | ||||
| 	/* Go through linked list, freeing from the malloced (t[-1]) address. */ | ||||
| 	while (p) { | ||||
| 		q = (--p)->v.t; | ||||
|  | @ -277,22 +284,23 @@ static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current | |||
| 
 | ||||
| 
 | ||||
| /* Given a list of code lengths and a maximum table size, make a set of
 | ||||
|  * tables to decode that set of codes.  Return zero on success, one if | ||||
|  * the given code set is incomplete (the tables are still built in this | ||||
|  * case), two if the input is invalid (all zero length codes or an | ||||
|  * oversubscribed set of lengths) - in this case stores NULL in *t. | ||||
|  * tables to decode that set of codes. | ||||
|  * | ||||
|  * b:	code lengths in bits (all assumed <= BMAX) | ||||
|  * n:	number of codes (assumed <= N_MAX) | ||||
|  * s:	number of simple-valued codes (0..s-1) | ||||
|  * d:	list of base values for non-simple codes | ||||
|  * e:	list of extra bits for non-simple codes | ||||
|  * t:	result: starting table | ||||
|  * cp_ext->cp,ext: list of base values/extra bits for non-simple codes | ||||
|  * m:	maximum lookup bits, returns actual | ||||
|  * result: starting table | ||||
|  * | ||||
|  * On error, returns a value with lowest-bit set on error. | ||||
|  * It can be just the value of 0x1, | ||||
|  * or a valid pointer to a Huffman table, ORed with 0x1 if incompete table | ||||
|  * is given: "fixed inflate" decoder feeds us such data. | ||||
|  */ | ||||
| static int huft_build(const unsigned *b, const unsigned n, | ||||
| 			const unsigned s, const unsigned short *d, | ||||
| 			const unsigned char *e, huft_t **t, unsigned *m) | ||||
| static huft_t* huft_build(const unsigned *b, const unsigned n, | ||||
| 			const unsigned s, const struct cp_ext *cp_ext, | ||||
| 			unsigned *m) | ||||
| { | ||||
| 	unsigned a;             /* counter for codes of length k */ | ||||
| 	unsigned c[BMAX + 1];   /* bit length count table */ | ||||
|  | @ -303,34 +311,42 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
| 	unsigned i;             /* counter, current code */ | ||||
| 	unsigned j;             /* counter */ | ||||
| 	int k;                  /* number of bits in current code */ | ||||
| 	unsigned *p;            /* pointer into c[], b[], or v[] */ | ||||
| 	const unsigned *p;      /* pointer into c[], b[], or v[] */ | ||||
| 	huft_t *q;              /* points to current table */ | ||||
| 	huft_t r;               /* table entry for structure assignment */ | ||||
| 	huft_t *u[BMAX];        /* table stack */ | ||||
| 	unsigned v[N_MAX];      /* values in order of bit length */ | ||||
| 	unsigned v[N_MAX + 1];  /* values in order of bit length. last v[] is never used */ | ||||
| 	int ws[BMAX + 1];       /* bits decoded stack */ | ||||
| 	int w;                  /* bits decoded */ | ||||
| 	unsigned x[BMAX + 1];   /* bit offsets, then code stack */ | ||||
| 	unsigned *xp;           /* pointer into x */ | ||||
| 	int y;                  /* number of dummy codes added */ | ||||
| 	unsigned z;             /* number of entries in current table */ | ||||
| 	huft_t *result; | ||||
| 	huft_t **t; | ||||
| 
 | ||||
| 	/* Length of EOB code, if any */ | ||||
| 	eob_len = n > 256 ? b[256] : BMAX; | ||||
| 
 | ||||
| 	*t = NULL; | ||||
| 	memset(&r, 0, sizeof(r)); | ||||
| 
 | ||||
| 	/* Generate counts for each bit length */ | ||||
| 	memset(c, 0, sizeof(c)); | ||||
| 	p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */ | ||||
| 	p = b; | ||||
| 	i = n; | ||||
| 	do { | ||||
| 		c[*p]++; /* assume all entries <= BMAX */ | ||||
| 		p++;     /* can't combine with above line (Solaris bug) */ | ||||
| 	} while (--i); | ||||
| 	if (c[0] == n) {  /* null input - all zero length codes */ | ||||
| 		*m = 0; | ||||
| 		return 2; | ||||
| 		q = xzalloc(3 * sizeof(*q)); | ||||
| 		//q[0].v.t = NULL;
 | ||||
| 		q[1].e = 99;    /* invalid code marker */ | ||||
| 		q[1].b = 1; | ||||
| 		q[2].e = 99;    /* invalid code marker */ | ||||
| 		q[2].b = 1; | ||||
| 		*m = 1; | ||||
| 		return q + 1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Find minimum and maximum length, bound *m by those */ | ||||
|  | @ -346,11 +362,11 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
| 	for (y = 1 << j; j < i; j++, y <<= 1) { | ||||
| 		y -= c[j]; | ||||
| 		if (y < 0) | ||||
| 			return 2; /* bad input: more codes than bits */ | ||||
| 			return ERR_RET; /* bad input: more codes than bits */ | ||||
| 	} | ||||
| 	y -= c[i]; | ||||
| 	if (y < 0) | ||||
| 		return 2; | ||||
| 		return ERR_RET; | ||||
| 	c[i] += y; | ||||
| 
 | ||||
| 	/* Generate starting offsets into the value table for each length */ | ||||
|  | @ -362,8 +378,12 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
| 		*xp++ = j; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Make a table of values in order of bit lengths */ | ||||
| 	p = (unsigned *) b; | ||||
| 	/* Make a table of values in order of bit lengths.
 | ||||
| 	 * To detect bad input, unused v[i]'s are set to invalid value UINT_MAX. | ||||
| 	 * In particular, last v[i] is never filled and must not be accessed. | ||||
| 	 */ | ||||
| 	memset(v, 0xff, sizeof(v)); | ||||
| 	p = b; | ||||
| 	i = 0; | ||||
| 	do { | ||||
| 		j = *p++; | ||||
|  | @ -373,6 +393,8 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
| 	} while (++i < n); | ||||
| 
 | ||||
| 	/* Generate the Huffman codes and for each, make the table entries */ | ||||
| 	result = ERR_RET; | ||||
| 	t = &result; | ||||
| 	x[0] = i = 0;   /* first Huffman code is zero */ | ||||
| 	p = v;          /* grab values in bit order */ | ||||
| 	htl = -1;       /* no tables yet--level -1 */ | ||||
|  | @ -430,14 +452,16 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
| 
 | ||||
| 			/* set up table entry in r */ | ||||
| 			r.b = (unsigned char) (k - w); | ||||
| 			if (p >= v + n) { | ||||
| 			if (/*p >= v + n || -- redundant, caught by the second check: */ | ||||
| 				*p == UINT_MAX /* do we access uninited v[i]? (see memset(v))*/ | ||||
| 			) { | ||||
| 				r.e = 99; /* out of values--invalid code */ | ||||
| 			} else if (*p < s) { | ||||
| 				r.e = (unsigned char) (*p < 256 ? 16 : 15);	/* 256 is EOB code */ | ||||
| 				r.v.n = (unsigned short) (*p++); /* simple code is just the value */ | ||||
| 			} else { | ||||
| 				r.e = (unsigned char) e[*p - s]; /* non-simple--look up in lists */ | ||||
| 				r.v.n = d[*p++ - s]; | ||||
| 				r.e = (unsigned char) cp_ext->ext[*p - s]; /* non-simple--look up in lists */ | ||||
| 				r.v.n = cp_ext->cp[*p++ - s]; | ||||
| 			} | ||||
| 
 | ||||
| 			/* fill code-like entries with r */ | ||||
|  | @ -462,8 +486,11 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
| 	/* return actual size of base table */ | ||||
| 	*m = ws[1]; | ||||
| 
 | ||||
| 	/* Return 1 if we were given an incomplete table */ | ||||
| 	return y != 0 && g != 1; | ||||
| 	if (y != 0 && g != 1) /* we were given an incomplete table */ | ||||
| 		/* return "result" ORed with 1 */ | ||||
| 		return (void*)((uintptr_t)result | 1); | ||||
| 
 | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -515,8 +542,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) | |||
| 		e = t->e; | ||||
| 		if (e > 16) | ||||
| 			do { | ||||
| 				if (e == 99) | ||||
| 					abort_unzip(PASS_STATE_ONLY);; | ||||
| 				if (e == 99) { | ||||
| 					abort_unzip(PASS_STATE_ONLY); | ||||
| 				} | ||||
| 				bb >>= t->b; | ||||
| 				k -= t->b; | ||||
| 				e -= 16; | ||||
|  | @ -552,8 +580,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) | |||
| 			e = t->e; | ||||
| 			if (e > 16) | ||||
| 				do { | ||||
| 					if (e == 99) | ||||
| 					if (e == 99) { | ||||
| 						abort_unzip(PASS_STATE_ONLY); | ||||
| 					} | ||||
| 					bb >>= t->b; | ||||
| 					k -= t->b; | ||||
| 					e -= 16; | ||||
|  | @ -762,14 +791,17 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
| 		for (; i < 288; i++) /* make a complete, but wrong code set */ | ||||
| 			ll[i] = 8; | ||||
| 		bl = 7; | ||||
| 		huft_build(ll, 288, 257, cplens, cplext, &inflate_codes_tl, &bl); | ||||
| 		/* huft_build() never return nonzero - we use known data */ | ||||
| 		inflate_codes_tl = huft_build(ll, 288, 257, &lit, &bl); | ||||
| 		/* ^^^ never returns error here - we use known data */ | ||||
| 
 | ||||
| 		/* set up distance table */ | ||||
| 		for (i = 0; i < 30; i++) /* make an incomplete code set */ | ||||
| 			ll[i] = 5; | ||||
| 		bd = 5; | ||||
| 		huft_build(ll, 30, 0, cpdist, cpdext, &inflate_codes_td, &bd); | ||||
| 		inflate_codes_td = huft_build(ll, 30, 0, &dist, &bd); | ||||
| 		/* ^^^ does return error here! (lsb bit is set) - we gave it incomplete code set */ | ||||
| 		/* clearing error bit: */ | ||||
| 		inflate_codes_td = (void*)((uintptr_t)inflate_codes_td & ~(uintptr_t)1); | ||||
| 
 | ||||
| 		/* set up data for inflate_codes() */ | ||||
| 		inflate_codes_setup(PASS_STATE bl, bd); | ||||
|  | @ -819,8 +851,9 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
| 
 | ||||
| 		b_dynamic >>= 4; | ||||
| 		k_dynamic -= 4; | ||||
| 		if (nl > 286 || nd > 30) | ||||
| 		if (nl > 286 || nd > 30) { | ||||
| 			abort_unzip(PASS_STATE_ONLY);	/* bad lengths */ | ||||
| 		} | ||||
| 
 | ||||
| 		/* read in bit-length-code lengths */ | ||||
| 		for (j = 0; j < nb; j++) { | ||||
|  | @ -834,9 +867,9 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
| 
 | ||||
| 		/* build decoding table for trees - single level, 7 bit lookup */ | ||||
| 		bl = 7; | ||||
| 		i = huft_build(ll, 19, 19, NULL, NULL, &inflate_codes_tl, &bl); | ||||
| 		if (i != 0) { | ||||
| 			abort_unzip(PASS_STATE_ONLY); //return i;	/* incomplete code set */
 | ||||
| 		inflate_codes_tl = huft_build(ll, 19, 19, NULL, &bl); | ||||
| 		if (BAD_HUFT(inflate_codes_tl)) { | ||||
| 			abort_unzip(PASS_STATE_ONLY);	/* incomplete code set */ | ||||
| 		} | ||||
| 
 | ||||
| 		/* read in literal and distance code lengths */ | ||||
|  | @ -899,14 +932,15 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
| 
 | ||||
| 		/* build the decoding tables for literal/length and distance codes */ | ||||
| 		bl = lbits; | ||||
| 
 | ||||
| 		i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl); | ||||
| 		if (i != 0) | ||||
| 		inflate_codes_tl = huft_build(ll, nl, 257, &lit, &bl); | ||||
| 		if (BAD_HUFT(inflate_codes_tl)) { | ||||
| 			abort_unzip(PASS_STATE_ONLY); | ||||
| 		} | ||||
| 		bd = dbits; | ||||
| 		i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd); | ||||
| 		if (i != 0) | ||||
| 		inflate_codes_td = huft_build(ll + nl, nd, 0, &dist, &bd); | ||||
| 		if (BAD_HUFT(inflate_codes_td)) { | ||||
| 			abort_unzip(PASS_STATE_ONLY); | ||||
| 		} | ||||
| 
 | ||||
| 		/* set up data for inflate_codes() */ | ||||
| 		inflate_codes_setup(PASS_STATE bl, bd); | ||||
|  | @ -976,7 +1010,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate) | |||
| 	ssize_t nwrote; | ||||
| 
 | ||||
| 	/* Allocate all global buffers (for DYN_ALLOC option) */ | ||||
| 	gunzip_window = xmalloc(GUNZIP_WSIZE); | ||||
| 	gunzip_window = xzalloc(GUNZIP_WSIZE); | ||||
| 	gunzip_outbuf_count = 0; | ||||
| 	gunzip_bytes_out = 0; | ||||
| 	gunzip_src_fd = xstate->src_fd; | ||||
|  | @ -995,6 +1029,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate) | |||
| 	error_msg = "corrupted data"; | ||||
| 	if (setjmp(error_jmp)) { | ||||
| 		/* Error from deep inside zip machinery */ | ||||
| 		bb_simple_error_msg("corrupted data"); | ||||
| 		n = -1; | ||||
| 		goto ret; | ||||
| 	} | ||||
|  | @ -1070,7 +1105,7 @@ static int top_up(STATE_PARAM unsigned n) | |||
| 		bytebuffer_offset = 0; | ||||
| 		bytebuffer_size = full_read(gunzip_src_fd, &bytebuffer[count], bytebuffer_max - count); | ||||
| 		if ((int)bytebuffer_size < 0) { | ||||
| 			bb_error_msg(bb_msg_read_error); | ||||
| 			bb_simple_error_msg(bb_msg_read_error); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		bytebuffer_size += count; | ||||
|  | @ -1122,9 +1157,8 @@ static int check_header_gzip(STATE_PARAM transformer_state_t *xstate) | |||
| 		} PACKED formatted; | ||||
| 	} header; | ||||
| 	PRAGMA_END_PACKED | ||||
| 	struct BUG_header { | ||||
| 		char BUG_header[sizeof(header) == 8 ? 1 : -1]; | ||||
| 	}; | ||||
| 
 | ||||
| 	BUILD_BUG_ON(sizeof(header) != 8); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Rewind bytebuffer. We use the beginning because the header has 8 | ||||
|  | @ -1165,6 +1199,7 @@ static int check_header_gzip(STATE_PARAM transformer_state_t *xstate) | |||
| 			do { | ||||
| 				if (!top_up(PASS_STATE 1)) | ||||
| 					return 0; | ||||
| 			// coverity[tainted_data]
 | ||||
| 			} while (bytebuffer[bytebuffer_offset++] != 0); | ||||
| 			if ((header.formatted.flags & 0x18) != 0x18) | ||||
| 				break; | ||||
|  | @ -1194,16 +1229,16 @@ unpack_gz_stream(transformer_state_t *xstate) | |||
| 	if (check_signature16(xstate, GZIP_MAGIC)) | ||||
| 		return -1; | ||||
| #else | ||||
| 	if (xstate->check_signature) { | ||||
| 	if (!xstate->signature_skipped) { | ||||
| 		uint16_t magic2; | ||||
| 
 | ||||
| 		if (full_read(xstate->src_fd, &magic2, 2) != 2) { | ||||
|  bad_magic: | ||||
| 			bb_error_msg("invalid magic"); | ||||
| 			bb_simple_error_msg("invalid magic"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		if (magic2 == COMPRESS_MAGIC) { | ||||
| 			xstate->check_signature = 0; | ||||
| 			xstate->signature_skipped = 2; | ||||
| 			return unpack_Z_stream(xstate); | ||||
| 		} | ||||
| 		if (magic2 != GZIP_MAGIC) | ||||
|  | @ -1230,7 +1265,7 @@ unpack_gz_stream(transformer_state_t *xstate) | |||
| 
 | ||||
|  again: | ||||
| 	if (!check_header_gzip(PASS_STATE xstate)) { | ||||
| 		bb_error_msg("corrupted data"); | ||||
| 		bb_simple_error_msg("corrupted data"); | ||||
| 		total = -1; | ||||
| 		goto ret; | ||||
| 	} | ||||
|  | @ -1243,7 +1278,7 @@ unpack_gz_stream(transformer_state_t *xstate) | |||
| 	total += n; | ||||
| 
 | ||||
| 	if (!top_up(PASS_STATE 8)) { | ||||
| 		bb_error_msg("corrupted data"); | ||||
| 		bb_simple_error_msg("corrupted data"); | ||||
| 		total = -1; | ||||
| 		goto ret; | ||||
| 	} | ||||
|  | @ -1251,7 +1286,7 @@ unpack_gz_stream(transformer_state_t *xstate) | |||
| 	/* Validate decompression - crc */ | ||||
| 	v32 = buffer_read_le_u32(PASS_STATE_ONLY); | ||||
| 	if ((~gunzip_crc) != v32) { | ||||
| 		bb_error_msg("crc error"); | ||||
| 		bb_simple_error_msg("crc error"); | ||||
| 		total = -1; | ||||
| 		goto ret; | ||||
| 	} | ||||
|  | @ -1259,7 +1294,7 @@ unpack_gz_stream(transformer_state_t *xstate) | |||
| 	/* Validate decompression - size */ | ||||
| 	v32 = buffer_read_le_u32(PASS_STATE_ONLY); | ||||
| 	if ((uint32_t)gunzip_bytes_out != v32) { | ||||
| 		bb_error_msg("incorrect length"); | ||||
| 		bb_simple_error_msg("incorrect length"); | ||||
| 		total = -1; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| /* vi: set sw=4 ts=4: */ | ||||
| /* uncompress for busybox -- (c) 2002 Robert Griebl
 | ||||
| /*
 | ||||
|  * uncompress for busybox -- (c) 2002 Robert Griebl | ||||
|  * | ||||
|  * based on the original compress42.c source | ||||
|  * (see disclaimer below) | ||||
|  */ | ||||
| 
 | ||||
| /* (N)compress42.c - File compression ala IEEE Computer, Mar 1992.
 | ||||
|  * | ||||
|  * Authors: | ||||
|  | @ -21,9 +21,7 @@ | |||
|  * marc@suse.de : a small security fix for a buffer overflow | ||||
|  * | ||||
|  * [... History snipped ...] | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "libbb.h" | ||||
| #include "bb_archive.h" | ||||
| 
 | ||||
|  | @ -115,7 +113,7 @@ unpack_Z_stream(transformer_state_t *xstate) | |||
| 	/* xread isn't good here, we have to return - caller may want
 | ||||
| 	 * to do some cleanup (e.g. delete incomplete unpacked file etc) */ | ||||
| 	if (full_read(xstate->src_fd, inbuf, 1) != 1) { | ||||
| 		bb_error_msg("short read"); | ||||
| 		bb_simple_error_msg("short read"); | ||||
| 		goto err; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -168,7 +166,7 @@ unpack_Z_stream(transformer_state_t *xstate) | |||
| 		if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { | ||||
| 			rsize = safe_read(xstate->src_fd, inbuf + insize, IBUFSIZ); | ||||
| 			if (rsize < 0) | ||||
| 				bb_error_msg_and_err(bb_msg_read_error); | ||||
| 				bb_simple_error_msg_and_die(bb_msg_read_error); | ||||
| 			insize += rsize; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -202,7 +200,7 @@ unpack_Z_stream(transformer_state_t *xstate) | |||
| 
 | ||||
| 			if (oldcode == -1) { | ||||
| 				if (code >= 256) | ||||
| 					bb_error_msg_and_err("corrupted data"); /* %ld", code); */ | ||||
| 					bb_simple_error_msg_and_die("corrupted data"); /* %ld", code); */ | ||||
| 				oldcode = code; | ||||
| 				finchar = (int) oldcode; | ||||
| 				outbuf[outpos++] = (unsigned char) finchar; | ||||
|  | @ -238,7 +236,7 @@ unpack_Z_stream(transformer_state_t *xstate) | |||
| 						insize, posbits, p[-1], p[0], p[1], p[2], p[3], | ||||
| 						(posbits & 07)); | ||||
| */ | ||||
| 					bb_error_msg("corrupted data"); | ||||
| 					bb_simple_error_msg("corrupted data"); | ||||
| 					goto err; | ||||
| 				} | ||||
| 
 | ||||
|  | @ -249,7 +247,7 @@ unpack_Z_stream(transformer_state_t *xstate) | |||
| 			/* Generate output characters in reverse order */ | ||||
| 			while (code >= 256) { | ||||
| 				if (stackp <= &htabof(0)) | ||||
| 					bb_error_msg_and_err("corrupted data"); | ||||
| 					bb_simple_error_msg_and_die("corrupted data"); | ||||
| 				*--stackp = tab_suffixof(code); | ||||
| 				code = tab_prefixof(code); | ||||
| 			} | ||||
|  | @ -301,7 +299,6 @@ unpack_Z_stream(transformer_state_t *xstate) | |||
| 			/* Remember previous code.  */ | ||||
| 			oldcode = incode; | ||||
| 		} | ||||
| 
 | ||||
| 	} while (rsize > 0); | ||||
| 
 | ||||
| 	if (outpos > 0) { | ||||
|  |  | |||
|  | @ -11,6 +11,13 @@ | |||
| #include "libbb.h" | ||||
| #include "bb_archive.h" | ||||
| 
 | ||||
| #if 0 | ||||
| # define dbg(...) bb_error_msg(__VA_ARGS__) | ||||
| #else | ||||
| # define dbg(...) ((void)0) | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #if ENABLE_FEATURE_LZMA_FAST | ||||
| #  define speed_inline ALWAYS_INLINE | ||||
| #  define size_inline | ||||
|  | @ -52,7 +59,7 @@ static void rc_read(rc_t *rc) | |||
| //TODO: return -1 instead
 | ||||
| //This will make unlzma delete broken unpacked file on unpack errors
 | ||||
| 	if (buffer_size <= 0) | ||||
| 		bb_error_msg_and_die("unexpected EOF"); | ||||
| 		bb_simple_error_msg_and_die("unexpected EOF"); | ||||
| 	rc->buffer_end = RC_BUFFER + buffer_size; | ||||
| 	rc->ptr = RC_BUFFER; | ||||
| } | ||||
|  | @ -220,9 +227,10 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
| 	rc_t *rc; | ||||
| 	int i; | ||||
| 	uint8_t *buffer; | ||||
| 	uint32_t buffer_size; | ||||
| 	uint8_t previous_byte = 0; | ||||
| 	size_t buffer_pos = 0, global_pos = 0; | ||||
| 	ssize_t nwrote; | ||||
| 	ssize_t nwrote = 0; | ||||
| 	int len = 0; | ||||
| 	int state = 0; | ||||
| 	uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; | ||||
|  | @ -230,7 +238,7 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
| 	if (full_read(xstate->src_fd, &header, sizeof(header)) != sizeof(header) | ||||
| 	 || header.pos >= (9 * 5 * 5) | ||||
| 	) { | ||||
| 		bb_error_msg("bad lzma header"); | ||||
| 		bb_simple_error_msg("bad lzma header"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -250,7 +258,8 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
| 	if (header.dict_size == 0) | ||||
| 		header.dict_size++; | ||||
| 
 | ||||
| 	buffer = xmalloc((size_t)MIN(header.dst_size, header.dict_size)); | ||||
| 	buffer_size = (uint32_t)MIN(header.dst_size, header.dict_size); | ||||
| 	buffer = xmalloc(buffer_size); | ||||
| 
 | ||||
| 	{ | ||||
| 		int num_probs; | ||||
|  | @ -267,14 +276,14 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
| 	while ((uint64_t)global_pos + buffer_pos < header.dst_size) { | ||||
| 		int pos_state = (buffer_pos + global_pos) & pos_state_mask; | ||||
| 		uintptr_t off1 = LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state; | ||||
| 		uint16_t *prob1 = p + off1; | ||||
| 		uint16_t *prob = p + off1; | ||||
| 
 | ||||
| 		if (!rc_is_bit_1(rc, prob1)) { | ||||
| 		if (!rc_is_bit_1(rc, prob)) { | ||||
| 			static const char next_state[LZMA_NUM_STATES] = | ||||
| 				{ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; | ||||
| 			int mi = 1; | ||||
| 
 | ||||
| 			prob1 = (p + LZMA_LITERAL | ||||
| 			prob = (p + LZMA_LITERAL | ||||
| 			        + (LZMA_LIT_SIZE * ((((buffer_pos + global_pos) & literal_pos_mask) << lc) | ||||
| 			                            + (previous_byte >> (8 - lc)) | ||||
| 			                           ) | ||||
|  | @ -283,23 +292,27 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
| 
 | ||||
| 			if (state >= LZMA_NUM_LIT_STATES) { | ||||
| 				int match_byte; | ||||
| 				uint32_t pos = (uint32_t)(buffer_pos - rep0); | ||||
| 				uint32_t pos; | ||||
| 
 | ||||
| 				while (pos >= header.dict_size) | ||||
| 				pos = (uint32_t)(buffer_pos - rep0); | ||||
| 				if ((int32_t)pos < 0) { | ||||
| 					pos += header.dict_size; | ||||
| 					if ((int32_t)pos < 0) | ||||
| 						goto bad; | ||||
| 				} | ||||
| 				match_byte = buffer[pos]; | ||||
| 				do { | ||||
| 					int bit; | ||||
| 
 | ||||
| 					match_byte <<= 1; | ||||
| 					bit = match_byte & 0x100; | ||||
| 					bit ^= (rc_get_bit(rc, prob1 + 0x100 + bit + mi, &mi) << 8); /* 0x100 or 0 */ | ||||
| 					bit ^= (rc_get_bit(rc, prob + 0x100 + bit + mi, &mi) << 8); /* 0x100 or 0 */ | ||||
| 					if (bit) | ||||
| 						break; | ||||
| 				} while (mi < 0x100); | ||||
| 			} | ||||
| 			while (mi < 0x100) { | ||||
| 				rc_get_bit(rc, prob1 + mi, &mi); | ||||
| 				rc_get_bit(rc, prob + mi, &mi); | ||||
| 			} | ||||
| 
 | ||||
| 			state = next_state[state]; | ||||
|  | @ -336,14 +349,24 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
| 			} else { | ||||
| 				prob2 += LZMA_IS_REP_G0 - LZMA_IS_REP; | ||||
| 				if (!rc_is_bit_1(rc, prob2)) { | ||||
| 					uintptr_t off2 = LZMA_IS_REP_0_LONG + (state << LZMA_NUM_POS_BITS_MAX) + pos_state; | ||||
| 					prob2 = p + off2; | ||||
| 					prob2 = (p + LZMA_IS_REP_0_LONG | ||||
| 					        + (state << LZMA_NUM_POS_BITS_MAX) | ||||
| 					        + pos_state | ||||
| 					); | ||||
| 					if (!rc_is_bit_1(rc, prob2)) { | ||||
| #if ENABLE_FEATURE_LZMA_FAST | ||||
| 						uint32_t pos = buffer_pos - rep0; | ||||
| 						uint32_t pos; | ||||
| 						state = state < LZMA_NUM_LIT_STATES ? 9 : 11; | ||||
| 						while (pos >= header.dict_size) | ||||
| 
 | ||||
| 						pos = buffer_pos - rep0; | ||||
| 						if ((int32_t)pos < 0) { | ||||
| 							pos += header.dict_size; | ||||
| 							/* see unzip_bad_lzma_2.zip: */ | ||||
| 							if (pos >= buffer_size) { | ||||
| 								dbg("%d pos:%d buffer_size:%d", __LINE__, pos, buffer_size); | ||||
| 								goto bad; | ||||
| 							} | ||||
| 						} | ||||
| 						previous_byte = buffer[pos]; | ||||
| 						goto one_byte1; | ||||
| #else | ||||
|  | @ -418,6 +441,9 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
| 						for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--) | ||||
| 							rep0 = (rep0 << 1) | rc_direct_bit(rc); | ||||
| 						rep0 <<= LZMA_NUM_ALIGN_BITS; | ||||
| 						// Note: (int32_t)rep0 may be < 0 here
 | ||||
| 						// (I have linux-3.3.4.tar.lzma which has it).
 | ||||
| 						// I moved the check after "++rep0 == 0" check below.
 | ||||
| 						prob3 = p + LZMA_ALIGN; | ||||
| 					} | ||||
| 					i2 = 1; | ||||
|  | @ -428,16 +454,43 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
| 						i2 <<= 1; | ||||
| 					} | ||||
| 				} | ||||
| 				if (++rep0 == 0) | ||||
| 				rep0++; | ||||
| 				if ((int32_t)rep0 <= 0) { | ||||
| 					if (rep0 == 0) | ||||
| 						break; | ||||
| 					dbg("%d rep0:%d", __LINE__, rep0); | ||||
| 					goto bad; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			len += LZMA_MATCH_MIN_LEN; | ||||
| 			/*
 | ||||
| 			 * LZMA SDK has this optimized: | ||||
| 			 * it precalculates size and copies many bytes | ||||
| 			 * in a loop with simpler checks, a-la: | ||||
| 			 *	do | ||||
| 			 *		*(dest) = *(dest + ofs); | ||||
| 			 *	while (++dest != lim); | ||||
| 			 * and | ||||
| 			 *	do { | ||||
| 			 *		buffer[buffer_pos++] = buffer[pos]; | ||||
| 			 *		if (++pos == header.dict_size) | ||||
| 			 *			pos = 0; | ||||
| 			 *	} while (--cur_len != 0); | ||||
| 			 * Our code is slower (more checks per byte copy): | ||||
| 			 */ | ||||
|  IF_NOT_FEATURE_LZMA_FAST(string:) | ||||
| 			do { | ||||
| 				uint32_t pos = (uint32_t)(buffer_pos - rep0); | ||||
| 				while (pos >= header.dict_size) | ||||
| 				if ((int32_t)pos < 0) { | ||||
| 					pos += header.dict_size; | ||||
| 					/* bug 10436 has an example file where this triggers: */ | ||||
| 					//if ((int32_t)pos < 0)
 | ||||
| 					//	goto bad;
 | ||||
| 					/* more stringent test (see unzip_bad_lzma_1.zip): */ | ||||
| 					if (pos >= buffer_size) | ||||
| 						goto bad; | ||||
| 				} | ||||
| 				previous_byte = buffer[pos]; | ||||
|  IF_NOT_FEATURE_LZMA_FAST(one_byte2:) | ||||
| 				buffer[buffer_pos++] = previous_byte; | ||||
|  | @ -453,6 +506,9 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
| 			} while (len != 0 && buffer_pos < header.dst_size); | ||||
| 			/* FIXME: ...........^^^^^
 | ||||
| 			 * shouldn't it be "global_pos + buffer_pos < header.dst_size"? | ||||
| 			 * It probably should, but it is a "do we accidentally | ||||
| 			 * unpack more bytes than expected?" check - which | ||||
| 			 * never happens for well-formed compression data... | ||||
| 			 */ | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -312,6 +312,7 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_zip_stream(transformer_state_t *xstat | |||
| 			xstate->dst_size = zip_header.formatted.ucmpsize; | ||||
| 			xstate->dst_name = xzalloc(zip_header.formatted.filename_len + 1); | ||||
| 			safe_read(xstate->src_fd, xstate->dst_name, zip_header.formatted.filename_len); | ||||
| 			xstate->dst_name[zip_header.formatted.filename_len] = 0; | ||||
| 			n = transformer_switch_file(xstate); | ||||
| 			free(xstate->dst_name); | ||||
| 			if (n < 0) | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ | |||
| /*
 | ||||
|  * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||||
|  */ | ||||
| 
 | ||||
| #include "libbb.h" | ||||
| #include "bb_archive.h" | ||||
| 
 | ||||
|  | @ -12,6 +11,7 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header) | |||
| 	struct tm *ptm = &tm_time; //localtime(&file_header->mtime);
 | ||||
| 
 | ||||
| #if ENABLE_FEATURE_TAR_UNAME_GNAME | ||||
| 	char modestr[12]; | ||||
| 	char uid[sizeof(int)*3 + 2]; | ||||
| 	/*char gid[sizeof(int)*3 + 2];*/ | ||||
| 	char *user; | ||||
|  | @ -30,7 +30,7 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header) | |||
| 		group = utoa(file_header->gid); | ||||
| 	} | ||||
| 	printf("%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s", | ||||
| 		bb_mode_string(file_header->mode), | ||||
| 		bb_mode_string(modestr, file_header->mode), | ||||
| 		user, | ||||
| 		group, | ||||
| 		file_header->size, | ||||
|  | @ -47,7 +47,7 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header) | |||
| 	localtime_r(&file_header->mtime, ptm); | ||||
| 
 | ||||
| 	printf("%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s", | ||||
| 		bb_mode_string(file_header->mode), | ||||
| 		bb_mode_string(modestr, file_header->mode), | ||||
| 		(unsigned)file_header->uid, | ||||
| 		(unsigned)file_header->gid, | ||||
| 		file_header->size, | ||||
|  |  | |||
|  | @ -52,7 +52,7 @@ | |||
| #define IF_NOT_FEATURE_LZMA_FAST(x) x | ||||
| 
 | ||||
| #define uoff_t unsigned off_t | ||||
| #define OFF_FMT "I64" | ||||
| #define OFF_FMT PRIi64 | ||||
| 
 | ||||
| #ifndef _MODE_T_ | ||||
| #define _MODE_T_ | ||||
|  | @ -86,6 +86,8 @@ typedef unsigned int uid_t; | |||
| #define PATH_MAX MAX_PATH | ||||
| #endif | ||||
| 
 | ||||
| #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) | ||||
| 
 | ||||
| #ifndef get_le64 | ||||
| #define get_le64(ptr) (*(const uint64_t *)(ptr)) | ||||
| #endif | ||||
|  | @ -146,6 +148,9 @@ extern unsigned long* bled_cancel_request; | |||
| #define bb_error_msg_and_err(...) do {bb_error_msg(__VA_ARGS__); goto err;} while(0) | ||||
| #define bb_perror_msg bb_error_msg | ||||
| #define bb_perror_msg_and_die bb_error_msg_and_die | ||||
| #define bb_simple_error_msg bb_error_msg | ||||
| #define bb_simple_perror_msg_and_die bb_error_msg_and_die | ||||
| #define bb_simple_error_msg_and_die bb_error_msg_and_die | ||||
| #define bb_putchar putchar | ||||
| 
 | ||||
| static inline void *xrealloc(void *ptr, size_t size) { | ||||
|  | @ -157,7 +162,7 @@ static inline void *xrealloc(void *ptr, size_t size) { | |||
| 
 | ||||
| #define bb_msg_read_error "read error" | ||||
| #define bb_msg_write_error "write error" | ||||
| #define bb_mode_string(mode) "[not implemented]" | ||||
| #define bb_mode_string(str, mode) "[not implemented]" | ||||
| #define bb_copyfd_exact_size(fd1, fd2, size) bb_error_msg("Not implemented") | ||||
| #define bb_make_directory(path, mode, flags) SHCreateDirectoryExU(NULL, path, NULL) | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ void FAST_FUNC init_transformer_state(transformer_state_t *xstate) | |||
| 
 | ||||
| int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16) | ||||
| { | ||||
| 	if (xstate->check_signature) { | ||||
| 	if (!xstate->signature_skipped) { | ||||
| 		uint16_t magic2; | ||||
| 		if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) { | ||||
| 			bb_error_msg("invalid magic"); | ||||
|  |  | |||
|  | @ -486,11 +486,11 @@ static __always_inline void XZ_FUNC rc_normalize(struct rc_dec *rc) | |||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Decode one bit. In some versions, this function has been splitted in three | ||||
|  * Decode one bit. In some versions, this function has been split in three | ||||
|  * functions so that the compiler is supposed to be able to more easily avoid | ||||
|  * an extra branch. In this particular version of the LZMA decoder, this | ||||
|  * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3 | ||||
|  * on x86). Using a non-splitted version results in nicer looking code too. | ||||
|  * on x86). Using a non-split version results in nicer looking code too. | ||||
|  * | ||||
|  * NOTE: This must return an int. Do not make it return a bool or the speed | ||||
|  * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care, | ||||
|  | @ -788,6 +788,7 @@ static void XZ_FUNC lzma_reset(struct xz_dec_lzma2 *s) | |||
| 	 */ | ||||
| 	probs = s->lzma.is_match[0]; | ||||
| 	for (i = 0; i < PROBS_TOTAL; ++i) | ||||
| 		// coverity[overrun-local]
 | ||||
| 		probs[i] = RC_BIT_MODEL_TOTAL / 2; | ||||
| 
 | ||||
| 	rc_reset(&s->rc); | ||||
|  | @ -995,10 +996,8 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run( | |||
| 					s->lzma2.need_props = false; | ||||
| 					s->lzma2.next_sequence | ||||
| 							= SEQ_PROPERTIES; | ||||
| 
 | ||||
| 				} else if (s->lzma2.need_props) { | ||||
| 					return XZ_DATA_ERROR; | ||||
| 
 | ||||
| 				} else { | ||||
| 					s->lzma2.next_sequence | ||||
| 							= SEQ_LZMA_PREPARE; | ||||
|  | @ -1044,6 +1043,7 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run( | |||
| 				return XZ_DATA_ERROR; | ||||
| 
 | ||||
| 			s->lzma2.sequence = SEQ_LZMA_PREPARE; | ||||
| 			// Fall through
 | ||||
| 
 | ||||
| 		case SEQ_LZMA_PREPARE: | ||||
| 			if (s->lzma2.compressed < RC_INIT_BYTES) | ||||
|  | @ -1054,6 +1054,7 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run( | |||
| 
 | ||||
| 			s->lzma2.compressed -= RC_INIT_BYTES; | ||||
| 			s->lzma2.sequence = SEQ_LZMA_RUN; | ||||
| 			// Fall through
 | ||||
| 
 | ||||
| 		case SEQ_LZMA_RUN: | ||||
| 			/*
 | ||||
|  | @ -1080,7 +1081,6 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run( | |||
| 
 | ||||
| 				rc_reset(&s->rc); | ||||
| 				s->lzma2.sequence = SEQ_CONTROL; | ||||
| 
 | ||||
| 			} else if (b->out_pos == b->out_size | ||||
| 					|| (b->in_pos == b->in_size | ||||
| 						&& s->temp.size | ||||
|  |  | |||
|  | @ -353,7 +353,6 @@ static enum xz_ret XZ_FUNC crc32_validate(struct xz_dec *s, struct xz_buf *b) | |||
| 			return XZ_DATA_ERROR; | ||||
| 
 | ||||
| 		s->pos += 8; | ||||
| 
 | ||||
| 	} while (s->pos < 32); | ||||
| 
 | ||||
| 	s->crc32 = 0; | ||||
|  | @ -546,7 +545,7 @@ static enum xz_ret XZ_FUNC dec_block_header(struct xz_dec *s) | |||
| 	return XZ_OK; | ||||
| } | ||||
| 
 | ||||
| static enum xz_ret XZ_FUNC dec_main(struct xz_dec *s, struct xz_buf *b) | ||||
| static NOINLINE enum xz_ret XZ_FUNC dec_main(struct xz_dec *s, struct xz_buf *b) | ||||
| { | ||||
| 	enum xz_ret ret; | ||||
| 
 | ||||
|  | @ -753,7 +752,6 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b) | |||
| 			b->in_pos = in_start; | ||||
| 			b->out_pos = out_start; | ||||
| 		} | ||||
| 
 | ||||
| 	} else if (ret == XZ_OK && in_start == b->in_pos | ||||
| 			&& out_start == b->out_pos) { | ||||
| 		if (s->allow_buf_error) | ||||
|  |  | |||
|  | @ -468,8 +468,11 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP | |||
| 			ctime = UINT32_MAX; | ||||
| 		inode.i_mode = 0100644; | ||||
| 		inode.i_links_count = 1; | ||||
| 		// coverity[store_truncates_time_t]
 | ||||
| 		inode.i_atime = (uint32_t)ctime; | ||||
| 		// coverity[store_truncates_time_t]
 | ||||
| 		inode.i_ctime = (uint32_t)ctime; | ||||
| 		// coverity[store_truncates_time_t]
 | ||||
| 		inode.i_mtime = (uint32_t)ctime; | ||||
| 		inode.i_size = fsize; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | |||
| IDD_DIALOG DIALOGEX 12, 12, 232, 326 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_ACCEPTFILES | ||||
| CAPTION "Rufus 3.21.1934" | ||||
| CAPTION "Rufus 3.21.1935" | ||||
| FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | ||||
| BEGIN | ||||
|     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP | ||||
|  | @ -395,8 +395,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 3,21,1934,0 | ||||
|  PRODUCTVERSION 3,21,1934,0 | ||||
|  FILEVERSION 3,21,1935,0 | ||||
|  PRODUCTVERSION 3,21,1935,0 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -414,13 +414,13 @@ BEGIN | |||
|             VALUE "Comments", "https://rufus.ie" | ||||
|             VALUE "CompanyName", "Akeo Consulting" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "3.21.1934" | ||||
|             VALUE "FileVersion", "3.21.1935" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011-2022 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" | ||||
|             VALUE "OriginalFilename", "rufus-3.21.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "3.21.1934" | ||||
|             VALUE "ProductVersion", "3.21.1935" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue