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    // the comma cannot be url-escaped!
92    { "data:%2Cblah",
93      false,
94      "",
95      "",
96      "" },
97
98    // invalid base64 content
99    { "data:;base64,aGVs_-_-",
100      false,
101      "",
102      "",
103      "" },
104
105    // Spaces should be removed from non-text data URLs (we already tested
106    // spaces above).
107    { "data:image/fractal,a b c d e f g",
108      true,
109      "image/fractal",
110      "US-ASCII",
111      "abcdefg" },
112
113    // Spaces should also be removed from anything base-64 encoded
114    { "data:;base64,aGVs bG8gd2  9ybGQ=",
115      true,
116      "text/plain",
117      "US-ASCII",
118      "hello world" },
119
120    // Other whitespace should also be removed from anything base-64 encoded.
121    { "data:;base64,aGVs bG8gd2  \n9ybGQ=",
122      true,
123      "text/plain",
124      "US-ASCII",
125      "hello world" },
126
127    // In base64 encoding, escaped whitespace should be stripped.
128    // (This test was taken from acid3)
129    // http://b/1054495
130    { "data:text/javascript;base64,%20ZD%20Qg%0D%0APS%20An%20Zm91cic%0D%0A%207"
131          "%20",
132      true,
133      "text/javascript",
134      "US-ASCII",
135      "d4 = 'four';" },
136
137    // Only unescaped whitespace should be stripped in non-base64.
138    // http://b/1157796
139    { "data:img/png,A  B  %20  %0A  C",
140      true,
141      "img/png",
142      "US-ASCII",
143      "AB \nC" },
144
145    { "data:text/plain;charset=utf-8;base64,SGVsbMO2",
146      true,
147      "text/plain",
148      "utf-8",
149      "Hell\xC3\xB6" },
150
151    // Not sufficiently padded.
152    { "data:;base64,aGVsbG8gd29ybGQ",
153      true,
154      "text/plain",
155      "US-ASCII",
156      "hello world" },
157
158    // Bad encoding (truncated).
159    { "data:;base64,aGVsbG8gd29yb",
160      false,
161      "",
162      "",
163      "" },
164
165    // TODO(darin): add more interesting tests
166  };
167
168  for (size_t i = 0; i < arraysize(tests); ++i) {
169    std::string mime_type;
170    std::string charset;
171    std::string data;
172    bool ok =
173        net::DataURL::Parse(GURL(tests[i].url), &mime_type, &charset, &data);
174    EXPECT_EQ(ok, tests[i].is_valid);
175    if (tests[i].is_valid) {
176      EXPECT_EQ(tests[i].mime_type, mime_type);
177      EXPECT_EQ(tests[i].charset, charset);
178      EXPECT_EQ(tests[i].data, data);
179    }
180  }
181}
182