external/afdko/UnpackedTarball_afdko.mk |    1 
 external/afdko/ubsan.patch.0            |  162 ++++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+)

New commits:
commit fc7232b50d3d7ddebe818143046a2580f2c410ab
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Mon Oct 20 15:44:49 2025 +0200
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Mon Oct 20 23:31:46 2025 +0200

    external/afdko: Address lots of UBSan findings
    
    ...in CppunitTest_sd_pdf_import_test and CppunitTest_sd_export_tests,
    
    > workdir/UnpackedTarball/afdko/c/shared/source/t1write/t1write.c:379:21: 
runtime error: signed integer overflow: 47774 * 52845 cannot be represented in 
type 'int'
    >  #0 in saveCstr at 
workdir/UnpackedTarball/afdko/c/shared/source/t1write/t1write.c:379:21
    >  #1 in saveSubr at 
workdir/UnpackedTarball/afdko/c/shared/source/t1write/t1write.c:572:9
    >  #2 in saveStdSubr at 
workdir/UnpackedTarball/afdko/c/shared/source/t1write/t1write.c:587:11
    >  #3 in saveStdSubrs at 
workdir/UnpackedTarball/afdko/c/shared/source/t1write/t1write.c:611:5
    >  #4 in t1wBegFont at 
workdir/UnpackedTarball/afdko/c/shared/source/t1write/t1write.c:2103:5
    >  #5 in t1_BegFont at 
workdir/UnpackedTarball/afdko/c/shared/source/tx_shared/tx_shared.c:2230:13
    >  #6 in ttrReadFont at 
workdir/UnpackedTarball/afdko/c/shared/source/tx_shared/tx_shared.c:4956:5
    >  #7 in convertTx(txCtx_*) at vcl/source/gdi/embeddedfontsafdko.cxx:55:17
    >  #8 in EmbeddedFontsManager::tx_t1(rtl::OUString const&, rtl::OUString 
const&) at vcl/source/gdi/embeddedfontsafdko.cxx:116:19
    >  #9 in toPfaCID(SubSetInfo&, rtl::OUString const&, rtl::OUString const&, 
bool&, std::__debug::map<int, int, std::less<int>, std::allocator<std::pair<int 
const, int>>>&, rtl::OString&, rtl::OString&, rtl::OString&) at 
svx/source/svdraw/svdpdf.cxx:1189:14
    >  #10 in ImpSdrPdfImport::convertToOTF(long, SubSetInfo&, rtl::OUString 
const&, rtl::OUString const&, rtl::OUString const&, 
std::basic_string_view<char16_t, std::char_traits<char16_t>>, 
std::__debug::vector<unsigned char, std::allocator<unsigned char>> const&) at 
svx/source/svdraw/svdpdf.cxx:1674:10
    >  #11 in ImpSdrPdfImport::CollectFonts() at 
svx/source/svdraw/svdpdf.cxx:328:27
    >  #12 in ImpSdrPdfImport::ImpSdrPdfImport(SdrModel&, 
o3tl::strong_int<short, SdrLayerIDTag>, tools::Rectangle const&, Graphic 
const&) at svx/source/svdraw/svdpdf.cxx:122:5
    >  #13 in SdrEditView::DoImportMarkedMtf(SvdProgressInfo*) at 
svx/source/svdraw/svdedtv2.cxx:2168:37
    >  #14 in testImportSimpleText::TestBody() at 
sd/qa/unit/SdrPdfImportTest.cxx:122:32
    
    etc. and
    
    > workdir/UnpackedTarball/afdko/c/makeotf/lib/typecomp/recode.c:1744:17: 
runtime error: left shift of negative value -51
    >  #0 in t1parse at 
workdir/UnpackedTarball/afdko/c/makeotf/lib/typecomp/recode.c:1744:17
    >  #1 in cstrRecode at 
workdir/UnpackedTarball/afdko/c/makeotf/lib/typecomp/recode.c:3279:11
    >  #2 in recodeAddChar at 
workdir/UnpackedTarball/afdko/c/makeotf/lib/typecomp/recode.c:3383:5
    >  #3 in csAddChar at 
workdir/UnpackedTarball/afdko/c/makeotf/lib/typecomp/cs.c:152:5
    >  #4 in cidAddChars at 
workdir/UnpackedTarball/afdko/c/makeotf/lib/typecomp/parse.c:3001:13
    >  #5 in parseFont at 
