summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakob <jakob@memeware.net>2017-06-06 15:40:40 -0400
committerjakob <jakob@memeware.net>2017-06-06 15:40:40 -0400
commitcfd5fb6e6fb47e084e66e1e4e2d6a99f19be661e (patch)
tree5fcfe91127c67f6dbb94a81848e8c1b9e6ddea7d
parent17b658ceadd08d693f23448c276958e2eea5970e (diff)
Cleaned up
-rw-r--r--README.md5
-rw-r--r--src/cli.c18
-rw-r--r--src/cli.h1
-rw-r--r--src/compress.c16
-rw-r--r--src/compress.h8
-rw-r--r--src/header.c32
-rw-r--r--src/main.c44
-rw-r--r--test/test_cli.c16
-rw-r--r--test/test_compress.c72
-rw-r--r--test/test_compress.h23
-rw-r--r--test/test_run.c3
-rw-r--r--test/vectors/test.binbin0 -> 176569 bytes
-rwxr-xr-xtest/vectors/test.pngbin0 -> 176608 bytes
13 files changed, 150 insertions, 88 deletions
diff --git a/README.md b/README.md
index f70a600..4bd0b1f 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,8 @@ You can add specific flags to the Makefile with `USER_CFLAGS` and/or `USER_LDFLA
## TODO
-* Full unit testing.
+* Full unit testing, test static functions.
* Clean up `main.c`, move functions like `load_table` and `make_dirs` into more appropriate files.
+* Clean up `create_archive`.
* Strict warnings.
-
+* Game-compatible file encryption on created archives.
diff --git a/src/cli.c b/src/cli.c
index 7f2703e..da6d3cc 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -26,15 +26,20 @@
#include "cli.h"
#include "crypto.h"
-#define NEKOPACK_VERSION "2.1.0b1"
+#define NEKOPACK_VERSION "2.1.0"
-/* Copies `optarg` into the out field of `p` and ensures that it ends in
- a trailing path delimiter. */
+/* Copies `optarg` into the out member of `p` and ensures that it has a
+ trailing path delimiter. */
static void parse_output_path(const char *optarg, struct params *p) {
p->out_len = strlen(optarg);
p->out = malloc(p->out_len + 2);
+
+ if (p->out == NULL)
+ return;
+
strcpy(p->out, optarg);
+
if (p->out[p->out_len - 1] != '/') {
p->out[p->out_len] = '/';
p->out_len += 1;
@@ -78,7 +83,6 @@ struct params parse_args(int argc, char **argv) {
{"extract", no_argument, NULL, 'e'},
{"list", no_argument, NULL, 'l'},
{"create", no_argument, NULL, 'c'},
- {"debug", no_argument, NULL, 'd'},
{"output", no_argument, NULL, 'o'},
{"game", no_argument, NULL, 'g'},
{NULL, 0, NULL, 0}
@@ -86,7 +90,7 @@ struct params parse_args(int argc, char **argv) {
do {
count++;
- cur = getopt_long(argc, argv, "hVvelcdqo:g:", long_opts, &opt_index);
+ cur = getopt_long(argc, argv, "hVvelcqo:g:", long_opts, &opt_index);
switch (cur) {
case 'h':
p.mode = HELP;
@@ -120,10 +124,6 @@ struct params parse_args(int argc, char **argv) {
case 'c':
p.mode = CREATE;
- break;
-
- case 'd':
- p.mode = DEBUG;
}
} while (cur >= 0);
diff --git a/src/cli.h b/src/cli.h
index 00e33fa..dfc8ef4 100644
--- a/src/cli.h
+++ b/src/cli.h
@@ -30,7 +30,6 @@ enum {
LIST,
EXTRACT,
CREATE,
- DEBUG,
};
/* Structure for storing options set from the command-line. */
diff --git a/src/compress.c b/src/compress.c
index e61780d..4df5ef7 100644
--- a/src/compress.c
+++ b/src/compress.c
@@ -26,7 +26,10 @@
#define LEVEL -1
-/* Inflates `s` into a newly allocated stream structure. */
+/* Inflates `len` bytes from the current position of `s` to a new stream
+ structure of size `decompressed_len` bytes. Stream inflation will not
+ work if `decompressed_len` does not represent the actual size of the
+ original data. */
struct stream *stream_inflate(struct stream *s, size_t len,
size_t decompressed_len) {
z_stream strm;
@@ -40,17 +43,17 @@ struct stream *stream_inflate(struct stream *s, size_t len,
return NULL;
int ret;
- struct stream *n = stream_new(decompressed_len);
+ struct stream *new = stream_new(decompressed_len);
do {
strm.avail_in = len;
strm.next_in = (Bytef *) s->_cur;
do {
strm.avail_out = decompressed_len;
- strm.next_out = (Bytef *) n->_cur;
+ strm.next_out = (Bytef *) new->_cur;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR) {
- stream_free(n);
+ stream_free(new);
inflateEnd(&strm);
return NULL;
}
@@ -58,11 +61,12 @@ struct stream *stream_inflate(struct stream *s, size_t len,
} while (ret != Z_STREAM_END);
inflateEnd(&strm);
- return n;
+ return new;
}
-/* Deflates `s` into a newly allocated stream structure. */
+/* Deflates `len` bytes from the current position of `s` to a new stream
+ structure, where the `len` member represents the decompressed size. */
struct stream *stream_deflate(struct stream *s, size_t len) {
struct stream *new = stream_new(len);
if (new == NULL)
diff --git a/src/compress.h b/src/compress.h
index cfb2487..e885231 100644
--- a/src/compress.h
+++ b/src/compress.h
@@ -21,9 +21,13 @@
#include "io.h"
-/* Inflates `s` into a newly allocated stream structure. */
+/* Inflates `len` bytes from the current position of `s` to a new stream
+ structure of size `decompressed_len` bytes. Stream inflation will not
+ work if `decompressed_len` does not represent the actual size of the
+ original data. */
struct stream *stream_inflate(struct stream *s, size_t len,
size_t decompressed_len);
-/* Deflates `s` into a newly allocated stream structure. */
+/* Deflates `len` bytes from the current position of `s` to a new stream
+ structure, where the `len` member represents the decompressed size. */
struct stream *stream_deflate(struct stream *s, size_t len);
diff --git a/src/header.c b/src/header.c
index 86f5e25..11dc654 100644
--- a/src/header.c
+++ b/src/header.c
@@ -39,6 +39,22 @@ static bool is_supported(struct header *h) {
}
+/* Generates an XP3 header structure readable by Nekopara. */
+struct header *create_header(void) {
+ struct header *h = malloc(sizeof(struct header));
+ if (h == NULL)
+ return NULL;
+
+ memcpy(h->magic, XP3_MAGIC, 11);
+ h->info_offset = 0x17;
+ h->version = 1;
+ h->flags = 0x80;
+ h->table_size = 0;
+ h->table_offset = 0;
+ return h;
+}
+
+
/* Reads from the given stream into a newly allocated header structure.
NULL is returned if the header contains an invalid magic number, or
if the archive's version is not supported. */
@@ -63,22 +79,6 @@ struct header *read_header(struct stream *s) {
}
-/* Generates an XP3 header structure readable by Nekopara. */
-struct header *create_header(void) {
- struct header *h = malloc(sizeof(struct header));
- if (h == NULL)
- return NULL;
-
- memcpy(h->magic, XP3_MAGIC, 11);
- h->info_offset = 0x17;
- h->version = 1;
- h->flags = 0x80;
- h->table_size = 0;
- h->table_offset = 0;
- return h;
-}
-
-
/* Dumps the XP3 header specified by `h` into `fp`. */
void dump_header(FILE *fp, struct header *h) {
fwrite(h->magic, 11, 1, fp);
diff --git a/src/main.c b/src/main.c
index ac21bb4..d50ee4c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -17,7 +17,6 @@
You should have received a copy of the GNU General Public License
along with Nekopack. If not, see <http://www.gnu.org/licenses/>. */
-#include <inttypes.h> /* Only used for debug mode. */
#include <errno.h>
#include <sys/stat.h>
#include <stdint.h>
@@ -35,9 +34,6 @@
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
-#define ANSI_TITLE "\x1b[36m\x1b[4m"
-#define ANSI_END "\x1b[0m"
-
static struct stream *load_table(struct stream *s) {
uint8_t compressed;
@@ -245,7 +241,6 @@ static void create_archive(char **paths, int argc, struct params p) {
return;
}
- /* TODO: Separate into own function. */
table_size += 20 + strlen(cur->filename) * 2;
table_size += 28 * cur->segment_count + 60;
@@ -286,11 +281,9 @@ static void create_archive(char **paths, int argc, struct params p) {
h->table_offset = 40 + data->len;
dump_header(fp, h);
- /* FIXME: Formatting and this initial seek might not be necessary. */
stream_seek(data, 0, SEEK_SET);
stream_dump(fp, data, data->len);
- /* FIXME: May be an incompatible value. Also, move this shitty hack. */
uint8_t compressed = 1;
fwrite(&compressed, sizeof(uint8_t), 1, fp);
fwrite(&table_compressed->len, sizeof(uint64_t), 1, fp);
@@ -300,38 +293,6 @@ static void create_archive(char **paths, int argc, struct params p) {
}
-/* The name is not particularly fitting to its function. */
-static void display_table(char *path, struct params p) {
- /* Replicated code. Could this be in map_entries? */
- struct stream *archive = stream_from_file(path);
- if (archive == NULL) {
- if (errno == ENOENT) {
- perror(path);
- } else {
- fprintf(stderr, "Error allocating memory.\n");
- }
- return;
- }
-
- struct header *h = read_header(archive);
- if (h == NULL) {
- fprintf(stderr, "File is not an XP3 archive.\n");
- return;
- }
-
- printf(ANSI_TITLE "Archive Header\n" ANSI_END);
- printf("Magic: ");
- for (int i = 0; i < 11; i++)
- printf("%x", h->magic[i]);
- printf("\n");
- printf("Info Offset: 0x%"PRIx64"\n", h->info_offset);
- printf("Version: 0x%"PRIx32"\n", h->version);
- printf("Flags: 0x%"PRIx8"\n", h->flags);
- printf("Table Size: 0x%"PRIx64"\n", h->table_size);
- printf("Table Offset: 0x%"PRIx64"\n", h->table_offset);
-}
-
-
int main(int argc, char **argv) {
struct params p = parse_args(argc, argv);
switch (p.mode) {
@@ -354,11 +315,6 @@ int main(int argc, char **argv) {
map_entries(argv[i], p);
break;
- case DEBUG:
- for (int i = p.vararg_index; i < argc; i++)
- display_table(argv[i], p);
- break;
-
case CREATE:
create_archive(argv + p.vararg_index, argc, p);
}
diff --git a/test/test_cli.c b/test/test_cli.c
index eed7e30..86d6a2e 100644
--- a/test/test_cli.c
+++ b/test/test_cli.c
@@ -37,19 +37,19 @@ char *test_out_path(void) {
}
-char *test_vararg_index(void) {
- char *argv[] = {"nekopack", "-l", "a.xp3"};
- struct params p = parse_args(3, argv);
- mu_assert("Invalid vararg index", !strcmp("a.xp3", argv[p.vararg_index]));
+char *test_game_id(void) {
+ char *argv[] = {"nekopack", "-g", "nekopara_volume_1", "a.xp3"};
+ struct params p = parse_args(4, argv);
+ mu_assert("Incorrect game ID", p.game == NEKOPARA_VOLUME_1);
free(p.out);
return NULL;
}
-char *test_game_id(void) {
- char *argv[] = {"nekopack", "-g", "nekopara_volume_1", "a.xp3"};
- struct params p = parse_args(4, argv);
- mu_assert("Incorrect game ID", p.game == NEKOPARA_VOLUME_1);
+char *test_vararg_index(void) {
+ char *argv[] = {"nekopack", "-l", "a.xp3"};
+ struct params p = parse_args(3, argv);
+ mu_assert("Invalid vararg index", !strcmp("a.xp3", argv[p.vararg_index]));
free(p.out);
return NULL;
}
diff --git a/test/test_compress.c b/test/test_compress.c
new file mode 100644
index 0000000..583dd8b
--- /dev/null
+++ b/test/test_compress.c
@@ -0,0 +1,72 @@
+/* test_compress.c -- MinUnit test cases for compress.c
+
+ Copyright (C) 2017 Jakob Kreuze, All Rights Reserved.
+
+ This file is part of Nekopack.
+
+ Nekopack is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at
+ your option) any later version.
+
+ Nekopack is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Nekopack. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <stdbool.h>
+
+#include "minunit.h"
+
+#include "compress.h"
+#include "io.h"
+
+extern int tests_run;
+
+/* FIXME: This won't hold up for the future. Even if it works across
+ different versions of zlib, if the compression rate is ever changed
+ this test will fail. */
+
+/* TODO: Replace with a proper stream comparison and put it in io.c? */
+static bool streams_eq(struct stream *a, struct stream *b) {
+ if (a->len != b->len)
+ return false;
+ for (unsigned long i = 0; i < a->len; i++) {
+ if (a->_start[i] != b->_start[i])
+ return false;
+ }
+ return true;
+}
+
+
+char *test_compress(void) {
+ struct stream *s = stream_from_file("test/vectors/test.png");
+ struct stream *expected = stream_from_file("test/vectors/test.bin");
+ mu_assert("Could not open test vectors", s != NULL && expected != NULL);
+
+ struct stream *res = stream_deflate(s, s->len);
+ mu_assert("Expected compression not met", streams_eq(res, expected));
+
+ stream_free(s);
+ stream_free(expected);
+ stream_free(res);
+ return NULL;
+}
+
+
+char *test_decompress(void) {
+ struct stream *s = stream_from_file("test/vectors/test.bin");
+ struct stream *expected = stream_from_file("test/vectors/test.png");
+ mu_assert("Could not open test vectors", s != NULL && expected != NULL);
+
+ struct stream *res = stream_inflate(s, s->len, 176608);
+ mu_assert("Expected compression not met", streams_eq(res, expected));
+
+ stream_free(s);
+ stream_free(expected);
+ stream_free(res);
+ return NULL;
+}
diff --git a/test/test_compress.h b/test/test_compress.h
new file mode 100644
index 0000000..0a1f3ea
--- /dev/null
+++ b/test/test_compress.h
@@ -0,0 +1,23 @@
+/* test_compress.h -- MinUnit test cases for compress.c
+
+ Copyright (C) 2017 Jakob Kreuze, All Rights Reserved.
+
+ This file is part of Nekopack.
+
+ Nekopack is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at
+ your option) any later version.
+
+ Nekopack is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Nekopack. If not, see <http://www.gnu.org/licenses/>. */
+
+#pragma once
+
+char *test_compress(void);
+char *test_decompress(void);
diff --git a/test/test_run.c b/test/test_run.c
index f1dc80e..4263c7f 100644
--- a/test/test_run.c
+++ b/test/test_run.c
@@ -22,6 +22,7 @@
#include "minunit.h"
#include "test_cli.h"
+#include "test_compress.h"
#include "test_crypto.h"
#include "test_encoding.h"
#include "test_header.h"
@@ -35,6 +36,8 @@ static char *run_all_tests(void) {
mu_run_test(test_out_path);
mu_run_test(test_vararg_index);
mu_run_test(test_game_id);
+ mu_run_test(test_compress);
+ mu_run_test(test_decompress);
mu_run_test(test_derive_initial);
mu_run_test(test_derive_primary);
mu_run_test(test_stream_obj);
diff --git a/test/vectors/test.bin b/test/vectors/test.bin
new file mode 100644
index 0000000..19fd87b
--- /dev/null
+++ b/test/vectors/test.bin
Binary files differ
diff --git a/test/vectors/test.png b/test/vectors/test.png
new file mode 100755
index 0000000..8fee322
--- /dev/null
+++ b/test/vectors/test.png
Binary files differ