tdf#171337: improve prefix generation to guarantee uniqueness

Commit b3bfae88b6 (separate ImpSdrPdfImport's
by prefix, 2025-10-17) introduced a prefix to font filenames, apparently
to avoid same filenames in different imports. It used ImpSdrPdfImport's
pointer for that. However, it may happen that the next time it imports, the
new instance of ImpSdrPdfImport may get allocated at exactly same address.
Then afdko's cbConvert may abort because of failed fileopen.

This adds a static counter to the prefix string. I decided to keep also
the pointer, to avoid a hypothetical clash in case of a font name statring
with a short number like 0 or 1. In theory, we should use methods that
create unique temporary names instead.

Change-Id: Ia52b45002d3fe9e008bed33bc90cec190929e519
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201785
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
This commit is contained in:
Mike Kaganski
2026-03-16 13:41:54 +01:00
parent 8ead7a5953
commit dc4f4b85c5
3 changed files with 20 additions and 12 deletions
+3 -4
View File
@@ -173,11 +173,10 @@ class ImpSdrPdfImport final
void DoObjects(SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport, int nPageIndex);
static ImportedFontMap CollectFonts(sal_Int64 nPrefix, vcl::pdf::PDFiumDocument& rPdfDocument);
static ImportedFontMap CollectFonts(std::u16string_view sPrefix,
vcl::pdf::PDFiumDocument& rPdfDocument);
sal_Int64 getPrefix() const { return reinterpret_cast<sal_Int64>(this); }
static EmbeddedFontInfo convertToOTF(sal_Int64 nPrefix, SubSetInfo& rSubSetInfo,
static EmbeddedFontInfo convertToOTF(std::u16string_view sPrefix, SubSetInfo& rSubSetInfo,
const OUString& fileUrl, const OUString& fontName,
const OUString& baseFontName,
std::u16string_view fontFileName,
+14 -8
View File
@@ -89,6 +89,12 @@
using namespace com::sun::star;
static OUString getPrefix(void* p)
{
static sal_Int64 snCounter = 0;
return OUString::number(reinterpret_cast<sal_IntPtr>(p)) + "_" + OUString::number(snCounter++);
}
ImpSdrPdfImport::ImpSdrPdfImport(SdrModel& rModel, SdrLayerID nLay, const tools::Rectangle& rRect,
Graphic const& rGraphic)
: maScaleRect(rRect)
@@ -135,7 +141,7 @@ ImpSdrPdfImport::ImpSdrPdfImport(SdrModel& rModel, SdrLayerID nLay, const tools:
if (!mxImportedFonts)
{
mxImportedFonts
= std::make_shared<ImportedFontMap>(CollectFonts(getPrefix(), *mpPdfDocument));
= std::make_shared<ImportedFontMap>(CollectFonts(getPrefix(this), *mpPdfDocument));
if (xGrfLink)
xGrfLink->setImportedFonts(mxImportedFonts);
}
@@ -231,17 +237,17 @@ OUString stripPostScriptStyle(const OUString& postScriptName, FontWeight& eWeigh
return sFontName;
}
OUString getFileUrlForTemporaryFont(sal_Int64 prefix, std::u16string_view name,
OUString getFileUrlForTemporaryFont(std::u16string_view prefix, std::u16string_view name,
std::u16string_view suffix)
{
return EmbeddedFontsManager::getFileUrlForTemporaryFont(
Concat2View(OUString::number(prefix) + name), suffix);
Concat2View(OUString::Concat(prefix) + name), suffix);
}
}
// Possibly there is some alternative route to query pdfium for all fonts without
// iterating through every object to see what font each uses
ImportedFontMap ImpSdrPdfImport::CollectFonts(sal_Int64 nPrefix,
ImportedFontMap ImpSdrPdfImport::CollectFonts(std::u16string_view sPrefix,
vcl::pdf::PDFiumDocument& rPdfDocument)
{
ImportedFontMap aImportedFonts;
@@ -338,7 +344,7 @@ ImportedFontMap ImpSdrPdfImport::CollectFonts(sal_Int64 nPrefix,
eFontWeight);
SAL_INFO_IF(!bTTF, "sd.filter", "not ttf/otf, converting");
OUString fileUrl
= getFileUrlForTemporaryFont(nPrefix, sFontFileName, bTTF ? u".ttf" : u".t1");
= getFileUrlForTemporaryFont(sPrefix, sFontFileName, bTTF ? u".ttf" : u".t1");
if (!writeFontFile(fileUrl, aFontData))
SAL_WARN("sd.filter", "ttf not written");
else
@@ -349,7 +355,7 @@ ImportedFontMap ImpSdrPdfImport::CollectFonts(sal_Int64 nPrefix,
if (!bTTF || !aToUnicodeData.empty())
{
EmbeddedFontInfo fontInfo
= convertToOTF(nPrefix, *pSubSetInfo, fileUrl, sFontName, sPostScriptName,
= convertToOTF(sPrefix, *pSubSetInfo, fileUrl, sFontName, sPostScriptName,
sFontFileName, aToUnicodeData, *font);
fileUrl = fontInfo.sFontFile;
sFontName = fontInfo.sFontName;
@@ -1498,7 +1504,7 @@ static OUString buildFontMenuName(const OUString& FontMenuNameDBUrl,
}
// https://adobe-type-tools.github.io/font-tech-notes/pdfs/5900.RFMFAH_Tutorial.pdf
static EmbeddedFontInfo mergeFontSubsets(sal_Int64 prefix, const OUString& mergedFontUrl,
static EmbeddedFontInfo mergeFontSubsets(std::u16string_view prefix, const OUString& mergedFontUrl,
const OUString& FontMenuNameDBUrl,
const OUString& postScriptName,
const OUString& longFontName, std::string_view Weight,
@@ -1654,7 +1660,7 @@ static EmbeddedFontInfo mergeFontSubsets(sal_Int64 prefix, const OUString& merge
}
//static
EmbeddedFontInfo ImpSdrPdfImport::convertToOTF(sal_Int64 prefix, SubSetInfo& rSubSetInfo,
EmbeddedFontInfo ImpSdrPdfImport::convertToOTF(std::u16string_view prefix, SubSetInfo& rSubSetInfo,
const OUString& fileUrl, const OUString& fontName,
const OUString& postScriptName,
std::u16string_view fontFileName,
+3
View File
@@ -338,6 +338,9 @@ bool EmbeddedFontsManager::makeotf(const OUString& srcFontUrl, const OUString& d
{
bool ret = false;
#if HAVE_FEATURE_AFDKO
// cbConvert may abort when dest file already exists
assert(osl::File(destFileUrl).open(osl_File_OpenFlag_Read) == osl::FileBase::E_NOENT);
OUString srcFontPath, destFilePath, charMapPath, fontMenuNameDBPath, featuresPath;
if (osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL(srcFontUrl, srcFontPath)
|| osl::FileBase::E_None