workdir/UnpackedTarball/afdko/c/makeotf/lib/typecomp/parse.c:1507:9
    >  #6 in tcAddFont at 
workdir/UnpackedTarball/afdko/c/makeotf/lib/typecomp/tc.c:1006:5
    >  #7 in tcCompactFont at 
workdir/UnpackedTarball/afdko/c/makeotf/lib/typecomp/tc.c:1054:5
    >  #8 in hotReadFont at 
workdir/UnpackedTarball/afdko/c/makeotf/lib/hotconv/hot.c:369:5
    >  #9 in psConvFont at 
workdir/UnpackedTarball/afdko/c/makeotf/source/cb.c:329:16
    >  #10 in cbConvert at 
workdir/UnpackedTarball/afdko/c/makeotf/source/cb.c:1622:20
    >  #11 in EmbeddedFontsManager::makeotf(rtl::OUString const&, rtl::OUString 
const&, rtl::OUString const&, rtl::OUString const&, rtl::OUString const&) at 
vcl/source/gdi/embeddedfontsafdko.cxx:263:5
    >  #12 in ImpSdrPdfImport::convertToOTF(long, SubSetInfo&, rtl::OUString 
const&, rtl::OUString const&, rtl::OUString const&, 
std::basic_string_view<char16_t, std::char_traits<char16_t>>, 
std::__debug::vector<unsigned char, std::allocator<unsigned char>> const&) at 
svx/source/svdraw/svdpdf.cxx:1721:9
    >  #13 in ImpSdrPdfImport::CollectFonts() at 
svx/source/svdraw/svdpdf.cxx:328:27
    >  #14 in ImpSdrPdfImport::ImpSdrPdfImport(SdrModel&, 
o3tl::strong_int<short, SdrLayerIDTag>, tools::Rectangle const&, Graphic 
const&) at svx/source/svdraw/svdpdf.cxx:122:5
    >  #15 in SdrEditView::DoImportMarkedMtf(SvdProgressInfo*) at 
svx/source/svdraw/svdedtv2.cxx:2168:37
    >  #16 in testImportSimpleText::TestBody() at 
sd/qa/unit/SdrPdfImportTest.cxx:122:32
    
    etc. and
    
    > workdir/UnpackedTarball/afdko/c/mergefonts/source/mergeFonts.c:300:5: 
runtime error: call to function cfwMergeFDArray through pointer to incorrect 
function type 'long (*)(void *, abfTopDict *, int *)'
    > workdir/UnpackedTarball/afdko/c/shared/source/cffwrite/cffwrite.c:491: 
note: cfwMergeFDArray defined here
    >  #0 in mergeFDArray at 
workdir/UnpackedTarball/afdko/c/mergefonts/source/mergeFonts.c:300:5
    >  #1 in t1rMergeFont at 
workdir/UnpackedTarball/afdko/c/mergefonts/source/mergeFonts.c:390:13
    >  #2 in mergeFile at 
workdir/UnpackedTarball/afdko/c/mergefonts/source/mergeFonts.c:1521:17
    >  #3 in doMergeFileSet at 
workdir/UnpackedTarball/afdko/c/mergefonts/source/mergeFonts.c:1726:9
    >  #4 in EmbeddedFontsManager::mergefonts(rtl::OUString const&, 
rtl::OUString const&, std::__debug::vector<std::pair<rtl::OUString, 
rtl::OUString>, std::allocator<std::pair<rtl::OUString, rtl::OUString>>> 
const&) at vcl/source/gdi/embeddedfontsafdko.cxx:179:24
    >  #5 in toPfaCID(SubSetInfo&, rtl::OUString const&, rtl::OUString const&, 
bool&, std::__debug::map<int, int, std::less<int>, std::allocator<std::pair<int 
const, int>>>&, rtl::OString&, rtl::OString&, rtl::OString&) at 
svx/source/svdraw/svdpdf.cxx:1197:14
    >  #6 in ImpSdrPdfImport::convertToOTF(long, SubSetInfo&, rtl::OUString 
const&, rtl::OUString const&, rtl::OUString const&, 
std::basic_string_view<char16_t, std::char_traits<char16_t>>, 
std::__debug::vector<unsigned char, std::allocator<unsigned char>> const&) at 
svx/source/svdraw/svdpdf.cxx:1674:10
    >  #7 in ImpSdrPdfImport::CollectFonts() at 
svx/source/svdraw/svdpdf.cxx:328:27
    >  #8 in ImpSdrPdfImport::ImpSdrPdfImport(SdrModel&, 
