diff options
author | Timothy <timmot@users.noreply.github.com> | 2021-08-18 23:33:09 +1000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-09 02:34:29 +0200 |
commit | 1c78ff1b9fbecf12d02f9435b6b5b963d7db808f (patch) | |
tree | 368ac03ea9ddcc3c22bd29d02dbe50428eab5b6f /Userland | |
parent | b953588e0e5ff2118954af064cc874d3996bacb6 (diff) | |
download | serenity-1c78ff1b9fbecf12d02f9435b6b5b963d7db808f.zip |
3DFileViewer: Use unveil and FileSystemAccessServer
This will restrict 3DFileViewer's access to the file system.
3DFileViewer loads a texture based on the path of the model loaded, this
will request access to the texture file before loading.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Applications/3DFileViewer/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Userland/Applications/3DFileViewer/main.cpp | 97 |
2 files changed, 79 insertions, 21 deletions
diff --git a/Userland/Applications/3DFileViewer/CMakeLists.txt b/Userland/Applications/3DFileViewer/CMakeLists.txt index 88abb914d6..1a9b2c0233 100644 --- a/Userland/Applications/3DFileViewer/CMakeLists.txt +++ b/Userland/Applications/3DFileViewer/CMakeLists.txt @@ -2,6 +2,7 @@ serenity_component( 3DFileViewer RECOMMENDED TARGETS 3DFileViewer + DEPENDS FileSystemAccessServer ) set(SOURCES @@ -11,4 +12,4 @@ set(SOURCES ) serenity_app(3DFileViewer ICON app-3d-file-viewer) -target_link_libraries(3DFileViewer LibGUI LibGL) +target_link_libraries(3DFileViewer LibGUI LibGL LibFileSystemAccessClient) diff --git a/Userland/Applications/3DFileViewer/main.cpp b/Userland/Applications/3DFileViewer/main.cpp index a3bae3e2d4..d1ae0549ea 100644 --- a/Userland/Applications/3DFileViewer/main.cpp +++ b/Userland/Applications/3DFileViewer/main.cpp @@ -6,6 +6,7 @@ #include <LibCore/ElapsedTimer.h> #include <LibCore/File.h> +#include <LibFileSystemAccessClient/Client.h> #include <LibGL/GL/gl.h> #include <LibGL/GLContext.h> #include <LibGUI/ActionGroup.h> @@ -33,7 +34,9 @@ class GLContextWidget final : public GUI::Frame { C_OBJECT(GLContextWidget); public: - bool load(const String& fname); + bool load_path(String const& fname); + bool load_fd_and_close(int fd, String const& fname); + bool load_file(Core::File& file, String const& fname); void toggle_rotate_x() { m_rotate_x = !m_rotate_x; } void toggle_rotate_y() { m_rotate_y = !m_rotate_y; } void toggle_rotate_z() { m_rotate_z = !m_rotate_z; } @@ -191,26 +194,43 @@ void GLContextWidget::timer_event(Core::TimerEvent&) m_cycles++; } -bool GLContextWidget::load(const String& filename) +bool GLContextWidget::load_path(String const& filename) { auto file = Core::File::construct(filename); - if (!file->filename().ends_with(".obj")) { - GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: invalid file type", filename), "Error", GUI::MessageBox::Type::Error); + if (!file->open(Core::OpenMode::ReadOnly) && file->error() != ENOENT) { + GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: {}", filename, strerror(errno)), "Error", GUI::MessageBox::Type::Error); return false; } - if (!file->open(Core::OpenMode::ReadOnly) && file->error() != ENOENT) { + return load_file(file, filename); +} + +bool GLContextWidget::load_fd_and_close(int fd, String const& filename) +{ + auto file = Core::File::construct(); + + if (!file->open(fd, Core::OpenMode::ReadOnly, Core::File::ShouldCloseFileDescriptor::Yes) && file->error() != ENOENT) { GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: {}", filename, strerror(errno)), "Error", GUI::MessageBox::Type::Error); return false; } - if (file->is_device()) { + return load_file(file, filename); +} + +bool GLContextWidget::load_file(Core::File& file, String const& filename) +{ + if (!filename.ends_with(".obj")) { + GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: invalid file type", filename), "Error", GUI::MessageBox::Type::Error); + return false; + } + + if (file.is_device()) { GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: Can't open device files", filename), "Error", GUI::MessageBox::Type::Error); return false; } - if (file->is_directory()) { + if (file.is_directory()) { GUI::MessageBox::show(window(), String::formatted("Opening \"{}\" failed: Can't open directories", filename), "Error", GUI::MessageBox::Type::Error); return false; } @@ -226,8 +246,21 @@ bool GLContextWidget::load(const String& filename) builder.append(filename.split('.').at(0)); builder.append(".bmp"); + String texture_path = Core::File::absolute_path(builder.string_view()); + // Attempt to open the texture file from disk - auto texture_image = Gfx::Bitmap::try_load_from_file(builder.string_view()); + RefPtr<Gfx::Bitmap> texture_image; + if (Core::File::exists(texture_path)) { + texture_image = Gfx::Bitmap::try_load_from_file(texture_path); + } else { + auto result = FileSystemAccessClient::Client::the().request_file(window()->window_id(), builder.string_view(), Core::OpenMode::ReadOnly); + + if (result.error != 0) { + return false; + } + + texture_image = Gfx::Bitmap::try_load_from_fd_and_close(*result.fd, *result.chosen_file); + } GLuint tex; glGenTextures(1, &tex); @@ -249,11 +282,36 @@ int main(int argc, char** argv) { auto app = GUI::Application::construct(argc, argv); - if (pledge("stdio thread recvfd sendfd rpath", nullptr) < 0) { + if (pledge("stdio thread recvfd sendfd rpath unix", nullptr) < 0) { perror("pledge"); return 1; } + if (unveil("/tmp/portal/filesystemaccess", "rw") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/home/anon/Documents/3D Models/teapot.obj", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/home/anon/Documents/3D Models/teapot.bmp", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/res", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil(nullptr, nullptr) < 0) { + perror("unveil"); + return 1; + } + // Construct the main window auto window = GUI::Window::construct(); auto app_icon = GUI::Icon::default_icon("app-3d-file-viewer"); @@ -273,20 +331,16 @@ int main(int argc, char** argv) auto& file_menu = window->add_menu("&File"); - auto load_model = [&](StringView const& filename) { - if (widget.load(filename)) { - auto canonical_path = Core::File::real_path_for(filename); - window->set_title(String::formatted("{} - 3D File Viewer", canonical_path)); - } - }; - file_menu.add_action(GUI::CommonActions::make_open_action([&](auto&) { - Optional<String> open_path = GUI::FilePicker::get_open_filepath(window); + auto result = FileSystemAccessClient::Client::the().open_file(window->window_id()); - if (!open_path.has_value()) + if (result.error != 0) return; - load_model(open_path.value()); + if (widget.load_fd_and_close(*result.fd, *result.chosen_file)) { + auto canonical_path = Core::File::absolute_path(*result.chosen_file); + window->set_title(String::formatted("{} - 3D File Viewer", canonical_path)); + } })); file_menu.add_separator(); file_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { @@ -465,7 +519,10 @@ int main(int argc, char** argv) window->show(); auto filename = argc > 1 ? argv[1] : "/home/anon/Documents/3D Models/teapot.obj"; - load_model(filename); + if (widget.load_path(filename)) { + auto canonical_path = Core::File::absolute_path(filename); + window->set_title(String::formatted("{} - 3D File Viewer", canonical_path)); + } return app->exec(); } |