aboutsummaryrefslogtreecommitdiff
path: root/src/lzma/suffix.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lzma/suffix.c74
1 files changed, 61 insertions, 13 deletions
diff --git a/src/lzma/suffix.c b/src/lzma/suffix.c
index 57afce82..41b4c352 100644
--- a/src/lzma/suffix.c
+++ b/src/lzma/suffix.c
@@ -20,14 +20,9 @@
#include "private.h"
-static const struct {
+struct suffix_pair {
const char *compressed;
const char *uncompressed;
-} suffixes[] = {
- { ".lzma", "" },
- { ".tlz", ".tar" },
- { ".ylz", ".yar" },
- { NULL, NULL }
};
@@ -63,13 +58,21 @@ test_suffix(const char *suffix, const char *src_name, size_t src_len)
/// \return Name of the uncompressed file, or NULL if file has unknown
/// suffix.
static char *
-uncompressed_name(const char *src_name)
+uncompressed_name(const char *src_name, const size_t src_len)
{
+ static const struct suffix_pair suffixes[] = {
+ { ".xz", "" },
+ { ".txz", ".tar" }, // .txz abbreviation for .txt.gz is rare.
+ { ".lzma", "" },
+ { ".tlz", ".tar" },
+ // { ".gz", "" },
+ // { ".tgz", ".tar" },
+ };
+
const char *new_suffix = "";
- const size_t src_len = strlen(src_name);
size_t new_len = 0;
- for (size_t i = 0; suffixes[i].compressed != NULL; ++i) {
+ for (size_t i = 0; i < ARRAY_SIZE(suffixes); ++i) {
new_len = test_suffix(suffixes[i].compressed,
src_name, src_len);
if (new_len != 0) {
@@ -103,10 +106,40 @@ uncompressed_name(const char *src_name)
/// \brief Appends suffix to src_name
+///
+/// In contrast to uncompressed_name(), we check only suffixes that are valid
+/// for the specified file format.
static char *
-compressed_name(const char *src_name)
+compressed_name(const char *src_name, const size_t src_len)
{
- const size_t src_len = strlen(src_name);
+ // The order of these must match the order in args.h.
+ static const struct suffix_pair all_suffixes[][3] = {
+ {
+ { ".xz", "" },
+ { ".txz", ".tar" },
+ { NULL, NULL }
+ }, {
+ { ".lzma", "" },
+ { ".tlz", ".tar" },
+ { NULL, NULL }
+/*
+ }, {
+ { ".gz", "" },
+ { ".tgz", ".tar" },
+ { NULL, NULL }
+*/
+ }, {
+ // --format=raw requires specifying the suffix
+ // manually or using stdout.
+ { NULL, NULL }
+ }
+ };
+
+ // args.c ensures this.
+ assert(opt_format != FORMAT_AUTO);
+
+ const size_t format = opt_format - 1;
+ const struct suffix_pair *const suffixes = all_suffixes[format];
for (size_t i = 0; suffixes[i].compressed != NULL; ++i) {
if (test_suffix(suffixes[i].compressed, src_name, src_len)
@@ -118,6 +151,15 @@ compressed_name(const char *src_name)
}
}
+ // TODO: Hmm, maybe it would be better to validate this in args.c,
+ // since the suffix handling when decoding is weird now.
+ if (opt_format == FORMAT_RAW && opt_suffix == NULL) {
+ errmsg(V_ERROR, _("%s: With --format=raw, --suffix=.SUF is "
+ "required unless writing to stdout"),
+ src_name);
+ return NULL;
+ }
+
const char *suffix = opt_suffix != NULL
? opt_suffix : suffixes[0].compressed;
const size_t suffix_len = strlen(suffix);
@@ -139,7 +181,13 @@ compressed_name(const char *src_name)
extern char *
get_dest_name(const char *src_name)
{
+ assert(src_name != NULL);
+
+ // Length of the name is needed in all cases to locate the end of
+ // the string to compare the suffix, so calculate the length here.
+ const size_t src_len = strlen(src_name);
+
return opt_mode == MODE_COMPRESS
- ? compressed_name(src_name)
- : uncompressed_name(src_name);
+ ? compressed_name(src_name, src_len)
+ : uncompressed_name(src_name, src_len);
}