o3tl::strong_int<short, SdrLayerIDTag>, tools::Rectangle const&, Graphic 
const&) at svx/source/svdraw/svdpdf.cxx:122:5
    >  #9 in SdrEditView::DoImportMarkedMtf(SvdProgressInfo*) at 
svx/source/svdraw/svdedtv2.cxx:2168:37
    >  #10 in testImportSimpleText::TestBody() at 
sd/qa/unit/SdrPdfImportTest.cxx:122:32
    
    and
    
    > workdir/UnpackedTarball/afdko/c/shared/source/dynarr/dynarr.c:111:9: 
runtime error: call to function initCharset through pointer to incorrect 
function type 'void (*)(void *, long, void *)'
    > 
workdir/UnpackedTarball/afdko/c/shared/source/cffwrite/cffwrite_charset.c:76: 
note: initCharset defined here
    >  #0 in dnaGrow at 
workdir/UnpackedTarball/afdko/c/shared/source/dynarr/dynarr.c:111:9
    >  #1 in dnaNext at 
workdir/UnpackedTarball/afdko/c/shared/source/dynarr/dynarr.c:162:13
    >  #2 in cfwCharsetNew at 
workdir/UnpackedTarball/afdko/c/shared/source/cffwrite/cffwrite_charset.c:98:28
    >  #3 in cfwNew at 
workdir/UnpackedTarball/afdko/c/shared/source/cffwrite/cffwrite.c:2236:5
    >  #4 in cff_SetMode at 
workdir/UnpackedTarball/afdko/c/shared/source/tx_shared/tx_shared.c:1129:22
    >  #5 in setMode at 
workdir/UnpackedTarball/afdko/c/shared/source/tx_shared/tx_shared.c:5585:13
    >  #6 in EmbeddedFontsManager::mergefonts(rtl::OUString const&, 
rtl::OUString const&, std::__debug::vector<std::pair<rtl::OUString, 
rtl::OUString>, std::allocator<std::pair<rtl::OUString, rtl::OUString>>> 
const&) at vcl/source/gdi/embeddedfontsafdko.cxx:167:5
    >  #7 in toPfaCID(SubSetInfo&, rtl::OUString const&, rtl::OUString const&, 
bool&, std::__debug::map<int, int, std::less<int>, std::allocator<std::pair<int 
const, int>>>&, rtl::OString&, rtl::OString&, rtl::OString&) at 
svx/source/svdraw/svdpdf.cxx:1197:14
    >  #8 in ImpSdrPdfImport::convertToOTF(long, SubSetInfo&, rtl::OUString 
const&, rtl::OUString const&, rtl::OUString const&, 
std::basic_string_view<char16_t, std::char_traits<char16_t>>, 
std::__debug::vector<unsigned char, std::allocator<unsigned char>> const&) at 
svx/source/svdraw/svdpdf.cxx:1674:10
    >  #9 in ImpSdrPdfImport::CollectFonts() at 
svx/source/svdraw/svdpdf.cxx:328:27
    >  #10 in ImpSdrPdfImport::ImpSdrPdfImport(SdrModel&, 
o3tl::strong_int<short, SdrLayerIDTag>, tools::Rectangle const&, Graphic 
const&) at svx/source/svdraw/svdpdf.cxx:122:5
    >  #11 in SdrEditView::DoImportMarkedMtf(SvdProgressInfo*) at 
svx/source/svdraw/svdedtv2.cxx:2168:37
    >  #12 in testImportSimpleText::TestBody() at 
sd/qa/unit/SdrPdfImportTest.cxx:122:32
    
    but which has been suppressed at least for now with an
    
    > __attribute__((no_sanitize("function")))
    
    as that appears to be a pervasive issue with the dnaDCL macro defined in
    workdir/UnpackedTarball/afdko/c/shared/include/dynarr.h
    
    Change-Id: Ib259a660713fa87f45020fefa841483cf810fc45
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192733
    Reviewed-by: Stephan Bergmann <[email protected]>
    Tested-by: Jenkins

diff --git a/external/afdko/UnpackedTarball_afdko.mk 
b/external/afdko/UnpackedTarball_afdko.mk
index fc13da9d6b4d..9cf0d6c50397 100644
--- a/external/afdko/UnpackedTarball_afdko.mk
+++ b/external/afdko/UnpackedTarball_afdko.mk
@@ -28,6 +28,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,afdko, \
     external/afdko/warnings.patch \
     external/afdko/antlr4-chrono.patch \
     external/afdko/mergeFonts_crash.patch \
