| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ppapi/tests/test_file_chooser.h" |
| |
| #include <stddef.h> |
| |
| #include "ppapi/c/pp_errors.h" |
| #include "ppapi/c/ppb_file_io.h" |
| #include "ppapi/cpp/dev/file_chooser_dev.h" |
| #include "ppapi/cpp/file_io.h" |
| #include "ppapi/cpp/trusted/file_chooser_trusted.h" |
| #include "ppapi/cpp/var.h" |
| |
| namespace { |
| |
| // Test data written by WriteDefaultContentsToFile(). |
| const char kTestFileContents[] = "Hello from PPAPI"; |
| const size_t kTestFileContentsSizeBytes = sizeof(kTestFileContents) - 1; |
| |
| } // namespace |
| |
| REGISTER_TEST_CASE(FileChooser); |
| |
| bool TestFileChooser::Init() { |
| return CheckTestingInterface() && EnsureRunningOverHTTP(); |
| } |
| |
| void TestFileChooser::RunTests(const std::string& filter) { |
| RUN_TEST(OpenSimple, filter); |
| RUN_TEST(OpenCancel, filter); |
| RUN_TEST(SaveAsSafeDefaultName, filter); |
| RUN_TEST(SaveAsUnsafeDefaultName, filter); |
| RUN_TEST(SaveAsCancel, filter); |
| RUN_TEST(SaveAsDangerousExecutableAllowed, filter); |
| RUN_TEST(SaveAsDangerousExecutableDisallowed, filter); |
| RUN_TEST(SaveAsDangerousExtensionListDisallowed, filter); |
| } |
| |
| bool TestFileChooser::WriteDefaultContentsToFile(const pp::FileRef& file_ref) { |
| TestCompletionCallback fileio_callback(instance_->pp_instance(), |
| callback_type()); |
| pp::FileIO fileio(instance()); |
| |
| fileio_callback.WaitForResult( |
| fileio.Open(file_ref, PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE, |
| fileio_callback.GetCallback())); |
| if (fileio_callback.result() != PP_OK) |
| return false; |
| |
| fileio_callback.WaitForResult(fileio.Write(0, kTestFileContents, |
| kTestFileContentsSizeBytes, |
| fileio_callback.GetCallback())); |
| return fileio_callback.result() == kTestFileContentsSizeBytes; |
| } |
| |
| // Tests that the plugin can invoke a simple file chooser and that the returned |
| // file can be read from. Note that this test doesn't test that the accepted |
| // file type list is honored. |
| std::string TestFileChooser::TestOpenSimple() { |
| pp::FileChooser_Dev file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, "*"); |
| ASSERT_FALSE(file_chooser.is_null()); |
| |
| TestCompletionCallbackWithOutput<std::vector<pp::FileRef>> |
| filechooser_callback(instance_->pp_instance(), callback_type()); |
| filechooser_callback.WaitForResult( |
| file_chooser.Show(filechooser_callback.GetCallback())); |
| |
| const std::vector<pp::FileRef>& output_ref = filechooser_callback.output(); |
| ASSERT_EQ(1u, output_ref.size()); |
| |
| TestCompletionCallback fileio_callback(instance_->pp_instance(), |
| callback_type()); |
| pp::FileIO fileio(instance()); |
| fileio_callback.WaitForResult(fileio.Open( |
| output_ref.front(), PP_FILEOPENFLAG_READ, fileio_callback.GetCallback())); |
| ASSERT_EQ(PP_OK, fileio_callback.result()); |
| PASS(); |
| } |
| |
| // Tests the behavior when the user cancels the file chooser. Browser-side logic |
| // for simulating the cancellation can be found at |
| // ppapi_filechooser_browsertest.cc |
| std::string TestFileChooser::TestOpenCancel() { |
| pp::FileChooser_Dev file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, "*"); |
| ASSERT_FALSE(file_chooser.is_null()); |
| |
| TestCompletionCallbackWithOutput<std::vector<pp::FileRef>> |
| filechooser_callback(instance_->pp_instance(), callback_type()); |
| filechooser_callback.WaitForResult( |
| file_chooser.Show(filechooser_callback.GetCallback())); |
| |
| const std::vector<pp::FileRef>& output_ref = filechooser_callback.output(); |
| ASSERT_EQ(0u, output_ref.size()); |
| PASS(); |
| } |
| |
| // Tests that the plugin can invoke a "Save as" dialog using the |
| // FileChooser_Trusted API and that the returned FileRef can be written to. |
| std::string TestFileChooser::TestSaveAsSafeDefaultName() { |
| pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, |
| ".txt", true /* save_as */, |
| "innocuous.txt"); |
| ASSERT_FALSE(file_chooser.is_null()); |
| |
| TestCompletionCallbackWithOutput<std::vector<pp::FileRef>> |
| filechooser_callback(instance_->pp_instance(), callback_type()); |
| filechooser_callback.WaitForResult( |
| file_chooser.Show(filechooser_callback.GetCallback())); |
| |
| const std::vector<pp::FileRef>& output_ref = filechooser_callback.output(); |
| ASSERT_EQ(1u, output_ref.size()); |
| |
| ASSERT_TRUE(WriteDefaultContentsToFile(output_ref.front())); |
| PASS(); |
| } |
| |
| // Similar to the previous test, but tests that an unsafe filename passed as the |
| // suggested name is sanitized. |
| std::string TestFileChooser::TestSaveAsUnsafeDefaultName() { |
| pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, |
| "text/plain,.html", true /* save_as */, |
| "unsafe.txt "); |
| ASSERT_FALSE(file_chooser.is_null()); |
| |
| TestCompletionCallbackWithOutput<std::vector<pp::FileRef>> |
| filechooser_callback(instance_->pp_instance(), callback_type()); |
| filechooser_callback.WaitForResult( |
| file_chooser.Show(filechooser_callback.GetCallback())); |
| |
| const std::vector<pp::FileRef>& output_ref = filechooser_callback.output(); |
| ASSERT_EQ(1u, output_ref.size()); |
| ASSERT_EQ("unsafe.txt_", output_ref.front().GetName().AsString()); |
| |
| ASSERT_TRUE(WriteDefaultContentsToFile(output_ref.front())); |
| PASS(); |
| } |
| |
| // Tests the behavior when the user cancels a Save As file chooser. Requires |
| // that the test runner cancel the Save As dialog. |
| std::string TestFileChooser::TestSaveAsCancel() { |
| pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, "*", |
| true /* save as */, "anything.txt"); |
| ASSERT_FALSE(file_chooser.is_null()); |
| |
| TestCompletionCallbackWithOutput<std::vector<pp::FileRef>> |
| filechooser_callback(instance_->pp_instance(), callback_type()); |
| filechooser_callback.WaitForResult( |
| file_chooser.Show(filechooser_callback.GetCallback())); |
| |
| const std::vector<pp::FileRef>& output_ref = filechooser_callback.output(); |
| ASSERT_EQ(0u, output_ref.size()); |
| PASS(); |
| } |
| |
| // Checks that a dangerous file is allowed to be downloaded via the |
| // FileChooser_Trusted API. Chrome should delegate the decision of which files |
| // are allowed over to SafeBrowsing (if enabled), and the current SafeBrowsing |
| // configuration should allow downloading of dangerous files for this test to |
| // work. |
| std::string TestFileChooser::TestSaveAsDangerousExecutableAllowed() { |
| pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, |
| ".exe", true /* save_as */, |
| "dangerous.exe"); |
| ASSERT_FALSE(file_chooser.is_null()); |
| |
| TestCompletionCallbackWithOutput<std::vector<pp::FileRef>> |
| filechooser_callback(instance_->pp_instance(), callback_type()); |
| filechooser_callback.WaitForResult( |
| file_chooser.Show(filechooser_callback.GetCallback())); |
| |
| const std::vector<pp::FileRef>& output_ref = filechooser_callback.output(); |
| ASSERT_EQ(1u, output_ref.size()); |
| ASSERT_EQ("dangerous.exe", output_ref.front().GetName().AsString()); |
| |
| ASSERT_TRUE(WriteDefaultContentsToFile(output_ref.front())); |
| PASS(); |
| } |
| |
| // Checks that a dangerous file is not allowed to be downloaded via the |
| // FileChooser_Trusted API. Chrome should delegate the decision of which files |
| // are allowed over to SafeBrowsing (if enabled), and the current SafeBrowsing |
| // configuration should disallow downloading of dangerous files for this test to |
| // work. |
| std::string TestFileChooser::TestSaveAsDangerousExecutableDisallowed() { |
| pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, |
| ".exe", true /* save_as */, |
| "dangerous.exe"); |
| ASSERT_FALSE(file_chooser.is_null()); |
| |
| TestCompletionCallbackWithOutput<std::vector<pp::FileRef>> |
| filechooser_callback(instance_->pp_instance(), callback_type()); |
| filechooser_callback.WaitForResult( |
| file_chooser.Show(filechooser_callback.GetCallback())); |
| |
| const std::vector<pp::FileRef>& output_ref = filechooser_callback.output(); |
| ASSERT_EQ(0u, output_ref.size()); |
| PASS(); |
| } |
| |
| // Checks that a dangerous file is not allowed to be downloaded via the |
| // FileChooser_Trusted API. Chrome should delegate the decision of which files |
| // are allowed over to SafeBrowsing (if enabled), and the current SafeBrowsing |
| // configuration should disallow downloading of dangerous files for this test to |
| // work. |
| std::string TestFileChooser::TestSaveAsDangerousExtensionListDisallowed() { |
| pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, |
| ".txt,.exe", true /* save_as */, |
| "innocuous.txt"); |
| ASSERT_FALSE(file_chooser.is_null()); |
| |
| TestCompletionCallbackWithOutput<std::vector<pp::FileRef>> |
| filechooser_callback(instance_->pp_instance(), callback_type()); |
| filechooser_callback.WaitForResult( |
| file_chooser.Show(filechooser_callback.GetCallback())); |
| |
| const std::vector<pp::FileRef>& output_ref = filechooser_callback.output(); |
| ASSERT_EQ(0u, output_ref.size()); |
| PASS(); |
| } |