From f510b2b180729b1ef41d1a9cdf7e5a9e40755d41 Mon Sep 17 00:00:00 2001 From: Rodrigo Tobar Date: Thu, 5 Jan 2023 23:49:40 +0800 Subject: [PATCH] LibPDF: Support null destination parameters Destination arrays contain a page number, a mode name, and parameters specific to that mode. In many cases these parameters can be set to "null", which our code wasn't taking into consideration. This commit parses these parameters taking into account whether they are null or actual numbers, and stores them as Optional instead of plain floats. The parameters are not yet used anywhere else other than when formatting a Destination object, so the change is fairly small. --- Userland/Libraries/LibPDF/Document.cpp | 12 +++++++++--- Userland/Libraries/LibPDF/Document.h | 14 ++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Userland/Libraries/LibPDF/Document.cpp b/Userland/Libraries/LibPDF/Document.cpp index 54b67d3c0d..a8f85e8a23 100644 --- a/Userland/Libraries/LibPDF/Document.cpp +++ b/Userland/Libraries/LibPDF/Document.cpp @@ -232,9 +232,15 @@ PDFErrorOr Document::create_destination_from_parameters(NonnullRefP auto page_ref = array->at(0); auto type_name = TRY(array->get_name_at(this, 1))->name(); - Vector parameters; - for (size_t i = 2; i < array->size(); i++) - parameters.append(array->at(i).to_float()); + Vector> parameters; + TRY(parameters.try_ensure_capacity(array->size() - 2)); + for (size_t i = 2; i < array->size(); i++) { + auto& param = array->at(i); + if (param.has()) + parameters.unchecked_append({}); + else + parameters.append(param.to_float()); + } Destination::Type type; if (type_name == CommonNames::XYZ) { diff --git a/Userland/Libraries/LibPDF/Document.h b/Userland/Libraries/LibPDF/Document.h index d58598e2b3..15305bb0c1 100644 --- a/Userland/Libraries/LibPDF/Document.h +++ b/Userland/Libraries/LibPDF/Document.h @@ -51,7 +51,7 @@ struct Destination { Type type; Optional page; - Vector parameters; + Vector> parameters; }; struct OutlineItem final : public RefCounted { @@ -232,9 +232,15 @@ struct Formatter : Formatter { TRY(builder.put_literal("{{}}"sv)); else TRY(builder.put_u64(destination.page.value())); - for (auto& param : destination.parameters) { - TRY(builder.put_f64(double(param))); - TRY(builder.put_literal(" "sv)); + if (!destination.parameters.is_empty()) { + TRY(builder.put_literal(" parameters="sv)); + for (auto const& param : destination.parameters) { + if (param.has_value()) + TRY(builder.put_f64(double(param.value()))); + else + TRY(builder.put_literal("{{}}"sv)); + TRY(builder.put_literal(" "sv)); + } } return builder.put_literal(" }}"sv); }