• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git a/third_party/lcms/src/cmslut.c b/third_party/lcms/src/cmslut.c
2index 9b0eb4b54..19d43361f 100644
3--- a/third_party/lcms/src/cmslut.c
4+++ b/third_party/lcms/src/cmslut.c
5@@ -1255,21 +1255,39 @@ cmsStage* CMSEXPORT cmsStageDup(cmsStage* mpe)
6 // ***********************************************************************************************************
7
8 // This function sets up the channel count
9-
10 static
11-void BlessLUT(cmsPipeline* lut)
12+cmsBool BlessLUT(cmsPipeline* lut)
13 {
14     // We can set the input/ouput channels only if we have elements.
15     if (lut ->Elements != NULL) {
16
17-        cmsStage *First, *Last;
18+        cmsStage* prev;
19+        cmsStage* next;
20+        cmsStage* First;
21+        cmsStage* Last;
22
23         First  = cmsPipelineGetPtrToFirstStage(lut);
24         Last   = cmsPipelineGetPtrToLastStage(lut);
25
26-        if (First != NULL)lut ->InputChannels = First ->InputChannels;
27-        if (Last != NULL) lut ->OutputChannels = Last ->OutputChannels;
28+        if (First == NULL || Last == NULL) return FALSE;
29+
30+        lut->InputChannels = First->InputChannels;
31+        lut->OutputChannels = Last->OutputChannels;
32+
33+        // Check chain consistency
34+        prev = First;
35+        next = prev->Next;
36+
37+        while (next != NULL)
38+        {
39+            if (next->InputChannels != prev->OutputChannels)
40+                return FALSE;
41+
42+            next = next->Next;
43+            prev = prev->Next;
44+        }
45     }
46+    return TRUE;
47 }
48
49
50@@ -1331,6 +1349,7 @@ cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number In
51 {
52        cmsPipeline* NewLUT;
53
54+       // A value of zero in channels is allowed as placeholder
55        if (InputChannels >= cmsMAXCHANNELS ||
56            OutputChannels >= cmsMAXCHANNELS) return NULL;
57
58@@ -1348,7 +1367,11 @@ cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number In
59        NewLUT ->Data        = NewLUT;
60        NewLUT ->ContextID   = ContextID;
61
62-       BlessLUT(NewLUT);
63+       if (!BlessLUT(NewLUT))
64+       {
65+           _cmsFree(ContextID, NewLUT);
66+           return NULL;
67+       }
68
69        return NewLUT;
70 }
71@@ -1454,7 +1477,12 @@ cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* lut)
72
73     NewLUT ->SaveAs8Bits    = lut ->SaveAs8Bits;
74
75-    BlessLUT(NewLUT);
76+    if (!BlessLUT(NewLUT))
77+    {
78+        _cmsFree(lut->ContextID, NewLUT);
79+        return NULL;
80+    }
81+
82     return NewLUT;
83 }
84
85@@ -1491,8 +1519,7 @@ int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage
86             return FALSE;
87     }
88
89-    BlessLUT(lut);
90-    return TRUE;
91+    return BlessLUT(lut);
92 }
93
94 // Unlink an element and return the pointer to it
95@@ -1547,6 +1574,7 @@ void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStag
96     else
97         cmsStageFree(Unlinked);
98
99+    // May fail, but we ignore it
100     BlessLUT(lut);
101 }
102
103@@ -1573,8 +1601,7 @@ cmsBool  CMSEXPORT cmsPipelineCat(cmsPipeline* l1, const cmsPipeline* l2)
104                 return FALSE;
105     }
106
107-    BlessLUT(l1);
108-    return TRUE;
109+    return BlessLUT(l1);
110 }
111
112
113diff --git a/third_party/lcms/src/cmstypes.c b/third_party/lcms/src/cmstypes.c
114index e5ed06c33..0256e247b 100644
115--- a/third_party/lcms/src/cmstypes.c
116+++ b/third_party/lcms/src/cmstypes.c
117@@ -1755,8 +1755,8 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
118     if (!_cmsReadUInt8Number(io, NULL)) goto Error;
119
120     // Do some checking
121-    if (InputChannels > cmsMAXCHANNELS)  goto Error;
122-    if (OutputChannels > cmsMAXCHANNELS) goto Error;
123+    if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS)  goto Error;
124+    if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error;
125
126    // Allocates an empty Pipeline
127     NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels);
128@@ -2048,8 +2048,8 @@ void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm
129     if (!_cmsReadUInt8Number(io, NULL)) return NULL;
130
131     // Do some checking
132-    if (InputChannels > cmsMAXCHANNELS)  goto Error;
133-    if (OutputChannels > cmsMAXCHANNELS) goto Error;
134+    if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS)  goto Error;
135+    if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error;
136
137     // Allocates an empty LUT
138     NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels);
139@@ -2486,7 +2486,10 @@ void* Type_LUTA2B_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c
140     if (!_cmsReadUInt32Number(io, &offsetC)) return NULL;
141     if (!_cmsReadUInt32Number(io, &offsetA)) return NULL;
142
143-   // Allocates an empty LUT
144+    if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL;
145+    if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL;
146+
147+    // Allocates an empty LUT
148     NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan);
149     if (NewLUT == NULL) return NULL;
150
151@@ -2794,6 +2797,9 @@ void* Type_LUTB2A_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c
152     if (!_cmsReadUInt8Number(io, &inputChan)) return NULL;
153     if (!_cmsReadUInt8Number(io, &outputChan)) return NULL;
154
155+    if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL;
156+    if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL;
157+
158     // Padding
159     if (!_cmsReadUInt16Number(io, NULL)) return NULL;
160
161@@ -4443,6 +4449,9 @@ void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
162     if (!_cmsReadUInt16Number(io, &InputChans)) return NULL;
163     if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL;
164
165+    if (InputChans == 0 || InputChans >= cmsMAXCHANNELS) return NULL;
166+    if (OutputChans == 0 || OutputChans >= cmsMAXCHANNELS) return NULL;
167+
168     // Allocates an empty LUT
169     NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans);
170     if (NewLUT == NULL) return NULL;
171