src/common/sysdefs.h
src/common/tuklib_common.h
src/common/tuklib_config.h
+ src/common/tuklib_mbstr_nonprint.c
+ src/common/tuklib_mbstr_nonprint.h
src/common/tuklib_exit.c
src/common/tuklib_exit.h
src/common/tuklib_gettext.h
../common/tuklib_progname.c \
../common/tuklib_exit.c \
../common/tuklib_mbstr_fw.c \
+ ../common/tuklib_mbstr_nonprint.c \
../common/tuklib_mbstr_width.c \
../common/tuklib_mbstr_wrap.c
strm.avail_out = 0;
while ((ret = lzma_code(&strm, LZMA_RUN))
== LZMA_UNSUPPORTED_CHECK)
- message_warning(_("%s: %s"), pair->src_name,
- message_strm(ret));
+ message_warning(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
+ message_strm(ret));
// With --single-stream lzma_code won't wait for
// LZMA_FINISH and thus it can return LZMA_STREAM_END
}
if (ret != LZMA_OK) {
- message_error(_("%s: %s"), pair->src_name, message_strm(ret));
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
+ message_strm(ret));
if (ret == LZMA_MEMLIMIT_ERROR)
message_mem_needed(V_ERROR, lzma_memusage(&strm));
// wrong and we print an error. Otherwise it's just
// a warning and coding can continue.
if (stop) {
- message_error(_("%s: %s"), pair->src_name,
- message_strm(ret));
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
+ message_strm(ret));
} else {
- message_warning(_("%s: %s"), pair->src_name,
- message_strm(ret));
+ message_warning(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
+ message_strm(ret));
// When compressing, all possible errors set
// stop to true.
continue;
message_error(_("%s: poll() failed: %s"),
- is_reading ? pair->src_name
- : pair->dest_name,
+ tuklib_mask_nonprint(is_reading
+ ? pair->src_name
+ : pair->dest_name),
strerror(errno));
return IO_WAIT_ERROR;
}
// of the original file, and in that case it obviously
// shouldn't be removed.
message_warning(_("%s: File seems to have been moved, "
- "not removing"), name);
+ "not removing"), tuklib_mask_nonprint(name));
else
#endif
// There's a race condition between lstat() and unlink()
// but at least we have tried to avoid removing wrong file.
if (unlink(name))
message_warning(_("%s: Cannot remove: %s"),
- name, strerror(errno));
+ tuklib_mask_nonprint(name),
+ strerror(errno));
return;
}
if (fchown(pair->dest_fd, pair->src_st.st_uid, (gid_t)(-1))
&& warn_fchown)
message_warning(_("%s: Cannot set the file owner: %s"),
- pair->dest_name, strerror(errno));
+ tuklib_mask_nonprint(pair->dest_name),
+ strerror(errno));
mode_t mode;
&& fchown(pair->dest_fd, (uid_t)(-1),
pair->src_st.st_gid)) {
message_warning(_("%s: Cannot set the file group: %s"),
- pair->dest_name, strerror(errno));
+ tuklib_mask_nonprint(pair->dest_name),
+ strerror(errno));
// We can still safely copy some additional permissions:
// 'group' must be at least as strict as 'other' and
// also vice versa.
if (fchmod(pair->dest_fd, mode))
message_warning(_("%s: Cannot set the file permissions: %s"),
- pair->dest_name, strerror(errno));
+ tuklib_mask_nonprint(pair->dest_name),
+ strerror(errno));
#endif
// Copy the timestamps. We have several possible ways to do this, of
if (!follow_symlinks) {
struct stat st;
if (lstat(pair->src_name, &st)) {
- message_error(_("%s: %s"), pair->src_name,
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
strerror(errno));
return true;
} else if (S_ISLNK(st.st_mode)) {
message_warning(_("%s: Is a symbolic link, "
- "skipping"), pair->src_name);
+ "skipping"),
+ tuklib_mask_nonprint(pair->src_name));
return true;
}
}
if (was_symlink)
message_warning(_("%s: Is a symbolic link, "
- "skipping"), pair->src_name);
+ "skipping"),
+ tuklib_mask_nonprint(pair->src_name));
else
#endif
// Something else than O_NOFOLLOW failing
// (assuming that the race conditions didn't
// confuse us).
- message_error(_("%s: %s"), pair->src_name,
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
strerror(errno));
return true;
if (S_ISDIR(pair->src_st.st_mode)) {
message_warning(_("%s: Is a directory, skipping"),
- pair->src_name);
+ tuklib_mask_nonprint(pair->src_name));
goto error;
}
if (reg_files_only && !S_ISREG(pair->src_st.st_mode)) {
message_warning(_("%s: Not a regular file, skipping"),
- pair->src_name);
+ tuklib_mask_nonprint(pair->src_name));
goto error;
}
// explicitly in io_copy_attr().
message_warning(_("%s: File has setuid or "
"setgid bit set, skipping"),
- pair->src_name);
+ tuklib_mask_nonprint(pair->src_name));
goto error;
}
if (pair->src_st.st_mode & S_ISVTX) {
message_warning(_("%s: File has sticky bit "
"set, skipping"),
- pair->src_name);
+ tuklib_mask_nonprint(pair->src_name));
goto error;
}
if (pair->src_st.st_nlink > 1) {
message_warning(_("%s: Input file has more "
- "than one hard link, "
- "skipping"), pair->src_name);
+ "than one hard link, skipping"),
+ tuklib_mask_nonprint(pair->src_name));
goto error;
}
}
return false;
error_msg:
- message_error(_("%s: %s"), pair->src_name, strerror(errno));
+ message_error(_("%s: %s"), tuklib_mask_nonprint(pair->src_name),
+ strerror(errno));
error:
(void)close(pair->src_fd);
return true;
if (st.st_dev == -1) {
message_error("%s: Refusing to write to "
"a DOS special file",
- pair->dest_name);
+ tuklib_mask_nonprint(
+ pair->dest_name));
free(pair->dest_name);
return true;
}
&& st.st_ino == pair->src_st.st_ino) {
message_error("%s: Output file is the same "
"as the input file",
- pair->dest_name);
+ tuklib_mask_nonprint(
+ pair->dest_name));
free(pair->dest_name);
return true;
}
// If --force was used, unlink the target file first.
if (opt_force && unlink(pair->dest_name) && errno != ENOENT) {
message_error(_("%s: Cannot remove: %s"),
- pair->dest_name, strerror(errno));
+ tuklib_mask_nonprint(pair->dest_name),
+ strerror(errno));
free(pair->dest_name);
return true;
}
pair->dest_fd = open(pair->dest_name, flags, mode);
if (pair->dest_fd == -1) {
- message_error(_("%s: %s"), pair->dest_name,
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->dest_name),
strerror(errno));
free(pair->dest_name);
return true;
else if (pair->dest_fd != STDOUT_FILENO
&& !S_ISREG(pair->dest_st.st_mode)) {
message_error("%s: Destination is not a regular file",
- pair->dest_name);
+ tuklib_mask_nonprint(pair->dest_name));
// dest_fd needs to be reset to -1 to keep io_close() working.
(void)close(pair->dest_fd);
if (close(pair->dest_fd)) {
message_error(_("%s: Closing the file failed: %s"),
- pair->dest_name, strerror(errno));
+ tuklib_mask_nonprint(pair->dest_name),
+ strerror(errno));
// Closing destination file failed, so we cannot trust its
// contents. Get rid of junk:
SEEK_CUR) == -1) {
message_error(_("%s: Seeking failed when trying "
"to create a sparse file: %s"),
- pair->dest_name, strerror(errno));
+ tuklib_mask_nonprint(pair->dest_name),
+ strerror(errno));
success = false;
} else {
const uint8_t zero[1] = { '\0' };
#endif
message_error(_("%s: Read error: %s"),
- pair->src_name, strerror(errno));
+ tuklib_mask_nonprint(pair->src_name),
+ strerror(errno));
return SIZE_MAX;
}
if (lseek(pair->src_fd, (off_t)(pos), SEEK_SET) == -1) {
message_error(_("%s: Error seeking the file: %s"),
- pair->src_name, strerror(errno));
+ tuklib_mask_nonprint(pair->src_name),
+ strerror(errno));
return true;
}
if (amount != size) {
message_error(_("%s: Unexpected end of file"),
- pair->src_name);
+ tuklib_mask_nonprint(pair->src_name));
return true;
}
// user_abort, and get EPIPE here.
if (errno != EPIPE)
message_error(_("%s: Write error: %s"),
- pair->dest_name, strerror(errno));
+ tuklib_mask_nonprint(pair->dest_name),
+ strerror(errno));
return true;
}
SEEK_CUR) == -1) {
message_error(_("%s: Seeking failed when "
"trying to create a sparse "
- "file: %s"), pair->dest_name,
+ "file: %s"),
+ tuklib_mask_nonprint(
+ pair->dest_name),
strerror(errno));
return true;
}
parse_indexes(xz_file_info *xfi, file_pair *pair)
{
if (pair->src_st.st_size <= 0) {
- message_error(_("%s: File is empty"), pair->src_name);
+ message_error(_("%s: File is empty"),
+ tuklib_mask_nonprint(pair->src_name));
return true;
}
if (pair->src_st.st_size < 2 * LZMA_STREAM_HEADER_SIZE) {
message_error(_("%s: Too small to be a valid .xz file"),
- pair->src_name);
+ tuklib_mask_nonprint(pair->src_name));
return true;
}
hardware_memlimit_get(MODE_LIST),
(uint64_t)(pair->src_st.st_size));
if (ret != LZMA_OK) {
- message_error(_("%s: %s"), pair->src_name, message_strm(ret));
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
+ message_strm(ret));
return true;
}
}
default:
- message_error(_("%s: %s"), pair->src_name,
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
message_strm(ret));
// If the error was too low memory usage limit,
break;
case LZMA_OPTIONS_ERROR:
- message_error(_("%s: %s"), pair->src_name,
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
message_strm(LZMA_OPTIONS_ERROR));
return true;
// Check if the stringification succeeded.
if (str_ret != LZMA_OK) {
- message_error(_("%s: %s"), pair->src_name,
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
message_strm(str_ret));
return true;
}
data_error:
// Show the error message.
- message_error(_("%s: %s"), pair->src_name,
+ message_error(_("%s: %s"),
+ tuklib_mask_nonprint(pair->src_name),
message_strm(LZMA_DATA_ERROR));
return true;
}
char checks[CHECKS_STR_SIZE];
get_check_names(checks, lzma_index_checks(xfi->idx), false);
- const char *cols[7] = {
+ const char *cols[6] = {
uint64_to_str(lzma_index_stream_count(xfi->idx), 0),
uint64_to_str(lzma_index_block_count(xfi->idx), 1),
uint64_to_nicestr(lzma_index_file_size(xfi->idx),
get_ratio(lzma_index_file_size(xfi->idx),
lzma_index_uncompressed_size(xfi->idx)),
checks,
- pair->src_name,
};
printf("%*s %*s %*s %*s %*s %-*s %s\n",
tuklib_mbstr_fw(cols[0], 5), cols[0],
tuklib_mbstr_fw(cols[3], 11), cols[3],
tuklib_mbstr_fw(cols[4], 5), cols[4],
tuklib_mbstr_fw(cols[5], 7), cols[5],
- cols[6]);
+ tuklib_mask_nonprint(pair->src_name));
return false;
}
char checks[CHECKS_STR_SIZE];
get_check_names(checks, lzma_index_checks(xfi->idx), false);
- printf("name\t%s\n", pair->src_name);
+ // Robot mode has to mask at least some control chars to prevent
+ // the output from getting out of sync if filename is malicious.
+ // Masking all non-printable chars is more than we need but
+ // perhaps this is good enough in practice.
+ printf("name\t%s\n", tuklib_mask_nonprint(pair->src_name));
printf("file\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64
"\t%s\t%s\t%" PRIu64 "\n",
continue;
message_error(_("%s: Error reading filenames: %s"),
- args->files_name, strerror(errno));
+ tuklib_mask_nonprint(args->files_name),
+ strerror(errno));
return NULL;
}
if (pos != 0)
message_error(_("%s: Unexpected end of input "
"when reading filenames"),
- args->files_name);
+ tuklib_mask_nonprint(
+ args->files_name));
return NULL;
}
message_error(_("%s: Null character found when "
"reading filenames; maybe you meant "
"to use '--files0' instead "
- "of '--files'?"), args->files_name);
+ "of '--files'?"),
+ tuklib_mask_nonprint(
+ args->files_name));
return NULL;
}
// If we don't know how many files there will be due
// to usage of --files or --files0.
if (files_total == 0)
- fprintf(file, "%s (%u)\n", filename,
+ fprintf(file, "%s (%u)\n",
+ tuklib_mask_nonprint(filename),
files_pos);
else
- fprintf(file, "%s (%u/%u)\n", filename,
+ fprintf(file, "%s (%u/%u)\n",
+ tuklib_mask_nonprint(filename),
files_pos, files_total);
signals_unblock();
cols[4]);
} else {
// The filename is always printed.
- fprintf(stderr, _("%s: "), filename);
+ fprintf(stderr, _("%s: "), tuklib_mask_nonprint(filename));
// Percentage is printed only if we didn't finish yet.
if (!finished) {
if (value == NULL || value[0] == '\0')
message_fatal(_("%s: Options must be 'name=value' "
- "pairs separated with commas"), str);
+ "pairs separated with commas"),
+ tuklib_mask_nonprint(str));
// Look for the option name from the option map.
unsigned i = 0;
while (true) {
if (opts[i].name == NULL)
message_fatal(_("%s: Invalid option name"),
- name);
+ tuklib_mask_nonprint(name));
if (strcmp(name, opts[i].name) == 0)
break;
if (opts[i].map[j].name == NULL)
message_fatal(_("%s: Invalid option value"),
- value);
+ tuklib_mask_nonprint(value));
set(filter_options, i, opts[i].map[j].id, value);
static void
error_lzma_preset(const char *valuestr)
{
- message_fatal(_("Unsupported LZMA1/LZMA2 preset: %s"), valuestr);
+ message_fatal(_("Unsupported LZMA1/LZMA2 preset: %s"),
+ tuklib_mask_nonprint(valuestr));
}
#include "tuklib_gettext.h"
#include "tuklib_progname.h"
#include "tuklib_exit.h"
+#include "tuklib_mbstr_nonprint.h"
#include "tuklib_mbstr.h"
#if defined(_WIN32) && !defined(__CYGWIN__)
if (new_len == 0) {
message_warning(_("%s: Filename has an unknown suffix, "
- "skipping"), src_name);
+ "skipping"), tuklib_mask_nonprint(src_name));
return NULL;
}
}
-/// This message is needed in multiple places in compressed_name(),
-/// so the message has been put into its own function.
static void
msg_suffix(const char *src_name, const char *suffix)
{
+ char *mem = NULL;
message_warning(_("%s: File already has '%s' suffix, skipping"),
- src_name, suffix);
+ tuklib_mask_nonprint(src_name),
+ tuklib_mask_nonprint_r(suffix, &mem));
+ free(mem);
return;
}
// Empty suffix and suffixes having a directory separator are
// rejected. Such suffixes would break things later.
if (suffix[0] == '\0' || has_dir_sep(suffix))
- message_fatal(_("%s: Invalid filename suffix"), suffix);
+ message_fatal(_("%s: Invalid filename suffix"),
+ tuklib_mask_nonprint(suffix));
// Replace the old custom_suffix (if any) with the new suffix.
free(custom_suffix);