diff --git a/source/dub/dub.d b/source/dub/dub.d index 3b0f372..c29b984 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -1848,7 +1848,7 @@ import configy.Read; const str1 = `{ - "registryUrls": [ "http://foo.bar" ], + "registryUrls": [ "http://foo.bar\/optional\/escape" ], "customCachePaths": [ "foo/bar", "foo/foo" ], "skipRegistry": "all", @@ -1878,7 +1878,7 @@ }`; auto c1 = parseConfigString!UserConfiguration(str1, "/dev/null"); - assert(c1.registryUrls == [ "http://foo.bar" ]); + assert(c1.registryUrls == [ "http://foo.bar/optional/escape" ]); assert(c1.customCachePaths == [ NativePath("foo/bar"), NativePath("foo/foo") ]); assert(c1.skipRegistry == SkipPackageSuppliers.all); assert(c1.defaultCompiler == "dmd"); @@ -1901,7 +1901,7 @@ auto m1 = c2.merge(c1); // c1 takes priority, so its registryUrls is first - assert(m1.registryUrls == [ "http://foo.bar", "http://bar.foo" ]); + assert(m1.registryUrls == [ "http://foo.bar/optional/escape", "http://bar.foo" ]); // Same with CCP assert(m1.customCachePaths == [ NativePath("foo/bar"), NativePath("foo/foo"), @@ -1916,7 +1916,7 @@ assert(m1.defaultEnvironments == c1.defaultEnvironments); auto m2 = c1.merge(c2); - assert(m2.registryUrls == [ "http://bar.foo", "http://foo.bar" ]); + assert(m2.registryUrls == [ "http://bar.foo", "http://foo.bar/optional/escape" ]); assert(m2.customCachePaths == [ NativePath("bar/foo"), NativePath("bar/bar"), NativePath("foo/bar"), NativePath("foo/foo"), diff --git a/source/dyaml/escapes.d b/source/dyaml/escapes.d index 32080a2..fa70eb1 100644 --- a/source/dyaml/escapes.d +++ b/source/dyaml/escapes.d @@ -11,7 +11,7 @@ import std.meta : AliasSeq; alias escapes = AliasSeq!('0', 'a', 'b', 't', '\t', 'n', 'v', 'f', 'r', 'e', ' ', - '\"', '\\', 'N', '_', 'L', 'P'); + '/', '\"', '\\', 'N', '_', 'L', 'P'); /// YAML hex codes specifying the length of the hex number. alias escapeHexCodeList = AliasSeq!('x', 'u', 'U'); @@ -32,6 +32,7 @@ case 'r': return '\x0D'; case 'e': return '\x1B'; case ' ': return '\x20'; + case '/': return '/'; case '\"': return '\"'; case '\\': return '\\'; case 'N': return '\x85'; //'\u0085'; @@ -90,3 +91,16 @@ } } +// Issue #302: Support optional escaping of forward slashes in string +// for JSON compatibility +@safe unittest +{ + import dyaml.loader : Loader; + + const str = `{ + "forward/slashes": "can\/be\/optionally\/escaped" +}`; + + auto node = Loader.fromString(str).load(); + assert(node["forward/slashes"] == "can/be/optionally/escaped"); +}