M115: Fix function pointer mix up in LCMS

Add an adapter to handle a case where the caller has a
_cmsPipelineEval16Fn function pointer, but the callee's signature is
_cmsInterpFn16.

Bug: chromium:1448746
Change-Id: Ida85c3bff7f38c27b69da164df8999eadee7d0b9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/108130
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
(cherry picked from commit 72aa5fbd5066753af272e16532cae8bf634a82d5)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/108450
diff --git a/third_party/lcms/0035-func-ptr-mixup.patch b/third_party/lcms/0035-func-ptr-mixup.patch
new file mode 100644
index 0000000..8232e21
--- /dev/null
+++ b/third_party/lcms/0035-func-ptr-mixup.patch
@@ -0,0 +1,29 @@
+diff --git a/third_party/lcms/src/cmsopt.c b/third_party/lcms/src/cmsopt.c
+index e3212fb4d..a5475709b 100644
+--- a/third_party/lcms/src/cmsopt.c
++++ b/third_party/lcms/src/cmsopt.c
+@@ -100,6 +100,15 @@ typedef struct {
+ 
+ } Curves16Data;
+ 
++// A simple adapter to prevent _cmsPipelineEval16Fn vs. _cmsInterpFn16
++// confusion, which trips up UBSAN.
++static
++void Lerp16Adapter(CMSREGISTER const cmsUInt16Number in[],
++                   CMSREGISTER cmsUInt16Number out[],
++                   const void* data) {
++    cmsInterpParams* params = (cmsInterpParams*)data;
++    params->Interpolation.Lerp16(in, out, params);
++}
+ 
+ // Simple optimizations ----------------------------------------------------------------------------------------------------------
+ 
+@@ -805,7 +814,7 @@ Error:
+ 
+     if (DataSetIn == NULL && DataSetOut == NULL) {
+ 
+-        _cmsPipelineSetOptimizationParameters(Dest, (_cmsPipelineEval16Fn) DataCLUT->Params->Interpolation.Lerp16, DataCLUT->Params, NULL, NULL);
++        _cmsPipelineSetOptimizationParameters(Dest, Lerp16Adapter, DataCLUT->Params, NULL, NULL);
+     }
+     else {
+ 
diff --git a/third_party/lcms/README.pdfium b/third_party/lcms/README.pdfium
index b71c6f2..335bdca 100644
--- a/third_party/lcms/README.pdfium
+++ b/third_party/lcms/README.pdfium
@@ -20,3 +20,4 @@
 0030-const-data.patch: Mark many data structures as const.
 0033-opt-integer-overflow.patch: Protect against integer overflow.
 0034-dead-code.patch: Remove dead code.
+0035-func-ptr-mixup.patch: Prevent mixing up function pointer types.
diff --git a/third_party/lcms/src/cmsopt.c b/third_party/lcms/src/cmsopt.c
index e3212fb..a547570 100644
--- a/third_party/lcms/src/cmsopt.c
+++ b/third_party/lcms/src/cmsopt.c
@@ -100,6 +100,15 @@
 
 } Curves16Data;
 
+// A simple adapter to prevent _cmsPipelineEval16Fn vs. _cmsInterpFn16
+// confusion, which trips up UBSAN.
+static
+void Lerp16Adapter(CMSREGISTER const cmsUInt16Number in[],
+                   CMSREGISTER cmsUInt16Number out[],
+                   const void* data) {
+    cmsInterpParams* params = (cmsInterpParams*)data;
+    params->Interpolation.Lerp16(in, out, params);
+}
 
 // Simple optimizations ----------------------------------------------------------------------------------------------------------
 
@@ -805,7 +814,7 @@
 
     if (DataSetIn == NULL && DataSetOut == NULL) {
 
-        _cmsPipelineSetOptimizationParameters(Dest, (_cmsPipelineEval16Fn) DataCLUT->Params->Interpolation.Lerp16, DataCLUT->Params, NULL, NULL);
+        _cmsPipelineSetOptimizationParameters(Dest, Lerp16Adapter, DataCLUT->Params, NULL, NULL);
     }
     else {