Gentoo Archives: gentoo-commits

From: "Alexis Ballier (aballier)" <aballier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in app-text/texlive-core/files/2007: xpdf-3.02pl2.patch
Date: Wed, 07 Nov 2007 23:31:30
Message-Id: E1IpuMh-0004v7-4u@stork.gentoo.org
1 aballier 07/11/07 23:31:19
2
3 Added: xpdf-3.02pl2.patch
4 Log:
5 security fix for libxpdf, bug #196735
6 (Portage version: 2.1.3.19)
7
8 Revision Changes Path
9 1.1 app-text/texlive-core/files/2007/xpdf-3.02pl2.patch
10
11 file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/app-text/texlive-core/files/2007/xpdf-3.02pl2.patch?rev=1.1&view=markup
12 plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/app-text/texlive-core/files/2007/xpdf-3.02pl2.patch?rev=1.1&content-type=text/plain
13
14 Index: xpdf-3.02pl2.patch
15 ===================================================================
16 Index: tetex-src-3.0/libs/xpdf/xpdf/Stream.cc
17 ===================================================================
18 --- tetex-src-3.0.orig/libs/xpdf/xpdf/Stream.cc
19 +++ tetex-src-3.0/libs/xpdf/xpdf/Stream.cc
20 @@ -1285,19 +1285,24 @@ CCITTFaxStream::CCITTFaxStream(Stream *s
21 error (-1, "invalid number of columns: %d\n", columns);
22 exit (1);
23 }
24 + else if (columns > INT_MAX - 2) columns = INT_MAX - 2;
25 rows = rowsA;
26 endOfBlock = endOfBlockA;
27 black = blackA;
28 - refLine = (short *)gmallocn(columns + 4, sizeof(short));
29 - codingLine = (short *)gmallocn(columns + 3, sizeof(short));
30 + // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = columns
31 + // ---> max codingLine size = columns + 1
32 + // refLine has one extra guard entry at the end
33 + // ---> max refLine size = columns + 2
34 + codingLine = (int *)gmallocn(columns + 1, sizeof(int));
35 + refLine = (int *)gmallocn(columns + 2, sizeof(int));
36
37 eof = gFalse;
38 row = 0;
39 nextLine2D = encoding < 0;
40 inputBits = 0;
41 - codingLine[0] = 0;
42 - codingLine[1] = refLine[2] = columns;
43 - a0 = 1;
44 + codingLine[0] = columns;
45 + a0i = 0;
46 + outputBits = 0;
47
48 buf = EOF;
49 }
50 @@ -1316,9 +1321,9 @@ void CCITTFaxStream::reset() {
51 row = 0;
52 nextLine2D = encoding < 0;
53 inputBits = 0;
54 - codingLine[0] = 0;
55 - codingLine[1] = refLine[2] = columns;
56 - a0 = 1;
57 + codingLine[0] = columns;
58 + a0i = 0;
59 + outputBits = 0;
60 buf = EOF;
61
62 // skip any initial zero bits and end-of-line marker, and get the 2D
63 @@ -1335,164 +1340,228 @@ void CCITTFaxStream::reset() {
64 }
65 }
66
67 +inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
68 + if (a1 > codingLine[a0i]) {
69 + if (a1 > columns) {
70 + error(getPos(), "CCITTFax row is wrong length (%d)", a1);
71 + err = gTrue;
72 + a1 = columns;
73 + }
74 + if ((a0i & 1) ^ blackPixels) {
75 + ++a0i;
76 + }
77 + codingLine[a0i] = a1;
78 + }
79 +}
80 +
81 +inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
82 + if (a1 > codingLine[a0i]) {
83 + if (a1 > columns) {
84 + error(getPos(), "CCITTFax row is wrong length (%d)", a1);
85 + err = gTrue;
86 + a1 = columns;
87 + }
88 + if ((a0i & 1) ^ blackPixels) {
89 + ++a0i;
90 + }
91 + codingLine[a0i] = a1;
92 + } else if (a1 < codingLine[a0i]) {
93 + if (a1 < 0) {
94 + error(getPos(), "Invalid CCITTFax code");
95 + err = gTrue;
96 + a1 = 0;
97 + }
98 + while (a0i > 0 && a1 <= codingLine[a0i - 1]) {
99 + --a0i;
100 + }
101 + codingLine[a0i] = a1;
102 + }
103 +}
104 +
105 int CCITTFaxStream::lookChar() {
106 short code1, code2, code3;
107 - int a0New;
108 - GBool err, gotEOL;
109 - int ret;
110 - int bits, i;
111 -
112 - // if at eof just return EOF
113 - if (eof && codingLine[a0] >= columns) {
114 - return EOF;
115 + int b1i, blackPixels, i, bits;
116 + GBool gotEOL;
117 +
118 + if (buf != EOF) {
119 + return buf;
120 }
121
122 // read the next row
123 - err = gFalse;
124 - if (codingLine[a0] >= columns) {
125 + if (outputBits == 0) {
126
127 + // if at eof just return EOF
128 + if (eof) {
129 + return EOF;
130 + }
131 +
132 + err = gFalse;
133 +
134 // 2-D encoding
135 if (nextLine2D) {
136 for (i = 0; codingLine[i] < columns; ++i)
137 refLine[i] = codingLine[i];
138 - refLine[i] = refLine[i + 1] = columns;
139 - b1 = 1;
140 - a0New = codingLine[a0 = 0] = 0;
141 - do {
142 - code1 = getTwoDimCode();
143 + refLine[i++] = columns;
144 + refLine[i] = columns;
145 + codingLine[0] = 0;
146 + a0i = 0;
147 + b1i = 0;
148 + blackPixels = 0;
149 + // invariant:
150 + // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1]
151 + // <= columns
152 + // exception at left edge:
153 + // codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
154 + // exception at right edge:
155 + // refLine[b1i] = refLine[b1i+1] = columns is possible
156 + while (codingLine[a0i] < columns) {
157 + code1 = getTwoDimCode();
158 switch (code1) {
159 - case twoDimPass:
160 - if (refLine[b1] < columns) {
161 - a0New = refLine[b1 + 1];
162 - b1 += 2;
163 - }
164 - break;
165 - case twoDimHoriz:
166 - if ((a0 & 1) == 0) {
167 - code1 = code2 = 0;
168 - do {
169 - code1 += code3 = getWhiteCode();
170 - } while (code3 >= 64);
171 - do {
172 - code2 += code3 = getBlackCode();
173 - } while (code3 >= 64);
174 - } else {
175 - code1 = code2 = 0;
176 - do {
177 - code1 += code3 = getBlackCode();
178 - } while (code3 >= 64);
179 - do {
180 - code2 += code3 = getWhiteCode();
181 - } while (code3 >= 64);
182 - }
183 - if (code1 > 0 || code2 > 0) {
184 - codingLine[a0 + 1] = a0New + code1;
185 - ++a0;
186 - a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
187 - ++a0;
188 - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
189 - b1 += 2;
190 - }
191 - break;
192 - case twoDimVert0:
193 - a0New = codingLine[++a0] = refLine[b1];
194 - if (refLine[b1] < columns) {
195 - ++b1;
196 - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
197 - b1 += 2;
198 - }
199 - break;
200 - case twoDimVertR1:
201 - a0New = codingLine[++a0] = refLine[b1] + 1;
202 - if (refLine[b1] < columns) {
203 - ++b1;
204 - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
205 - b1 += 2;
206 - }
207 - break;
208 - case twoDimVertL1:
209 - if (a0 == 0 || refLine[b1] - 1 > a0New) {
210 - a0New = codingLine[++a0] = refLine[b1] - 1;
211 - --b1;
212 - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
213 - b1 += 2;
214 - }
215 - break;
216 - case twoDimVertR2:
217 - a0New = codingLine[++a0] = refLine[b1] + 2;
218 - if (refLine[b1] < columns) {
219 - ++b1;
220 - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
221 - b1 += 2;
222 - }
223 - break;
224 - case twoDimVertL2:
225 - if (a0 == 0 || refLine[b1] - 2 > a0New) {
226 - a0New = codingLine[++a0] = refLine[b1] - 2;
227 - --b1;
228 - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
229 - b1 += 2;
230 - }
231 - break;
232 - case twoDimVertR3:
233 - a0New = codingLine[++a0] = refLine[b1] + 3;
234 - if (refLine[b1] < columns) {
235 - ++b1;
236 - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
237 - b1 += 2;
238 - }
239 - break;
240 - case twoDimVertL3:
241 - if (a0 == 0 || refLine[b1] - 3 > a0New) {
242 - a0New = codingLine[++a0] = refLine[b1] - 3;
243 - --b1;
244 - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
245 - b1 += 2;
246 - }
247 - break;
248 - case EOF:
249 - eof = gTrue;
250 - codingLine[a0 = 0] = columns;
251 - return EOF;
252 - default:
253 - error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
254 - err = gTrue;
255 - break;
256 + case twoDimPass:
257 + addPixels(refLine[b1i + 1], blackPixels);
258 + if (refLine[b1i + 1] < columns) {
259 + b1i += 2;
260 + }
261 + break;
262 + case twoDimHoriz:
263 + code1 = code2 = 0;
264 + if (blackPixels) {
265 + do {
266 + code1 += code3 = getBlackCode();
267 + } while (code3 >= 64);
268 + do {
269 + code2 += code3 = getWhiteCode();
270 + } while (code3 >= 64);
271 + } else {
272 + do {
273 + code1 += code3 = getWhiteCode();
274 + } while (code3 >= 64);
275 + do {
276 + code2 += code3 = getBlackCode();
277 + } while (code3 >= 64);
278 + }
279 + addPixels(codingLine[a0i] + code1, blackPixels);
280 + if (codingLine[a0i] < columns) {
281 + addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
282 + }
283 + while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
284 + b1i += 2;
285 + }
286 + break;
287 + case twoDimVertR3:
288 + addPixels(refLine[b1i] + 3, blackPixels);
289 + blackPixels ^= 1;
290 + if (codingLine[a0i] < columns) {
291 + ++b1i;
292 + while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
293 + b1i += 2;
294 + }
295 + }
296 + break;
297 + case twoDimVertR2:
298 + addPixels(refLine[b1i] + 2, blackPixels);
299 + blackPixels ^= 1;
300 + if (codingLine[a0i] < columns) {
301 + ++b1i;
302 + while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
303 + b1i += 2;
304 + }
305 + }
306 + break;
307 + case twoDimVertR1:
308 + addPixels(refLine[b1i] + 1, blackPixels);
309 + blackPixels ^= 1;
310 + if (codingLine[a0i] < columns) {
311 + ++b1i;
312 + while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
313 + b1i += 2;
314 + }
315 + }
316 + break;
317 + case twoDimVert0:
318 + addPixels(refLine[b1i], blackPixels);
319 + blackPixels ^= 1;
320 + if (codingLine[a0i] < columns) {
321 + ++b1i;
322 + while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
323 + b1i += 2;
324 + }
325 + }
326 + break;
327 + case twoDimVertL3:
328 + addPixelsNeg(refLine[b1i] - 3, blackPixels);
329 + blackPixels ^= 1;
330 + if (codingLine[a0i] < columns) {
331 + if (b1i > 0) {
332 + --b1i;
333 + } else {
334 + ++b1i;
335 + }
336 + while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
337 + b1i += 2;
338 + }
339 + }
340 + break;
341 + case twoDimVertL2:
342 + addPixelsNeg(refLine[b1i] - 2, blackPixels);
343 + blackPixels ^= 1;
344 + if (codingLine[a0i] < columns) {
345 + if (b1i > 0) {
346 + --b1i;
347 + } else {
348 + ++b1i;
349 + }
350 + while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
351 + b1i += 2;
352 + }
353 + }
354 + break;
355 + case twoDimVertL1:
356 + addPixelsNeg(refLine[b1i] - 1, blackPixels);
357 + blackPixels ^= 1;
358 + if (codingLine[a0i] < columns) {
359 + if (b1i > 0) {
360 + --b1i;
361 + } else {
362 + ++b1i;
363 + }
364 + while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
365 + b1i += 2;
366 + }
367 + }
368 + break;
369 + case EOF:
370 + addPixels(columns, 0);
371 + eof = gTrue;
372 + break;
373 + default:
374 + error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
375 + addPixels(columns, 0);
376 + err = gTrue;
377 + break;
378 + }
379 }
380 - } while (codingLine[a0] < columns);
381
382 // 1-D encoding
383 } else {
384 - codingLine[a0 = 0] = 0;
385 - while (1) {
386 - code1 = 0;
387 - do {
388 - code1 += code3 = getWhiteCode();
389 - } while (code3 >= 64);
390 - codingLine[a0+1] = codingLine[a0] + code1;
391 - ++a0;
392 - if (codingLine[a0] >= columns)
393 - break;
394 - code2 = 0;
395 - do {
396 - code2 += code3 = getBlackCode();
397 - } while (code3 >= 64);
398 - codingLine[a0+1] = codingLine[a0] + code2;
399 - ++a0;
400 - if (codingLine[a0] >= columns)
401 - break;
402 - }
403 - }
404 -
405 - if (codingLine[a0] != columns) {
406 - error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
407 - // force the row to be the correct length
408 - while (codingLine[a0] > columns) {
409 - --a0;
410 + codingLine[0] = 0;
411 + a0i = 0;
412 + blackPixels = 0;
413 + while (codingLine[a0i] < columns) {
414 + code1 = 0;
415 + if (blackPixels) {
416 + do {
417 + code1 += code3 = getBlackCode();
418 + } while (code3 >= 64);
419 + } else {
420 + do {
421 + code1 += code3 = getWhiteCode();
422 + } while (code3 >= 64);
423 + }
424 + addPixels(codingLine[a0i] + code1, blackPixels);
425 + blackPixels ^= 1;
426 + }
427 }
428 - codingLine[++a0] = columns;
429 - err = gTrue;
430 - }
431
432 // byte-align the row
433 if (byteAlign) {
434 @@ -1552,14 +1621,17 @@ int CCITTFaxStream::lookChar() {
435 // this if we know the stream contains end-of-line markers because
436 // the "just plow on" technique tends to work better otherwise
437 } else if (err && endOfLine) {
438 - do {
439 + while (1) {
440 + code1 = lookBits(13);
441 if (code1 == EOF) {
442 eof = gTrue;
443 return EOF;
444 }
445 + if ((code1 >> 1) == 0x001) {
446 + break;
447 + }
448 eatBits(1);
449 - code1 = lookBits(13);
450 - } while ((code1 >> 1) != 0x001);
451 + }
452 eatBits(12);
453 if (encoding > 0) {
454 eatBits(1);
455 @@ -1567,11 +1639,11 @@ int CCITTFaxStream::lookChar() {
456 }
457 }
458
459 - a0 = 0;
460 - outputBits = codingLine[1] - codingLine[0];
461 - if (outputBits == 0) {
462 - a0 = 1;
463 - outputBits = codingLine[2] - codingLine[1];
464 + // set up for output
465 + if (codingLine[0] > 0) {
466 + outputBits = codingLine[a0i = 0];
467 + } else {
468 + outputBits = codingLine[a0i = 1];
469 }
470
471 ++row;
472 @@ -1579,39 +1651,43 @@ int CCITTFaxStream::lookChar() {
473
474 // get a byte
475 if (outputBits >= 8) {
476 - ret = ((a0 & 1) == 0) ? 0xff : 0x00;
477 - if ((outputBits -= 8) == 0) {
478 - ++a0;
479 - if (codingLine[a0] < columns) {
480 - outputBits = codingLine[a0 + 1] - codingLine[a0];
481 - }
482 + buf = (a0i & 1) ? 0x00 : 0xff;
483 + outputBits -= 8;
484 + if (outputBits == 0 && codingLine[a0i] < columns) {
485 + ++a0i;
486 + outputBits = codingLine[a0i] - codingLine[a0i - 1];
487 }
488 } else {
489 bits = 8;
490 - ret = 0;
491 + buf = 0;
492 do {
493 if (outputBits > bits) {
494 - i = bits;
495 - bits = 0;
496 - if ((a0 & 1) == 0) {
497 - ret |= 0xff >> (8 - i);
498 + buf <<= bits;
499 + if (!(a0i & 1)) {
500 + buf |= 0xff >> (8 - bits);
501 }
502 - outputBits -= i;
503 + outputBits -= bits;
504 + bits = 0;
505 } else {
506 - i = outputBits;
507 - bits -= outputBits;
508 - if ((a0 & 1) == 0) {
509 - ret |= (0xff >> (8 - i)) << bits;
510 + buf <<= outputBits;
511 + if (!(a0i & 1)) {
512 + buf |= 0xff >> (8 - outputBits);
513 }
514 + bits -= outputBits;
515 outputBits = 0;
516 - ++a0;
517 - if (codingLine[a0] < columns) {
518 - outputBits = codingLine[a0 + 1] - codingLine[a0];
519 + if (codingLine[a0i] < columns) {
520 + ++a0i;
521 + outputBits = codingLine[a0i] - codingLine[a0i - 1];
522 + } else if (bits > 0) {
523 + buf <<= bits;
524 + bits = 0;
525 }
526 }
527 - } while (bits > 0 && codingLine[a0] < columns);
528 + } while (bits);
529 + }
530 + if (black) {
531 + buf ^= 0xff;
532 }
533 - buf = black ? (ret ^ 0xff) : ret;
534 return buf;
535 }
536
537 @@ -1653,6 +1729,9 @@ short CCITTFaxStream::getWhiteCode() {
538 code = 0; // make gcc happy
539 if (endOfBlock) {
540 code = lookBits(12);
541 + if (code == EOF) {
542 + return 1;
543 + }
544 if ((code >> 5) == 0) {
545 p = &whiteTab1[code];
546 } else {
547 @@ -1665,6 +1744,9 @@ short CCITTFaxStream::getWhiteCode() {
548 } else {
549 for (n = 1; n <= 9; ++n) {
550 code = lookBits(n);
551 + if (code == EOF) {
552 + return 1;
553 + }
554 if (n < 9) {
555 code <<= 9 - n;
556 }
557 @@ -1676,6 +1758,9 @@ short CCITTFaxStream::getWhiteCode() {
558 }
559 for (n = 11; n <= 12; ++n) {
560 code = lookBits(n);
561 + if (code == EOF) {
562 + return 1;
563 + }
564 if (n < 12) {
565 code <<= 12 - n;
566 }
567 @@ -1701,6 +1786,9 @@ short CCITTFaxStream::getBlackCode() {
568 code = 0; // make gcc happy
569 if (endOfBlock) {
570 code = lookBits(13);
571 + if (code == EOF) {
572 + return 1;
573 + }
574 if ((code >> 7) == 0) {
575 p = &blackTab1[code];
576 } else if ((code >> 9) == 0) {
577 @@ -1715,6 +1803,9 @@ short CCITTFaxStream::getBlackCode() {
578 } else {
579 for (n = 2; n <= 6; ++n) {
580 code = lookBits(n);
581 + if (code == EOF) {
582 + return 1;
583 + }
584 if (n < 6) {
585 code <<= 6 - n;
586 }
587 @@ -1726,6 +1817,9 @@ short CCITTFaxStream::getBlackCode() {
588 }
589 for (n = 7; n <= 12; ++n) {
590 code = lookBits(n);
591 + if (code == EOF) {
592 + return 1;
593 + }
594 if (n < 12) {
595 code <<= 12 - n;
596 }
597 @@ -1739,6 +1833,9 @@ short CCITTFaxStream::getBlackCode() {
598 }
599 for (n = 10; n <= 13; ++n) {
600 code = lookBits(n);
601 + if (code == EOF) {
602 + return 1;
603 + }
604 if (n < 13) {
605 code <<= 13 - n;
606 }
607 @@ -1961,6 +2058,12 @@ void DCTStream::reset() {
608 // allocate a buffer for the whole image
609 bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
610 bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
611 + if (bufWidth <= 0 || bufHeight <= 0 ||
612 + bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
613 + error(getPos(), "Invalid image size in DCT stream");
614 + y = height;
615 + return;
616 + }
617 for (i = 0; i < numComps; ++i) {
618 frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
619 memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
620 @@ -3024,6 +3127,11 @@ GBool DCTStream::readScanInfo() {
621 }
622 scanInfo.firstCoeff = str->getChar();
623 scanInfo.lastCoeff = str->getChar();
624 + if (scanInfo.firstCoeff < 0 || scanInfo.lastCoeff > 63 ||
625 + scanInfo.firstCoeff > scanInfo.lastCoeff) {
626 + error(getPos(), "Bad DCT coefficient numbers in scan info block");
627 + return gFalse;
628 + }
629 c = str->getChar();
630 scanInfo.ah = (c >> 4) & 0x0f;
631 scanInfo.al = c & 0x0f;
632 Index: tetex-src-3.0/libs/xpdf/xpdf/Stream.h
633 ===================================================================
634 --- tetex-src-3.0.orig/libs/xpdf/xpdf/Stream.h
635 +++ tetex-src-3.0/libs/xpdf/xpdf/Stream.h
636 @@ -519,13 +519,15 @@ private:
637 int row; // current row
638 int inputBuf; // input buffer
639 int inputBits; // number of bits in input buffer
640 - short *refLine; // reference line changing elements
641 - int b1; // index into refLine
642 - short *codingLine; // coding line changing elements
643 - int a0; // index into codingLine
644 + int *codingLine; // coding line changing elements
645 + int *refLine; // reference line changing elements
646 + int a0i; // index into codingLine
647 + GBool err; // error on current line
648 int outputBits; // remaining ouput bits
649 int buf; // character buffer
650
651 + void addPixels(int a1, int black);
652 + void addPixelsNeg(int a1, int black);
653 short getTwoDimCode();
654 short getWhiteCode();
655 short getBlackCode();
656
657
658
659 --
660 gentoo-commits@g.o mailing list