aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--serd/serd.h8
-rw-r--r--src/node.c5
-rw-r--r--tests/serd_test.c12
3 files changed, 16 insertions, 9 deletions
diff --git a/serd/serd.h b/serd/serd.h
index 4388c3b4..94679a46 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -423,6 +423,11 @@ serd_node_new_uri_from_string(const uint8_t* str,
/**
Create a new file URI node from a file system path and optional hostname.
+
+ Backslashes in Windows paths will be converted and '%' will always be
+ percent encoded. If @c escape is true, all other invalid characters will be
+ percent encoded as well.
+
If @c path is relative, @c hostname is ignored.
If @c out is not NULL, it will be set to the parsed URI.
*/
@@ -430,7 +435,8 @@ SERD_API
SerdNode
serd_node_new_file_uri(const uint8_t* path,
const uint8_t* hostname,
- SerdURI* out);
+ SerdURI* out,
+ bool escape);
/**
Create a new node by serialising @c uri into a new string.
diff --git a/src/node.c b/src/node.c
index 1644b6fc..fce2b4cb 100644
--- a/src/node.c
+++ b/src/node.c
@@ -139,7 +139,8 @@ SERD_API
SerdNode
serd_node_new_file_uri(const uint8_t* path,
const uint8_t* hostname,
- SerdURI* out)
+ SerdURI* out,
+ bool escape)
{
const size_t path_len = strlen((const char*)path);
const size_t hostname_len = hostname ? strlen((const char*)hostname) : 0;
@@ -161,7 +162,7 @@ serd_node_new_file_uri(const uint8_t* path,
serd_chunk_sink("/", 1, &chunk);
} else if (path[i] == '%') {
serd_chunk_sink("%%", 2, &chunk);
- } else if (is_uri_path_char(path[i])) {
+ } else if (!escape || is_uri_path_char(path[i])) {
serd_chunk_sink(path + i, 1, &chunk);
} else {
char escape[4] = { '%', 0, 0, 0 };
diff --git a/tests/serd_test.c b/tests/serd_test.c
index 50e761a5..3a4584ed 100644
--- a/tests/serd_test.c
+++ b/tests/serd_test.c
@@ -255,7 +255,7 @@ main()
// Test serd_node_new_file_uri and serd_file_uri_parse
SerdURI furi;
const uint8_t* path_str = USTR("C:/My 100%");
- SerdNode file_node = serd_node_new_file_uri(path_str, 0, &furi);
+ SerdNode file_node = serd_node_new_file_uri(path_str, 0, &furi, true);
uint8_t* hostname = NULL;
uint8_t* out_path = serd_file_uri_parse(file_node.buf, &hostname);
if (strcmp((const char*)file_node.buf, "file:///C:/My%20100%%")) {
@@ -270,7 +270,7 @@ main()
serd_node_free(&file_node);
path_str = USTR("C:\\Pointless Space");
- file_node = serd_node_new_file_uri(path_str, USTR("pwned"), 0);
+ file_node = serd_node_new_file_uri(path_str, USTR("pwned"), 0, true);
hostname = NULL;
out_path = serd_file_uri_parse(file_node.buf, &hostname);
if (strcmp((const char*)file_node.buf, "file://pwned/C:/Pointless%20Space")) {
@@ -286,7 +286,7 @@ main()
serd_node_free(&file_node);
path_str = USTR("/foo/bar");
- file_node = serd_node_new_file_uri(path_str, 0, 0);
+ file_node = serd_node_new_file_uri(path_str, 0, 0, true);
hostname = NULL;
out_path = serd_file_uri_parse(file_node.buf, &hostname);
if (strcmp((const char*)file_node.buf, "file:///foo/bar")) {
@@ -301,7 +301,7 @@ main()
serd_node_free(&file_node);
path_str = USTR("/foo/bar");
- file_node = serd_node_new_file_uri(path_str, USTR("localhost"), 0);
+ file_node = serd_node_new_file_uri(path_str, USTR("localhost"), 0, true);
out_path = serd_file_uri_parse(file_node.buf, &hostname);
if (strcmp((const char*)file_node.buf, "file://localhost/foo/bar")) {
return failure("Bad URI %s\n", file_node.buf);
@@ -316,9 +316,9 @@ main()
serd_node_free(&file_node);
path_str = USTR("a/relative path");
- file_node = serd_node_new_file_uri(path_str, 0, 0);
+ file_node = serd_node_new_file_uri(path_str, 0, 0, false);
out_path = serd_file_uri_parse(file_node.buf, &hostname);
- if (strcmp((const char*)file_node.buf, "a/relative%20path")) {
+ if (strcmp((const char*)file_node.buf, "a/relative path")) {
return failure("Bad URI %s\n", file_node.buf);
} else if (hostname) {
return failure("hostname `%s' shouldn't exist\n", hostname);