OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/image_decoder.h" | 5 #include "chrome/browser/image_decoder.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
9 #include "chrome/grit/generated_resources.h" | 9 #include "chrome/grit/generated_resources.h" |
10 #include "chrome/test/base/in_process_browser_test.h" | 10 #include "chrome/test/base/in_process_browser_test.h" |
11 #include "content/public/browser/browser_child_process_observer.h" | 11 #include "content/public/browser/browser_child_process_observer.h" |
12 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
13 #include "content/public/browser/child_process_data.h" | 13 #include "content/public/browser/child_process_data.h" |
14 #include "content/public/test/test_utils.h" | 14 #include "content/public/test/test_utils.h" |
15 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
16 | 16 |
17 using content::BrowserThread; | 17 using content::BrowserThread; |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 std::string GetValidPngString() { | 21 std::vector<uint8_t> GetValidPngData() { |
22 // 1x1 PNG. Does not get much smaller than this. | 22 // 1x1 PNG. Does not get much smaller than this. |
23 static const char kPngData[] = | 23 static const char kPngData[] = |
24 "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" | 24 "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" |
25 "\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90\x77\x53" | 25 "\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90\x77\x53" |
26 "\xde\x00\x00\x00\x0c\x49\x44\x41\x54\x08\xd7\x63\xf8\xff\xff\x3f" | 26 "\xde\x00\x00\x00\x0c\x49\x44\x41\x54\x08\xd7\x63\xf8\xff\xff\x3f" |
27 "\x00\x05\xfe\x02\xfe\xdc\xcc\x59\xe7\x00\x00\x00\x00\x49\x45\x4e" | 27 "\x00\x05\xfe\x02\xfe\xdc\xcc\x59\xe7\x00\x00\x00\x00\x49\x45\x4e" |
28 "\x44\xae\x42\x60\x82"; | 28 "\x44\xae\x42\x60\x82"; |
29 // Need to specify the buffer size because it contains NULs. | 29 // Need to specify the buffer size because it contains NULs. |
30 return std::string(kPngData, sizeof(kPngData) - 1); | 30 return std::vector<uint8_t>(kPngData, kPngData + sizeof(kPngData) - 1); |
31 } | 31 } |
32 | 32 |
33 #if defined(OS_CHROMEOS) | 33 #if defined(OS_CHROMEOS) |
34 | 34 |
35 std::string GetValidJpgString() { | 35 std::vector<uint8_t> GetValidJpgData() { |
36 // 1x1 JPG created from the 1x1 PNG above. | 36 // 1x1 JPG created from the 1x1 PNG above. |
37 static const char kJpgData[] = | 37 static const char kJpgData[] = |
38 "\xFF\xD8\xFF\xE0\x00\x10\x4A\x46\x49\x46\x00\x01\x01\x01\x00\x48" | 38 "\xFF\xD8\xFF\xE0\x00\x10\x4A\x46\x49\x46\x00\x01\x01\x01\x00\x48" |
39 "\x00\x48\x00\x00\xFF\xDB\x00\x43\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" | 39 "\x00\x48\x00\x00\xFF\xDB\x00\x43\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" |
40 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" | 40 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" |
41 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" | 41 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" |
42 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" | 42 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" |
43 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xDB\x00\x43\x01\xFF\xFF" | 43 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xDB\x00\x43\x01\xFF\xFF" |
44 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" | 44 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" |
45 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" | 45 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" |
46 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" | 46 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" |
47 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0" | 47 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0" |
48 "\x00\x11\x08\x00\x01\x00\x01\x03\x01\x22\x00\x02\x11\x01\x03\x11" | 48 "\x00\x11\x08\x00\x01\x00\x01\x03\x01\x22\x00\x02\x11\x01\x03\x11" |
49 "\x01\xFF\xC4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00" | 49 "\x01\xFF\xC4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00" |
50 "\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xC4\x00\x14\x10\x01\x00\x00" | 50 "\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xC4\x00\x14\x10\x01\x00\x00" |
51 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xC4" | 51 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xC4" |
52 "\x00\x14\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | 52 "\x00\x14\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
53 "\x00\x00\x00\x00\xFF\xC4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00" | 53 "\x00\x00\x00\x00\xFF\xC4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00" |
54 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xDA\x00\x0C\x03\x01" | 54 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xDA\x00\x0C\x03\x01" |
55 "\x00\x02\x11\x03\x11\x00\x3F\x00\xA0\x00\xFF\xD9"; | 55 "\x00\x02\x11\x03\x11\x00\x3F\x00\xA0\x00\xFF\xD9"; |
56 // Need to specify the buffer size because it contains NULs. | 56 // Need to specify the buffer size because it contains NULs. |
57 return std::string(kJpgData, sizeof(kJpgData) - 1); | 57 return std::vector<uint8_t>(kJpgData, kJpgData + sizeof(kJpgData) - 1); |
58 } | 58 } |
59 | 59 |
60 #endif // defined(OS_CHROMEOS) | 60 #endif // defined(OS_CHROMEOS) |
61 | 61 |
62 class TestImageRequest : public ImageDecoder::ImageRequest { | 62 class TestImageRequest : public ImageDecoder::ImageRequest { |
63 public: | 63 public: |
64 explicit TestImageRequest(const base::Closure& quit_closure) | 64 explicit TestImageRequest(const base::Closure& quit_closure) |
65 : decode_succeeded_(false), | 65 : decode_succeeded_(false), |
66 quit_closure_(quit_closure), | 66 quit_closure_(quit_closure), |
67 quit_called_(false) { | 67 quit_called_(false) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 | 156 |
157 } // namespace | 157 } // namespace |
158 | 158 |
159 class ImageDecoderBrowserTest : public InProcessBrowserTest { | 159 class ImageDecoderBrowserTest : public InProcessBrowserTest { |
160 }; | 160 }; |
161 | 161 |
162 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, Basic) { | 162 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, Basic) { |
163 scoped_refptr<content::MessageLoopRunner> runner = | 163 scoped_refptr<content::MessageLoopRunner> runner = |
164 new content::MessageLoopRunner; | 164 new content::MessageLoopRunner; |
165 TestImageRequest test_request(runner->QuitClosure()); | 165 TestImageRequest test_request(runner->QuitClosure()); |
166 ImageDecoder::Start(&test_request, std::string()); | 166 ImageDecoder::Start(&test_request, std::vector<uint8_t>()); |
167 runner->Run(); | 167 runner->Run(); |
168 EXPECT_FALSE(test_request.decode_succeeded()); | 168 EXPECT_FALSE(test_request.decode_succeeded()); |
169 } | 169 } |
170 | 170 |
171 #if defined(OS_CHROMEOS) | 171 #if defined(OS_CHROMEOS) |
172 | 172 |
| 173 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, BasicDecodeWithOptionsString) { |
| 174 scoped_refptr<content::MessageLoopRunner> runner = |
| 175 new content::MessageLoopRunner; |
| 176 TestImageRequest test_request(runner->QuitClosure()); |
| 177 const std::vector<uint8_t> data = GetValidPngData(); |
| 178 ImageDecoder::StartWithOptions(&test_request, |
| 179 std::string(data.begin(), data.end()), |
| 180 ImageDecoder::ROBUST_PNG_CODEC, |
| 181 false /* shrink_to_fit */); |
| 182 runner->Run(); |
| 183 EXPECT_TRUE(test_request.decode_succeeded()); |
| 184 } |
| 185 |
173 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustJpegCodecWithJpegData) { | 186 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustJpegCodecWithJpegData) { |
174 scoped_refptr<content::MessageLoopRunner> runner = | 187 scoped_refptr<content::MessageLoopRunner> runner = |
175 new content::MessageLoopRunner; | 188 new content::MessageLoopRunner; |
176 TestImageRequest test_request(runner->QuitClosure()); | 189 TestImageRequest test_request(runner->QuitClosure()); |
177 ImageDecoder::StartWithOptions(&test_request, GetValidJpgString(), | 190 ImageDecoder::StartWithOptions(&test_request, GetValidJpgData(), |
178 ImageDecoder::ROBUST_JPEG_CODEC, | 191 ImageDecoder::ROBUST_JPEG_CODEC, |
179 false /* shrink_to_fit */); | 192 false /* shrink_to_fit */); |
180 runner->Run(); | 193 runner->Run(); |
181 EXPECT_TRUE(test_request.decode_succeeded()); | 194 EXPECT_TRUE(test_request.decode_succeeded()); |
182 } | 195 } |
183 | 196 |
184 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustJpegCodecWithPngData) { | 197 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustJpegCodecWithPngData) { |
185 scoped_refptr<content::MessageLoopRunner> runner = | 198 scoped_refptr<content::MessageLoopRunner> runner = |
186 new content::MessageLoopRunner; | 199 new content::MessageLoopRunner; |
187 TestImageRequest test_request(runner->QuitClosure()); | 200 TestImageRequest test_request(runner->QuitClosure()); |
188 ImageDecoder::StartWithOptions(&test_request, GetValidPngString(), | 201 ImageDecoder::StartWithOptions(&test_request, GetValidPngData(), |
189 ImageDecoder::ROBUST_JPEG_CODEC, | 202 ImageDecoder::ROBUST_JPEG_CODEC, |
190 false /* shrink_to_fit */); | 203 false /* shrink_to_fit */); |
191 runner->Run(); | 204 runner->Run(); |
192 // Should fail with PNG data because only JPEG data is allowed. | 205 // Should fail with PNG data because only JPEG data is allowed. |
193 EXPECT_FALSE(test_request.decode_succeeded()); | 206 EXPECT_FALSE(test_request.decode_succeeded()); |
194 } | 207 } |
195 | 208 |
196 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustPngCodecWithPngData) { | 209 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustPngCodecWithPngData) { |
197 scoped_refptr<content::MessageLoopRunner> runner = | 210 scoped_refptr<content::MessageLoopRunner> runner = |
198 new content::MessageLoopRunner; | 211 new content::MessageLoopRunner; |
199 TestImageRequest test_request(runner->QuitClosure()); | 212 TestImageRequest test_request(runner->QuitClosure()); |
200 ImageDecoder::StartWithOptions(&test_request, GetValidPngString(), | 213 ImageDecoder::StartWithOptions(&test_request, GetValidPngData(), |
201 ImageDecoder::ROBUST_PNG_CODEC, | 214 ImageDecoder::ROBUST_PNG_CODEC, |
202 false /* shrink_to_fit */); | 215 false /* shrink_to_fit */); |
203 runner->Run(); | 216 runner->Run(); |
204 EXPECT_TRUE(test_request.decode_succeeded()); | 217 EXPECT_TRUE(test_request.decode_succeeded()); |
205 } | 218 } |
206 | 219 |
207 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustPngCodecWithJpegData) { | 220 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, RobustPngCodecWithJpegData) { |
208 scoped_refptr<content::MessageLoopRunner> runner = | 221 scoped_refptr<content::MessageLoopRunner> runner = |
209 new content::MessageLoopRunner; | 222 new content::MessageLoopRunner; |
210 TestImageRequest test_request(runner->QuitClosure()); | 223 TestImageRequest test_request(runner->QuitClosure()); |
211 ImageDecoder::StartWithOptions(&test_request, GetValidJpgString(), | 224 ImageDecoder::StartWithOptions(&test_request, GetValidJpgData(), |
212 ImageDecoder::ROBUST_PNG_CODEC, | 225 ImageDecoder::ROBUST_PNG_CODEC, |
213 false /* shrink_to_fit */); | 226 false /* shrink_to_fit */); |
214 runner->Run(); | 227 runner->Run(); |
215 // Should fail with JPEG data because only PNG data is allowed. | 228 // Should fail with JPEG data because only PNG data is allowed. |
216 EXPECT_FALSE(test_request.decode_succeeded()); | 229 EXPECT_FALSE(test_request.decode_succeeded()); |
217 } | 230 } |
218 | 231 |
219 #endif // defined(OS_CHROMEOS) | 232 #endif // defined(OS_CHROMEOS) |
220 | 233 |
221 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, BasicDecode) { | 234 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, BasicDecode) { |
222 scoped_refptr<content::MessageLoopRunner> runner = | 235 scoped_refptr<content::MessageLoopRunner> runner = |
223 new content::MessageLoopRunner; | 236 new content::MessageLoopRunner; |
224 TestImageRequest test_request(runner->QuitClosure()); | 237 TestImageRequest test_request(runner->QuitClosure()); |
225 ImageDecoder::Start(&test_request, GetValidPngString()); | 238 ImageDecoder::Start(&test_request, GetValidPngData()); |
226 runner->Run(); | 239 runner->Run(); |
227 EXPECT_TRUE(test_request.decode_succeeded()); | 240 EXPECT_TRUE(test_request.decode_succeeded()); |
228 } | 241 } |
| 242 |
| 243 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, BasicDecodeString) { |
| 244 scoped_refptr<content::MessageLoopRunner> runner = |
| 245 new content::MessageLoopRunner; |
| 246 TestImageRequest test_request(runner->QuitClosure()); |
| 247 const std::vector<uint8_t> data = GetValidPngData(); |
| 248 ImageDecoder::Start(&test_request, std::string(data.begin(), data.end())); |
| 249 runner->Run(); |
| 250 EXPECT_TRUE(test_request.decode_succeeded()); |
| 251 } |
229 | 252 |
230 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, StartAndDestroy) { | 253 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, StartAndDestroy) { |
231 scoped_refptr<content::MessageLoopRunner> runner = | 254 scoped_refptr<content::MessageLoopRunner> runner = |
232 new content::MessageLoopRunner; | 255 new content::MessageLoopRunner; |
233 std::unique_ptr<TestImageRequest> test_request( | 256 std::unique_ptr<TestImageRequest> test_request( |
234 new TestImageRequest(runner->QuitClosure())); | 257 new TestImageRequest(runner->QuitClosure())); |
235 ImageDecoder::Start(test_request.get(), std::string()); | 258 ImageDecoder::Start(test_request.get(), std::vector<uint8_t>()); |
236 test_request.reset(); | 259 test_request.reset(); |
237 runner->Run(); | 260 runner->Run(); |
238 } | 261 } |
239 | 262 |
240 // Killing the utility process counts as a crash. Thus the request fails. | 263 // Killing the utility process counts as a crash. Thus the request fails. |
241 // If ImageDecoder did not handle the crash properly, the request never finishes | 264 // If ImageDecoder did not handle the crash properly, the request never finishes |
242 // and this test would hang. | 265 // and this test would hang. |
243 // Note: This test is inherently racy because KillProcessObserver lives on the | 266 // Note: This test is inherently racy because KillProcessObserver lives on the |
244 // UI thread but ImageDecoder does its work mainly on the IO thread. So the test | 267 // UI thread but ImageDecoder does its work mainly on the IO thread. So the test |
245 // checks for both possible valid outcomes. | 268 // checks for both possible valid outcomes. |
246 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, StartAndKillProcess) { | 269 IN_PROC_BROWSER_TEST_F(ImageDecoderBrowserTest, StartAndKillProcess) { |
247 KillProcessObserver observer; | 270 KillProcessObserver observer; |
248 scoped_refptr<content::MessageLoopRunner> runner = | 271 scoped_refptr<content::MessageLoopRunner> runner = |
249 new content::MessageLoopRunner; | 272 new content::MessageLoopRunner; |
250 TestImageRequest test_request(runner->QuitClosure()); | 273 TestImageRequest test_request(runner->QuitClosure()); |
251 ImageDecoder::Start(&test_request, GetValidPngString()); | 274 ImageDecoder::Start(&test_request, GetValidPngData()); |
252 runner->Run(); | 275 runner->Run(); |
253 if (!test_request.decode_succeeded()) { | 276 if (!test_request.decode_succeeded()) { |
254 // The UI thread won the race. Make sure the utility process did get killed. | 277 // The UI thread won the race. Make sure the utility process did get killed. |
255 EXPECT_TRUE(observer.did_kill()); | 278 EXPECT_TRUE(observer.did_kill()); |
256 } | 279 } |
257 // Else the IO thread won the race and the image got decoded. Oh well. | 280 // Else the IO thread won the race and the image got decoded. Oh well. |
258 } | 281 } |
OLD | NEW |