From 48648e4330b224391307343198152cce4f446874 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 29 Jan 2015 22:49:40 +0000 Subject: Add lilv_file_uri_parse() for correct URI to path conversion. git-svn-id: http://svn.drobilla.net/lad/trunk/lilv@5528 a436a847-0d15-0410-975c-d299462d15a1 --- NEWS | 5 +++-- lilv/lilv.h | 20 +++++++++++++++++++- src/instance.c | 7 +++++-- src/lib.c | 6 +++++- src/util.c | 6 ++++++ test/lilv_test.c | 12 ------------ wscript | 2 +- 7 files changed, 39 insertions(+), 19 deletions(-) diff --git a/NEWS b/NEWS index 10986ad..60fc3c5 100644 --- a/NEWS +++ b/NEWS @@ -1,13 +1,14 @@ -lilv (0.20.1) unstable; +lilv (0.21.1) unstable; * Fix loading files with spaces in their path + * Add lilv_file_uri_parse() for correct URI to path conversion * Tolerate passing NULL to lilv_state_restore() * Fix a few minor/unlikely memory errors * Configure based on compiler target OS for cross-compilation * Windows fixes (thanks John Emmas) * Minor documentation improvements - -- David Robillard Wed, 10 Dec 2014 14:32:08 -0500 + -- David Robillard Thu, 29 Jan 2015 17:40:17 -0500 lilv (0.20.0) stable; diff --git a/lilv/lilv.h b/lilv/lilv.h index faaade4..ca63e90 100644 --- a/lilv/lilv.h +++ b/lilv/lilv.h @@ -45,6 +45,11 @@ #else # define LILV_API #endif +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +# define LILV_DEPRECATED __attribute__((__deprecated__)) +#else +# define LILV_DEPRECATED +#endif #ifdef __cplusplus extern "C" { @@ -104,11 +109,24 @@ typedef void LilvNodes; /**< set. */ Convert a file URI string to a local path string. For example, "file://foo/bar/baz.ttl" returns "/foo/bar/baz.ttl". Return value is shared and must not be deleted by caller. + This function does not handle escaping correctly and should not be used for + general file URIs. Use lilv_file_uri_parse() instead. @return `uri` converted to a path, or NULL on failure (URI is not local). */ -LILV_API const char* +LILV_API LILV_DEPRECATED const char* lilv_uri_to_path(const char* uri); +/** + Convert a file URI string to a local path string. + For example, "file://foo/bar%20one/baz.ttl" returns "/foo/bar one/baz.ttl". + Return value must be freed by caller. + @param uri The file URI to parse. + @param hostname If non-NULL, set to the hostname in the URI, if any. + @return `uri` converted to a path, or NULL on failure (URI is not local). +*/ +LILV_API char* +lilv_file_uri_parse(const char* uri, char** hostname); + /** Create a new URI value. Returned value must be freed by caller with lilv_node_free(). diff --git a/src/instance.c b/src/instance.c index a3e2c91..ef64405 100644 --- a/src/instance.c +++ b/src/instance.c @@ -33,11 +33,12 @@ lilv_plugin_instantiate(const LilvPlugin* plugin, const LilvNode* const lib_uri = lilv_plugin_get_library_uri(plugin); const LilvNode* const bundle_uri = lilv_plugin_get_bundle_uri(plugin); - const char* bundle_path = lilv_uri_to_path( - lilv_node_as_uri(lilv_plugin_get_bundle_uri(plugin))); + char* const bundle_path = lilv_file_uri_parse( + lilv_node_as_uri(lilv_plugin_get_bundle_uri(plugin)), NULL); LilvLib* lib = lilv_lib_open(plugin->world, lib_uri, bundle_path, features); if (!lib) { + free(bundle_path); return NULL; } @@ -46,6 +47,7 @@ lilv_plugin_instantiate(const LilvPlugin* plugin, SerdURI base_uri; if (serd_uri_parse((const uint8_t*)bundle_uri_str, &base_uri)) { lilv_lib_close(lib); + free(bundle_path); return NULL; } @@ -93,6 +95,7 @@ lilv_plugin_instantiate(const LilvPlugin* plugin, } free(local_features); + free(bundle_path); if (result) { // Failed to instantiate diff --git a/src/lib.c b/src/lib.c index 22c0437..ddf3d8e 100644 --- a/src/lib.c +++ b/src/lib.c @@ -33,7 +33,7 @@ lilv_lib_open(LilvWorld* world, } const char* const lib_uri = lilv_node_as_uri(uri); - const char* const lib_path = lilv_uri_to_path(lib_uri); + char* const lib_path = lilv_file_uri_parse(lib_uri, NULL); if (!lib_path) { return NULL; } @@ -42,6 +42,7 @@ lilv_lib_open(LilvWorld* world, void* lib = dlopen(lib_path, RTLD_NOW); if (!lib) { LILV_ERRORF("Failed to open library %s (%s)\n", lib_path, dlerror()); + free(lib_path); return NULL; } @@ -56,14 +57,17 @@ lilv_lib_open(LilvWorld* world, desc = ldf(bundle_path, features); if (!desc) { LILV_ERRORF("Call to `lv2_lib_descriptor' in %s failed\n", lib_path); + free(lib_path); return NULL; } } else if (!df) { LILV_ERRORF("No `lv2_descriptor' or `lv2_lib_descriptor' in %s\n", lib_path); dlclose(lib); + free(lib_path); return NULL; } + free(lib_path); LilvLib* llib = (LilvLib*)malloc(sizeof(LilvLib)); llib->world = world; diff --git a/src/util.c b/src/util.c index 65688b2..31c9238 100644 --- a/src/util.c +++ b/src/util.c @@ -118,6 +118,12 @@ lilv_uri_to_path(const char* uri) return (const char*)serd_uri_to_path((const uint8_t*)uri); } +char* +lilv_file_uri_parse(const char* uri, char** hostname) +{ + return (char*)serd_file_uri_parse((const uint8_t*)uri, (uint8_t**)hostname); +} + /** Return the current LANG converted to Turtle (i.e. RFC3066) style. * For example, if LANG is set to "en_CA.utf-8", this returns "en-ca". */ diff --git a/test/lilv_test.c b/test/lilv_test.c index 6d652c1..a1b8f04 100644 --- a/test/lilv_test.c +++ b/test/lilv_test.c @@ -214,17 +214,6 @@ cleanup_uris(void) /*****************************************************************************/ -static int -test_utils(void) -{ - TEST_ASSERT(!strcmp(lilv_uri_to_path("file:///tmp/blah"), "/tmp/blah")); - TEST_ASSERT(!lilv_uri_to_path("file:/example.org/blah")); - TEST_ASSERT(!lilv_uri_to_path("http://example.org/blah")); - return 1; -} - -/*****************************************************************************/ - static int test_value(void) { @@ -1867,7 +1856,6 @@ test_string(void) /* add tests here */ static struct TestCase tests[] = { - TEST_CASE(utils), TEST_CASE(value), TEST_CASE(verify), TEST_CASE(no_verify), diff --git a/wscript b/wscript index d2af25e..b222bf0 100644 --- a/wscript +++ b/wscript @@ -12,7 +12,7 @@ import waflib.Logs as Logs # major increment <=> incompatible changes # minor increment <=> compatible changes (additions) # micro increment <=> no interface changes -LILV_VERSION = '0.20.1' +LILV_VERSION = '0.21.1' LILV_MAJOR_VERSION = '0' # Mandatory waf variables -- cgit v1.2.1