summaryrefslogtreecommitdiff
path: root/media-libs/libcaca/files/Fix-a-problem-in-the-caca_resize-overflow-detection-.patch
blob: 5305a6bdf21cd636937a186ebe5ba91e8ab8909c (plain)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
From: Sam Hocevar <sam@hocevar.net>
Date: Fri, 26 Feb 2021 12:40:06 +0100
Subject: [2/2] Fix a problem in the caca_resize() overflow detection and add
 several unit tests.
Origin: https://github.com/cacalabs/libcaca/commit/e4968ba6e93e9fd35429eb16895c785c51072015
Bug: https://github.com/cacalabs/libcaca/issues/52
Bug-Debian: https://bugs.debian.org/983686
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-3410

---
 caca/canvas.c     | 16 ++++++++--------
 test/canvas.cpp   | 18 +++++++++++++++---
 tools/makefont.c  | 22 +++++++++++++++++++---
 3 files changed, 42 insertions(+), 14 deletions(-)

--- a/caca/canvas.c
+++ b/caca/canvas.c
@@ -367,6 +367,14 @@ int caca_resize(caca_canvas_t *cv, int w
 {
     int x, y, f, old_width, old_height, old_size;
 
+    /* Check for overflow */
+    int new_size = width * height;
+    if (new_size < 0 || (width > 0 && new_size / width != height))
+    {
+        seterrno(EOVERFLOW);
+        return -1;
+    }
+
     old_width = cv->width;
     old_height = cv->height;
     old_size = old_width * old_height;
@@ -377,14 +385,6 @@ int caca_resize(caca_canvas_t *cv, int w
      * dirty rectangle handling */
     cv->width = width;
     cv->height = height;
-    int new_size = width * height;
-
-    /* Check for overflow */
-    if (new_size / width != height)
-    {
-        seterrno(EOVERFLOW);
-        return -1;
-    }
 
     /* If width or height is smaller (or both), we have the opportunity to
      * reduce or even remove dirty rectangles */
--- a/test/canvas.cpp
+++ b/test/canvas.cpp
@@ -16,6 +16,7 @@
 #include <cppunit/TestCaller.h>
 #include <cppunit/TestCase.h>
 #include <cppunit/TestSuite.h>
+#include <climits>
 
 #include "caca.h"
 
@@ -53,18 +54,29 @@ public:
         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_width(cv), 0);
         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_height(cv), 0);
 
-        caca_set_canvas_size(cv, 1, 1);
+        int ret = caca_set_canvas_size(cv, 1, 1);
+        CPPUNIT_ASSERT_EQUAL(ret, 0);
         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_width(cv), 1);
         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_height(cv), 1);
 
-        caca_set_canvas_size(cv, 1234, 1001);
+        ret = caca_set_canvas_size(cv, 1234, 1001);
+        CPPUNIT_ASSERT_EQUAL(ret, 0);
         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_width(cv), 1234);
         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_height(cv), 1001);
 
-        caca_set_canvas_size(cv, 0, 0);
+        ret = caca_set_canvas_size(cv, 0, 0);
+        CPPUNIT_ASSERT_EQUAL(ret, 0);
         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_width(cv), 0);
         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_height(cv), 0);
 
+        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, -1, 50));
+        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, 50, -1));
+        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, -1, -1));
+        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, INT_MAX / 2, 3));
+        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, 3, INT_MAX / 2));
+        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, INT_MAX / 2, INT_MAX / 2));
+        CPPUNIT_ASSERT_EQUAL(0, caca_set_canvas_size(cv, 0, 0));
+
         caca_free_canvas(cv);
     }
 
--- a/tools/makefont.c
+++ b/tools/makefont.c
@@ -40,7 +40,8 @@
  * and the UTF-8 glyphs necessary for canvas rotation and mirroring. */
 static unsigned int const blocklist[] =
 {
-    0x0000, 0x0080, /* Basic latin: A, B, C, a, b, c */
+    0x0020, 0x0080, /* Basic latin: A, B, C, a, b, c */
+#if 0
     0x0080, 0x0100, /* Latin-1 Supplement: Ä, Ç, å, ß */
     0x0100, 0x0180, /* Latin Extended-A: Ā č Ō œ */
     0x0180, 0x0250, /* Latin Extended-B: Ǝ Ƹ */
@@ -63,6 +64,7 @@ static unsigned int const blocklist[] =
     0x30a0, 0x3100, /* Katakana: ロ ル */
     0xff00, 0xfff0, /* Halfwidth and Fullwidth Forms: A, B, C, a, b, c */
     0x10400, 0x10450, /* Deseret: 𐐒 𐐋 */
+#endif
     0, 0
 };
 
@@ -317,8 +319,22 @@ int main(int argc, char *argv[])
             printf_unicode(&gtab[n]);
 
             if(gtab[n].same_as == n)
-                printf_hex(" */ %s\n",
-                           glyph_data + gtab[n].data_offset, gtab[n].data_size);
+            {
+                char const *lut = " .:nmW@";
+                printf("\n");
+                for (int y = 0; y < height; ++y)
+                {
+                    for (int x = 0; x < gtab[n].data_width; ++x)
+                    {
+                        int val = glyph_data[gtab[n].data_offset + y * gtab[n].data_width + x];
+                        char ch = lut[val * val * 7 / 256 / 256];
+                        printf("%c%c", ch, ch);
+                    }
+                    printf("\n");
+                }
+                //printf_hex(" */ %s\n",
+                //           glyph_data + gtab[n].data_offset, gtab[n].data_size);
+            }
             else
             {
                 printf(" is ");