diff options
Diffstat (limited to 't/unit-tests')
| -rw-r--r-- | t/unit-tests/t-ctype.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-hash.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-hashmap.c | 4 | ||||
| -rw-r--r-- | t/unit-tests/t-mem-pool.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-prio-queue.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-reftable-basics.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-reftable-block.c | 371 | ||||
| -rw-r--r-- | t/unit-tests/t-reftable-merged.c | 31 | ||||
| -rw-r--r-- | t/unit-tests/t-reftable-pq.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-reftable-readwrite.c | 94 | ||||
| -rw-r--r-- | t/unit-tests/t-reftable-record.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-reftable-tree.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-strbuf.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-strcmp-offset.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-strvec.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-trailer.c | 2 | ||||
| -rw-r--r-- | t/unit-tests/t-urlmatch-normalization.c | 271 |
17 files changed, 715 insertions, 80 deletions
diff --git a/t/unit-tests/t-ctype.c b/t/unit-tests/t-ctype.c index e28a7f50f9..6043f0d9bc 100644 --- a/t/unit-tests/t-ctype.c +++ b/t/unit-tests/t-ctype.c @@ -31,7 +31,7 @@ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ "\x7f" -int cmd_main(int argc, const char **argv) { +int cmd_main(int argc UNUSED, const char **argv UNUSED) { TEST_CHAR_CLASS(isspace, " \n\r\t"); TEST_CHAR_CLASS(isdigit, DIGIT); TEST_CHAR_CLASS(isalpha, LOWER UPPER); diff --git a/t/unit-tests/t-hash.c b/t/unit-tests/t-hash.c index e9a78bf2c0..e62647019b 100644 --- a/t/unit-tests/t-hash.c +++ b/t/unit-tests/t-hash.c @@ -38,7 +38,7 @@ static void check_hash_data(const void *data, size_t data_length, "SHA1 and SHA256 (%s) works", #literal); \ } while (0) -int cmd_main(int argc, const char **argv) +int cmd_main(int argc UNUSED, const char **argv UNUSED) { struct strbuf aaaaaaaaaa_100000 = STRBUF_INIT; struct strbuf alphabet_100000 = STRBUF_INIT; diff --git a/t/unit-tests/t-hashmap.c b/t/unit-tests/t-hashmap.c index 09a48c2c4e..83b79dff39 100644 --- a/t/unit-tests/t-hashmap.c +++ b/t/unit-tests/t-hashmap.c @@ -322,7 +322,7 @@ static void t_alloc(struct hashmap *map, unsigned int ignore_case) free(removed); } -static void t_intern(struct hashmap *map, unsigned int ignore_case) +static void t_intern(void) { const char *values[] = { "value1", "Value1", "value2", "value2" }; @@ -356,6 +356,6 @@ int cmd_main(int argc UNUSED, const char **argv UNUSED) TEST(setup(t_iterate, 0), "iterate works"); TEST(setup(t_iterate, 1), "iterate (case insensitive) works"); TEST(setup(t_alloc, 0), "grow / shrink works"); - TEST(setup(t_intern, 0), "string interning works"); + TEST(t_intern(), "string interning works"); return test_done(); } diff --git a/t/unit-tests/t-mem-pool.c b/t/unit-tests/t-mem-pool.c index a0d57df761..fe500c704b 100644 --- a/t/unit-tests/t-mem-pool.c +++ b/t/unit-tests/t-mem-pool.c @@ -20,7 +20,7 @@ static void t_calloc_100(struct mem_pool *pool) check(pool->mp_block->end != NULL); } -int cmd_main(int argc, const char **argv) +int cmd_main(int argc UNUSED, const char **argv UNUSED) { TEST(setup_static(t_calloc_100, 1024 * 1024), "mem_pool_calloc returns 100 zeroed bytes with big block"); diff --git a/t/unit-tests/t-prio-queue.c b/t/unit-tests/t-prio-queue.c index 7a4e5780e1..fe6ae37935 100644 --- a/t/unit-tests/t-prio-queue.c +++ b/t/unit-tests/t-prio-queue.c @@ -69,7 +69,7 @@ static void test_prio_queue(int *input, size_t input_size, #define TEST_INPUT(input, result) \ test_prio_queue(input, ARRAY_SIZE(input), result, ARRAY_SIZE(result)) -int cmd_main(int argc, const char **argv) +int cmd_main(int argc UNUSED, const char **argv UNUSED) { TEST(TEST_INPUT(((int []){ 2, 6, 3, 10, 9, 5, 7, 4, 5, 8, 1, DUMP }), ((int []){ 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10 })), diff --git a/t/unit-tests/t-reftable-basics.c b/t/unit-tests/t-reftable-basics.c index 1dd60ab5f0..e5556ebf52 100644 --- a/t/unit-tests/t-reftable-basics.c +++ b/t/unit-tests/t-reftable-basics.c @@ -20,7 +20,7 @@ static int integer_needle_lesseq(size_t i, void *_args) return args->needle <= args->haystack[i]; } -int cmd_main(int argc, const char *argv[]) +int cmd_main(int argc UNUSED, const char *argv[] UNUSED) { if_test ("binary search with binsearch works") { int haystack[] = { 2, 4, 6, 8, 10 }; diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c new file mode 100644 index 0000000000..f1a49485e2 --- /dev/null +++ b/t/unit-tests/t-reftable-block.c @@ -0,0 +1,371 @@ +/* +Copyright 2020 Google LLC + +Use of this source code is governed by a BSD-style +license that can be found in the LICENSE file or at +https://developers.google.com/open-source/licenses/bsd +*/ + +#include "test-lib.h" +#include "reftable/block.h" +#include "reftable/blocksource.h" +#include "reftable/constants.h" +#include "reftable/reftable-error.h" + +static void t_ref_block_read_write(void) +{ + const int header_off = 21; /* random */ + struct reftable_record recs[30]; + const size_t N = ARRAY_SIZE(recs); + const size_t block_size = 1024; + struct reftable_block block = { 0 }; + struct block_writer bw = { + .last_key = STRBUF_INIT, + }; + struct reftable_record rec = { + .type = BLOCK_TYPE_REF, + }; + size_t i = 0; + int ret; + struct block_reader br = { 0 }; + struct block_iter it = BLOCK_ITER_INIT; + struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + + REFTABLE_CALLOC_ARRAY(block.data, block_size); + block.len = block_size; + block_source_from_strbuf(&block.source ,&buf); + block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size, + header_off, hash_size(GIT_SHA1_FORMAT_ID)); + + rec.u.ref.refname = (char *) ""; + rec.u.ref.value_type = REFTABLE_REF_DELETION; + ret = block_writer_add(&bw, &rec); + check_int(ret, ==, REFTABLE_API_ERROR); + + for (i = 0; i < N; i++) { + rec.u.ref.refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); + rec.u.ref.value_type = REFTABLE_REF_VAL1; + memset(rec.u.ref.value.val1, i, GIT_SHA1_RAWSZ); + + recs[i] = rec; + ret = block_writer_add(&bw, &rec); + rec.u.ref.refname = NULL; + rec.u.ref.value_type = REFTABLE_REF_DELETION; + check_int(ret, ==, 0); + } + + ret = block_writer_finish(&bw); + check_int(ret, >, 0); + + block_writer_release(&bw); + + block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + + block_iter_seek_start(&it, &br); + + for (i = 0; ; i++) { + ret = block_iter_next(&it, &rec); + check_int(ret, >=, 0); + if (ret > 0) { + check_int(i, ==, N); + break; + } + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + } + + for (i = 0; i < N; i++) { + block_iter_reset(&it); + reftable_record_key(&recs[i], &want); + + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + + want.len--; + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + } + + block_reader_release(&br); + block_iter_close(&it); + reftable_record_release(&rec); + reftable_block_done(&br.block); + strbuf_release(&want); + strbuf_release(&buf); + for (i = 0; i < N; i++) + reftable_record_release(&recs[i]); +} + +static void t_log_block_read_write(void) +{ + const int header_off = 21; + struct reftable_record recs[30]; + const size_t N = ARRAY_SIZE(recs); + const size_t block_size = 2048; + struct reftable_block block = { 0 }; + struct block_writer bw = { + .last_key = STRBUF_INIT, + }; + struct reftable_record rec = { + .type = BLOCK_TYPE_LOG, + }; + size_t i = 0; + int ret; + struct block_reader br = { 0 }; + struct block_iter it = BLOCK_ITER_INIT; + struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + + REFTABLE_CALLOC_ARRAY(block.data, block_size); + block.len = block_size; + block_source_from_strbuf(&block.source ,&buf); + block_writer_init(&bw, BLOCK_TYPE_LOG, block.data, block_size, + header_off, hash_size(GIT_SHA1_FORMAT_ID)); + + for (i = 0; i < N; i++) { + rec.u.log.refname = xstrfmt("branch%02"PRIuMAX , (uintmax_t)i); + rec.u.log.update_index = i; + rec.u.log.value_type = REFTABLE_LOG_UPDATE; + + recs[i] = rec; + ret = block_writer_add(&bw, &rec); + rec.u.log.refname = NULL; + rec.u.log.value_type = REFTABLE_LOG_DELETION; + check_int(ret, ==, 0); + } + + ret = block_writer_finish(&bw); + check_int(ret, >, 0); + + block_writer_release(&bw); + + block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + + block_iter_seek_start(&it, &br); + + for (i = 0; ; i++) { + ret = block_iter_next(&it, &rec); + check_int(ret, >=, 0); + if (ret > 0) { + check_int(i, ==, N); + break; + } + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + } + + for (i = 0; i < N; i++) { + block_iter_reset(&it); + strbuf_reset(&want); + strbuf_addstr(&want, recs[i].u.log.refname); + + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + + want.len--; + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + } + + block_reader_release(&br); + block_iter_close(&it); + reftable_record_release(&rec); + reftable_block_done(&br.block); + strbuf_release(&want); + strbuf_release(&buf); + for (i = 0; i < N; i++) + reftable_record_release(&recs[i]); +} + +static void t_obj_block_read_write(void) +{ + const int header_off = 21; + struct reftable_record recs[30]; + const size_t N = ARRAY_SIZE(recs); + const size_t block_size = 1024; + struct reftable_block block = { 0 }; + struct block_writer bw = { + .last_key = STRBUF_INIT, + }; + struct reftable_record rec = { + .type = BLOCK_TYPE_OBJ, + }; + size_t i = 0; + int ret; + struct block_reader br = { 0 }; + struct block_iter it = BLOCK_ITER_INIT; + struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + + REFTABLE_CALLOC_ARRAY(block.data, block_size); + block.len = block_size; + block_source_from_strbuf(&block.source, &buf); + block_writer_init(&bw, BLOCK_TYPE_OBJ, block.data, block_size, + header_off, hash_size(GIT_SHA1_FORMAT_ID)); + + for (i = 0; i < N; i++) { + uint8_t bytes[] = { i, i + 1, i + 2, i + 3, i + 5 }, *allocated; + DUP_ARRAY(allocated, bytes, ARRAY_SIZE(bytes)); + + rec.u.obj.hash_prefix = allocated; + rec.u.obj.hash_prefix_len = 5; + + recs[i] = rec; + ret = block_writer_add(&bw, &rec); + rec.u.obj.hash_prefix = NULL; + rec.u.obj.hash_prefix_len = 0; + check_int(ret, ==, 0); + } + + ret = block_writer_finish(&bw); + check_int(ret, >, 0); + + block_writer_release(&bw); + + block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + + block_iter_seek_start(&it, &br); + + for (i = 0; ; i++) { + ret = block_iter_next(&it, &rec); + check_int(ret, >=, 0); + if (ret > 0) { + check_int(i, ==, N); + break; + } + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + } + + for (i = 0; i < N; i++) { + block_iter_reset(&it); + reftable_record_key(&recs[i], &want); + + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + } + + block_reader_release(&br); + block_iter_close(&it); + reftable_record_release(&rec); + reftable_block_done(&br.block); + strbuf_release(&want); + strbuf_release(&buf); + for (i = 0; i < N; i++) + reftable_record_release(&recs[i]); +} + +static void t_index_block_read_write(void) +{ + const int header_off = 21; + struct reftable_record recs[30]; + const size_t N = ARRAY_SIZE(recs); + const size_t block_size = 1024; + struct reftable_block block = { 0 }; + struct block_writer bw = { + .last_key = STRBUF_INIT, + }; + struct reftable_record rec = { + .type = BLOCK_TYPE_INDEX, + .u.idx.last_key = STRBUF_INIT, + }; + size_t i = 0; + int ret; + struct block_reader br = { 0 }; + struct block_iter it = BLOCK_ITER_INIT; + struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + + REFTABLE_CALLOC_ARRAY(block.data, block_size); + block.len = block_size; + block_source_from_strbuf(&block.source, &buf); + block_writer_init(&bw, BLOCK_TYPE_INDEX, block.data, block_size, + header_off, hash_size(GIT_SHA1_FORMAT_ID)); + + for (i = 0; i < N; i++) { + strbuf_init(&recs[i].u.idx.last_key, 9); + + recs[i].type = BLOCK_TYPE_INDEX; + strbuf_addf(&recs[i].u.idx.last_key, "branch%02"PRIuMAX, (uintmax_t)i); + recs[i].u.idx.offset = i; + + ret = block_writer_add(&bw, &recs[i]); + check_int(ret, ==, 0); + } + + ret = block_writer_finish(&bw); + check_int(ret, >, 0); + + block_writer_release(&bw); + + block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + + block_iter_seek_start(&it, &br); + + for (i = 0; ; i++) { + ret = block_iter_next(&it, &rec); + check_int(ret, >=, 0); + if (ret > 0) { + check_int(i, ==, N); + break; + } + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + } + + for (i = 0; i < N; i++) { + block_iter_reset(&it); + reftable_record_key(&recs[i], &want); + + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + + check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + + want.len--; + ret = block_iter_seek_key(&it, &br, &want); + check_int(ret, ==, 0); + + ret = block_iter_next(&it, &rec); + check_int(ret, ==, 0); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + } + + block_reader_release(&br); + block_iter_close(&it); + reftable_record_release(&rec); + reftable_block_done(&br.block); + strbuf_release(&want); + strbuf_release(&buf); + for (i = 0; i < N; i++) + reftable_record_release(&recs[i]); +} + +int cmd_main(int argc UNUSED, const char *argv[] UNUSED) +{ + TEST(t_index_block_read_write(), "read-write operations on index blocks work"); + TEST(t_log_block_read_write(), "read-write operations on log blocks work"); + TEST(t_obj_block_read_write(), "read-write operations on obj blocks work"); + TEST(t_ref_block_read_write(), "read-write operations on ref blocks work"); + + return test_done(); +} diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/t-reftable-merged.c index b6263ee8b5..e9d100a01e 100644 --- a/t/unit-tests/t-reftable-merged.c +++ b/t/unit-tests/t-reftable-merged.c @@ -12,7 +12,6 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable/merged.h" #include "reftable/reader.h" #include "reftable/reftable-error.h" -#include "reftable/reftable-generic.h" #include "reftable/reftable-merged.h" #include "reftable/reftable-writer.h" @@ -22,7 +21,7 @@ static ssize_t strbuf_add_void(void *b, const void *data, const size_t sz) return sz; } -static int noop_flush(void *arg) +static int noop_flush(void *arg UNUSED) { return 0; } @@ -94,10 +93,8 @@ merged_table_from_records(struct reftable_ref_record **refs, struct strbuf *buf, const size_t n) { struct reftable_merged_table *mt = NULL; - struct reftable_table *tabs; int err; - REFTABLE_CALLOC_ARRAY(tabs, n); REFTABLE_CALLOC_ARRAY(*readers, n); REFTABLE_CALLOC_ARRAY(*source, n); @@ -105,13 +102,12 @@ merged_table_from_records(struct reftable_ref_record **refs, write_test_table(&buf[i], refs[i], sizes[i]); block_source_from_strbuf(&(*source)[i], &buf[i]); - err = reftable_new_reader(&(*readers)[i], &(*source)[i], + err = reftable_reader_new(&(*readers)[i], &(*source)[i], "name"); check(!err); - reftable_table_from_reader(&tabs[i], (*readers)[i]); } - err = reftable_new_merged_table(&mt, tabs, n, GIT_SHA1_FORMAT_ID); + err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID); check(!err); return mt; } @@ -119,7 +115,7 @@ merged_table_from_records(struct reftable_ref_record **refs, static void readers_destroy(struct reftable_reader **readers, const size_t n) { for (size_t i = 0; i < n; i++) - reftable_reader_free(readers[i]); + reftable_reader_decref(readers[i]); reftable_free(readers); } @@ -272,10 +268,8 @@ merged_table_from_log_records(struct reftable_log_record **logs, struct strbuf *buf, const size_t n) { struct reftable_merged_table *mt = NULL; - struct reftable_table *tabs; int err; - REFTABLE_CALLOC_ARRAY(tabs, n); REFTABLE_CALLOC_ARRAY(*readers, n); REFTABLE_CALLOC_ARRAY(*source, n); @@ -283,13 +277,12 @@ merged_table_from_log_records(struct reftable_log_record **logs, write_test_log_table(&buf[i], logs[i], sizes[i], i + 1); block_source_from_strbuf(&(*source)[i], &buf[i]); - err = reftable_new_reader(&(*readers)[i], &(*source)[i], + err = reftable_reader_new(&(*readers)[i], &(*source)[i], "name"); check(!err); - reftable_table_from_reader(&tabs[i], (*readers)[i]); } - err = reftable_new_merged_table(&mt, tabs, n, GIT_SHA1_FORMAT_ID); + err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID); check(!err); return mt; } @@ -418,7 +411,6 @@ static void t_default_write_opts(void) }; int err; struct reftable_block_source source = { 0 }; - struct reftable_table *tab = reftable_calloc(1, sizeof(*tab)); uint32_t hash_id; struct reftable_reader *rd = NULL; struct reftable_merged_table *merged = NULL; @@ -434,25 +426,24 @@ static void t_default_write_opts(void) block_source_from_strbuf(&source, &buf); - err = reftable_new_reader(&rd, &source, "filename"); + err = reftable_reader_new(&rd, &source, "filename"); check(!err); hash_id = reftable_reader_hash_id(rd); check_int(hash_id, ==, GIT_SHA1_FORMAT_ID); - reftable_table_from_reader(&tab[0], rd); - err = reftable_new_merged_table(&merged, tab, 1, GIT_SHA256_FORMAT_ID); + err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA256_FORMAT_ID); check_int(err, ==, REFTABLE_FORMAT_ERROR); - err = reftable_new_merged_table(&merged, tab, 1, GIT_SHA1_FORMAT_ID); + err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA1_FORMAT_ID); check(!err); - reftable_reader_free(rd); + reftable_reader_decref(rd); reftable_merged_table_free(merged); strbuf_release(&buf); } -int cmd_main(int argc, const char *argv[]) +int cmd_main(int argc UNUSED, const char *argv[] UNUSED) { TEST(t_default_write_opts(), "merged table with default write opts"); TEST(t_merged_logs(), "merged table with multiple log updates for same ref"); diff --git a/t/unit-tests/t-reftable-pq.c b/t/unit-tests/t-reftable-pq.c index 039bd0f1f9..ada4c19f18 100644 --- a/t/unit-tests/t-reftable-pq.c +++ b/t/unit-tests/t-reftable-pq.c @@ -142,7 +142,7 @@ static void t_merged_iter_pqueue_top(void) merged_iter_pqueue_release(&pq); } -int cmd_main(int argc, const char *argv[]) +int cmd_main(int argc UNUSED, const char *argv[] UNUSED) { TEST(t_pq_record(), "pq works with record-based comparison"); TEST(t_pq_index(), "pq works with index-based comparison"); diff --git a/t/unit-tests/t-reftable-readwrite.c b/t/unit-tests/t-reftable-readwrite.c index 2ce56a0523..82bfaf3287 100644 --- a/t/unit-tests/t-reftable-readwrite.c +++ b/t/unit-tests/t-reftable-readwrite.c @@ -26,7 +26,7 @@ static ssize_t strbuf_add_void(void *b, const void *data, size_t sz) return sz; } -static int noop_flush(void *arg) +static int noop_flush(void *arg UNUSED) { return 0; } @@ -205,7 +205,7 @@ static void t_log_write_read(void) struct reftable_log_record log = { 0 }; int n; struct reftable_iterator it = { 0 }; - struct reftable_reader rd = { 0 }; + struct reftable_reader *reader; struct reftable_block_source source = { 0 }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = @@ -246,10 +246,10 @@ static void t_log_write_read(void) block_source_from_strbuf(&source, &buf); - err = init_reader(&rd, &source, "file.log"); + err = reftable_reader_new(&reader, &source, "file.log"); check(!err); - reftable_reader_init_ref_iterator(&rd, &it); + reftable_reader_init_ref_iterator(reader, &it); err = reftable_iterator_seek_ref(&it, names[N - 1]); check(!err); @@ -264,7 +264,7 @@ static void t_log_write_read(void) reftable_iterator_destroy(&it); reftable_ref_record_release(&ref); - reftable_reader_init_log_iterator(&rd, &it); + reftable_reader_init_log_iterator(reader, &it); err = reftable_iterator_seek_log(&it, ""); check(!err); @@ -285,7 +285,7 @@ static void t_log_write_read(void) /* cleanup. */ strbuf_release(&buf); free_names(names); - reader_close(&rd); + reftable_reader_decref(reader); } static void t_log_zlib_corruption(void) @@ -294,7 +294,7 @@ static void t_log_zlib_corruption(void) .block_size = 256, }; struct reftable_iterator it = { 0 }; - struct reftable_reader rd = { 0 }; + struct reftable_reader *reader; struct reftable_block_source source = { 0 }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = @@ -337,18 +337,18 @@ static void t_log_zlib_corruption(void) block_source_from_strbuf(&source, &buf); - err = init_reader(&rd, &source, "file.log"); + err = reftable_reader_new(&reader, &source, "file.log"); check(!err); - reftable_reader_init_log_iterator(&rd, &it); + reftable_reader_init_log_iterator(reader, &it); err = reftable_iterator_seek_log(&it, "refname"); check_int(err, ==, REFTABLE_ZLIB_ERROR); reftable_iterator_destroy(&it); /* cleanup. */ + reftable_reader_decref(reader); strbuf_release(&buf); - reader_close(&rd); } static void t_table_read_write_sequential(void) @@ -358,7 +358,7 @@ static void t_table_read_write_sequential(void) int N = 50; struct reftable_iterator it = { 0 }; struct reftable_block_source source = { 0 }; - struct reftable_reader rd = { 0 }; + struct reftable_reader *reader; int err = 0; int j = 0; @@ -366,10 +366,10 @@ static void t_table_read_write_sequential(void) block_source_from_strbuf(&source, &buf); - err = init_reader(&rd, &source, "file.ref"); + err = reftable_reader_new(&reader, &source, "file.ref"); check(!err); - reftable_reader_init_ref_iterator(&rd, &it); + reftable_reader_init_ref_iterator(reader, &it); err = reftable_iterator_seek_ref(&it, ""); check(!err); @@ -384,11 +384,11 @@ static void t_table_read_write_sequential(void) reftable_ref_record_release(&ref); } check_int(j, ==, N); + reftable_iterator_destroy(&it); + reftable_reader_decref(reader); strbuf_release(&buf); free_names(names); - - reader_close(&rd); } static void t_table_write_small_table(void) @@ -407,7 +407,7 @@ static void t_table_read_api(void) char **names; struct strbuf buf = STRBUF_INIT; int N = 50; - struct reftable_reader rd = { 0 }; + struct reftable_reader *reader; struct reftable_block_source source = { 0 }; int err; struct reftable_log_record log = { 0 }; @@ -417,10 +417,10 @@ static void t_table_read_api(void) block_source_from_strbuf(&source, &buf); - err = init_reader(&rd, &source, "file.ref"); + err = reftable_reader_new(&reader, &source, "file.ref"); check(!err); - reftable_reader_init_ref_iterator(&rd, &it); + reftable_reader_init_ref_iterator(reader, &it); err = reftable_iterator_seek_ref(&it, names[0]); check(!err); @@ -430,7 +430,7 @@ static void t_table_read_api(void) strbuf_release(&buf); free_names(names); reftable_iterator_destroy(&it); - reader_close(&rd); + reftable_reader_decref(reader); strbuf_release(&buf); } @@ -439,7 +439,7 @@ static void t_table_read_write_seek(int index, int hash_id) char **names; struct strbuf buf = STRBUF_INIT; int N = 50; - struct reftable_reader rd = { 0 }; + struct reftable_reader *reader; struct reftable_block_source source = { 0 }; int err; int i = 0; @@ -452,17 +452,18 @@ static void t_table_read_write_seek(int index, int hash_id) block_source_from_strbuf(&source, &buf); - err = init_reader(&rd, &source, "file.ref"); + err = reftable_reader_new(&reader, &source, "file.ref"); check(!err); - check_int(hash_id, ==, reftable_reader_hash_id(&rd)); + check_int(hash_id, ==, reftable_reader_hash_id(reader)); - if (!index) - rd.ref_offsets.index_offset = 0; - else - check_int(rd.ref_offsets.index_offset, >, 0); + if (!index) { + reader->ref_offsets.index_offset = 0; + } else { + check_int(reader->ref_offsets.index_offset, >, 0); + } for (i = 1; i < N; i++) { - reftable_reader_init_ref_iterator(&rd, &it); + reftable_reader_init_ref_iterator(reader, &it); err = reftable_iterator_seek_ref(&it, names[i]); check(!err); err = reftable_iterator_next_ref(&it, &ref); @@ -478,7 +479,7 @@ static void t_table_read_write_seek(int index, int hash_id) strbuf_addstr(&pastLast, names[N - 1]); strbuf_addstr(&pastLast, "/"); - reftable_reader_init_ref_iterator(&rd, &it); + reftable_reader_init_ref_iterator(reader, &it); err = reftable_iterator_seek_ref(&it, pastLast.buf); if (err == 0) { struct reftable_ref_record ref = { 0 }; @@ -493,7 +494,7 @@ static void t_table_read_write_seek(int index, int hash_id) strbuf_release(&buf); free_names(names); - reader_close(&rd); + reftable_reader_decref(reader); } static void t_table_read_write_seek_linear(void) @@ -525,7 +526,7 @@ static void t_table_refs_for(int indexed) int i = 0; int n; int err; - struct reftable_reader rd; + struct reftable_reader *reader; struct reftable_block_source source = { 0 }; struct strbuf buf = STRBUF_INIT; @@ -573,17 +574,17 @@ static void t_table_refs_for(int indexed) block_source_from_strbuf(&source, &buf); - err = init_reader(&rd, &source, "file.ref"); + err = reftable_reader_new(&reader, &source, "file.ref"); check(!err); if (!indexed) - rd.obj_offsets.is_present = 0; + reader->obj_offsets.is_present = 0; - reftable_reader_init_ref_iterator(&rd, &it); + reftable_reader_init_ref_iterator(reader, &it); err = reftable_iterator_seek_ref(&it, ""); check(!err); reftable_iterator_destroy(&it); - err = reftable_reader_refs_for(&rd, &it, want_hash); + err = reftable_reader_refs_for(reader, &it, want_hash); check(!err); for (j = 0; ; j++) { @@ -600,7 +601,7 @@ static void t_table_refs_for(int indexed) strbuf_release(&buf); free_names(want_names); reftable_iterator_destroy(&it); - reader_close(&rd); + reftable_reader_decref(reader); } static void t_table_refs_for_no_index(void) @@ -635,7 +636,7 @@ static void t_write_empty_table(void) block_source_from_strbuf(&source, &buf); - err = reftable_new_reader(&rd, &source, "filename"); + err = reftable_reader_new(&rd, &source, "filename"); check(!err); reftable_reader_init_ref_iterator(rd, &it); @@ -646,7 +647,7 @@ static void t_write_empty_table(void) check_int(err, >, 0); reftable_iterator_destroy(&it); - reftable_reader_free(rd); + reftable_reader_decref(rd); strbuf_release(&buf); } @@ -844,7 +845,7 @@ static void t_write_multiple_indices(void) check_int(stats->log_stats.index_offset, >, 0); block_source_from_strbuf(&source, &writer_buf); - err = reftable_new_reader(&reader, &source, "filename"); + err = reftable_reader_new(&reader, &source, "filename"); check(!err); /* @@ -857,7 +858,7 @@ static void t_write_multiple_indices(void) reftable_iterator_destroy(&it); reftable_writer_free(writer); - reftable_reader_free(reader); + reftable_reader_decref(reader); strbuf_release(&writer_buf); strbuf_release(&buf); } @@ -901,7 +902,7 @@ static void t_write_multi_level_index(void) check_int(stats->ref_stats.max_index_level, ==, 2); block_source_from_strbuf(&source, &writer_buf); - err = reftable_new_reader(&reader, &source, "filename"); + err = reftable_reader_new(&reader, &source, "filename"); check(!err); /* @@ -913,7 +914,7 @@ static void t_write_multi_level_index(void) reftable_iterator_destroy(&it); reftable_writer_free(writer); - reftable_reader_free(reader); + reftable_reader_decref(reader); strbuf_release(&writer_buf); strbuf_release(&buf); } @@ -922,11 +923,11 @@ static void t_corrupt_table_empty(void) { struct strbuf buf = STRBUF_INIT; struct reftable_block_source source = { 0 }; - struct reftable_reader rd = { 0 }; + struct reftable_reader *reader; int err; block_source_from_strbuf(&source, &buf); - err = init_reader(&rd, &source, "file.log"); + err = reftable_reader_new(&reader, &source, "file.log"); check_int(err, ==, REFTABLE_FORMAT_ERROR); } @@ -935,17 +936,18 @@ static void t_corrupt_table(void) uint8_t zeros[1024] = { 0 }; struct strbuf buf = STRBUF_INIT; struct reftable_block_source source = { 0 }; - struct reftable_reader rd = { 0 }; + struct reftable_reader *reader; int err; strbuf_add(&buf, zeros, sizeof(zeros)); block_source_from_strbuf(&source, &buf); - err = init_reader(&rd, &source, "file.log"); + err = reftable_reader_new(&reader, &source, "file.log"); check_int(err, ==, REFTABLE_FORMAT_ERROR); + strbuf_release(&buf); } -int cmd_main(int argc, const char *argv[]) +int cmd_main(int argc UNUSED, const char *argv[] UNUSED) { TEST(t_buffer(), "strbuf works as blocksource"); TEST(t_corrupt_table(), "read-write on corrupted table"); diff --git a/t/unit-tests/t-reftable-record.c b/t/unit-tests/t-reftable-record.c index cb649ee419..a7f67d4d9f 100644 --- a/t/unit-tests/t-reftable-record.c +++ b/t/unit-tests/t-reftable-record.c @@ -532,7 +532,7 @@ static void t_reftable_index_record_roundtrip(void) strbuf_release(&in.u.idx.last_key); } -int cmd_main(int argc, const char *argv[]) +int cmd_main(int argc UNUSED, const char *argv[] UNUSED) { TEST(t_reftable_ref_record_comparison(), "comparison operations work on ref record"); TEST(t_reftable_log_record_comparison(), "comparison operations work on log record"); diff --git a/t/unit-tests/t-reftable-tree.c b/t/unit-tests/t-reftable-tree.c index e7d774d774..700479d34b 100644 --- a/t/unit-tests/t-reftable-tree.c +++ b/t/unit-tests/t-reftable-tree.c @@ -75,7 +75,7 @@ static void t_infix_walk(void) tree_free(root); } -int cmd_main(int argc, const char *argv[]) +int cmd_main(int argc UNUSED, const char *argv[] UNUSED) { TEST(t_tree_search(), "tree_search works"); TEST(t_infix_walk(), "infix_walk works"); diff --git a/t/unit-tests/t-strbuf.c b/t/unit-tests/t-strbuf.c index 6027dafef7..3f4044d697 100644 --- a/t/unit-tests/t-strbuf.c +++ b/t/unit-tests/t-strbuf.c @@ -105,7 +105,7 @@ static void t_addstr(struct strbuf *buf, const void *data) check_str(buf->buf + orig_len, text); } -int cmd_main(int argc, const char **argv) +int cmd_main(int argc UNUSED, const char **argv UNUSED) { if (!TEST(t_static_init(), "static initialization works")) test_skip_all("STRBUF_INIT is broken"); diff --git a/t/unit-tests/t-strcmp-offset.c b/t/unit-tests/t-strcmp-offset.c index fe4c2706b1..6880f21161 100644 --- a/t/unit-tests/t-strcmp-offset.c +++ b/t/unit-tests/t-strcmp-offset.c @@ -24,7 +24,7 @@ static void check_strcmp_offset(const char *string1, const char *string2, expect_offset), \ "strcmp_offset(%s, %s) works", #string1, #string2) -int cmd_main(int argc, const char **argv) +int cmd_main(int argc UNUSED, const char **argv UNUSED) { TEST_STRCMP_OFFSET("abc", "abc", 0, 3); TEST_STRCMP_OFFSET("abc", "def", -1, 0); diff --git a/t/unit-tests/t-strvec.c b/t/unit-tests/t-strvec.c index c4bac8fc91..5c844cf0c9 100644 --- a/t/unit-tests/t-strvec.c +++ b/t/unit-tests/t-strvec.c @@ -19,7 +19,7 @@ } \ } while (0) -int cmd_main(int argc, const char **argv) +int cmd_main(int argc UNUSED, const char **argv UNUSED) { if_test ("static initialization") { struct strvec vec = STRVEC_INIT; diff --git a/t/unit-tests/t-trailer.c b/t/unit-tests/t-trailer.c index 2ecca359d9..e1c6ad7461 100644 --- a/t/unit-tests/t-trailer.c +++ b/t/unit-tests/t-trailer.c @@ -308,7 +308,7 @@ static void run_t_trailer_iterator(void) } } -int cmd_main(int argc, const char **argv) +int cmd_main(int argc UNUSED, const char **argv UNUSED) { run_t_trailer_iterator(); return test_done(); diff --git a/t/unit-tests/t-urlmatch-normalization.c b/t/unit-tests/t-urlmatch-normalization.c new file mode 100644 index 0000000000..1769c357b9 --- /dev/null +++ b/t/unit-tests/t-urlmatch-normalization.c @@ -0,0 +1,271 @@ +#include "test-lib.h" +#include "urlmatch.h" + +static void check_url_normalizable(const char *url, unsigned int normalizable) +{ + char *url_norm = url_normalize(url, NULL); + + if (!check_int(normalizable, ==, url_norm ? 1 : 0)) + test_msg("input url: %s", url); + free(url_norm); +} + +static void check_normalized_url(const char *url, const char *expect) +{ + char *url_norm = url_normalize(url, NULL); + + if (!check_str(url_norm, expect)) + test_msg("input url: %s", url); + free(url_norm); +} + +static void compare_normalized_urls(const char *url1, const char *url2, + unsigned int equal) +{ + char *url1_norm = url_normalize(url1, NULL); + char *url2_norm = url_normalize(url2, NULL); + + if (equal) { + if (!check_str(url1_norm, url2_norm)) + test_msg("input url1: %s\n input url2: %s", url1, + url2); + } else if (!check_int(strcmp(url1_norm, url2_norm), !=, 0)) { + test_msg(" normalized url1: %s\n normalized url2: %s\n" + " input url1: %s\n input url2: %s", + url1_norm, url2_norm, url1, url2); + } + free(url1_norm); + free(url2_norm); +} + +static void check_normalized_url_length(const char *url, size_t len) +{ + struct url_info info; + char *url_norm = url_normalize(url, &info); + + if (!check_int(info.url_len, ==, len)) + test_msg(" input url: %s\n normalized url: %s", url, + url_norm); + free(url_norm); +} + +/* Note that only "file:" URLs should be allowed without a host */ +static void t_url_scheme(void) +{ + check_url_normalizable("", 0); + check_url_normalizable("_", 0); + check_url_normalizable("scheme", 0); + check_url_normalizable("scheme:", 0); + check_url_normalizable("scheme:/", 0); + check_url_normalizable("scheme://", 0); + check_url_normalizable("file", 0); + check_url_normalizable("file:", 0); + check_url_normalizable("file:/", 0); + check_url_normalizable("file://", 1); + check_url_normalizable("://acme.co", 0); + check_url_normalizable("x_test://acme.co", 0); + check_url_normalizable("-test://acme.co", 0); + check_url_normalizable("0test://acme.co", 0); + check_url_normalizable("+test://acme.co", 0); + check_url_normalizable(".test://acme.co", 0); + check_url_normalizable("schem%6e://", 0); + check_url_normalizable("x-Test+v1.0://acme.co", 1); + check_normalized_url("AbCdeF://x.Y", "abcdef://x.y/"); +} + +static void t_url_authority(void) +{ + check_url_normalizable("scheme://user:pass@", 0); + check_url_normalizable("scheme://?", 0); + check_url_normalizable("scheme://#", 0); + check_url_normalizable("scheme:///", 0); + check_url_normalizable("scheme://:", 0); + check_url_normalizable("scheme://:555", 0); + check_url_normalizable("file://user:pass@", 1); + check_url_normalizable("file://?", 1); + check_url_normalizable("file://#", 1); + check_url_normalizable("file:///", 1); + check_url_normalizable("file://:", 1); + check_url_normalizable("file://:555", 0); + check_url_normalizable("scheme://user:pass@host", 1); + check_url_normalizable("scheme://@host", 1); + check_url_normalizable("scheme://%00@host", 1); + check_url_normalizable("scheme://%%@host", 0); + check_url_normalizable("scheme://host_", 1); + check_url_normalizable("scheme://user:pass@host/", 1); + check_url_normalizable("scheme://@host/", 1); + check_url_normalizable("scheme://host/", 1); + check_url_normalizable("scheme://host?x", 1); + check_url_normalizable("scheme://host#x", 1); + check_url_normalizable("scheme://host/@", 1); + check_url_normalizable("scheme://host?@x", 1); + check_url_normalizable("scheme://host#@x", 1); + check_url_normalizable("scheme://[::1]", 1); + check_url_normalizable("scheme://[::1]/", 1); + check_url_normalizable("scheme://hos%41/", 0); + check_url_normalizable("scheme://[invalid....:/", 1); + check_url_normalizable("scheme://invalid....:]/", 1); + check_url_normalizable("scheme://invalid....:[/", 0); + check_url_normalizable("scheme://invalid....:[", 0); +} + +static void t_url_port(void) +{ + check_url_normalizable("xyz://q@some.host:", 1); + check_url_normalizable("xyz://q@some.host:456/", 1); + check_url_normalizable("xyz://q@some.host:0", 0); + check_url_normalizable("xyz://q@some.host:0000000", 0); + check_url_normalizable("xyz://q@some.host:0000001?", 1); + check_url_normalizable("xyz://q@some.host:065535#", 1); + check_url_normalizable("xyz://q@some.host:65535", 1); + check_url_normalizable("xyz://q@some.host:65536", 0); + check_url_normalizable("xyz://q@some.host:99999", 0); + check_url_normalizable("xyz://q@some.host:100000", 0); + check_url_normalizable("xyz://q@some.host:100001", 0); + check_url_normalizable("http://q@some.host:80", 1); + check_url_normalizable("https://q@some.host:443", 1); + check_url_normalizable("http://q@some.host:80/", 1); + check_url_normalizable("https://q@some.host:443?", 1); + check_url_normalizable("http://q@:8008", 0); + check_url_normalizable("http://:8080", 0); + check_url_normalizable("http://:", 0); + check_url_normalizable("xyz://q@some.host:456/", 1); + check_url_normalizable("xyz://[::1]:456/", 1); + check_url_normalizable("xyz://[::1]:/", 1); + check_url_normalizable("xyz://[::1]:000/", 0); + check_url_normalizable("xyz://[::1]:0%300/", 0); + check_url_normalizable("xyz://[::1]:0x80/", 0); + check_url_normalizable("xyz://[::1]:4294967297/", 0); + check_url_normalizable("xyz://[::1]:030f/", 0); +} + +static void t_url_port_normalization(void) +{ + check_normalized_url("http://x:800", "http://x:800/"); + check_normalized_url("http://x:0800", "http://x:800/"); + check_normalized_url("http://x:00000800", "http://x:800/"); + check_normalized_url("http://x:065535", "http://x:65535/"); + check_normalized_url("http://x:1", "http://x:1/"); + check_normalized_url("http://x:80", "http://x/"); + check_normalized_url("http://x:080", "http://x/"); + check_normalized_url("http://x:000000080", "http://x/"); + check_normalized_url("https://x:443", "https://x/"); + check_normalized_url("https://x:0443", "https://x/"); + check_normalized_url("https://x:000000443", "https://x/"); +} + +static void t_url_general_escape(void) +{ + check_url_normalizable("http://x.y?%fg", 0); + check_normalized_url("X://W/%7e%41^%3a", "x://w/~A%5E%3A"); + check_normalized_url("X://W/:/?#[]@", "x://w/:/?#[]@"); + check_normalized_url("X://W/$&()*+,;=", "x://w/$&()*+,;="); + check_normalized_url("X://W/'", "x://w/'"); + check_normalized_url("X://W?!", "x://w/?!"); +} + +static void t_url_high_bit(void) +{ + check_normalized_url( + "x://q/\x01\x02\x03\x04\x05\x06\x07\x08\x0e\x0f\x10\x11\x12", + "x://q/%01%02%03%04%05%06%07%08%0E%0F%10%11%12"); + check_normalized_url( + "x://q/\x13\x14\x15\x16\x17\x18\x19\x1b\x1c\x1d\x1e\x1f\x7f", + "x://q/%13%14%15%16%17%18%19%1B%1C%1D%1E%1F%7F"); + check_normalized_url( + "x://q/\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f", + "x://q/%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F"); + check_normalized_url( + "x://q/\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", + "x://q/%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F"); + check_normalized_url( + "x://q/\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + "x://q/%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF"); + check_normalized_url( + "x://q/\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", + "x://q/%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF"); + check_normalized_url( + "x://q/\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", + "x://q/%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF"); + check_normalized_url( + "x://q/\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf", + "x://q/%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF"); + check_normalized_url( + "x://q/\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef", + "x://q/%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF"); + check_normalized_url( + "x://q/\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", + "x://q/%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF"); +} + +static void t_url_utf8_escape(void) +{ + check_normalized_url( + "x://q/\xc2\x80\xdf\xbf\xe0\xa0\x80\xef\xbf\xbd\xf0\x90\x80\x80\xf0\xaf\xbf\xbd", + "x://q/%C2%80%DF%BF%E0%A0%80%EF%BF%BD%F0%90%80%80%F0%AF%BF%BD"); +} + +static void t_url_username_pass(void) +{ + check_normalized_url("x://%41%62(^):%70+d@foo", "x://Ab(%5E):p+d@foo/"); +} + +static void t_url_length(void) +{ + check_normalized_url_length("Http://%4d%65:%4d^%70@The.Host", 25); + check_normalized_url_length("http://%41:%42@x.y/%61/", 17); + check_normalized_url_length("http://@x.y/^", 15); +} + +static void t_url_dots(void) +{ + check_normalized_url("x://y/.", "x://y/"); + check_normalized_url("x://y/./", "x://y/"); + check_normalized_url("x://y/a/.", "x://y/a"); + check_normalized_url("x://y/a/./", "x://y/a/"); + check_normalized_url("x://y/.?", "x://y/?"); + check_normalized_url("x://y/./?", "x://y/?"); + check_normalized_url("x://y/a/.?", "x://y/a?"); + check_normalized_url("x://y/a/./?", "x://y/a/?"); + check_normalized_url("x://y/a/./b/.././../c", "x://y/c"); + check_normalized_url("x://y/a/./b/../.././c/", "x://y/c/"); + check_normalized_url("x://y/a/./b/.././../c/././.././.", "x://y/"); + check_url_normalizable("x://y/a/./b/.././../c/././.././..", 0); + check_normalized_url("x://y/a/./?/././..", "x://y/a/?/././.."); + check_normalized_url("x://y/%2e/", "x://y/"); + check_normalized_url("x://y/%2E/", "x://y/"); + check_normalized_url("x://y/a/%2e./", "x://y/"); + check_normalized_url("x://y/b/.%2E/", "x://y/"); + check_normalized_url("x://y/c/%2e%2E/", "x://y/"); +} + +/* + * "http://@foo" specifies an empty user name but does not specify a password. + * "http://foo" specifies neither a user name nor a password. + * So they should not be equivalent. + */ +static void t_url_equivalents(void) +{ + compare_normalized_urls("httP://x", "Http://X/", 1); + compare_normalized_urls("Http://%4d%65:%4d^%70@The.Host", "hTTP://Me:%4D^p@the.HOST:80/", 1); + compare_normalized_urls("https://@x.y/^", "httpS://x.y:443/^", 0); + compare_normalized_urls("https://@x.y/^", "httpS://@x.y:0443/^", 1); + compare_normalized_urls("https://@x.y/^/../abc", "httpS://@x.y:0443/abc", 1); + compare_normalized_urls("https://@x.y/^/..", "httpS://@x.y:0443/", 1); +} + +int cmd_main(int argc UNUSED, const char **argv UNUSED) +{ + TEST(t_url_scheme(), "url scheme"); + TEST(t_url_authority(), "url authority"); + TEST(t_url_port(), "url port checks"); + TEST(t_url_port_normalization(), "url port normalization"); + TEST(t_url_general_escape(), "url general escapes"); + TEST(t_url_high_bit(), "url high-bit escapes"); + TEST(t_url_utf8_escape(), "url utf8 escapes"); + TEST(t_url_username_pass(), "url username/password escapes"); + TEST(t_url_length(), "url normalized lengths"); + TEST(t_url_dots(), "url . and .. segments"); + TEST(t_url_equivalents(), "url equivalents"); + return test_done(); +} |
