File: Fix-crash-on-invalid-data.patch

package info (click to toggle)
rlottie 0.1%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 9,864 kB
  • sloc: cpp: 20,368; asm: 221; ansic: 194; makefile: 15
file content (73 lines) | stat: -rw-r--r-- 2,875 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Description: Fix some crashes on invalid data.
 Should fix CVE-2021-31318, CVE-2021-31319, CVE-2021-31320, CVE-2021-31322.
Origin: https://github.com/desktop-app/rlottie/commit/e0ea6af518345c4a46195c4951e023e621a9eb8f
        https://github.com/desktop-app/rlottie/commit/839dcab7f083a51b8130061ea5ec245195af6c58
Author: John Preston <johnprestonmail@gmail.com>
Acked-By: Nicholas Guriev <guriev-ns@ya.ru>
Last-Update: Sat, 22 May 2021 19:07:06 +0300

--- a/src/lottie/lottieitem.cpp
+++ b/src/lottie/lottieitem.cpp
@@ -451,6 +451,9 @@ LOTCompLayerItem::LOTCompLayerItem(LOTLa
     // as lottie model keeps the data in front-toback-order.
     for (auto it = mLayerData->mChildren.crbegin();
          it != mLayerData->mChildren.rend(); ++it ) {
+        if ((*it)->type() != LOTData::Type::Layer) {
+            continue;
+        }
         auto model = static_cast<LOTLayerData *>(*it);
         auto item = createLayerItem(model, allocator);
         if (item) mLayers.push_back(item);
--- a/src/lottie/lottiemodel.cpp
+++ b/src/lottie/lottiemodel.cpp
@@ -244,11 +244,18 @@ void LOTGradient::populate(VGradientStop
     LottieGradient gradData = mGradient.value(frameNo);
     auto            size = gradData.mGradient.size();
     float *        ptr = gradData.mGradient.data();
+    if (!ptr) {
+        return;
+    }
     int            colorPoints = mColorPoints;
-    if (colorPoints == -1) {  // for legacy bodymovin (ref: lottie-android)
+    if (colorPoints < 0 || colorPoints > int(size / 4)) {
         colorPoints = int(size / 4);
     }
     auto    opacityArraySize = size - colorPoints * 4;
+    if ((opacityArraySize % 2 != 0) ||
+            (std::size_t(colorPoints) > opacityArraySize / 2 && opacityArraySize < 4)) {
+        opacityArraySize = 0;
+    }
     float *opacityPtr = ptr + (colorPoints * 4);
     stops.clear();
     size_t j = 0;
@@ -302,6 +309,9 @@ void LOTGradient::populate(VGradientStop
         }
         ptr += 4;
     }
+    if (stops.empty()) {
+        stops.push_back(std::make_pair(0.0f, VColor(255, 255, 255, 255)));
+    }
 }
 
 void LOTGradient::update(std::unique_ptr<VGradient> &grad, int frameNo)
--- a/src/vector/vdrawhelper.cpp
+++ b/src/vector/vdrawhelper.cpp
@@ -146,6 +146,9 @@ bool VGradientCache::generateGradientCol
                                                 float                 opacity,
                                                 uint32_t *colorTable, int size)
 {
+    if (stops.empty()) {
+        return false;
+    }
     int                  dist, idist, pos = 0;
     size_t i;
     bool                 alpha = false;
@@ -165,7 +168,7 @@ bool VGradientCache::generateGradientCol
 
     colorTable[pos++] = curColor;
 
-    while (fpos <= curr->first) {
+    while (fpos <= curr->first && pos < size) {
         colorTable[pos] = colorTable[pos - 1];
         pos++;
         fpos += incr;