15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/data_url.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParseTestData {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* url;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_valid;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* mime_type;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* charset;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* data;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(DataURLTest, Parse) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ParseTestData tests[] = {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:",
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       false,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "",
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "",
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "" },
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:,",
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain",
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "" },
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:;base64,",
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain",
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "" },
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:;charset=,test",
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      false,
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "",
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "",
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "" },
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:TeXt/HtMl,<b>x</b>",
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html",
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "<b>x</b>" },
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:,foo",
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain",
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foo" },
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:;base64,aGVsbG8gd29ybGQ=",
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain",
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "hello world" },
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch    // Allow invalid mediatype for backward compatibility but set mime_type to
67ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch    // "text/plain" instead of the invalid mediatype.
68ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch    { "data:foo,boo",
69ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      true,
70ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      "text/plain",
71ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      "US-ASCII",
72ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      "boo" },
73ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch
74ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch    // When accepting an invalid mediatype, override charset with "US-ASCII"
75ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch    { "data:foo;charset=UTF-8,boo",
76ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      true,
77ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      "text/plain",
78ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      "US-ASCII",
79ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      "boo" },
80ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch
81ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch    // Invalid mediatype. Includes a slash but the type part is not a token.
82ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch    { "data:f(oo/bar;baz=1;charset=kk,boo",
83ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      true,
84ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      "text/plain",
85ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      "US-ASCII",
86ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      "boo" },
87ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:foo/bar;baz=1;charset=kk,boo",
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foo/bar",
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "kk",
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "boo" },
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:foo/bar;charset=kk;baz=1,boo",
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foo/bar",
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "kk",
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "boo" },
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:text/html,%3Chtml%3E%3Cbody%3E%3Cb%3Ehello%20world"
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "%3C%2Fb%3E%3C%2Fbody%3E%3C%2Fhtml%3E",
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html",
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "<html><body><b>hello world</b></body></html>" },
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:text/html,<html><body><b>hello world</b></body></html>",
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/html",
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "<html><body><b>hello world</b></body></html>" },
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the comma cannot be url-escaped!
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:%2Cblah",
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "" },
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // invalid base64 content
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:;base64,aGVs_-_-",
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "" },
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Spaces should be removed from non-text data URLs (we already tested
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // spaces above).
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:image/fractal,a b c d e f g",
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "image/fractal",
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "abcdefg" },
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Spaces should also be removed from anything base-64 encoded
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:;base64,aGVs bG8gd2  9ybGQ=",
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain",
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "hello world" },
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Other whitespace should also be removed from anything base-64 encoded.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:;base64,aGVs bG8gd2  \n9ybGQ=",
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain",
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "hello world" },
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In base64 encoding, escaped whitespace should be stripped.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (This test was taken from acid3)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // http://b/1054495
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:text/javascript;base64,%20ZD%20Qg%0D%0APS%20An%20Zm91cic%0D%0A%207"
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "%20",
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/javascript",
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "d4 = 'four';" },
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only unescaped whitespace should be stripped in non-base64.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // http://b/1157796
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:img/png,A  B  %20  %0A  C",
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "img/png",
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "AB \nC" },
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:text/plain;charset=utf-8;base64,SGVsbMO2",
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain",
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "utf-8",
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Hell\xC3\xB6" },
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not sufficiently padded.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:;base64,aGVsbG8gd29ybGQ",
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "text/plain",
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "US-ASCII",
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "hello world" },
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Bad encoding (truncated).
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "data:;base64,aGVsbG8gd29yb",
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "" },
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(darin): add more interesting tests
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(tests); ++i) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string mime_type;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string charset;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string data;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ok =
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::DataURL::Parse(GURL(tests[i].url), &mime_type, &charset, &data);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ok, tests[i].is_valid);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].is_valid) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].mime_type, mime_type);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].charset, charset);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].data, data);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
204