Magellan Linux

Contents of /trunk/kdegraphics/patches/post-3.5.8-kdegraphics-kpdf.diff

Parent Directory Parent Directory | Revision Log Revision Log


Revision 424 - (show annotations) (download)
Sun Dec 9 14:54:12 2007 UTC (16 years, 4 months ago) by niro
File size: 17412 byte(s)
-security update

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