1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/basictypes.h"
6#include "net/base/data_url.h"
7#include "testing/gtest/include/gtest/gtest.h"
8#include "url/gurl.h"
9
10namespace {
11
12struct ParseTestData {
13  const char* url;
14  bool is_valid;
15  const char* mime_type;
16  const char* charset;
17  const char* data;
18};
19
20}
21
22TEST(DataURLTest, Parse) {
23  const ParseTestData tests[] = {
24    { "data:",
25       false,
26       "",
27       "",
28       "" },
29
30    { "data:,",
31      true,
32      "text/plain",
33      "US-ASCII",
34      "" },
35
36    { "data:;base64,",
37      true,
38      "text/plain",
39      "US-ASCII",
40      "" },
41
42    { "data:;charset=,test",
43      true,
44      "text/plain",
45      "US-ASCII",
46      "test" },
47
48    { "data:TeXt/HtMl,<b>x</b>",
49      true,
50      "text/html",
51      "US-ASCII",
52      "<b>x</b>" },
53
54    { "data:,foo",
55      true,
56      "text/plain",
57      "US-ASCII",
58      "foo" },
59
60    { "data:;base64,aGVsbG8gd29ybGQ=",
61      true,
62      "text/plain",
63      "US-ASCII",
64      "hello world" },
65
66    { "data:foo/bar;baz=1;charset=kk,boo",
67      true,
68      "foo/bar",
69      "kk",
70      "boo" },
71
72    { "data:foo/bar;charset=kk;baz=1,boo",
73      true,
74      "foo/bar",
75      "kk",
76      "boo" },
77
78    { "data:text/html,%3Chtml%3E%3Cbody%3E%3Cb%3Ehello%20world"
79          "%3C%2Fb%3E%3C%2Fbody%3E%3C%2Fhtml%3E",
80      true,
81      "text/html",
82      "US-ASCII",
83      "<html><body><b>hello world</b></body></html>" },
84
85    { "data:text/html,<html><body><b>hello world</b></body></html>",
86      true,
87      "text/html",
88      "US-ASCII",
89      "<html><body><b>hello world</b></body></html>" },
90
91    // Bad mime type
92    { "data:f(oo/bar;baz=1;charset=kk,boo",
93      false,
94      "",
95      "",
96      "" },
97
98    // the comma cannot be url-escaped!
99    { "data:%2Cblah",
100      false,
101      "",
102      "",
103      "" },
104
105    // invalid base64 content
106    { "data:;base64,aGVs_-_-",
107      false,
108      "",
109      "",
110      "" },
111
112    // Spaces should be removed from non-text data URLs (we already tested
113    // spaces above).
114    { "data:image/fractal,a b c d e f g",
115      true,
116      "image/fractal",
117      "US-ASCII",
118      "abcdefg" },
119
120    // Spaces should also be removed from anything base-64 encoded
121    { "data:;base64,aGVs bG8gd2  9ybGQ=",
122      true,
123      "text/plain",
124      "US-ASCII",
125      "hello world" },
126
127    // Other whitespace should also be removed from anything base-64 encoded.
128    { "data:;base64,aGVs bG8gd2  \n9ybGQ=",
129      true,
130      "text/plain",
131      "US-ASCII",
132      "hello world" },
133
134    // In base64 encoding, escaped whitespace should be stripped.
135    // (This test was taken from acid3)
136    // http://b/1054495
137    { "data:text/javascript;base64,%20ZD%20Qg%0D%0APS%20An%20Zm91cic%0D%0A%207"
138          "%20",
139      true,
140      "text/javascript",
141      "US-ASCII",
142      "d4 = 'four';" },
143
144    // Only unescaped whitespace should be stripped in non-base64.
145    // http://b/1157796
146    { "data:img/png,A  B  %20  %0A  C",
147      true,
148      "img/png",
149      "US-ASCII",
150      "AB \nC" },
151
152    { "data:text/plain;charset=utf-8;base64,SGVsbMO2",
153      true,
154      "text/plain",
155      "utf-8",
156      "Hell\xC3\xB6" },
157
158    // Not sufficiently padded.
159    { "data:;base64,aGVsbG8gd29ybGQ",
160      true,
161      "text/plain",
162      "US-ASCII",
163      "hello world" },
164
165    // Bad encoding (truncated).
166    { "data:;base64,aGVsbG8gd29yb",
167      false,
168      "",
169      "",
170      "" },
171
172    // TODO(darin): add more interesting tests
173  };
174
175  for (size_t i = 0; i < arraysize(tests); ++i) {
176    std::string mime_type;
177    std::string charset;
178    std::string data;
179    bool ok =
180        net::DataURL::Parse(GURL(tests[i].url), &mime_type, &charset, &data);
181    EXPECT_EQ(ok, tests[i].is_valid);
182    if (tests[i].is_valid) {
183      EXPECT_EQ(tests[i].mime_type, mime_type);
184      EXPECT_EQ(tests[i].charset, charset);
185      EXPECT_EQ(tests[i].data, data);
186    }
187  }
188}
189