diff --git a/index.html b/index.html index bc904e6..74e832f 100644 --- a/index.html +++ b/index.html @@ -1852,6 +1852,11 @@

Validators

local hostnames such as 10.0.1.1 or localhost. The default is false. +
  • + allowDataUrl - A boolean that if true allows + data URLs as defined in RFC 2397. + The default is false +
  • validate({website: "http://google.com"}, {website: {url: true}});
     // => undefined
    @@ -1881,6 +1886,19 @@ 

    Validators

    } } }); +// => undefined + +validate({website: "data:,Hello%2C%20World!"}, {website: {url: true}}); +// => {"website": ["Website is not a valid url"]} + +validate({website: "data:,Hello%2C%20World!"}, { + website: { + url: { + allowDataUrl: true + } + } + } +); // => undefined
    diff --git a/specs/validators/url-spec.js b/specs/validators/url-spec.js index eefb9df..8fe7f38 100644 --- a/specs/validators/url-spec.js +++ b/specs/validators/url-spec.js @@ -118,6 +118,20 @@ describe("validators.url", function() { expect(url("http://nicklas:password@localhost:4711/foo", {allowLocal: true})).not.toBeDefined(); }); + it("allows data urls", function () { + //Examples from https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs + expect(url("data:,Hello%2C%20World!", { allowDataUrl: true })).not.toBeDefined(); + expect(url("data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D", { allowDataUrl: true })).not.toBeDefined(); + expect(url("data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E", { allowDataUrl: true })).not.toBeDefined(); + }); + + it("fails data urls without the option", function () { + //Examples from https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs + expect(url("data:,Hello%2C%20World!", { allowDataUrl: false })).toBeDefined(); + expect(url("data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D", { allowDataUrl: false })).toBeDefined(); + expect(url("data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E", { allowDataUrl: false })).toBeDefined(); + }); + it("allows custom schemes option is set", function() { var options = {schemes: ['ftp', 'jdbc']}; expect(url("ftp://foo.bar.com", options)).not.toBeDefined(); diff --git a/validate.js b/validate.js index 610d0bc..2b0e653 100644 --- a/validate.js +++ b/validate.js @@ -1099,8 +1099,8 @@ var message = options.message || this.message || "is not a valid url" , schemes = options.schemes || this.schemes || ['http', 'https'] - , allowLocal = options.allowLocal || this.allowLocal || false; - + , allowLocal = options.allowLocal || this.allowLocal || false + , allowDataUrl = options.allowDataUrl || this.allowDataUrl || false; if (!v.isString(value)) { return message; } @@ -1149,6 +1149,14 @@ "(?:[/?#]\\S*)?" + "$"; + if (allowDataUrl) { + // RFC 2397 + var mediaType = "\\w+\\/[-+.\\w]+(?:;[\\w=]+)*"; + var urlchar = "[A-Za-z0-9-_.!~\\*'();\\/?:@&=+$,%]*"; + var dataurl = "data:(?:"+mediaType+")?(?:;base64)?,"+urlchar; + regex = "(?:"+regex+")|(?:^"+dataurl+"$)"; + } + var PATTERN = new RegExp(regex, 'i'); if (!PATTERN.exec(value)) { return message;