Mainly so a local cache tree traversal recovers from a malformed URI.
1. Atomize append operations
Failure used to leave the path builder in an essentially undefined
state, which meant the path had to be thrown away, precluding further
tree traversal.
A failing `append()` no longer modifies the path builder, allowing the
tree traversal to simply skip the ailing branch.
2. Remove lazy failure
The old path_builder was postponing error reporting to path compilation
(`pb_peek()` and `pb_compile()`).
This was an old optimization (meant to simplify path building code),
and was getting in the way of the atomizing.
Errors are now fail-fast, thrown during path construction
(`pb_append*()`).
3. Move path normalization to `uri`
Path normalization (collapsing `.`, `..` and `/`) was getting in the
way of the atomizing, in addition to only really being useful for the
URI-to-cache conversion code.
3. Restore support for absolute paths
This was just a small TODO spawned a few commits ago.
int error;
pb_init(&pb);
- pb_append(&pb, config_get_local_repository());
- pb_append(&pb, "metadata.json");
+ error = pb_append(&pb, config_get_local_repository());
+ if (error)
+ goto cancel;
+ error = pb_append(&pb, "metadata.json");
+ if (error)
+ goto cancel;
- error = pb_compile(&pb, filename);
- if (error) {
- pr_op_err("Unable to build metadata.json's path: %s",
- strerror(error));
- }
+ *filename = pb.string;
+ return 0;
+cancel:
+ pb_cleanup(&pb);
return error;
}
{
struct path_builder pb;
struct cache_node *cursor;
- char *path;
int error;
pb_init(&pb);
- for (cursor = node; cursor != NULL; cursor = cursor->parent)
- pb_append(&pb, cursor->basename);
- pb_append(&pb, config_get_local_repository());
- pb_reverse(&pb);
- error = pb_compile(&pb, &path);
- if (error) {
- pr_val_err("Cannot override '%s'; path is bogus: %s",
- node->basename, strerror(error));
- return error;
+ for (cursor = node; cursor != NULL; cursor = cursor->parent) {
+ error = pb_append(&pb, cursor->basename);
+ if (error)
+ goto cancel;
}
+ error = pb_append(&pb, config_get_local_repository());
+ if (error)
+ goto cancel;
+ pb_reverse(&pb);
if (is_file) {
- if (remove(path) != 0) {
+ if (remove(pb.string) != 0) {
error = errno;
pr_val_err("Cannot override file '%s': %s",
- path, strerror(error));
+ pb.string, strerror(error));
}
} else {
- error = file_rm_rf(path);
+ error = file_rm_rf(pb.string);
pr_val_err("Cannot override directory '%s': %s",
- path, strerror(error));
+ pb.string, strerror(error));
}
- free(path);
+ pb_cleanup(&pb);
+ return error;
+
+cancel:
+ pb_cleanup(&pb);
return error;
}
static void
pb_rm_r(struct path_builder *pb, char const *filename, bool force)
{
- char const *path;
int error;
- error = pb_peek(pb, &path);
- if (error) {
- pr_op_err("Path builder error code %d; cannot delete directory. (Basename is '%s')",
- error, filename);
- return;
- }
-
- error = file_rm_rf(path);
+ error = file_rm_rf(pb->string);
if (error && !force)
- pr_op_err("Cannot delete %s: %s", path, strerror(error));
+ pr_op_err("Cannot delete %s: %s", pb->string, strerror(error));
}
/* Safe removal, Postorder */
return;
}
+ /* FIXME test these error paths */
while (node->children != NULL) {
- /* FIXME We need to recover from path too long... */
- pb_append(pb, node->basename);
+ if (pb_append(pb, node->basename) != 0) {
+ node = node->parent;
+ goto end;
+ }
node = node->children;
}
- pb_append(pb, "a");
+ if (pb_append(pb, "a") != 0)
+ node = node->parent;
+
+end:
ctt->pb = pb;
ctt->next = node;
ctt->next_sibling = true;
pb_pop(ctt->pb, true);
if (ctt->next_sibling)
- pb_append(ctt->pb, next->basename);
+ pb_append(ctt->pb, next->basename); /* FIXME */
if (next->hh.next != NULL) {
ctt->next = next->hh.next;
{
struct cache_tree_traverser ctt;
struct path_builder pb;
- char const *path;
struct stat meta;
DIR *dir;
struct dirent *file;
int error;
pb_init(&pb);
- pb_append(&pb, config_get_local_repository());
+ if (pb_append(&pb, config_get_local_repository()) != 0)
+ goto end;
if (node == NULL) {
/* File might exist but node doesn't: Delete file */
- pb_append(&pb, name);
+ if (pb_append(&pb, name) != 0)
+ goto end;
pb_rm_r(&pb, name, true);
- pb_cancel(&pb);
+ pb_cleanup(&pb);
return;
}
ctt_init(&ctt, node, &pb);
while ((node = ctt_next(&ctt)) != NULL) {
- error = pb_peek(&pb, &path);
- if (error) {
- pr_op_err("Cannot clean up directory (basename is '%s'): %s",
- node->basename, strerror(error));
- break;
- }
-
- if (stat(path, &meta) != 0) {
+ if (stat(pb.string, &meta) != 0) {
error = errno;
if (error == ENOENT) {
/* Node exists but file doesn't: Delete node */
}
pr_op_err("Cannot clean up '%s'; stat() returned errno %d: %s",
- path, error, strerror(error));
+ pb.string, error, strerror(error));
break;
}
if (!S_ISDIR(meta.st_mode)) {
/* File is not a directory; welp. */
- remove(path);
+ remove(pb.string);
delete_node(node);
}
- dir = opendir(path);
+ dir = opendir(pb.string);
if (dir == NULL) {
error = errno;
pr_op_err("Cannot clean up '%s'; S_ISDIR() but !opendir(): %s",
- path, strerror(error));
+ pb.string, strerror(error));
continue; /* AAAAAAAAAAAAAAAAAH */
}
child->flags |= CNF_FOUND;
} else {
/* File child's node does not exist: Delete. */
- pb_append(&pb, file->d_name);
- pb_rm_r(&pb, file->d_name, false);
- pb_pop(&pb, true);
+ if (pb_append(&pb, file->d_name) == 0) {
+ pb_rm_r(&pb, file->d_name, false);
+ pb_pop(&pb, true);
+ }
}
}
}
}
- pb_cancel(&pb);
+end:
+ pb_cleanup(&pb);
}
static int
cache_tmpfile(char **filename)
{
struct path_builder pb;
+ int error;
pb_init(&pb);
- pb_append(&pb, config_get_local_repository());
- pb_append(&pb, "tmp");
- pb_append_uint(&pb, atomic_fetch_add(&file_counter, 1u));
+ error = pb_append(&pb, config_get_local_repository());
+ if (error)
+ return error;
+ error = pb_append(&pb, "tmp");
+ if (error)
+ return error;
+ error = pb_append_u32(&pb, atomic_fetch_add(&file_counter, 1u));
+ if (error)
+ return error;
- return pb_compile(&pb, filename);
+ *filename = pb.string;
+ return 0;
}
/* These are arbitrary; feel free to change them. */
#ifndef INITIAL_CAPACITY /* Unit tests want to override this */
-#define INITIAL_CAPACITY 128
+#define INITIAL_CAPACITY 128u
#endif
-#define MAX_CAPACITY 4096
+#define MAX_CAPACITY 4096u
void
pb_init(struct path_builder *pb)
{
pb->string = pmalloc(INITIAL_CAPACITY);
+ pb->string[0] = 0;
pb->len = 0;
pb->capacity = INITIAL_CAPACITY;
- pb->error = 0;
}
-/*
- * Returns true on success, false on failure.
- */
-static bool
-pb_grow(struct path_builder *pb, size_t total_len)
+static int
+pb_grow(struct path_builder *pb, size_t total_len, char const *addend)
{
if (total_len > MAX_CAPACITY) {
- free(pb->string);
- pr_val_err("Path too long: %zu > %u characters.", total_len,
- MAX_CAPACITY);
- pb->error = ENOSPC;
- return false;
+ pr_val_err("Unable to concatenate '%.32s' (might be truncated) to path '%s': Path too long (%zu > %u)",
+ addend, pb->string, total_len, MAX_CAPACITY);
+ return ENOSPC;
}
do {
} while (total_len > pb->capacity);
pb->string = prealloc(pb->string, pb->capacity);
- return true;
-}
-
-static char const *
-find_slash(char const *str, size_t len)
-{
- char const *wall;
-
- for (wall = str + len; str < wall; str++)
- if (str[0] == '/')
- return str;
-
- return str;
+ return 0;
}
-/*
- * Do NOT include the null character in @addlen.
- * Assumes @addend needs no slashes.
- */
-static void
-add(struct path_builder *pb, char const *addend, size_t addlen)
+int
+pb_appendn(struct path_builder *pb, char const *addend, size_t addlen)
{
size_t total_len;
+ bool add_slash;
+ int error;
- total_len = pb->len + addlen;
- if (total_len > pb->capacity && !pb_grow(pb, total_len))
- return;
+ if (addlen == 0)
+ return 0;
- memcpy(pb->string + pb->len, addend, addlen);
- pb->len += addlen;
-}
+ add_slash = (pb->len != 0);
+ if (add_slash)
+ addlen++;
-static void
-add_slashed(struct path_builder *pb, char const *addend, size_t addlen)
-{
- /* Normalize first */
- switch (addlen) {
- case 1:
- if (addend[0] == '.')
- return;
- break;
- case 2:
- if (addend[0] == '.' && addend[1] == '.') {
- pb_pop(pb, false);
- return;
- }
- break;
+ total_len = pb->len + addlen + 1;
+ if (total_len > pb->capacity) {
+ error = pb_grow(pb, total_len, addend);
+ if (error)
+ return error;
}
- /* Ok, do */
- if (pb->len > 0)
- add(pb, "/", 1);
- add(pb, addend, addlen);
-}
-
-/* Do NOT include the null character in @addlen. */
-static void
-pb_append_limited(struct path_builder *pb, char const *addend, size_t addlen)
-{
- char const *wall;
- char const *next_slash;
+ if (add_slash) {
+ pb->string[pb->len] = '/';
+ memcpy(pb->string + pb->len + 1, addend, addlen);
+ } else {
+ memcpy(pb->string + pb->len, addend, addlen);
+ }
- if (pb->error)
- return;
+ pb->len += addlen;
+ pb->string[pb->len] = 0;
- do {
- for (wall = addend + addlen; addend < wall; addend++, addlen--)
- if (addend[0] != '/')
- break;
- next_slash = find_slash(addend, addlen);
- if (addend == next_slash)
- return;
- add_slashed(pb, addend, next_slash - addend);
- addlen -= next_slash - addend;
- addend = next_slash;
- } while (addlen > 0);
+ return 0;
}
-void
+int
pb_append(struct path_builder *pb, char const *addend)
{
- pb_append_limited(pb, addend, strlen(addend));
+ return pb_appendn(pb, addend, strlen(addend));
}
-void
-pb_append_guri(struct path_builder *pb, struct rpki_uri *uri)
-{
- char const *guri;
- char const *colon;
- size_t schema_len;
-
- if (pb->error)
- return;
-
- guri = uri_get_global(uri);
-
- colon = strstr(guri, ":");
- schema_len = colon - guri;
- pb_append_limited(pb, guri, schema_len);
-
- pb_append_limited(pb, colon + 3,
- uri_get_global_len(uri) - schema_len - 3);
-}
-
-void
-pb_append_uint(struct path_builder *pb, unsigned int num)
+int
+pb_append_u32(struct path_builder *pb, uint32_t num)
{
- size_t room;
+#define MAX_STRLEN 9 /* 8 hexadecimal digits plus null chara */
+ char buffer[MAX_STRLEN];
int num_len;
- if (pb->error)
- return;
-
- if (pb->len != 0 && pb->string[pb->len - 1] != '/')
- add(pb, "/", 1);
-
- room = pb->capacity - pb->len;
- num_len = snprintf(pb->string + pb->len, room, "%X", num);
- if (num_len < 0)
- goto bad_print;
- if (num_len >= room) {
- if (!pb_grow(pb, pb->len + num_len + 1))
- return;
-
- room = pb->capacity - pb->len;
- num_len = snprintf(pb->string + pb->len, room, "%X", num);
- if (num_len < 0)
- goto bad_print;
- if (num_len >= room)
- pr_crit("pb: %d %zu", num_len, room);
+ num_len = snprintf(buffer, MAX_STRLEN, "%X", num);
+ if (num_len < 0) {
+ pr_val_err("Cannot stringify number '%u': Unknown cause. Error code might be %d.",
+ num, num_len);
+ return EIO; /* num_len is not necessarily an error code */
}
+ if (num_len >= MAX_STRLEN)
+ pr_crit("pb: Number %u requires %d digits", num, num_len);
- pb->len += num_len;
- return;
-
-bad_print:
- free(pb->string);
- pb->error = EIO; /* num_len is not necessarily an error code */
+ return pb_appendn(pb, buffer, num_len);
}
/* Removes the last component added. */
-void
+int
pb_pop(struct path_builder *pb, bool fatal)
{
size_t i;
- if (pb->error)
- return;
- if (pb->len == 0) {
+ if (pb->len == 0 || (pb->len == 1 && pb->string[0] == '/')) {
if (fatal)
pr_crit("Programming error: Attempting to pop empty path builder");
- free(pb->string);
- pb->error = -pr_val_err("Path cannot '..' over the root.");
- return;
+ return -pr_val_err("Path cannot '..' over the root.");
}
for (i = pb->len - 1; i >= 1; i--) {
if (pb->string[i] == '/') {
+ pb->string[i] = 0;
pb->len = i;
- return;
+ return 0;
}
}
- pb->len = (pb->string[0] == '/') && (pb->len > 1);
+ if (pb->string[0] == '/') {
+ pb->string[1] = 0;
+ pb->len = 1;
+ } else {
+ pb->string[0] = 0;
+ pb->len = 0;
+ }
+ return 0;
}
static void
size_t min;
size_t max;
- if (pb->error)
- return;
-
reverse_string(pb->string, pb->len);
min = 0;
reverse_string(&pb->string[min], pb->len - min);
}
-/*
- * Returns @pb's current accumulated path. Do not free it.
- * Result is a temporary pointer; it becomes junk if you call any other pb
- * functions on @pb afterwards.
- */
-int
-pb_peek(struct path_builder *pb, char const **result)
-{
- add(pb, "\0", 1);
- if (pb->error)
- return pb->error;
-
- *result = pb->string;
- pb->len--;
- return 0;
-}
-
-/* Should not be called more than once. */
-int
-pb_compile(struct path_builder *pb, char **result)
-{
- add(pb, "\0", 1);
- if (pb->error)
- return pb->error;
-
- *result = pb->string;
- return 0;
-}
-
void
-pb_cancel(struct path_builder *pb)
+pb_cleanup(struct path_builder *pb)
{
free(pb->string);
}
#ifndef SRC_DATA_STRUCTURE_PATH_BUILDER_H_
#define SRC_DATA_STRUCTURE_PATH_BUILDER_H_
-/* FIXME add support for absolute paths */
-
#include <stdbool.h>
#include <stddef.h>
#include "types/uri.h"
struct path_builder {
char *string;
- size_t len;
+ size_t len; /* Includes the null chara */
size_t capacity;
- int error;
};
void pb_init(struct path_builder *);
/*
- * Note, the append()s merge slashes:
- *
- * a + b = a/b
- * a/ + b = a/b
- * a + /b = a/b
- * a/ + /b = a/b
- * a// + ///b = a/b
- * a///b + c//d = a/b/c/d
+ * The appends are atomic.
+ * They are also naive; they don't collapse `.`, `..` nor slashes.
*/
-void pb_append(struct path_builder *, char const *);
-void pb_append_guri(struct path_builder *, struct rpki_uri *);
-void pb_append_uint(struct path_builder *, unsigned int);
+int pb_appendn(struct path_builder *, char const *, size_t);
+int pb_append(struct path_builder *, char const *);
+int pb_append_u32(struct path_builder *, uint32_t);
-void pb_pop(struct path_builder *, bool);
+int pb_pop(struct path_builder *, bool);
void pb_reverse(struct path_builder *);
-int pb_peek(struct path_builder *, char const **);
-int pb_compile(struct path_builder *, char **);
-
-void pb_cancel(struct path_builder *);
+void pb_cleanup(struct path_builder *);
#endif /* SRC_DATA_STRUCTURE_PATH_BUILDER_H_ */
return 0;
}
-/*
- * Maps "rsync://a.b.c/d/e.cer" into "<local-repository>/rsync/a.b.c/d/e.cer".
- */
+struct path_parser {
+ char const *token;
+ char const *slash;
+ size_t len;
+};
+
+/* Return true if there's a new token, false if we're done. */
+static bool
+path_next(struct path_parser *parser)
+{
+ if (parser->slash == NULL)
+ return false;
+
+ parser->token = parser->slash + 1;
+ parser->slash = strchr(parser->token, '/');
+ parser->len = (parser->slash != NULL)
+ ? (parser->slash - parser->token)
+ : strlen(parser->token);
+
+ return parser->token[0] != 0;
+}
+
+static bool
+path_is_dot(struct path_parser *parser)
+{
+ return parser->len == 1 && parser->token[0] == '.';
+}
+
+static bool
+path_is_dotdots(struct path_parser *parser)
+{
+ return parser->len == 2
+ && parser->token[0] == '.'
+ && parser->token[1] == '.' ;
+}
+
static int
-map_simple(struct rpki_uri *uri, char const *gprefix, char const *lprefix,
- int err)
+append_guri(struct path_builder *pb, char const *guri, char const *gprefix,
+ int err, bool skip_schema)
{
- struct path_builder pb;
+ struct path_parser parser;
+ size_t dot_dot_limit;
int error;
- if (!str_starts_with(uri->global, gprefix)) {
- pr_val_err("URI '%s' does not begin with '%s'.",
- uri->global, lprefix);
+ /* Schema */
+ if (!str_starts_with(guri, gprefix)) {
+ pr_val_err("URI '%s' does not begin with '%s'.", guri, gprefix);
return err;
}
- pb_init(&pb);
- pb_append_guri(&pb, uri);
- error = pb_compile(&pb, &uri->local);
+ if (!skip_schema) {
+ error = pb_appendn(pb, guri, 5);
+ if (error)
+ return error;
+ }
+
+ /* Domain */
+ parser.slash = guri + 7;
+ if (!path_next(&parser))
+ return pr_val_err("URI '%s' seems to lack a domain.", guri);
+ if (path_is_dot(&parser)) {
+ /* Dumping files to the cache root is unsafe. */
+ return pr_val_err("URI '%s' employs the root domain. This is not really cacheable, so I'm going to distrust it.",
+ guri);
+ }
+ if (path_is_dotdots(&parser)) {
+ return pr_val_err("URI '%s' seems to be dot-dotting past its own schema.",
+ guri);
+ }
+ error = pb_appendn(pb, parser.token, parser.len);
if (error)
return error;
- if (!str_starts_with(uri->local, lprefix)) {
- pr_val_err("URI '%s' seems to be dot-dotting to its scheme.",
- uri->global);
- free(uri->local);
- return -EINVAL;
+ /* Other components */
+ dot_dot_limit = pb->len;
+ while (path_next(&parser)) {
+ if (path_is_dotdots(&parser)) {
+ error = pb_pop(pb, false);
+ if (error)
+ return error;
+ if (pb->len < dot_dot_limit) {
+ return pr_val_err("URI '%s' seems to be dot-dotting past its own domain.",
+ guri);
+ }
+ } else if (!path_is_dot(&parser)) {
+ error = pb_appendn(pb, parser.token, parser.len);
+ if (error)
+ return error;
+ }
}
return 0;
}
+/*
+ * Maps "rsync://a.b.c/d/e.cer" into "<local-repository>/rsync/a.b.c/d/e.cer".
+ */
+static int
+map_simple(struct rpki_uri *uri, char const *gprefix, int err)
+{
+ struct path_builder pb;
+ int error;
+
+ pb_init(&pb);
+ error = append_guri(&pb, uri->global, gprefix, err, false);
+ if (error) {
+ pb_cleanup(&pb);
+ return error;
+ }
+
+ uri->local = pb.string;
+ return 0;
+}
+
/*
* Maps "rsync://a.b.c/d/e.cer" into
* "<local-repository>/rrdp/<notification-path>/a.b.c/d/e.cer".
{
struct path_builder pb;
struct rpki_uri *notification;
+ int error;
notification = validation_get_notification_uri(state_retrieve());
if (notification == NULL)
pb_init(&pb);
- pb_append(&pb, "rrdp");
- pb_append_guri(&pb, notification);
- pb_append_guri(&pb, uri);
+ error = pb_append(&pb, "rrdp");
+ if (error)
+ return error;
+ error = append_guri(&pb, notification->global, "https://", ENOTHTTPS, true);
+ if (error)
+ return error;
+ error = append_guri(&pb, uri->global, "rsync://", ENOTRSYNC, true);
+ if (error)
+ return error;
- return pb_compile(&pb, &uri->local);
+ uri->local = pb.string;
+ return 0;
}
static int
{
switch (uri->type) {
case UT_RSYNC:
- return map_simple(uri, "rsync://", "rsync/", ENOTRSYNC);
+ return map_simple(uri, "rsync://", ENOTRSYNC);
case UT_HTTPS:
- return map_simple(uri, "https://", "https/", ENOTHTTPS);
+ return map_simple(uri, "https://", ENOTHTTPS);
case UT_CAGED:
return map_caged(uri);
}
}
ck_assert_ptr_eq(expected_parent, actual->parent);
- pb_append(pb, expected->basename);
+ ck_assert_int_eq(0, pb_append(pb, expected->basename));
HASH_ITER(hh, expected->children, expected_child, tmp) {
HASH_FIND_STR(actual->children, expected_child->basename,
static void
validate_file(struct cache_node *expected, struct path_builder *pb)
{
- char const *path;
struct stat meta;
DIR *dir;
struct dirent *file;
if (expected == NULL)
return;
- pb_append(pb, expected->basename);
- ck_assert_int_eq(0, pb_peek(pb, &path));
+ ck_assert_int_eq(0, pb_append(pb, expected->basename));
if (is_rsync(expected)) {
/* Currently, the unit tests do not fake rsync files */
}
must_be_file:
- ck_assert_int_eq(0, stat(path, &meta));
+ ck_assert_int_eq(0, stat(pb->string, &meta));
ck_assert_int_eq(1, S_ISREG(meta.st_mode));
goto end;
must_be_dir:
errno = 0;
- dir = opendir(path);
+ dir = opendir(pb->string);
error = errno;
ck_assert_int_eq(0, error);
ck_assert_ptr_nonnull(dir);
HASH_FIND_STR(expected->children, file->d_name, child);
if (child == NULL) {
ck_abort_msg("file %s/%s is not supposed to exist.",
- path, file->d_name);
+ pb->string, file->d_name);
}
validate_file(child, pb);
ck_assert_int_eq(0, error);
HASH_ITER(hh, expected->children, child, tmp)
- search_dir(dir, path, child->basename);
+ search_dir(dir, pb->string, child->basename);
closedir(dir);
end:
}
pb_init(&pb);
- pb_append(&pb, "tmp");
+ ck_assert_int_eq(0, pb_append(&pb, "tmp"));
validate_node(nodes, NULL, actual, &pb);
validate_file(files, &pb);
- pb_cancel(&pb);
+ pb_cleanup(&pb);
delete_node(nodes);
if (nodes != files)
#include "mock.c"
#include "data_structure/path_builder.c"
-/* Mocks */
-
-__MOCK_ABORT(uri_get_global, char const *, NULL, struct rpki_uri *uri)
-__MOCK_ABORT(uri_get_global_len, size_t, 0, struct rpki_uri *uri)
-
-/* Tests */
-
-#define CHECK_PB(_len, _capacity, _error) \
- ck_assert_uint_eq(_len, pb.len); \
- ck_assert_uint_eq(_capacity, pb.capacity); \
- ck_assert_int_eq(_error, pb.error)
-
-#define CHECK_RESULTS(expected) \
- ck_assert_uint_eq(0, pb_peek(&pb, &peek_result)); \
- ck_assert_str_eq(expected, peek_result); \
- ck_assert_uint_eq(0, pb_compile(&pb, &compile_result)); \
- ck_assert_str_eq(expected, compile_result); \
- free(compile_result);
-
-#define CHECK_ERROR \
- ck_assert_uint_eq(EINVAL, pb_peek(&pb, &peek_result)); \
- ck_assert_uint_eq(EINVAL, pb_compile(&pb, &compile_result));
+#define CHECK_PB(_string, _capacity) \
+ ck_assert_str_eq(_string, pb.string); \
+ ck_assert_uint_eq(strlen(_string), pb.len); \
+ ck_assert_uint_eq(_capacity, pb.capacity);
START_TEST(test_append)
{
struct path_builder pb;
- char const *peek_result;
- char *compile_result;
pb_init(&pb);
- pb_append(&pb, "");
- CHECK_PB(0, 8, 0);
- CHECK_RESULTS("");
+ ck_assert_int_eq(0, pb_append(&pb, ""));
+ CHECK_PB("", 8);
+ pb_cleanup(&pb);
+
+ pb_init(&pb);
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
+ CHECK_PB("a", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "a");
- CHECK_PB(1, 8, 0);
- CHECK_RESULTS("a");
+ ck_assert_int_eq(0, pb_append(&pb, "/a"));
+ CHECK_PB("/a", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "a");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "b");
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("a/b");
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
+ CHECK_PB("a", 8);
+ ck_assert_int_eq(0, pb_append(&pb, "b"));
+ CHECK_PB("a/b", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "a/b");
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("a/b");
+ ck_assert_int_eq(0, pb_append(&pb, "a/b"));
+ CHECK_PB("a/b", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "a/");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "b/");
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("a/b");
+ ck_assert_int_eq(0, pb_append(&pb, "a/"));
+ CHECK_PB("a/", 8);
+ ck_assert_int_eq(0, pb_append(&pb, "b/"));
+ CHECK_PB("a//b/", 8);
+ pb_cleanup(&pb);
- /* notes from .h */
pb_init(&pb);
- pb_append(&pb, "a/");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "b");
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("a/b");
+ ck_assert_int_eq(0, pb_append(&pb, "a/"));
+ CHECK_PB("a/", 8);
+ ck_assert_int_eq(0, pb_append(&pb, "b"));
+ CHECK_PB("a//b", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "a");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "/b");
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("a/b");
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
+ CHECK_PB("a", 8);
+ ck_assert_int_eq(0, pb_append(&pb, "/b"));
+ CHECK_PB("a//b", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "a/");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "/b");
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("a/b");
+ ck_assert_int_eq(0, pb_append(&pb, "a/"));
+ CHECK_PB("a/", 8);
+ ck_assert_int_eq(0, pb_append(&pb, "/b"));
+ CHECK_PB("a///b", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "//a");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "///");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "b////");
- CHECK_PB(3, 8, 0);
- pb_append(&pb, "/////c//////");
- CHECK_PB(5, 8, 0);
- CHECK_RESULTS("a/b/c");
+ ck_assert_int_eq(0, pb_append(&pb, "//a"));
+ CHECK_PB("//a", 8);
+ ck_assert_int_eq(0, pb_append(&pb, "///"));
+ CHECK_PB("//a////", 8);
+ ck_assert_int_eq(0, pb_append(&pb, "b////"));
+ CHECK_PB("//a/////b////", 16);
+ ck_assert_int_eq(0, pb_append(&pb, "/////c//////"));
+ CHECK_PB("//a/////b//////////c//////", 32);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "//a///b//c//");
- CHECK_PB(5, 8, 0);
- CHECK_RESULTS("a/b/c");
+ ck_assert_int_eq(0, pb_append(&pb, "//a///b//c//"));
+ CHECK_PB("//a///b//c//", 16);
+ pb_cleanup(&pb);
}
END_TEST
START_TEST(test_uint)
{
struct path_builder pb;
- char const *peek_result;
- char *compile_result;
pb_init(&pb);
- pb_append_uint(&pb, 291);
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("123"); /* hex */
+ pb_append_u32(&pb, 0x123);
+ CHECK_PB("123", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append_uint(&pb, 19088743);
- CHECK_PB(7, 8, 0);
- CHECK_RESULTS("1234567");
+ pb_append_u32(&pb, 0x1234567);
+ CHECK_PB("1234567", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append_uint(&pb, 305419896);
- CHECK_PB(8, 16, 0);
- CHECK_RESULTS("12345678");
+ pb_append_u32(&pb, 0x12345678);
+ CHECK_PB("12345678", 16);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append_uint(&pb, 74565);
- CHECK_PB(5, 8, 0);
- pb_append_uint(&pb, 7);
- CHECK_PB(7, 8, 0);
- CHECK_RESULTS("12345/7");
+ pb_append_u32(&pb, 0x12345);
+ CHECK_PB("12345", 8);
+ pb_append_u32(&pb, 0x7);
+ CHECK_PB("12345/7", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append_uint(&pb, 74565);
- CHECK_PB(5, 8, 0);
- pb_append_uint(&pb, 120);
- CHECK_PB(8, 16, 0);
- CHECK_RESULTS("12345/78");
+ pb_append_u32(&pb, 0x12345);
+ CHECK_PB("12345", 8);
+ pb_append_u32(&pb, 0x78);
+ CHECK_PB("12345/78", 16);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append_uint(&pb, 74565);
- CHECK_PB(5, 8, 0);
- pb_append_uint(&pb, 1929);
- CHECK_PB(9, 16, 0);
- CHECK_RESULTS("12345/789");
+ pb_append_u32(&pb, 0x12345);
+ CHECK_PB("12345", 8);
+ pb_append_u32(&pb, 0x789);
+ CHECK_PB("12345/789", 16);
+ pb_cleanup(&pb);
}
END_TEST
START_TEST(test_pop)
{
struct path_builder pb;
- char const *peek_result;
- char *compile_result;
-
- pb_init(&pb);
- pb_append(&pb, "a");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "b");
- CHECK_PB(3, 8, 0);
- pb_pop(&pb, false);
- CHECK_PB(1, 8, 0);
- CHECK_RESULTS("a");
-
- pb_init(&pb);
- pb_append(&pb, "abc");
- CHECK_PB(3, 8, 0);
- pb_append(&pb, "def");
- CHECK_PB(7, 8, 0);
- pb_pop(&pb, false);
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("abc");
-
- pb_init(&pb);
- pb_append(&pb, "a");
- CHECK_PB(1, 8, 0);
- pb_pop(&pb, false);
- CHECK_PB(0, 8, 0);
- CHECK_RESULTS("");
-
- pb_init(&pb);
- pb_append(&pb, "/a");
- CHECK_PB(1, 8, 0);
- pb_pop(&pb, false);
- CHECK_PB(0, 8, 0);
- CHECK_RESULTS("");
-
- pb_init(&pb);
- pb_pop(&pb, false);
- CHECK_PB(0, 8, EINVAL);
- CHECK_ERROR;
-
- pb_init(&pb);
- pb_append(&pb, "a");
- pb_pop(&pb, false);
- CHECK_PB(0, 8, 0);
- pb_pop(&pb, false);
- CHECK_PB(0, 8, EINVAL);
- CHECK_ERROR;
-
-// pb_init(&pb);
-// pb_append(&pb, "/");
-// CHECK_PB(1, 8, 0);
-// pb_pop(&pb);
-// CHECK_PB(0, 8, 0);
-// CHECK_RESULTS("");
-//
-// pb_init(&pb);
-// pb_append(&pb, "///");
-// CHECK_PB(3, 8, 0);
-// pb_pop(&pb);
-// CHECK_PB(2, 8, 0);
-// pb_pop(&pb);
-// CHECK_PB(1, 8, 0);
-// pb_pop(&pb);
-// CHECK_PB(0, 8, 0);
-// CHECK_RESULTS("");
-}
-END_TEST
-
-START_TEST(test_peek)
-{
- struct path_builder pb;
- char const *peek_result;
-
- /*
- * Most of pb_peek() has already been tested above,
- * just check it leaves the pb in a stable state.
- */
pb_init(&pb);
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
+ CHECK_PB("a", 8);
+ ck_assert_int_eq(0, pb_append(&pb, "b"));
+ CHECK_PB("a/b", 8);
+ ck_assert_int_eq(0, pb_pop(&pb, false));
+ CHECK_PB("a", 8);
+ pb_cleanup(&pb);
- pb_peek(&pb, &peek_result);
- ck_assert_str_eq("", peek_result);
+ pb_init(&pb);
+ ck_assert_int_eq(0, pb_append(&pb, "abc"));
+ CHECK_PB("abc", 8);
+ ck_assert_int_eq(0, pb_append(&pb, "def"));
+ CHECK_PB("abc/def", 8);
+ ck_assert_int_eq(0, pb_pop(&pb, false));
+ CHECK_PB("abc", 8);
+ pb_cleanup(&pb);
- pb_append(&pb, "a");
- pb_peek(&pb, &peek_result);
- ck_assert_str_eq("a", peek_result);
+ pb_init(&pb);
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
+ CHECK_PB("a", 8);
+ ck_assert_int_eq(0, pb_pop(&pb, false));
+ CHECK_PB("", 8);
+ pb_cleanup(&pb);
- pb_append(&pb, "b");
- pb_peek(&pb, &peek_result);
- ck_assert_str_eq("a/b", peek_result);
+ pb_init(&pb);
+ ck_assert_int_eq(0, pb_append(&pb, "/a"));
+ CHECK_PB("/a", 8);
+ ck_assert_int_eq(0, pb_pop(&pb, false));
+ CHECK_PB("/", 8);
+ pb_cleanup(&pb);
- pb_pop(&pb, true);
- pb_peek(&pb, &peek_result);
- ck_assert_str_eq("a", peek_result);
+ pb_init(&pb);
+ ck_assert_int_eq(EINVAL, pb_pop(&pb, false));
+ CHECK_PB("", 8);
+ pb_cleanup(&pb);
- pb_pop(&pb, true);
- pb_peek(&pb, &peek_result);
- ck_assert_str_eq("", peek_result);
+ pb_init(&pb);
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
+ ck_assert_int_eq(0, pb_pop(&pb, false));
+ CHECK_PB("", 8);
+ ck_assert_int_eq(EINVAL, pb_pop(&pb, false));
+ CHECK_PB("", 8);
+ pb_cleanup(&pb);
- free(pb.string);
+ pb_init(&pb);
+ ck_assert_int_eq(0, pb_append(&pb, "/"));
+ CHECK_PB("/", 8);
+ ck_assert_int_eq(EINVAL, pb_pop(&pb, false));
+ CHECK_PB("/", 8);
+ pb_cleanup(&pb);
}
END_TEST
START_TEST(test_reverse)
{
struct path_builder pb;
- char const *peek_result;
- char *compile_result;
/* 0 components */
pb_init(&pb);
pb_reverse(&pb);
- CHECK_PB(0, 8, 0);
- CHECK_RESULTS("");
+ CHECK_PB("", 8);
+ pb_cleanup(&pb);
/* 1 component */
pb_init(&pb);
- pb_append(&pb, "a");
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
pb_reverse(&pb);
- CHECK_PB(1, 8, 0);
- CHECK_RESULTS("a");
+ CHECK_PB("a", 8);
+ pb_cleanup(&pb);
/* 2 components */
pb_init(&pb);
- pb_append(&pb, "a");
- pb_append(&pb, "b");
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
+ ck_assert_int_eq(0, pb_append(&pb, "b"));
pb_reverse(&pb);
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("b/a");
+ CHECK_PB("b/a", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "abc");
- pb_append(&pb, "def");
+ ck_assert_int_eq(0, pb_append(&pb, "abc"));
+ ck_assert_int_eq(0, pb_append(&pb, "def"));
pb_reverse(&pb);
- CHECK_PB(7, 8, 0);
- CHECK_RESULTS("def/abc");
+ CHECK_PB("def/abc", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "abcd");
- pb_append(&pb, "efgh");
+ ck_assert_int_eq(0, pb_append(&pb, "abcd"));
+ ck_assert_int_eq(0, pb_append(&pb, "efgh"));
pb_reverse(&pb);
- CHECK_PB(9, 16, 0);
- CHECK_RESULTS("efgh/abcd");
+ CHECK_PB("efgh/abcd", 16);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "abc");
- pb_append(&pb, "efgh");
+ ck_assert_int_eq(0, pb_append(&pb, "abc"));
+ ck_assert_int_eq(0, pb_append(&pb, "efgh"));
pb_reverse(&pb);
- CHECK_PB(8, 8, 0);
- CHECK_RESULTS("efgh/abc");
+ CHECK_PB("efgh/abc", 16);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "abcd");
- pb_append(&pb, "fgh");
+ ck_assert_int_eq(0, pb_append(&pb, "abcd"));
+ ck_assert_int_eq(0, pb_append(&pb, "fgh"));
pb_reverse(&pb);
- CHECK_PB(8, 8, 0);
- CHECK_RESULTS("fgh/abcd");
+ CHECK_PB("fgh/abcd", 16);
+ pb_cleanup(&pb);
/* 3 components */
pb_init(&pb);
- pb_append(&pb, "abc");
- pb_append(&pb, "def");
- pb_append(&pb, "ghi");
+ ck_assert_int_eq(0, pb_append(&pb, "abc"));
+ ck_assert_int_eq(0, pb_append(&pb, "def"));
+ ck_assert_int_eq(0, pb_append(&pb, "ghi"));
pb_reverse(&pb);
- CHECK_PB(11, 16, 0);
- CHECK_RESULTS("ghi/def/abc");
+ CHECK_PB("ghi/def/abc", 16);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "ab");
- pb_append(&pb, "cde");
- pb_append(&pb, "fghi");
+ ck_assert_int_eq(0, pb_append(&pb, "ab"));
+ ck_assert_int_eq(0, pb_append(&pb, "cde"));
+ ck_assert_int_eq(0, pb_append(&pb, "fghi"));
pb_reverse(&pb);
- CHECK_PB(11, 16, 0);
- CHECK_RESULTS("fghi/cde/ab");
+ CHECK_PB("fghi/cde/ab", 16);
+ pb_cleanup(&pb);
/* 4 components */
pb_init(&pb);
- pb_append(&pb, "a");
- pb_append(&pb, "b");
- pb_append(&pb, "c");
- pb_append(&pb, "d");
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
+ ck_assert_int_eq(0, pb_append(&pb, "b"));
+ ck_assert_int_eq(0, pb_append(&pb, "c"));
+ ck_assert_int_eq(0, pb_append(&pb, "d"));
pb_reverse(&pb);
- CHECK_PB(7, 8, 0);
- CHECK_RESULTS("d/c/b/a");
+ CHECK_PB("d/c/b/a", 8);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "ab");
- pb_append(&pb, "cd");
- pb_append(&pb, "ef");
- pb_append(&pb, "gh");
+ ck_assert_int_eq(0, pb_append(&pb, "ab"));
+ ck_assert_int_eq(0, pb_append(&pb, "cd"));
+ ck_assert_int_eq(0, pb_append(&pb, "ef"));
+ ck_assert_int_eq(0, pb_append(&pb, "gh"));
pb_reverse(&pb);
- CHECK_PB(11, 16, 0);
- CHECK_RESULTS("gh/ef/cd/ab");
+ CHECK_PB("gh/ef/cd/ab", 16);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "a");
- pb_append(&pb, "bcd");
- pb_append(&pb, "efgh");
- pb_append(&pb, "ijklm");
+ ck_assert_int_eq(0, pb_append(&pb, "a"));
+ ck_assert_int_eq(0, pb_append(&pb, "bcd"));
+ ck_assert_int_eq(0, pb_append(&pb, "efgh"));
+ ck_assert_int_eq(0, pb_append(&pb, "ijklm"));
pb_reverse(&pb);
- CHECK_PB(16, 16, 0);
- CHECK_RESULTS("ijklm/efgh/bcd/a");
+ CHECK_PB("ijklm/efgh/bcd/a", 32);
+ pb_cleanup(&pb);
pb_init(&pb);
- pb_append(&pb, "abcdefghijklmnopq");
- pb_append(&pb, "r");
- pb_append(&pb, "stu");
- pb_append(&pb, "vx");
+ ck_assert_int_eq(0, pb_append(&pb, "abcdefghijklmnopq"));
+ ck_assert_int_eq(0, pb_append(&pb, "r"));
+ ck_assert_int_eq(0, pb_append(&pb, "stu"));
+ ck_assert_int_eq(0, pb_append(&pb, "vx"));
pb_reverse(&pb);
- CHECK_PB(26, 32, 0);
- CHECK_RESULTS("vx/stu/r/abcdefghijklmnopq");
-}
-END_TEST
-
-START_TEST(test_normalization)
-{
- struct path_builder pb;
- char const *peek_result;
- char *compile_result;
-
- pb_init(&pb);
- pb_append(&pb, ".");
- CHECK_PB(0, 8, 0);
- CHECK_RESULTS("");
-
- pb_init(&pb);
- pb_append(&pb, "a");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, ".");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "b");
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("a/b");
-
- pb_init(&pb);
- pb_append(&pb, ".");
- CHECK_PB(0, 8, 0);
- pb_append(&pb, ".");
- CHECK_PB(0, 8, 0);
- pb_append(&pb, "a");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, ".");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, ".");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "b");
- CHECK_PB(3, 8, 0);
- pb_append(&pb, ".");
- CHECK_PB(3, 8, 0);
- pb_append(&pb, ".");
- CHECK_PB(3, 8, 0);
- CHECK_RESULTS("a/b");
-
- pb_init(&pb);
- pb_append(&pb, "..");
- CHECK_PB(0, 8, EINVAL);
- CHECK_ERROR;
-
- pb_init(&pb);
- pb_append(&pb, "a");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "b");
- CHECK_PB(3, 8, 0);
- pb_append(&pb, "..");
- CHECK_PB(1, 8, 0);
- CHECK_RESULTS("a");
-
- pb_init(&pb);
- pb_append(&pb, "a");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "b");
- CHECK_PB(3, 8, 0);
- pb_append(&pb, "..");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, ".");
- CHECK_PB(1, 8, 0);
- pb_append(&pb, "..");
- CHECK_PB(0, 8, 0);
- CHECK_RESULTS("");
-
- /* dot dot injection */
- pb_init(&pb);
- pb_append(&pb, "a/../b");
- CHECK_PB(1, 8, 0);
- CHECK_RESULTS("b");
+ CHECK_PB("vx/stu/r/abcdefghijklmnopq", 32);
+ pb_cleanup(&pb);
}
END_TEST
tcase_add_test(core, test_append);
tcase_add_test(core, test_uint);
tcase_add_test(core, test_pop);
- tcase_add_test(core, test_peek);
tcase_add_test(core, test_reverse);
- tcase_add_test(core, test_normalization);
suite = suite_create("path_builder");
suite_add_tcase(suite, core);
type name(__VA_ARGS__) { __MOCK_ABORT_MSG; return result; }
#define MOCK_ABORT_INT(name, ...) \
__MOCK_ABORT(name, int, 0, __VA_ARGS__)
-/* FIXME delete? */
-#define MOCK_ABORT_BOOL(name, ...) \
- __MOCK_ABORT(name, bool, false, __VA_ARGS__)
#define MOCK_ABORT_ENUM(name, type, ...) \
__MOCK_ABORT(name, enum type, 0, __VA_ARGS__)
#define MOCK_ABORT_PTR(name, type, ...) \
{
struct rpki_uri *uri;
- ck_assert_int_eq(0, uri_create(&uri, UT_HTTPS, "https://a.b.c/d/e"));
- ck_assert_str_eq("https://a.b.c/d/e", uri_get_global(uri));
- ck_assert_str_eq("https/a.b.c/d/e", uri_get_local(uri));
- uri_refput(uri);
+ ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, ""));
+ ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, "h"));
+ ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, "http"));
+ ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, "https"));
+ ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, "https:"));
+ ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, "https:/"));
+ ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://"));
ck_assert_int_eq(0, uri_create(&uri, UT_HTTPS, "https://a.b.c"));
ck_assert_str_eq("https://a.b.c", uri_get_global(uri));
ck_assert_str_eq("https/a.b.c", uri_get_local(uri));
uri_refput(uri);
- ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://"));
+ ck_assert_int_eq(0, uri_create(&uri, UT_HTTPS, "https://a.b.c/"));
+ ck_assert_str_eq("https://a.b.c/", uri_get_global(uri));
+ ck_assert_str_eq("https/a.b.c", uri_get_local(uri));
+ uri_refput(uri);
+
+ ck_assert_int_eq(0, uri_create(&uri, UT_HTTPS, "https://a.b.c/d"));
+ ck_assert_str_eq("https://a.b.c/d", uri_get_global(uri));
+ ck_assert_str_eq("https/a.b.c/d", uri_get_local(uri));
+ uri_refput(uri);
+
+ ck_assert_int_eq(0, uri_create(&uri, UT_HTTPS, "https://a.b.c/d/e"));
+ ck_assert_str_eq("https://a.b.c/d/e", uri_get_global(uri));
+ ck_assert_str_eq("https/a.b.c/d/e", uri_get_local(uri));
+ uri_refput(uri);
ck_assert_int_eq(0, uri_create(&uri, UT_HTTPS, "https://a.b.c/d/.."));
ck_assert_str_eq("https://a.b.c/d/..", uri_get_global(uri));
ck_assert_str_eq("https/a.b.c", uri_get_local(uri));
uri_refput(uri);
- ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://a.b.c/.."));
- ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://a.b.c/d/../.."));
-
ck_assert_int_eq(0, uri_create(&uri, UT_HTTPS, "https://a.b.c/."));
ck_assert_str_eq("https://a.b.c/.", uri_get_global(uri));
ck_assert_str_eq("https/a.b.c", uri_get_local(uri));
uri_refput(uri);
- ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, "rsync://a.b.c/d"));
- ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, ""));
- ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://.."));
+ ck_assert_int_eq(0, uri_create(&uri, UT_HTTPS, "https://a.b.c/././d/././e/./."));
+ ck_assert_str_eq("https://a.b.c/././d/././e/./.", uri_get_global(uri));
+ ck_assert_str_eq("https/a.b.c/d/e", uri_get_local(uri));
+ uri_refput(uri);
+
+ ck_assert_int_eq(0, uri_create(&uri, UT_HTTPS, "https://a.b.c/a/b/.././.."));
+ ck_assert_str_eq("https://a.b.c/a/b/.././..", uri_get_global(uri));
+ ck_assert_str_eq("https/a.b.c", uri_get_local(uri));
+ uri_refput(uri);
+
+ ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://a.b.c/.."));
ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://a.b.c/../.."));
+ ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://a.b.c/d/../.."));
+ ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://a.b.c/d/../../.."));
+ ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://."));
+ ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://./."));
+ ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://.."));
+ ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://../.."));
+ ck_assert_int_eq(-EINVAL, uri_create(&uri, UT_HTTPS, "https://../../.."));
ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, "rsync://a.b.c/d"));
ck_assert_int_eq(ENOTHTTPS, uri_create(&uri, UT_HTTPS, "http://a.b.c/d"));
ck_assert_int_eq(0, uri_create(¬ification, UT_HTTPS, "https://a.b.c/d/e.xml"));
ck_assert_int_eq(0, uri_create(&uri, UT_CAGED, "rsync://x.y.z/v/w.cer"));
- ck_assert_str_eq("rrdp/https/a.b.c/d/e.xml/rsync/x.y.z/v/w.cer", uri_get_local(uri));
+ ck_assert_str_eq("rrdp/a.b.c/d/e.xml/x.y.z/v/w.cer", uri_get_local(uri));
uri_refput(uri);
uri_refput(notification);
- ck_assert_int_eq(0, uri_create(¬ification, UT_RSYNC, "rsync://a.b.c"));
- ck_assert_int_eq(0, uri_create(&uri, UT_CAGED, "https://w"));
- ck_assert_str_eq("rrdp/rsync/a.b.c/https/w", uri_get_local(uri));
+ ck_assert_int_eq(0, uri_create(¬ification, UT_HTTPS, "https://a.b.c"));
+ ck_assert_int_eq(0, uri_create(&uri, UT_CAGED, "rsync://w"));
+ ck_assert_str_eq("rrdp/a.b.c/w", uri_get_local(uri));
uri_refput(uri);
uri_refput(notification);
}