+    external/afdko/ubsan.patch.0 \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/afdko/ubsan.patch.0 b/external/afdko/ubsan.patch.0
new file mode 100644
index 000000000000..f79429697f28
--- /dev/null
+++ b/external/afdko/ubsan.patch.0
@@ -0,0 +1,162 @@
+--- c/makeotf/lib/cffread/cffread.c
++++ c/makeotf/lib/cffread/cffread.c
+@@ -49,7 +49,7 @@
+ /* Type conversions */
+ #define INT(f) ((int16_t)(((f)&0xffff0000) >> 16))
+ #define FRAC(f) ((f)&0x0000ffff)
+-#define INT2FIX(i) ((Fixed)(i) << 16)
++#define INT2FIX(i) ((Fixed)((uint32_t)(i) << 16))
+ #define FIX2INT(f) ((short)(((f) + FixedHalf) >> 16))
+ #define FIX2DBL(f) ((double)((f) / fixedScale))
+ #define DBL2FIX(d) ((Fixed)((d)*fixedScale + ((d) < 0 ? -0.5 : 0.5)))
+--- c/makeotf/lib/typecomp/common.h
++++ c/makeotf/lib/typecomp/common.h
+@@ -36,7 +36,7 @@
+ #define INDEX_SIZE(items, size) \
+     ((items) == 0 ? sizeCard16 : (sizeCard16 + sizeCard8 + ((items) + 1) * 
INDEX_OFF_SIZE(size) + (size)))
+ #define FixedHalf ((Fixed)0x00008000)
+-#define INT2FIX(i) ((Fixed)((uint32_t)i) << 16)
++#define INT2FIX(i) ((Fixed)((uint32_t)i << 16))
+ #define DBL2FIX(d) ((Fixed)((double)(d)*65536.0 + ((d) < 0 ? -0.5 : 0.5)))
+ #define FIX2DBL(f) ((double)(f) / 65536.0)
+ #define RNDFIX(f) (((f) + FixedHalf) & 0xffff0000)
+--- c/makeotf/lib/typecomp/recode.c
++++ c/makeotf/lib/typecomp/recode.c
+@@ -1727,10 +1727,10 @@
+ 
+             case 255: {
+                 /* 5 byte number */
+-                int32_t value = (int32_t)cstr[i + 1] << 24 | (int32_t)cstr[i 
+ 2] << 16 |
+-                                (int32_t)cstr[i + 3] << 8 | (int32_t)cstr[i + 
4];
++                int32_t value = (uint32_t)cstr[i + 1] << 24 | 
(uint32_t)cstr[i + 2] << 16 |
++                                (uint32_t)cstr[i + 3] << 8 | (uint32_t)cstr[i 
+ 4];
+                 if (-32000 <= value && value <= 32000) {
+-                    value <<= 16;
++                    value = (uint32_t)value << 16;
+                 } else {
+                     h->intDiv = 1;
+                 }
+@@ -3690,7 +3690,7 @@
+     /* Remove encryption */
+     for (i = 0; i < length; i++) {
+         unsigned char plain = cstr[i] ^ (r1 >> 8);
+-        r1 = (cstr[i] + r1) * 52845 + 22719;
++        r1 = (unsigned)(cstr[i] + r1) * 52845 + 22719;
+         cstr[i] = plain;
+     }
+ }
+--- c/shared/include/cffwrite.h
++++ c/shared/include/cffwrite.h
+@@ -156,7 +156,7 @@
+    compatible with a destination font dict of the same FontName, the function
+    returns 1 else it returns 0. */
+ 
+-int cfwMergeFDArray(cfwCtx h, abfTopDict *top, int *newFDIndex);
++long cfwMergeFDArray(void *h, abfTopDict *top, int *newFDIndex);
+ 
+ /* cfwMergeFDArray() merges all the fdArray font dicts of the passed-in source
+    font top dict into the destination font. It also fills in the array pointed
+--- c/shared/source/cffwrite/cffwrite.c
++++ c/shared/source/cffwrite/cffwrite.c
+@@ -488,7 +488,8 @@
+     return newFDIndex;
+ }
+ 
+-int cfwMergeFDArray(cfwCtx g, abfTopDict *top, int *newFDIndex) {
++long cfwMergeFDArray(void *g_, abfTopDict *top, int *newFDIndex) {
++    cfwCtx g = g_;
+     abfFontDict *srcDict = &top->FDArray.array[0];
+     int i = 0;
+ 
+--- c/shared/source/dynarr/dynarr.c
++++ c/shared/source/dynarr/dynarr.c
+@@ -68,6 +68,9 @@
+    0. If the client has arranged to trap allocation failures in the memory
+    callback functions by using setjmp/longjmp, for example, the -1 return will
+    never occur and the macro wrappers provided will be safe to use. */
++#if defined __clang__
++__attribute__((no_sanitize("function")))
++#endif
+ long dnaGrow(void *object, size_t elemsize, long index) {
+     void *new_ptr;
+     size_t new_size;
+--- c/shared/source/pstoken/pstoken.c
++++ c/shared/source/pstoken/pstoken.c
+@@ -201,7 +201,7 @@
+         else {
+             unsigned char cipher = hi_nib << 4 | nib;
+             *dst++ = cipher ^ (h->cipher.r >> 8);
+-            h->cipher.r = (cipher + h->cipher.r) * 52845 + 22719;
++            h->cipher.r = (unsigned)(cipher + h->cipher.r) * 52845 + 22719;
+             hi_nib = -1;
+         }
+     } while (src < end);
+@@ -232,7 +232,7 @@
+     for (i = 0; i < length; i++) {
+         unsigned char cipher = *src++;
+         *dst++ = cipher ^ (h->cipher.r >> 8);
+-        h->cipher.r = (cipher + h->cipher.r) * 52845 + 22719;
++        h->cipher.r = (unsigned)(cipher + h->cipher.r) * 52845 + 22719;
+     }
+ 
+     return 0;
+--- c/shared/source/t1cstr/t1cstr.c
++++ c/shared/source/t1cstr/t1cstr.c
+@@ -1504,13 +1504,13 @@
+ 
+         /* Prime state from random initial bytes */
+         while (lenIV--)
+-            r = (*c++ + r) * 52845 + 22719;
++            r = (unsigned)(*c++ + r) * 52845 + 22719;
+ 
+         /* Decrypt and copy bytes */
+         while (cnt--) {
+             unsigned char c1 = *c++;
+             *p++ = c1 ^ (r >> 8);
+-            r = (c1 + r) * 52845 + 22719;
++            r = (unsigned)(c1 + r) * 52845 + 22719;
+         }
+     }
+     return t1cSuccess;
+--- c/shared/source/t1write/t1write.c
++++ c/shared/source/t1write/t1write.c
+@@ -187,7 +187,7 @@
+     char *q = buf;
+     while (cnt--) {
+         unsigned char c = *p++ ^ h->eexec.r >> 8;
+-        h->eexec.r = (c + h->eexec.r) * 52845 + 22719;
++        h->eexec.r = (unsigned)(c + h->eexec.r) * 52845 + 22719;
+         *q++ = hexmap[c >> 4 & 0xf];
+         *q++ = hexmap[c & 0xf];
+     }
+@@ -376,7 +376,7 @@
+     p = data;
+     for (i = 0; i < length; i++) {
+         unsigned char c = *p ^ (r >> 8);
+-        r = (c + r) * 52845 + 22719;
++        r = (unsigned)(c + r) * 52845 + 22719;
+         *p++ = c;
+     }
+ 
+--- c/shared/source/t2cstr/t2cstr.c
++++ c/shared/source/t2cstr/t2cstr.c
+@@ -673,7 +673,7 @@
+ 
+     /* Compute mask length and unused bit mask */
+     h->mask.length = (short)((h->stems.cnt + 7) / 8);
+-    h->mask.unused = ~(~0 << (h->mask.length * 8 - h->stems.cnt));
++    h->mask.unused = ~(~0U << (h->mask.length * 8 - h->stems.cnt));
+ 
+     return 0;
+ }
+--- c/shared/source/ttread/ttread.c
++++ c/shared/source/ttread/ttread.c
+@@ -721,7 +721,7 @@
+ 
+ /* Read 4-byte signed number. */
+ static int32_t sread4(ttrCtx h) {
+-    uint32_t value = (int32_t)read1(h) << 24;
++    uint32_t value = (uint32_t)read1(h) << 24;
+     value |= (uint32_t)read1(h) << 16;
+     value |= (uint32_t)read1(h) << 8;
+     value |= (uint32_t)read1(h);

Reply via email to