yams/plugins/zyp/pdf_metadata.h
trvon 4e566f6387
fix: harden buffer and parser contracts
Validate Simeon buffer boundaries and replace ZYP reverse pointer arithmetic with bounded indexing. Keep release SIMD kernels unchecked while asserting contracts in debug builds.
2026-07-29 19:00:10 -04:00

70 lines
1.8 KiB
C++

/**
* @file pdf_metadata.h
* @brief Minimal PDF metadata extraction
*
* This provides basic PDF metadata extraction by parsing the trailer /Info dictionary.
* zpdf focuses on text extraction and doesn't expose metadata, so we implement
* a minimal parser for common metadata fields.
*/
#pragma once
#include <cstdint>
#include <optional>
#include <span>
#include <string>
#include <string_view>
#include <unordered_map>
namespace yams::zyp {
namespace detail {
/**
* Find the final occurrence of a byte sequence.
*
* Returns nullptr when either input is empty or the sequence is absent.
*/
[[nodiscard]] const uint8_t* findBackwards(std::span<const uint8_t> data, std::string_view needle);
} // namespace detail
/**
* PDF document metadata.
*/
struct PdfMetadata {
std::optional<std::string> title;
std::optional<std::string> author;
std::optional<std::string> subject;
std::optional<std::string> keywords;
std::optional<std::string> creator; /**< Application that created the original */
std::optional<std::string> producer; /**< PDF producer application */
std::optional<std::string> creationDate;
std::optional<std::string> modDate;
/**
* Convert metadata to a key-value map.
* Only includes fields that have values.
*/
[[nodiscard]] std::unordered_map<std::string, std::string> toMap() const;
/**
* Check if any metadata fields are present.
*/
[[nodiscard]] bool empty() const;
};
/**
* Extract metadata from a PDF buffer.
*
* This is a minimal parser that:
* 1. Finds the trailer dictionary
* 2. Locates the /Info reference
* 3. Parses the info dictionary for standard fields
*
* @param data PDF file content
* @return Metadata if found, nullopt on parse error
*/
[[nodiscard]] std::optional<PdfMetadata> extractMetadata(std::span<const uint8_t> data);
} // namespace yams::zyp