pdfium/testing/font_renamer.cpp
Lei Zhang a7fca8a4f3 Add a way to undo a previous FPDF_SetSystemFontInfo() call
Modify FPDF_SetSystemFontInfo() to be able to take a nullptr without
crashing. Handle the nullptr case by releasing PDFium's hold on the
previously passed in pointer. Since no existing embedder could have
passed in a nullptr before without crashing, this is a safe enhancement
to an existing stable API.

This gives FPDF_SetSystemFontInfo() callers that need to also call
FPDF_FreeDefaultSystemFontInfo() a way to safely release PDFium's
pointer to the default system font info, before freeing the font info.
Use this where appropriate to balance out prior FPDF_SetSystemFontInfo()
calls in existing code.

Update pdfium_test.cc to make the call at the appropriate time, before
the FPDF_DestroyLibrary() call, by adjusting std::unique_ptr lifetimes.

In a follow-up CL, PartitionAllocator class instances will stop living
forever. Thus after FPDF_DestroyLibrary(), it is too late to call
FPDF_FreeDefaultSystemFontInfo(), as the font info was allocated inside
a destroyed partition.

Bug: pdfium:1876
Change-Id: Ic3835bae5f95604f89afb35bfaf8c0d568c6bc4b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/116771
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
2024-02-21 20:05:15 +00:00

93 lines
2.7 KiB
C++

// Copyright 2022 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "testing/font_renamer.h"
#include <string>
#include "testing/test_fonts.h"
namespace {
FPDF_SYSFONTINFO* GetImpl(FPDF_SYSFONTINFO* info) {
return static_cast<FontRenamer*>(info)->impl();
}
void ReleaseImpl(FPDF_SYSFONTINFO* info) {
FPDF_SYSFONTINFO* impl = GetImpl(info);
impl->Release(impl);
}
void EnumFontsImpl(FPDF_SYSFONTINFO* info, void* mapper) {
FPDF_SYSFONTINFO* impl = GetImpl(info);
impl->EnumFonts(impl, mapper);
}
void* MapFontImpl(FPDF_SYSFONTINFO* info,
int weight,
FPDF_BOOL italic,
int charset,
int pitch_family,
const char* face,
FPDF_BOOL* exact) {
std::string renamed_face = TestFonts::RenameFont(face);
FPDF_SYSFONTINFO* impl = GetImpl(info);
return impl->MapFont(impl, weight, italic, charset, pitch_family,
renamed_face.c_str(), exact);
}
void* GetFontImpl(FPDF_SYSFONTINFO* info, const char* face) {
// Any non-null return will do.
FPDF_SYSFONTINFO* impl = GetImpl(info);
std::string renamed_face = TestFonts::RenameFont(face);
return impl->GetFont(impl, renamed_face.c_str());
}
unsigned long GetFontDataImpl(FPDF_SYSFONTINFO* info,
void* font,
unsigned int table,
unsigned char* buffer,
unsigned long buf_size) {
FPDF_SYSFONTINFO* impl = GetImpl(info);
return impl->GetFontData(impl, font, table, buffer, buf_size);
}
unsigned long GetFaceNameImpl(FPDF_SYSFONTINFO* info,
void* font,
char* buffer,
unsigned long buf_size) {
FPDF_SYSFONTINFO* impl = GetImpl(info);
return impl->GetFaceName(impl, font, buffer, buf_size);
}
int GetFontCharsetImpl(FPDF_SYSFONTINFO* info, void* font) {
FPDF_SYSFONTINFO* impl = GetImpl(info);
return impl->GetFontCharset(impl, font);
}
void DeleteFontImpl(FPDF_SYSFONTINFO* info, void* font) {
FPDF_SYSFONTINFO* impl = GetImpl(info);
impl->DeleteFont(impl, font);
}
} // namespace
FontRenamer::FontRenamer() : impl_(FPDF_GetDefaultSystemFontInfo()) {
version = 1;
Release = ReleaseImpl;
EnumFonts = EnumFontsImpl;
MapFont = MapFontImpl;
GetFont = GetFontImpl;
GetFontData = GetFontDataImpl;
GetFaceName = GetFaceNameImpl;
GetFontCharset = GetFontCharsetImpl;
DeleteFont = DeleteFontImpl;
FPDF_SetSystemFontInfo(this);
}
FontRenamer::~FontRenamer() {
FPDF_SetSystemFontInfo(nullptr);
FPDF_FreeDefaultSystemFontInfo(impl_.ExtractAsDangling());
}