fixed segv for files with wrong font types
[swftools.git] / lib / pdf / xpdf-changes.patch
1 --- xpdf/Catalog.cc.orig        2010-05-18 11:22:18.000000000 -0700
2 +++ xpdf/Catalog.cc     2010-05-18 11:22:18.000000000 -0700
3 @@ -193,7 +193,7 @@
4    if (!kids.isArray()) {
5      error(-1, "Kids object (page %d) is wrong type (%s)",
6           start+1, kids.getTypeName());
7 -    goto err1;
8 +    return start;
9    }
10    for (i = 0; i < kids.arrayGetLength(); ++i) {
11      kids.arrayGetNF(i, &kidRef);
12 --- xpdf/CharCodeToUnicode.cc.orig      2010-05-18 11:22:18.000000000 -0700
13 +++ xpdf/CharCodeToUnicode.cc   2010-05-18 11:22:18.000000000 -0700
14 @@ -208,13 +208,13 @@
15                                    int nBits) {
16    PSTokenizer *pst;
17    char tok1[256], tok2[256], tok3[256];
18 -  int nDigits, n1, n2, n3;
19 +  int maxCode, n1, n2, n3;
20    CharCode i;
21    CharCode code1, code2;
22    GString *name;
23    FILE *f;
24  
25 -  nDigits = nBits / 4;
26 +  maxCode = (nBits == 8) ? 0xff : (nBits == 16) ? 0xffff : 0xffffffff;
27    pst = new PSTokenizer(getCharFunc, data);
28    pst->getToken(tok1, sizeof(tok1), &n1);
29    while (pst->getToken(tok2, sizeof(tok2), &n2)) {
30 @@ -241,9 +241,9 @@
31           error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
32           break;
33         }
34 -       if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
35 +       if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' &&
36               tok2[0] == '<' && tok2[n2 - 1] == '>')) {
37 -         error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
38 +         error(-1, "Illegal entry in bfchar block in ToUnicode CMap.");
39           continue;
40         }
41         tok1[n1 - 1] = tok2[n2 - 1] = '\0';
42 @@ -251,6 +251,9 @@
43           error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
44           continue;
45         }
46 +        if (code1 > maxCode) {
47 +          error(-1, "Invalid entry in bfchar block in ToUnicode CMap");
48 +        }
49         addMapping(code1, tok2 + 1, n2 - 2, 0);
50        }
51        pst->getToken(tok1, sizeof(tok1), &n1);
52 @@ -266,8 +269,8 @@
53           error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
54           break;
55         }
56 -       if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
57 -             n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
58 +       if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' &&
59 +             tok2[0] == '<' && tok2[n2 - 1] == '>')) {
60           error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
61           continue;
62         }
63 @@ -277,6 +280,10 @@
64           error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
65           continue;
66         }
67 +        if (code1 > maxCode || code2 > maxCode) {
68 +           error(-1, "Invalid entry in bfrange block in ToUnicode CMap");
69 +       }
70 +
71         if (!strcmp(tok3, "[")) {
72           i = 0;
73           while (pst->getToken(tok1, sizeof(tok1), &n1) &&
74 @@ -320,7 +327,13 @@
75    if (code >= mapLen) {
76      oldLen = mapLen;
77      mapLen = (code + 256) & ~255;
78 +    Unicode *oldmap;
79      map = (Unicode *)greallocn(map, mapLen, sizeof(Unicode));
80 +    if(!map) {
81 +       /* we sometimes get overflows for files trying to use 0xffffffff as charcode */
82 +       map = oldmap;
83 +       return;
84 +    }
85      for (i = oldLen; i < mapLen; ++i) {
86        map[i] = 0;
87      }
88 --- xpdf/CoreOutputDev.cc.orig  2010-05-18 11:22:18.000000000 -0700
89 +++ xpdf/CoreOutputDev.cc       2010-05-18 11:22:18.000000000 -0700
90 @@ -57,5 +57,5 @@
91  
92  void CoreOutputDev::clear() {
93    startDoc(NULL);
94 -  startPage(0, NULL);
95 +  startPage(0, NULL, 0,0,0,0);
96  }
97 --- xpdf/Decrypt.cc.orig        2010-05-18 11:22:18.000000000 -0700
98 +++ xpdf/Decrypt.cc     2010-05-18 11:22:18.000000000 -0700
99 @@ -596,6 +596,7 @@
100    s->bufIdx = 0;
101    if (last) {
102      n = s->buf[15];
103 +    if(!n || n>16) n=16;
104      for (i = 15; i >= n; --i) {
105        s->buf[i] = s->buf[i-n];
106      }
107 --- xpdf/Gfx.cc.orig    2010-05-18 11:22:18.000000000 -0700
108 +++ xpdf/Gfx.cc 2010-05-18 11:22:18.000000000 -0700
109 @@ -454,7 +454,11 @@
110    fontChanged = gFalse;
111    clip = clipNone;
112    ignoreUndef = 0;
113 -  out->startPage(pageNum, state);
114 +  if(cropBox) {
115 +      out->startPage(pageNum, state, cropBox->x1,cropBox->y1,cropBox->x2,cropBox->y2);
116 +  } else {
117 +      out->startPage(pageNum, state, 0,0,0,0);
118 +  }
119    out->setDefaultCTM(state->getCTM());
120    out->updateAll(state);
121    for (i = 0; i < 6; ++i) {
122 @@ -465,6 +469,7 @@
123    abortCheckCbkData = abortCheckCbkDataA;
124  
125    // set crop box
126 +#ifdef XPDFEXE
127    if (cropBox) {
128      state->moveTo(cropBox->x1, cropBox->y1);
129      state->lineTo(cropBox->x2, cropBox->y1);
130 @@ -475,6 +480,7 @@
131      out->clip(state);
132      state->clearPath();
133    }
134 +#endif
135  }
136  
137  Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict,
138 @@ -3182,8 +3188,11 @@
139                             u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
140                             &dx, &dy, &originX, &originY);
141        dx = dx * state->getFontSize() + state->getCharSpace();
142 -      if (n == 1 && *p == ' ') {
143 -       dx += state->getWordSpace();
144 +      if (n == 1 && (*p == ' ' || *p == 0)) {
145 +        double w=state->getWordSpace();
146 +        if (w==0 && dx==0)
147 +          w=state->getFontSize()/3; // workaround for zero word space
148 +        dx += w;
149        }
150        dx *= state->getHorizScaling();
151        dy *= state->getFontSize();
152 @@ -3476,11 +3485,13 @@
153        }
154      }
155      if (!obj1.isNull()) {
156 -      colorSpace = GfxColorSpace::parse(&obj1);
157 +      colorSpace = GfxColorSpace::parse(&obj1, csMode);
158      } else if (csMode == streamCSDeviceGray) {
159        colorSpace = new GfxDeviceGrayColorSpace();
160      } else if (csMode == streamCSDeviceRGB) {
161        colorSpace = new GfxDeviceRGBColorSpace();
162 +    } else if (csMode == streamCSDeviceRGBX) {
163 +      colorSpace = new GfxDeviceRGBXColorSpace();
164      } else if (csMode == streamCSDeviceCMYK) {
165        colorSpace = new GfxDeviceCMYKColorSpace();
166      } else {
167 @@ -3824,6 +3835,7 @@
168      out->beginTransparencyGroup(state, bbox, blendingColorSpace,
169                                 isolated, knockout, softMask);
170    }
171 +  GfxState*old_state = state;
172  
173    // set new base matrix
174    for (i = 0; i < 6; ++i) {
175 @@ -3835,6 +3847,9 @@
176    display(str, gFalse);
177  
178    if (softMask || transpGroup) {
179 +    // restore graphics state
180 +    while(state != old_state)
181 +       restoreState();
182      out->endTransparencyGroup(state);
183    }
184  
185 --- xpdf/GfxFont.cc.orig        2010-05-18 11:22:18.000000000 -0700
186 +++ xpdf/GfxFont.cc     2010-05-18 11:22:18.000000000 -0700
187 @@ -194,7 +194,7 @@
188        embFontID = obj2.getRef();
189        if (type != fontType1) {
190         error(-1, "Mismatch between font type and embedded font file");
191 -       type = fontType1;
192 +       type = isCIDFont() ? fontCIDType0 : fontType1;
193        }
194      }
195      obj2.free();
196 @@ -919,6 +919,10 @@
197    return 1;
198  }
199  
200 +CharCodeToUnicode* Gfx8BitFont::getCTU() {
201 +    return ctu;
202 +}
203 +
204  CharCodeToUnicode *Gfx8BitFont::getToUnicode() {
205    ctu->incRefCnt();
206    return ctu;
207 @@ -1411,6 +1415,10 @@
208    }
209  }
210  
211 +CharCodeToUnicode* GfxCIDFont::getCTU() {
212 +    return ctu;
213 +}
214 +
215  int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
216                             Unicode *u, int uSize, int *uLen,
217                             double *dx, double *dy, double *ox, double *oy) {
218 --- xpdf/GfxFont.h.orig 2010-05-18 11:22:18.000000000 -0700
219 +++ xpdf/GfxFont.h      2010-05-18 11:22:18.000000000 -0700
220 @@ -164,6 +164,7 @@
221    virtual int getNextChar(char *s, int len, CharCode *code,
222                           Unicode *u, int uSize, int *uLen,
223                           double *dx, double *dy, double *ox, double *oy) = 0;
224 +  virtual CharCodeToUnicode* getCTU() = 0;
225  
226  protected:
227  
228 @@ -204,6 +205,7 @@
229    virtual int getNextChar(char *s, int len, CharCode *code,
230                           Unicode *u, int uSize, int *uLen,
231                           double *dx, double *dy, double *ox, double *oy);
232 +  virtual CharCodeToUnicode* getCTU();
233  
234    // Return the encoding.
235    char **getEncoding() { return enc; }
236 @@ -212,7 +214,7 @@
237    CharCodeToUnicode *getToUnicode();
238  
239    // Return the character name associated with <code>.
240 -  char *getCharName(int code) { return enc[code]; }
241 +  char *getCharName(int code) { return code>=256?0:enc[code]; }
242  
243    // Returns true if the PDF font specified an encoding.
244    GBool getHasEncoding() { return hasEncoding; }
245 @@ -266,6 +268,7 @@
246    virtual int getNextChar(char *s, int len, CharCode *code,
247                           Unicode *u, int uSize, int *uLen,
248                           double *dx, double *dy, double *ox, double *oy);
249 +  virtual CharCodeToUnicode* getCTU();
250  
251    // Return the writing mode (0=horizontal, 1=vertical).
252    virtual int getWMode();
253 --- xpdf/GfxState.cc.orig       2010-05-18 11:22:18.000000000 -0700
254 +++ xpdf/GfxState.cc    2010-05-18 11:22:18.000000000 -0700
255 @@ -21,6 +21,7 @@
256  #include "Array.h"
257  #include "Page.h"
258  #include "GfxState.h"
259 +#include "cmyk.h"
260  
261  //------------------------------------------------------------------------
262  
263 @@ -92,7 +93,7 @@
264  GfxColorSpace::~GfxColorSpace() {
265  }
266  
267 -GfxColorSpace *GfxColorSpace::parse(Object *csObj) {
268 +GfxColorSpace *GfxColorSpace::parse(Object *csObj, StreamColorSpaceMode csMode) {
269    GfxColorSpace *cs;
270    Object obj1;
271  
272 @@ -101,7 +102,10 @@
273      if (csObj->isName("DeviceGray") || csObj->isName("G")) {
274        cs = new GfxDeviceGrayColorSpace();
275      } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) {
276 -      cs = new GfxDeviceRGBColorSpace();
277 +      if(csMode == streamCSDeviceRGBX)
278 +       cs = new GfxDeviceRGBXColorSpace();
279 +      else
280 +       cs = new GfxDeviceRGBColorSpace();
281      } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) {
282        cs = new GfxDeviceCMYKColorSpace();
283      } else if (csObj->isName("Pattern")) {
284 @@ -114,7 +118,10 @@
285      if (obj1.isName("DeviceGray") || obj1.isName("G")) {
286        cs = new GfxDeviceGrayColorSpace();
287      } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) {
288 -      cs = new GfxDeviceRGBColorSpace();
289 +      if(csMode == streamCSDeviceRGBX)
290 +        cs = new GfxDeviceRGBColorSpace();
291 +      else
292 +       cs = new GfxDeviceRGBColorSpace();
293      } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {
294        cs = new GfxDeviceCMYKColorSpace();
295      } else if (obj1.isName("CalGray")) {
296 @@ -333,6 +340,17 @@
297  }
298  
299  //------------------------------------------------------------------------
300 +// GfxDeviceRGBXColorSpace
301 +//------------------------------------------------------------------------
302 +
303 +GfxDeviceRGBXColorSpace::GfxDeviceRGBXColorSpace() {
304 +}
305 +
306 +GfxColorSpace *GfxDeviceRGBXColorSpace::copy() {
307 +  return new GfxDeviceRGBXColorSpace();
308 +}
309 +
310 +//------------------------------------------------------------------------
311  // GfxCalRGBColorSpace
312  //------------------------------------------------------------------------
313  
314 @@ -490,6 +508,18 @@
315                                 - 0.11 * color->c[2] + 0.5));
316  }
317  
318 +/*void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
319 +    unsigned char r,g,b;
320 +    float c = color->c[0];
321 +    float m = color->c[1];
322 +    float y = color->c[2];
323 +    float k = color->c[3];
324 +    convert_cmyk2rgb(c,m,y,k, &r,&g,&b);
325 +    rgb->r = r/255.0;
326 +    rgb->g = g/255.0;
327 +    rgb->b = b/255.0;
328 +}*/
329 +
330  void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
331    double c, m, y, k, c1, m1, y1, k1, r, g, b, x;
332  
333 @@ -3187,6 +3217,7 @@
334    GfxIndexedColorSpace *indexedCS;
335    GfxSeparationColorSpace *sepCS;
336    int maxPixel, indexHigh;
337 +  int maxPixelForAlloc;
338    Guchar *lookup2;
339    Function *sepFunc;
340    Object obj;
341 @@ -3199,6 +3230,7 @@
342    // bits per component and color space
343    bits = bitsA;
344    maxPixel = (1 << bits) - 1;
345 +  maxPixelForAlloc = (1 << (bits>8?bits:8));
346    colorSpace = colorSpaceA;
347  
348    // initialize
349 @@ -3253,7 +3285,7 @@
350      lookup2 = indexedCS->getLookup();
351      colorSpace2->getDefaultRanges(x, y, indexHigh);
352      for (k = 0; k < nComps2; ++k) {
353 -      lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
354 +      lookup[k] = (GfxColorComp *)gmallocn(maxPixelForAlloc + 1,
355                                            sizeof(GfxColorComp));
356        for (i = 0; i <= maxPixel; ++i) {
357         j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5);
358 @@ -3272,7 +3304,7 @@
359      nComps2 = colorSpace2->getNComps();
360      sepFunc = sepCS->getFunc();
361      for (k = 0; k < nComps2; ++k) {
362 -      lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
363 +      lookup[k] = (GfxColorComp *)gmallocn(maxPixelForAlloc + 1,
364                                            sizeof(GfxColorComp));
365        for (i = 0; i <= maxPixel; ++i) {
366         x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel;
367 @@ -3282,7 +3314,7 @@
368      }
369    } else {
370      for (k = 0; k < nComps; ++k) {
371 -      lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
372 +      lookup[k] = (GfxColorComp *)gmallocn(maxPixelForAlloc + 1,
373                                            sizeof(GfxColorComp));
374        for (i = 0; i <= maxPixel; ++i) {
375         lookup[k][i] = dblToCol(decodeLow[k] +
376 @@ -3754,7 +3786,10 @@
377  }
378  
379  void GfxState::setPath(GfxPath *pathA) {
380 +  if(pathA) {
381 +      if(path)
382    delete path;
383 +  }
384    path = pathA;
385  }
386  
387 --- xpdf/GfxState.h.orig        2010-05-18 11:22:18.000000000 -0700
388 +++ xpdf/GfxState.h     2010-05-18 11:22:18.000000000 -0700
389 @@ -138,7 +138,7 @@
390    virtual GfxColorSpaceMode getMode() = 0;
391  
392    // Construct a color space.  Returns NULL if unsuccessful.
393 -  static GfxColorSpace *parse(Object *csObj);
394 +  static GfxColorSpace *parse(Object *csObj, StreamColorSpaceMode csMode = streamCSNone);
395  
396    // Convert to gray, RGB, or CMYK.
397    virtual void getGray(GfxColor *color, GfxGray *gray) = 0;
398 @@ -252,6 +252,19 @@
399  };
400  
401  //------------------------------------------------------------------------
402 +// GfxDeviceRGBXColorSpace
403 +//------------------------------------------------------------------------
404 +
405 +class GfxDeviceRGBXColorSpace: public GfxDeviceRGBColorSpace {
406 +public:
407 +
408 +  GfxDeviceRGBXColorSpace();
409 +  virtual GfxColorSpace *copy();
410 +  virtual int getNComps() { return 4; }
411 +private:
412 +};
413 +
414 +//------------------------------------------------------------------------
415  // GfxCalRGBColorSpace
416  //------------------------------------------------------------------------
417  
418 --- xpdf/GlobalParams.cc.orig   2010-05-18 11:22:18.000000000 -0700
419 +++ xpdf/GlobalParams.cc        2010-05-18 11:22:18.000000000 -0700
420 @@ -914,6 +914,29 @@
421    int line;
422    char buf[512];
423  
424 +  /* extract path */
425 +  if(fileName) {
426 +    char* cfgFileName = fileName->getCString();
427 +    char* pos1 = strrchr(cfgFileName, '/');
428 +    char* pos2 = strrchr(cfgFileName, '\\');
429 +    char* p = pos1>pos2?pos1:pos2;
430 +    int pos = p ? p-cfgFileName : -1;
431 +    GString*path = new GString(new GString(cfgFileName), 0, (pos < 0 ? strlen(cfgFileName): pos));
432 +    if(pos1>=0)
433 +       path->append('/');
434 +    else if(pos2>=0)
435 +       path->append('\\');
436 +    else
437 +#ifdef WIN32
438 +       path->append('\\');
439 +#else
440 +       path->append('/');
441 +#endif
442 +    this->path = path;
443 +  } else {
444 +    this->path = new GString();
445 +  }
446 +  
447    line = 1;
448    while (getLine(buf, sizeof(buf) - 1, f)) {
449      parseLine(buf, fileName, line);
450 @@ -1114,6 +1137,42 @@
451    deleteGList(tokens, GString);
452  }
453  
454 +static char is_absolute(char*filename)
455 +{
456 +    int l = strlen(filename);
457 +    if(filename[0] == '/' || filename[0] == '\\') 
458 +       return 1;
459 +    if(l>2 && filename[1]==':' && (filename[2]=='\\' || filename[2]=='/'))
460 +       return 1;
461 +    return 0;
462 +}
463 +
464 +static GString* qualify_filename(GString*path, GString*filename)
465 +{
466 +  GString*fullpath = 0;
467 +  char*prefix = "/usr/local/share/xpdf/";
468 +
469 +  if (!is_absolute(filename->getCString())) {
470 +    /* relative path */
471 +    fullpath = path->copy();
472 +    fullpath->append(filename);
473 +  } else if (!strncmp(filename->getCString(), prefix, strlen(prefix))) {
474 +    /* xpdf default path */
475 +    char*s = strchr(filename->getCString()+strlen(prefix), '/');
476 +    if(s) {
477 +       fullpath = path->copy();
478 +       fullpath->append(s+1);
479 +    } else {
480 +       fullpath = filename->copy();
481 +    }
482 +  } else {
483 +    /* absolute path */
484 +    fullpath = filename->copy();
485 +  }
486 +  //printf("%s -%s-> %s\n", filename->getCString(), path->getCString(), fullpath->getCString());
487 +  return fullpath;
488 +}
489 +
490  void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
491                                          int line) {
492    GString *name;
493 @@ -1128,10 +1187,10 @@
494           fileName->getCString(), line);
495      return;
496    }
497 -  name = (GString *)tokens->get(1);
498 +  name = qualify_filename(this->path, (GString *)tokens->get(1));
499    if (!(f = fopen(name->getCString(), "r"))) {
500 -    error(-1, "Couldn't open 'nameToUnicode' file '%s'",
501 -         name->getCString());
502 +    error(-1, "Couldn't open 'nameToUnicode' file '%s' using path '%s'",
503 +         name->getCString(), path->getCString());
504      return;
505    }
506    line2 = 1;
507 @@ -1160,10 +1219,12 @@
508    }
509    collection = (GString *)tokens->get(1);
510    name = (GString *)tokens->get(2);
511 +
512    if ((old = (GString *)cidToUnicodes->remove(collection))) {
513      delete old;
514    }
515 -  cidToUnicodes->add(collection->copy(), name->copy());
516 +
517 +  cidToUnicodes->add(collection->copy(), qualify_filename(this->path, name));
518  }
519  
520  void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName,
521 @@ -1180,7 +1241,8 @@
522    if ((old = (GString *)unicodeToUnicodes->remove(font))) {
523      delete old;
524    }
525 -  unicodeToUnicodes->add(font->copy(), file->copy());
526 +
527 +  unicodeToUnicodes->add(font->copy(), qualify_filename(this->path, file));
528  }
529  
530  void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
531 @@ -1197,7 +1259,8 @@
532    if ((old = (GString *)unicodeMaps->remove(encodingName))) {
533      delete old;
534    }
535 -  unicodeMaps->add(encodingName->copy(), name->copy());
536 +
537 +  unicodeMaps->add(encodingName->copy(), qualify_filename(this->path, name));
538  }
539  
540  void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
541 @@ -1215,23 +1278,30 @@
542      list = new GList();
543      cMapDirs->add(collection->copy(), list);
544    }
545 -  list->append(dir->copy());
546 +
547 +  list->append(qualify_filename(this->path, dir));
548  }
549  
550  void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
551                                      int line) {
552 +  GString *dir;
553 +
554    if (tokens->getLength() != 2) {
555      error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
556           fileName->getCString(), line);
557      return;
558    }
559 -  toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
560 +
561 +  dir = (GString *)tokens->get(1);
562 +
563 +  toUnicodeDirs->append(qualify_filename(this->path, dir));
564  }
565  
566  void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
567                                     DisplayFontParamKind kind,
568                                     GString *fileName, int line) {
569    DisplayFontParam *param, *old;
570 +  GString *file;
571  
572    if (tokens->getLength() < 2) {
573      goto err1;
574 @@ -1243,13 +1313,15 @@
575      if (tokens->getLength() != 3) {
576        goto err2;
577      }
578 -    param->t1.fileName = ((GString *)tokens->get(2))->copy();
579 +    file = (GString *)tokens->get(2);
580 +    param->t1.fileName = qualify_filename(this->path, file);
581      break;
582    case displayFontTT:
583      if (tokens->getLength() != 3) {
584        goto err2;
585      }
586 -    param->tt.fileName = ((GString *)tokens->get(2))->copy();
587 +    file = (GString *)tokens->get(2);
588 +    param->tt.fileName = qualify_filename(this->path, file);
589      break;
590    }
591  
592 --- xpdf/GlobalParams.h.orig    2010-05-18 11:22:18.000000000 -0700
593 +++ xpdf/GlobalParams.h 2010-05-18 11:22:18.000000000 -0700
594 @@ -196,7 +196,7 @@
595    // file.
596    GlobalParams(char *cfgFileName);
597  
598 -  ~GlobalParams();
599 +  virtual ~GlobalParams();
600  
601    void setBaseDir(char *dir);
602    void setupBaseFonts(char *dir);
603 @@ -213,8 +213,8 @@
604    FILE *getUnicodeMapFile(GString *encodingName);
605    FILE *findCMapFile(GString *collection, GString *cMapName);
606    FILE *findToUnicodeFile(GString *name);
607 -  DisplayFontParam *getDisplayFont(GString *fontName);
608 -  DisplayFontParam *getDisplayCIDFont(GString *fontName, GString *collection);
609 +  virtual DisplayFontParam *getDisplayFont(GString *fontName);
610 +  virtual DisplayFontParam *getDisplayCIDFont(GString *fontName, GString *collection);
611    GString *getPSFile();
612    int getPSPaperWidth();
613    int getPSPaperHeight();
614 @@ -316,7 +316,7 @@
615  private:
616  
617    void createDefaultKeyBindings();
618 -  void parseFile(GString *fileName, FILE *f);
619 +public: void parseFile(GString *fileName, FILE *f); private:
620    void parseNameToUnicode(GList *tokens, GString *fileName, int line);
621    void parseCIDToUnicode(GList *tokens, GString *fileName, int line);
622    void parseUnicodeToUnicode(GList *tokens, GString *fileName, int line);
623 @@ -358,6 +358,10 @@
624    GBool loadPlugin(char *type, char *name);
625  #endif
626  
627 +  //----- config file base path
628 +
629 +  GString*path;
630 +
631    //----- static tables
632  
633    NameToCharCode *             // mapping from char name to
634 --- xpdf/JBIG2Stream.cc.orig    2010-05-18 11:22:18.000000000 -0700
635 +++ xpdf/JBIG2Stream.cc 2010-05-18 11:22:18.000000000 -0700
636 @@ -1514,11 +1514,14 @@
637    }
638  
639    // compute symbol code length
640 -  symCodeLen = 1;
641 -  i = (numInputSyms + numNewSyms) >> 1;
642 -  while (i) {
643 -    ++symCodeLen;
644 -    i >>= 1;
645 +  symCodeLen = 0;
646 +  i = 1;
647 +  while (i < numInputSyms + numNewSyms) {
648 +   ++symCodeLen;
649 +   i <<= 1;
650 +  }
651 +  if (huff && symCodeLen == 0) {
652 +   symCodeLen = 1;
653    }
654  
655    // get the input symbol bitmaps
656 @@ -1921,6 +1924,9 @@
657      ++symCodeLen;
658      i <<= 1;
659    }
660 +  if (huff && symCodeLen == 0) {
661 +    symCodeLen = 1;
662 +  }
663  
664    // get the symbol bitmaps
665    syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *));
666 --- xpdf/JPXStream.cc.orig      2010-05-18 11:22:18.000000000 -0700
667 +++ xpdf/JPXStream.cc   2010-05-18 11:22:18.000000000 -0700
668 @@ -241,6 +242,12 @@
669    haveCompMap = gFalse;
670    haveChannelDefn = gFalse;
671  
672 +  img.xSize = 0;
673 +  img.ySize = 0;
674 +  img.xOffset = 0;
675 +  img.yOffset = 0;
676 +  curX = 0;
677 +  curY = 0;
678    img.tiles = NULL;
679    bitBuf = 0;
680    bitBufLen = 0;
681 @@ -450,6 +450,7 @@
682    GBool haveBPC, haveCSMode;
683  
684    csPrec = 0; // make gcc happy
685 +  Guint num_components = 0;
686    haveBPC = haveCSMode = gFalse;
687    str->reset();
688    if (str->lookChar() == 0xff) {
689 @@ -463,7 +464,7 @@
690         cover(1);
691         if (readULong(&dummy) &&
692             readULong(&dummy) &&
693 -           readUWord(&dummy) &&
694 +           readUWord(&num_components) &&
695             readUByte(&bpc1) &&
696             readUByte(&dummy) &&
697             readUByte(&dummy) &&
698 @@ -519,6 +520,9 @@
699        }
700      }
701    }
702 +  if(*csMode == streamCSDeviceRGB && num_components == 4) {
703 +    *csMode = streamCSDeviceRGBX;
704 +  }
705    str->close();
706  }
707  
708 --- xpdf/Lexer.cc.orig  2010-05-18 11:22:18.000000000 -0700
709 +++ xpdf/Lexer.cc       2010-05-18 11:22:18.000000000 -0700
710 @@ -74,6 +74,7 @@
711      curStr.streamReset();
712    }
713  }
714 +static int illegalChars = 0;
715  
716  Lexer::~Lexer() {
717    if (!curStr.isNone()) {
718 @@ -83,6 +84,9 @@
719    if (freeArray) {
720      delete streams;
721    }
722 +  if(illegalChars)
723 +      error(0, "Illegal characters in hex string (%d)", illegalChars);
724 +  illegalChars = 0;
725  }
726  
727  int Lexer::getChar() {
728 @@ -330,7 +334,8 @@
729         } else if (c2 >= 'a' && c2 <= 'f') {
730           c += c2 - 'a' + 10;
731         } else {
732 -         error(getPos(), "Illegal digit in hex char in name");
733 +         illegalChars++;
734 +         //error(getPos(), "Illegal digit in hex char in name");
735         }
736        }
737       notEscChar:
738 @@ -384,8 +389,10 @@
739             c2 += c - 'A' + 10;
740           else if (c >= 'a' && c <= 'f')
741             c2 += c - 'a' + 10;
742 -         else
743 -           error(getPos(), "Illegal character <%02x> in hex string", c);
744 +         else {
745 +           illegalChars++;
746 +           //error(getPos(), "Illegal character <%02x> in hex string", c);
747 +         }
748           if (++m == 2) {
749             if (n == tokBufSize) {
750               if (!s)
751 @@ -421,7 +428,8 @@
752        tokBuf[2] = '\0';
753        obj->initCmd(tokBuf);
754      } else {
755 -      error(getPos(), "Illegal character '>'");
756 +      illegalChars++;
757 +      //error(getPos(), "Illegal character '>'");
758        obj->initError();
759      }
760      break;
761 @@ -430,7 +438,8 @@
762    case ')':
763    case '{':
764    case '}':
765 -    error(getPos(), "Illegal character '%c'", c);
766 +    //error(getPos(), "Illegal character '%c'", c);
767 +    illegalChars++;
768      obj->initError();
769      break;
770  
771 @@ -459,7 +468,6 @@
772      }
773      break;
774    }
775 -
776    return obj;
777  }
778  
779 --- xpdf/Link.cc.orig   2010-05-18 11:22:18.000000000 -0700
780 +++ xpdf/Link.cc        2010-05-18 11:22:18.000000000 -0700
781 @@ -430,10 +430,9 @@
782        delete dest;
783        dest = NULL;
784      }
785 -
786    // error
787    } else {
788 -    error(-1, "Illegal annotation destination");
789 +    error(-1, "Illegal annotation destination %d", destObj->getType());
790    }
791  }
792  
793 @@ -468,10 +467,9 @@
794        delete dest;
795        dest = NULL;
796      }
797 -
798    // error
799    } else {
800 -    error(-1, "Illegal annotation destination");
801 +    error(-1, "Illegal annotation destination %d", destObj->getType());
802    }
803  }
804  
805 --- xpdf/OutputDev.h.orig       2010-05-18 11:22:18.000000000 -0700
806 +++ xpdf/OutputDev.h    2010-05-18 11:22:18.000000000 -0700
807 @@ -17,6 +17,7 @@
808  
809  #include "gtypes.h"
810  #include "CharTypes.h"
811 +#include "Object.h"
812  
813  class GString;
814  class GfxState;
815 @@ -94,7 +95,7 @@
816      { return gTrue; }
817  
818    // Start a page.
819 -  virtual void startPage(int pageNum, GfxState *state) {}
820 +  virtual void startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2) {}
821  
822    // End a page.
823    virtual void endPage() {}
824 --- xpdf/SplashFTFont.cc.orig   2010-05-18 11:22:18.000000000 -0700
825 +++ xpdf/SplashFTFont.cc        2010-05-18 11:22:18.000000000 -0700
826 @@ -46,6 +46,7 @@
827    int x, y;
828  
829    face = fontFileA->face;
830 +  
831    if (FT_New_Size(face, &sizeObj)) {
832      return;
833    }
834 @@ -54,6 +55,10 @@
835    if (FT_Set_Pixel_Sizes(face, 0, (int)size)) {
836      return;
837    }
838
839 +  this->ascender = face->ascender;
840 +  this->descender = face->descender;
841 +
842    // if the textMat values are too small, FreeType's fixed point
843    // arithmetic doesn't work so well
844    textScale = splashSqrt(textMat[2]*textMat[2] + textMat[3]*textMat[3]) / size;
845 @@ -228,6 +233,12 @@
846    GBool needClose;
847  };
848  
849 +int SplashFTFont::getNumChars()
850 +{
851 +  SplashFTFontFile* ff = (SplashFTFontFile *)fontFile;
852 +  return ff->face->num_glyphs;
853 +}
854 +
855  SplashPath *SplashFTFont::getGlyphPath(int c) {
856    static FT_Outline_Funcs outlineFuncs = {
857  #if FREETYPE_MINOR <= 1
858 @@ -249,6 +260,8 @@
859    FT_UInt gid;
860    FT_Glyph glyph;
861  
862 +  this->last_advance = -1;
863 +
864    ff = (SplashFTFontFile *)fontFile;
865    ff->face->size = sizeObj;
866    FT_Set_Transform(ff->face, &textMatrix, NULL);
867 @@ -262,17 +275,24 @@
868      // skip the TrueType notdef glyph
869      return NULL;
870    }
871 -  if (FT_Load_Glyph(ff->face, gid, FT_LOAD_NO_BITMAP)) {
872 +  int error = 0;
873 +  if ((error=FT_Load_Glyph(ff->face, gid, FT_LOAD_NO_BITMAP|FT_LOAD_NO_HINTING))) {
874 +      fprintf(stderr, "Truetype wasn't able to load glyph %d, error %d\n", gid, error);
875      return NULL;
876    }
877    if (FT_Get_Glyph(slot, &glyph)) {
878      return NULL;
879    }
880 +  this->last_advance = glyph->advance.x/65536.0;
881 +
882    path.path = new SplashPath();
883    path.textScale = textScale;
884    path.needClose = gFalse;
885 -  FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline,
886 +  error = FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline,
887                        &outlineFuncs, &path);
888 +  if(error) {
889 +      fprintf(stderr, "Truetype wasn't able to read glyph %d, error %d\n", gid, error);
890 +  }
891    if (path.needClose) {
892      path.path->close();
893    }
894 --- xpdf/SplashFTFont.h.orig    2010-05-18 11:22:18.000000000 -0700
895 +++ xpdf/SplashFTFont.h 2010-05-18 11:22:18.000000000 -0700
896 @@ -42,6 +42,9 @@
897    virtual GBool makeGlyph(int c, int xFrac, int yFrac,
898                           SplashGlyphBitmap *bitmap);
899  
900 +  // return the number of characters in this font
901 +  virtual int getNumChars();
902 +
903    // Return the path for a glyph.
904    virtual SplashPath *getGlyphPath(int c);
905  
906 --- xpdf/SplashFTFontEngine.cc.orig     2010-05-18 11:22:18.000000000 -0700
907 +++ xpdf/SplashFTFontEngine.cc  2010-05-18 11:22:18.000000000 -0700
908 @@ -13,9 +13,7 @@
909  #endif
910  
911  #include <stdio.h>
912 -#ifndef WIN32
913  #  include <unistd.h>
914 -#endif
915  #include "gmem.h"
916  #include "GString.h"
917  #include "gfile.h"
918 --- xpdf/SplashFont.cc.orig     2010-05-18 11:22:18.000000000 -0700
919 +++ xpdf/SplashFont.cc  2010-05-18 11:22:18.000000000 -0700
920 @@ -48,6 +48,10 @@
921    cacheTags = NULL;
922  
923    xMin = yMin = xMax = yMax = 0;
924 +
925 +  last_advance = -1;
926 +  ascender = -1;
927 +  descender = -1;
928  }
929  
930  void SplashFont::initCache() {
931 --- xpdf/SplashFont.h.orig      2010-05-18 11:22:18.000000000 -0700
932 +++ xpdf/SplashFont.h   2010-05-18 11:22:18.000000000 -0700
933 @@ -73,6 +73,9 @@
934    virtual GBool makeGlyph(int c, int xFrac, int yFrac,
935                           SplashGlyphBitmap *bitmap) = 0;
936  
937 +  // return the number of characters in this font
938 +  virtual int getNumChars() = 0;
939 +
940    // Return the path for a glyph.
941    virtual SplashPath *getGlyphPath(int c) = 0;
942  
943 @@ -83,6 +86,9 @@
944    void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA)
945      { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
946  
947 +  double ascender;
948 +  double descender;
949 +  double last_advance; //set after getGlyphPath()
950  protected:
951  
952    SplashFontFile *fontFile;
953 --- xpdf/SplashFontFile.cc.orig 2010-05-18 11:22:18.000000000 -0700
954 +++ xpdf/SplashFontFile.cc      2010-05-18 11:22:18.000000000 -0700
955 @@ -11,9 +11,7 @@
956  #endif
957  
958  #include <stdio.h>
959 -#ifndef WIN32
960 -#  include <unistd.h>
961 -#endif
962 +#include <unistd.h>
963  #include "GString.h"
964  #include "SplashFontFile.h"
965  #include "SplashFontFileID.h"
966 --- xpdf/SplashOutputDev.cc.orig        2010-05-18 11:22:18.000000000 -0700
967 +++ xpdf/SplashOutputDev.cc     2010-05-18 11:22:18.000000000 -0700
968 @@ -13,6 +13,7 @@
969  #endif
970  
971  #include <string.h>
972 +#include <unistd.h>
973  #include <math.h>
974  #include "gfile.h"
975  #include "GlobalParams.h"
976 @@ -702,7 +703,7 @@
977    nT3Fonts = 0;
978  }
979  
980 -void SplashOutputDev::startPage(int pageNum, GfxState *state) {
981 +void SplashOutputDev::startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2) {
982    int w, h;
983    double *ctm;
984    SplashCoord mat[6];
985 @@ -2646,9 +2647,9 @@
986  
987    softMask = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
988                               1, splashModeMono8, gFalse);
989 -  memset(softMask->getDataPtr(), 0,
990 -        softMask->getRowSize() * softMask->getHeight());
991 +  memset(softMask->getDataPtr(), 0x00, softMask->getRowSize()*softMask->getHeight());
992    p = softMask->getDataPtr() + ty * softMask->getRowSize() + tx;
993 +  if (tx<softMask->getWidth() && ty<softMask->getHeight())
994    for (y = 0; y < tBitmap->getHeight(); ++y) {
995      for (x = 0; x < tBitmap->getWidth(); ++x) {
996        tBitmap->getPixel(x, y, color);
997 --- xpdf/SplashOutputDev.h.orig 2010-05-18 11:22:18.000000000 -0700
998 +++ xpdf/SplashOutputDev.h      2010-05-18 11:22:18.000000000 -0700
999 @@ -70,7 +70,7 @@
1000    //----- initialization and control
1001  
1002    // Start a page.
1003 -  virtual void startPage(int pageNum, GfxState *state);
1004 +  virtual void startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2);
1005  
1006    // End a page.
1007    virtual void endPage();
1008 @@ -196,6 +196,9 @@
1009    virtual void setVectorAntialias(GBool vaa);
1010  #endif
1011  
1012 +  void doUpdateFont(GfxState *state);
1013 +  
1014 +  SplashPath *convertPath(GfxState *state, GfxPath *path);
1015  private:
1016  
1017    void setupScreenParams(double hDPI, double vDPI);
1018 @@ -204,8 +207,6 @@
1019  #else
1020    SplashPattern *getColor(GfxGray gray, GfxRGB *rgb);
1021  #endif
1022 -  SplashPath *convertPath(GfxState *state, GfxPath *path);
1023 -  void doUpdateFont(GfxState *state);
1024    void drawType3Glyph(T3FontCache *t3Font,
1025                       T3FontCacheTag *tag, Guchar *data);
1026    static GBool imageMaskSrc(void *data, SplashColorPtr line);
1027 --- xpdf/SplashScreen.cc.orig   2010-05-18 11:22:18.000000000 -0700
1028 +++ xpdf/SplashScreen.cc        2010-05-18 11:22:18.000000000 -0700
1029 @@ -363,6 +363,8 @@
1030  int SplashScreen::test(int x, int y, Guchar value) {
1031    int xx, yy;
1032  
1033 +  return 1;
1034 +
1035    if (value < minVal) {
1036      return 0;
1037    }
1038 --- xpdf/SplashXPathScanner.cc.orig     2010-05-18 11:22:18.000000000 -0700
1039 +++ xpdf/SplashXPathScanner.cc  2010-05-18 11:22:18.000000000 -0700
1040 @@ -394,10 +394,10 @@
1041           *p++ &= mask;
1042           xx = (xx & ~7) + 8;
1043         }
1044 -       for (; xx + 7 <= xx0; xx += 8) {
1045 +       for (; xx + 7 < xx0; xx += 8) {
1046           *p++ = 0x00;
1047         }
1048 -       if (xx <= xx0) {
1049 +       if (xx < xx0) {
1050           *p &= 0xff >> (xx0 & 7);
1051         }
1052        }
1053 @@ -417,10 +417,10 @@
1054         *p++ &= mask;
1055         xx = (xx & ~7) + 8;
1056        }
1057 -      for (; xx + 7 <= xx0; xx += 8) {
1058 +      for (; xx + 7 < xx0; xx += 8) {
1059         *p++ = 0x00;
1060        }
1061 -      if (xx <= xx0) {
1062 +      if (xx < xx0) {
1063         *p &= 0xff >> (xx0 & 7);
1064        }
1065      }
1066 --- xpdf/Stream.cc.orig 2010-05-18 11:22:18.000000000 -0700
1067 +++ xpdf/Stream.cc      2010-05-18 11:22:18.000000000 -0700
1068 @@ -18,6 +18,8 @@
1069  #include <limits.h>
1070  #ifndef WIN32
1071  #include <unistd.h>
1072 +#else
1073 +extern "C" int unlink(char *filename);
1074  #endif
1075  #include <string.h>
1076  #include <ctype.h>
1077 @@ -2456,6 +2460,9 @@
1078    // check for an EOB run
1079    if (eobRun > 0) {
1080      while (i <= scanInfo.lastCoeff) {
1081 +      if(i>=64) {
1082 +         return gFalse;
1083 +      }
1084        j = dctZigZag[i++];
1085        if (data[j] != 0) {
1086         if ((bit = readBit()) == EOF) {
1087 @@ -2480,6 +2487,9 @@
1088      if (c == 0xf0) {
1089        k = 0;
1090        while (k < 16) {
1091 +        if(i>=64) {
1092 +         return gFalse;
1093 +       }
1094         j = dctZigZag[i++];
1095         if (data[j] == 0) {
1096           ++k;
1097 @@ -2505,6 +2515,9 @@
1098        }
1099        eobRun += 1 << j;
1100        while (i <= scanInfo.lastCoeff) {
1101 +       if(i>=64) {
1102 +         return gFalse;
1103 +       }
1104         j = dctZigZag[i++];
1105         if (data[j] != 0) {
1106           if ((bit = readBit()) == EOF) {
1107 @@ -2527,6 +2540,9 @@
1108        }
1109        k = 0;
1110        do {
1111 +       if(i>=64) {
1112 +         return gFalse;
1113 +       }
1114         j = dctZigZag[i++];
1115         while (data[j] != 0) {
1116           if ((bit = readBit()) == EOF) {
1117 @@ -2535,6 +2551,9 @@
1118           if (bit) {
1119             data[j] += 1 << scanInfo.al;
1120           }
1121 +         if(i>=64) {
1122 +           return gFalse;
1123 +         }
1124           j = dctZigZag[i++];
1125         }
1126         ++k;
1127 --- xpdf/Stream.h.orig  2010-05-18 11:22:18.000000000 -0700
1128 +++ xpdf/Stream.h       2010-05-18 11:22:18.000000000 -0700
1129 @@ -41,7 +41,8 @@
1130    streamCSNone,
1131    streamCSDeviceGray,
1132    streamCSDeviceRGB,
1133 -  streamCSDeviceCMYK
1134 +  streamCSDeviceCMYK,
1135 +  streamCSDeviceRGBX
1136  };
1137  
1138  //------------------------------------------------------------------------
1139 --- xpdf/TextOutputDev.cc.orig  2010-05-18 11:22:18.000000000 -0700
1140 +++ xpdf/TextOutputDev.cc       2010-05-18 11:22:18.000000000 -0700
1141 @@ -3877,7 +3877,7 @@
1142    }
1143  }
1144  
1145 -void TextOutputDev::startPage(int pageNum, GfxState *state) {
1146 +void TextOutputDev::startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2) {
1147    text->startPage(state);
1148  }
1149  
1150 --- xpdf/TextOutputDev.h.orig   2010-05-18 11:22:18.000000000 -0700
1151 +++ xpdf/TextOutputDev.h        2010-05-18 11:22:18.000000000 -0700
1152 @@ -170,6 +170,7 @@
1153    friend class TextFlow;
1154    friend class TextWordList;
1155    friend class TextPage;
1156 +  friend class XMLOutputDev;
1157  };
1158  
1159  //------------------------------------------------------------------------
1160 @@ -578,7 +579,7 @@
1161    //----- initialization and control
1162  
1163    // Start a page.
1164 -  virtual void startPage(int pageNum, GfxState *state);
1165 +  virtual void startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2);
1166  
1167    // End a page.
1168    virtual void endPage();
1169 --- xpdf/gfile.cc.orig  2010-05-18 11:22:18.000000000 -0700
1170 +++ xpdf/gfile.cc       2010-05-18 11:22:18.000000000 -0700
1171 @@ -439,6 +439,52 @@
1172  #endif
1173  }
1174  
1175 +static char* getTempDir()
1176 +{
1177 +#ifdef WIN32
1178 +    char*dir = getenv("TMP");
1179 +    if(!dir) dir = getenv("TEMP");
1180 +    if(!dir) dir = getenv("tmp");
1181 +    if(!dir) dir = getenv("temp");
1182 +    if(!dir) dir = "C:\\";
1183 +#else
1184 +    char* dir = "/tmp/";
1185 +#endif
1186 +    return dir;
1187 +}
1188 +
1189 +char* mktmpname(char*ptr) {
1190 +    static char tmpbuf[128];
1191 +    char*dir = getTempDir();
1192 +    int l = strlen(dir);
1193 +    char*sep = "";
1194 +    if(!ptr)
1195 +       ptr = tmpbuf;
1196 +    if(l && dir[l-1]!='/' && dir[l-1]!='\\') {
1197 +#ifdef WIN32
1198 +       sep = "\\";
1199 +#else
1200 +       sep = "/";
1201 +#endif
1202 +    }
1203 +
1204 + //   used to be mktemp. This does remove the warnings, but
1205 + //   It's not exactly an improvement.
1206 +#ifdef HAVE_LRAND48
1207 +    sprintf(ptr, "%s%s%08x%08x",dir,sep,(unsigned int)lrand48(),(unsigned int)lrand48());
1208 +#else
1209 +#   ifdef HAVE_RAND
1210 +       sprintf(ptr, "%s%s%08x%08x",dir,sep,rand(),rand());
1211 +#   else
1212 +       static int count = 1;
1213 +       sprintf(ptr, "%s%s%08x%04x%04x",dir,sep,time(0),(unsigned int)tmpbuf^((unsigned int)tmpbuf)>>16,count);
1214 +       count ++;
1215 +#   endif
1216 +#endif
1217 +     return ptr;
1218 +}
1219 +
1220 +
1221  GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) {
1222  #if defined(WIN32)
1223    //---------- Win32 ----------
1224 @@ -460,7 +506,7 @@
1225    s->append("x");
1226    t = (int)time(NULL);
1227    for (i = 0; i < 1000; ++i) {
1228 -    sprintf(buf, "%d", t + i);
1229 +    sprintf(buf, "%08x-%08x", t + i, GetCurrentThreadId());
1230      s2 = s->copy()->append(buf);
1231      if (ext) {
1232        s2->append(ext);
1233 @@ -468,8 +514,7 @@
1234      if (!(f2 = fopen(s2->getCString(), "r"))) {
1235        if (!(f2 = fopen(s2->getCString(), mode))) {
1236         delete s2;
1237 -       delete s;
1238 -       return gFalse;
1239 +        continue;
1240        }
1241        *name = s2;
1242        *f = f2;
1243 @@ -479,6 +524,7 @@
1244      fclose(f2);
1245      delete s2;
1246    }
1247 +  fprintf(stderr, "Couldn't create temporary file\n");
1248    delete s;
1249    return gFalse;
1250  #elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS)
1251 @@ -489,7 +535,7 @@
1252    // with this file name after the tmpnam call and before the fopen
1253    // call.  I will happily accept fixes to this function for non-Unix
1254    // OSs.
1255 -  if (!(s = tmpnam(NULL))) {
1256 +  if (!(s = mktmpname(NULL))) {
1257      return gFalse;
1258    }
1259    *name = new GString(s);
1260 @@ -516,7 +562,7 @@
1261      (*name)->append("/XXXXXX")->append(ext);
1262      fd = mkstemps((*name)->getCString(), strlen(ext));
1263  #else
1264 -    if (!(s = tmpnam(NULL))) {
1265 +    if (!(s = mktmpname(NULL))) {
1266        return gFalse;
1267      }
1268      *name = new GString(s);
1269 @@ -533,7 +579,7 @@
1270      (*name)->append("/XXXXXX");
1271      fd = mkstemp((*name)->getCString());
1272  #else // HAVE_MKSTEMP
1273 -    if (!(s = tmpnam(NULL))) {
1274 +    if (!(s = mktmpname(NULL))) {
1275        return gFalse;
1276      }
1277      *name = new GString(s);
1278 --- xpdf/gfile.h.orig   2010-05-18 11:22:18.000000000 -0700
1279 +++ xpdf/gfile.h        2010-05-18 11:22:18.000000000 -0700
1280 @@ -58,6 +58,9 @@
1281  // Get current directory.
1282  extern GString *getCurrentDir();
1283  
1284 +/* create a temporary filename */
1285 +char* mktmpname(char*ptr);
1286 +
1287  // Append a file name to a path string.  <path> may be an empty
1288  // string, denoting the current directory).  Returns <path>.
1289  extern GString *appendToPath(GString *path, char *fileName);
1290 --- xpdf/JBIG2Stream.cc.orig    2010-05-18 11:33:21.000000000 -0700
1291 +++ xpdf/JBIG2Stream.cc 2010-06-03 16:55:03.000000000 -0700
1292 @@ -6,7 +6,24 @@
1293  //
1294  //========================================================================
1295  
1296 -#include <aconf.h>
1297 +//========================================================================
1298 +//
1299 +// Modified under the Poppler project - http://poppler.freedesktop.org
1300 +//
1301 +// All changes made under the Poppler project to this file are licensed
1302 +// under GPL version 2 or later
1303 +//
1304 +// Copyright (C) 2006 Raj Kumar <rkumar@archive.org>
1305 +// Copyright (C) 2006 Paul Walmsley <paul@booyaka.com>
1306 +// Copyright (C) 2006-2009 Albert Astals Cid <aacid@kde.org>
1307 +// Copyright (C) 2009 David Benjamin <davidben@mit.edu>
1308 +//
1309 +// To see a description of the changes please see the Changelog file that
1310 +// came with your tarball or type make ChangeLog if you are building from git
1311 +//
1312 +//========================================================================
1313 +
1314 +#include <config.h>
1315  
1316  #ifdef USE_GCC_PRAGMAS
1317  #pragma implementation
1318 @@ -24,8 +41,8 @@
1319  
1320  //------------------------------------------------------------------------
1321  
1322 -static int contextSize[4] = { 16, 13, 10, 10 };
1323 -static int refContextSize[2] = { 13, 10 };
1324 +static const int contextSize[4] = { 16, 13, 10, 10 };
1325 +static const int refContextSize[2] = { 13, 10 };
1326  
1327  //------------------------------------------------------------------------
1328  // JBIG2HuffmanTable
1329 @@ -42,7 +59,7 @@
1330    Guint prefix;
1331  };
1332  
1333 -JBIG2HuffmanTable huffTableA[] = {
1334 +static JBIG2HuffmanTable huffTableA[] = {
1335    {     0, 1,  4,              0x000 },
1336    {    16, 2,  8,              0x002 },
1337    {   272, 3, 16,              0x006 },
1338 @@ -50,7 +67,7 @@
1339    {     0, 0, jbig2HuffmanEOT, 0     }
1340  };
1341  
1342 -JBIG2HuffmanTable huffTableB[] = {
1343 +static JBIG2HuffmanTable huffTableB[] = {
1344    {     0, 1,  0,              0x000 },
1345    {     1, 2,  0,              0x002 },
1346    {     2, 3,  0,              0x006 },
1347 @@ -61,7 +78,7 @@
1348    {     0, 0, jbig2HuffmanEOT, 0     }
1349  };
1350  
1351 -JBIG2HuffmanTable huffTableC[] = {
1352 +static JBIG2HuffmanTable huffTableC[] = {
1353    {     0, 1,  0,              0x000 },
1354    {     1, 2,  0,              0x002 },
1355    {     2, 3,  0,              0x006 },
1356 @@ -74,7 +91,7 @@
1357    {     0, 0, jbig2HuffmanEOT, 0     }
1358  };
1359  
1360 -JBIG2HuffmanTable huffTableD[] = {
1361 +static JBIG2HuffmanTable huffTableD[] = {
1362    {     1, 1,  0,              0x000 },
1363    {     2, 2,  0,              0x002 },
1364    {     3, 3,  0,              0x006 },
1365 @@ -84,7 +101,7 @@
1366    {     0, 0, jbig2HuffmanEOT, 0     }
1367  };
1368  
1369 -JBIG2HuffmanTable huffTableE[] = {
1370 +static JBIG2HuffmanTable huffTableE[] = {
1371    {     1, 1,  0,              0x000 },
1372    {     2, 2,  0,              0x002 },
1373    {     3, 3,  0,              0x006 },
1374 @@ -96,7 +113,7 @@
1375    {     0, 0, jbig2HuffmanEOT, 0     }
1376  };
1377  
1378 -JBIG2HuffmanTable huffTableF[] = {
1379 +static JBIG2HuffmanTable huffTableF[] = {
1380    {     0, 2,  7,              0x000 },
1381    {   128, 3,  7,              0x002 },
1382    {   256, 3,  8,              0x003 },
1383 @@ -114,7 +131,7 @@
1384    {     0, 0, jbig2HuffmanEOT, 0     }
1385  };
1386  
1387 -JBIG2HuffmanTable huffTableG[] = {
1388 +static JBIG2HuffmanTable huffTableG[] = {
1389    {  -512, 3,  8,              0x000 },
1390    {   256, 3,  8,              0x001 },
1391    {   512, 3,  9,              0x002 },
1392 @@ -133,7 +150,7 @@
1393    {     0, 0, jbig2HuffmanEOT, 0     }
1394  };
1395  
1396 -JBIG2HuffmanTable huffTableH[] = {
1397 +static JBIG2HuffmanTable huffTableH[] = {
1398    {     0, 2,  1,              0x000 },
1399    {     0, 2, jbig2HuffmanOOB, 0x001 },
1400    {     4, 3,  4,              0x004 },
1401 @@ -158,7 +175,7 @@
1402    {     0, 0, jbig2HuffmanEOT, 0     }
1403  };
1404  
1405 -JBIG2HuffmanTable huffTableI[] = {
1406 +static JBIG2HuffmanTable huffTableI[] = {
1407    {     0, 2, jbig2HuffmanOOB, 0x000 },
1408    {    -1, 3,  1,              0x002 },
1409    {     1, 3,  1,              0x003 },
1410 @@ -184,7 +201,7 @@
1411    {     0, 0, jbig2HuffmanEOT, 0     }
1412  };
1413  
1414 -JBIG2HuffmanTable huffTableJ[] = {
1415 +static JBIG2HuffmanTable huffTableJ[] = {
1416    {    -2, 2,  2,              0x000 },
1417    {     6, 2,  6,              0x001 },
1418    {     0, 2, jbig2HuffmanOOB, 0x002 },
1419 @@ -209,7 +226,7 @@
1420    {     0, 0, jbig2HuffmanEOT, 0     }
1421  };
1422  
1423 -JBIG2HuffmanTable huffTableK[] = {
1424 +static JBIG2HuffmanTable huffTableK[] = {
1425    {     1, 1,  0,              0x000 },
1426    {     2, 2,  1,              0x002 },
1427    {     4, 4,  0,              0x00c },
1428 @@ -226,7 +243,7 @@
1429    {     0, 0, jbig2HuffmanEOT, 0     }
1430  };
1431  
1432 -JBIG2HuffmanTable huffTableL[] = {
1433 +static JBIG2HuffmanTable huffTableL[] = {
1434    {     1, 1,  0,              0x000 },
1435    {     2, 2,  0,              0x002 },
1436    {     3, 3,  1,              0x006 },
1437 @@ -243,7 +260,7 @@
1438    {     0, 0, jbig2HuffmanEOT, 0     }
1439  };
1440  
1441 -JBIG2HuffmanTable huffTableM[] = {
1442 +static JBIG2HuffmanTable huffTableM[] = {
1443    {     1, 1,  0,              0x000 },
1444    {     2, 3,  0,              0x004 },
1445    {     7, 3,  3,              0x005 },
1446 @@ -260,7 +277,7 @@
1447    {     0, 0, jbig2HuffmanEOT, 0     }
1448  };
1449  
1450 -JBIG2HuffmanTable huffTableN[] = {
1451 +static JBIG2HuffmanTable huffTableN[] = {
1452    {     0, 1,  0,              0x000 },
1453    {    -2, 3,  0,              0x004 },
1454    {    -1, 3,  0,              0x005 },
1455 @@ -269,7 +286,7 @@
1456    {     0, 0, jbig2HuffmanEOT, 0     }
1457  };
1458  
1459 -JBIG2HuffmanTable huffTableO[] = {
1460 +static JBIG2HuffmanTable huffTableO[] = {
1461    {     0, 1,  0,              0x000 },
1462    {    -1, 3,  0,              0x004 },
1463    {     1, 3,  0,              0x005 },
1464 @@ -473,7 +490,7 @@
1465  }
1466  
1467  int JBIG2MMRDecoder::get2DCode() {
1468 -  CCITTCode *p;
1469 +  const CCITTCode *p;
1470  
1471    if (bufLen == 0) {
1472      buf = str->getChar() & 0xff;
1473 @@ -500,7 +517,7 @@
1474  }
1475  
1476  int JBIG2MMRDecoder::getWhiteCode() {
1477 -  CCITTCode *p;
1478 +  const CCITTCode *p;
1479    Guint code;
1480  
1481    if (bufLen == 0) {
1482 @@ -543,7 +560,7 @@
1483  }
1484  
1485  int JBIG2MMRDecoder::getBlackCode() {
1486 -  CCITTCode *p;
1487 +  const CCITTCode *p;
1488    Guint code;
1489  
1490    if (bufLen == 0) {
1491 @@ -670,6 +687,7 @@
1492    void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
1493    Guchar *getDataPtr() { return data; }
1494    int getDataSize() { return h * line; }
1495 +  GBool isOk() { return data != NULL; }
1496  
1497  private:
1498  
1499 @@ -685,10 +703,11 @@
1500    w = wA;
1501    h = hA;
1502    line = (wA + 7) >> 3;
1503 +
1504    if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
1505 -    // force a call to gmalloc(-1), which will throw an exception
1506 -    h = -1;
1507 -    line = 2;
1508 +    error(-1, "invalid width/height");
1509 +    data = NULL;
1510 +    return;
1511    }
1512    // need to allocate one extra guard byte for use in combine()
1513    data = (Guchar *)gmalloc(h * line + 1);
1514 @@ -701,10 +720,11 @@
1515    w = bitmap->w;
1516    h = bitmap->h;
1517    line = bitmap->line;
1518 +
1519    if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
1520 -    // force a call to gmalloc(-1), which will throw an exception
1521 -    h = -1;
1522 -    line = 2;
1523 +    error(-1, "invalid width/height");
1524 +    data = NULL;
1525 +    return;
1526    }
1527    // need to allocate one extra guard byte for use in combine()
1528    data = (Guchar *)gmalloc(h * line + 1);
1529 @@ -735,6 +755,9 @@
1530  
1531  void JBIG2Bitmap::expand(int newH, Guint pixel) {
1532    if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
1533 +    error(-1, "invalid width/height");
1534 +    gfree(data);
1535 +    data = NULL;
1536      return;
1537    }
1538    // need to allocate one extra guard byte for use in combine()
1539 @@ -1002,6 +1025,7 @@
1540    Guint getSize() { return size; }
1541    void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1542    JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1543 +  GBool isOk() { return bitmaps != NULL; }
1544    void setGenericRegionStats(JArithmeticDecoderStats *stats)
1545      { genericRegionStats = stats; }
1546    void setRefinementRegionStats(JArithmeticDecoderStats *stats)
1547 @@ -1022,13 +1046,9 @@
1548  JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1549    JBIG2Segment(segNumA)
1550  {
1551 -  Guint i;
1552 -
1553    size = sizeA;
1554    bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1555 -  for (i = 0; i < size; ++i) {
1556 -    bitmaps[i] = NULL;
1557 -  }
1558 +  if (!bitmaps) size = 0;
1559    genericRegionStats = NULL;
1560    refinementRegionStats = NULL;
1561  }
1562 @@ -1037,9 +1057,7 @@
1563    Guint i;
1564  
1565    for (i = 0; i < size; ++i) {
1566 -    if (bitmaps[i]) {
1567 -      delete bitmaps[i];
1568 -    }
1569 +    delete bitmaps[i];
1570    }
1571    gfree(bitmaps);
1572    if (genericRegionStats) {
1573 @@ -1247,6 +1265,7 @@
1574    Guint segNum, segFlags, segType, page, segLength;
1575    Guint refFlags, nRefSegs;
1576    Guint *refSegs;
1577 +  int segDataPos;
1578    int c1, c2, c3;
1579    Guint i;
1580  
1581 @@ -1314,6 +1333,9 @@
1582        goto eofError2;
1583      }
1584  
1585 +    // keep track of the start of the segment data 
1586 +    segDataPos = getPos();
1587 +
1588      // check for missing page information segment
1589      if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
1590                         (segType >= 20 && segType <= 43))) {
1591 @@ -1398,6 +1420,45 @@
1592        break;
1593      }
1594  
1595 +    // Make sure the segment handler read all of the bytes in the 
1596 +    // segment data, unless this segment is marked as having an
1597 +    // unknown length (section 7.2.7 of the JBIG2 Final Committee Draft)
1598 +
1599 +    if (segLength != 0xffffffff) {
1600 +
1601 +      int segExtraBytes = segDataPos + segLength - getPos();
1602 +      if (segExtraBytes > 0) {
1603 +
1604 +       // If we didn't read all of the bytes in the segment data,
1605 +       // indicate an error, and throw away the rest of the data.
1606 +       
1607 +       // v.3.1.01.13 of the LuraTech PDF Compressor Server will
1608 +       // sometimes generate an extraneous NULL byte at the end of
1609 +       // arithmetic-coded symbol dictionary segments when numNewSyms
1610 +       // == 0.  Segments like this often occur for blank pages.
1611 +       
1612 +       error(getPos(), "%d extraneous byte%s after segment",
1613 +             segExtraBytes, (segExtraBytes > 1) ? "s" : "");
1614 +       
1615 +       // Burn through the remaining bytes -- inefficient, but
1616 +       // hopefully we're not doing this much
1617 +       
1618 +       int trash;
1619 +       for (int i = segExtraBytes; i > 0; i--) {
1620 +         readByte(&trash);
1621 +       }
1622 +       
1623 +      } else if (segExtraBytes < 0) {
1624 +       
1625 +       // If we read more bytes than we should have, according to the 
1626 +       // segment length field, note an error.
1627 +       
1628 +       error(getPos(), "Previous segment handler read too many bytes");
1629 +       
1630 +      }
1631 +
1632 +    }
1633 +    
1634      gfree(refSegs);
1635    }
1636  
1637 @@ -1493,6 +1554,9 @@
1638    codeTables = new GList();
1639    numInputSyms = 0;
1640    for (i = 0; i < nRefSegs; ++i) {
1641 +    // This is need by bug 12014, returning gFalse makes it not crash
1642 +    // but we end up with a empty page while acroread is able to render
1643 +    // part of it
1644      if ((seg = findSegment(refSegs[i]))) {
1645        if (seg->getType() == jbig2SegSymbolDict) {
1646         j = ((JBIG2SymbolDict *)seg)->getSize();
1647 @@ -1503,8 +1567,11 @@
1648         }
1649         numInputSyms += j;
1650        } else if (seg->getType() == jbig2SegCodeTable) {
1651 -       codeTables->append(seg);
1652 +        codeTables->append(seg);
1653        }
1654 +    } else {
1655 +      delete codeTables;
1656 +      return gFalse;
1657      }
1658    }
1659    if (numInputSyms > UINT_MAX - numNewSyms) {
1660 @@ -1530,12 +1600,11 @@
1661    k = 0;
1662    inputSymbolDict = NULL;
1663    for (i = 0; i < nRefSegs; ++i) {
1664 -    if ((seg = findSegment(refSegs[i]))) {
1665 -      if (seg->getType() == jbig2SegSymbolDict) {
1666 -       inputSymbolDict = (JBIG2SymbolDict *)seg;
1667 -       for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1668 -         bitmaps[k++] = inputSymbolDict->getBitmap(j);
1669 -       }
1670 +    seg = findSegment(refSegs[i]);
1671 +    if (seg != NULL && seg->getType() == jbig2SegSymbolDict) {
1672 +      inputSymbolDict = (JBIG2SymbolDict *)seg;
1673 +      for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1674 +       bitmaps[k++] = inputSymbolDict->getBitmap(j);
1675        }
1676      }
1677    }
1678 @@ -1753,6 +1822,10 @@
1679  
1680    // create the symbol dict object
1681    symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1682 +  if (!symbolDict->isOk()) {
1683 +    delete symbolDict;
1684 +    goto syntaxError;
1685 +  }
1686  
1687    // exported symbol list
1688    i = j = 0;
1689 @@ -1766,6 +1839,7 @@
1690      if (i + run > numInputSyms + numNewSyms ||
1691         (ex && j + run > numExSyms)) {
1692        error(getPos(), "Too many exported symbols in JBIG2 symbol dictionary");
1693 +      for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1694        delete symbolDict;
1695        goto syntaxError;
1696      }
1697 @@ -1780,6 +1854,7 @@
1698    }
1699    if (j != numExSyms) {
1700      error(getPos(), "Too few symbols in JBIG2 symbol dictionary");
1701 +    for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1702      delete symbolDict;
1703      goto syntaxError;
1704    }
1705 @@ -2095,18 +2170,20 @@
1706  
1707    gfree(syms);
1708  
1709 -  // combine the region bitmap into the page bitmap
1710 -  if (imm) {
1711 -    if (pageH == 0xffffffff && y + h > curPageH) {
1712 -      pageBitmap->expand(y + h, pageDefPixel);
1713 -    }
1714 -    pageBitmap->combine(bitmap, x, y, extCombOp);
1715 -    delete bitmap;
1716 +  if (bitmap) {
1717 +    // combine the region bitmap into the page bitmap
1718 +    if (imm) {
1719 +      if (pageH == 0xffffffff && y + h > curPageH) {
1720 +        pageBitmap->expand(y + h, pageDefPixel);
1721 +      }
1722 +      pageBitmap->combine(bitmap, x, y, extCombOp);
1723 +      delete bitmap;
1724  
1725 -  // store the region bitmap
1726 -  } else {
1727 -    bitmap->setSegNum(segNum);
1728 -    segments->append(bitmap);
1729 +    // store the region bitmap
1730 +    } else {
1731 +      bitmap->setSegNum(segNum);
1732 +      segments->append(bitmap);
1733 +    }
1734    }
1735  
1736    // clean up the Huffman decoder
1737 @@ -2159,6 +2236,10 @@
1738  
1739    // allocate the bitmap
1740    bitmap = new JBIG2Bitmap(0, w, h);
1741 +  if (!bitmap->isOk()) {
1742 +    delete bitmap;
1743 +    return NULL;
1744 +  }
1745    if (defPixel) {
1746      bitmap->clearToOne();
1747    } else {
1748 @@ -2235,73 +2316,84 @@
1749           ri = 0;
1750         }
1751         if (ri) {
1752 +         GBool decodeSuccess;
1753           if (huff) {
1754 -           huffDecoder->decodeInt(&rdw, huffRDWTable);
1755 -           huffDecoder->decodeInt(&rdh, huffRDHTable);
1756 -           huffDecoder->decodeInt(&rdx, huffRDXTable);
1757 -           huffDecoder->decodeInt(&rdy, huffRDYTable);
1758 -           huffDecoder->decodeInt(&bmSize, huffRSizeTable);
1759 +           decodeSuccess = huffDecoder->decodeInt(&rdw, huffRDWTable);
1760 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdh, huffRDHTable);
1761 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdx, huffRDXTable);
1762 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdy, huffRDYTable);
1763 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&bmSize, huffRSizeTable);
1764             huffDecoder->reset();
1765             arithDecoder->start();
1766           } else {
1767 -           arithDecoder->decodeInt(&rdw, iardwStats);
1768 -           arithDecoder->decodeInt(&rdh, iardhStats);
1769 -           arithDecoder->decodeInt(&rdx, iardxStats);
1770 -           arithDecoder->decodeInt(&rdy, iardyStats);
1771 +           decodeSuccess = arithDecoder->decodeInt(&rdw, iardwStats);
1772 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdh, iardhStats);
1773 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdx, iardxStats);
1774 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats);
1775 +         }
1776 +         
1777 +         if (decodeSuccess && syms[symID])
1778 +         {
1779 +           refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
1780 +           refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
1781 +
1782 +           symbolBitmap =
1783 +             readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
1784 +                                         rdh + syms[symID]->getHeight(),
1785 +                                         templ, gFalse, syms[symID],
1786 +                                         refDX, refDY, atx, aty);
1787           }
1788 -         refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
1789 -         refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
1790 -
1791 -         symbolBitmap =
1792 -           readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
1793 -                                       rdh + syms[symID]->getHeight(),
1794 -                                       templ, gFalse, syms[symID],
1795 -                                       refDX, refDY, atx, aty);
1796           //~ do we need to use the bmSize value here (in Huffman mode)?
1797         } else {
1798           symbolBitmap = syms[symID];
1799         }
1800  
1801 -       // combine the symbol bitmap into the region bitmap
1802 -       //~ something is wrong here - refCorner shouldn't degenerate into
1803 -       //~   two cases
1804 -       bw = symbolBitmap->getWidth() - 1;
1805 -       bh = symbolBitmap->getHeight() - 1;
1806 -       if (transposed) {
1807 -         switch (refCorner) {
1808 -         case 0: // bottom left
1809 -           bitmap->combine(symbolBitmap, tt, s, combOp);
1810 -           break;
1811 -         case 1: // top left
1812 -           bitmap->combine(symbolBitmap, tt, s, combOp);
1813 -           break;
1814 -         case 2: // bottom right
1815 -           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1816 -           break;
1817 -         case 3: // top right
1818 -           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1819 -           break;
1820 +       if (symbolBitmap) {
1821 +         // combine the symbol bitmap into the region bitmap
1822 +         //~ something is wrong here - refCorner shouldn't degenerate into
1823 +         //~   two cases
1824 +         bw = symbolBitmap->getWidth() - 1;
1825 +         bh = symbolBitmap->getHeight() - 1;
1826 +         if (transposed) {
1827 +           switch (refCorner) {
1828 +           case 0: // bottom left
1829 +             bitmap->combine(symbolBitmap, tt, s, combOp);
1830 +             break;
1831 +           case 1: // top left
1832 +             bitmap->combine(symbolBitmap, tt, s, combOp);
1833 +             break;
1834 +           case 2: // bottom right
1835 +             bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1836 +             break;
1837 +           case 3: // top right
1838 +             bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1839 +             break;
1840 +           }
1841 +           s += bh;
1842 +         } else {
1843 +           switch (refCorner) {
1844 +           case 0: // bottom left
1845 +             bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1846 +             break;
1847 +           case 1: // top left
1848 +             bitmap->combine(symbolBitmap, s, tt, combOp);
1849 +             break;
1850 +           case 2: // bottom right
1851 +             bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1852 +             break;
1853 +           case 3: // top right
1854 +             bitmap->combine(symbolBitmap, s, tt, combOp);
1855 +             break;
1856 +           }
1857 +           s += bw;
1858           }
1859 -         s += bh;
1860 -       } else {
1861 -         switch (refCorner) {
1862 -         case 0: // bottom left
1863 -           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1864 -           break;
1865 -         case 1: // top left
1866 -           bitmap->combine(symbolBitmap, s, tt, combOp);
1867 -           break;
1868 -         case 2: // bottom right
1869 -           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1870 -           break;
1871 -         case 3: // top right
1872 -           bitmap->combine(symbolBitmap, s, tt, combOp);
1873 -           break;
1874 +         if (ri) {
1875 +           delete symbolBitmap;
1876           }
1877 -         s += bw;
1878 -       }
1879 -       if (ri) {
1880 -         delete symbolBitmap;
1881 +       } else {
1882 +         // NULL symbolBitmap only happens on error
1883 +         delete bitmap;
1884 +         return NULL;
1885         }
1886        }
1887  
1888 @@ -2431,11 +2523,12 @@
1889      error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
1890      return;
1891    }
1892 -  if (!(seg = findSegment(refSegs[0])) ||
1893 -      seg->getType() != jbig2SegPatternDict) {
1894 +  seg = findSegment(refSegs[0]);
1895 +  if (seg == NULL || seg->getType() != jbig2SegPatternDict) {
1896      error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
1897      return;
1898    }
1899 +
1900    patternDict = (JBIG2PatternDict *)seg;
1901    bpp = 0;
1902    i = 1;
1903 @@ -2591,6 +2684,8 @@
1904    // read the bitmap
1905    bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
1906                              NULL, atx, aty, mmr ? length - 18 : 0);
1907 +  if (!bitmap)
1908 +    return;
1909  
1910    // combine the region bitmap into the page bitmap
1911    if (imm) {
1912 @@ -2616,7 +2711,7 @@
1913                                       int *codingLine, int *a0i, int w) {
1914    if (a1 > codingLine[*a0i]) {
1915      if (a1 > w) {
1916 -      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
1917 +      error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
1918        a1 = w;
1919      }
1920      if ((*a0i & 1) ^ blackPixels) {
1921 @@ -2630,7 +2725,7 @@
1922                                          int *codingLine, int *a0i, int w) {
1923    if (a1 > codingLine[*a0i]) {
1924      if (a1 > w) {
1925 -      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
1926 +      error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
1927        a1 = w;
1928      }
1929      if ((*a0i & 1) ^ blackPixels) {
1930 @@ -2657,13 +2752,17 @@
1931    JBIG2Bitmap *bitmap;
1932    GBool ltp;
1933    Guint ltpCX, cx, cx0, cx1, cx2;
1934 -  JBIG2BitmapPtr cxPtr0, cxPtr1;
1935 -  JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
1936 +  JBIG2BitmapPtr cxPtr0 = {0}, cxPtr1 = {0};
1937 +  JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0};
1938    int *refLine, *codingLine;
1939    int code1, code2, code3;
1940    int x, y, a0i, b1i, blackPixels, pix, i;
1941  
1942    bitmap = new JBIG2Bitmap(0, w, h);
1943 +  if (!bitmap->isOk()) {
1944 +    delete bitmap;
1945 +    return NULL;
1946 +  }
1947    bitmap->clearToZero();
1948  
1949    //----- MMR decode
1950 @@ -2682,7 +2781,7 @@
1951      // ---> max refLine size = w + 2
1952      codingLine = (int *)gmallocn(w + 1, sizeof(int));
1953      refLine = (int *)gmallocn(w + 2, sizeof(int));
1954 -    codingLine[0] = w;
1955 +    for (i = 0; i < w + 1; ++i) codingLine[i] = w;
1956  
1957      for (y = 0; y < h; ++y) {
1958  
1959 @@ -3093,8 +3192,8 @@
1960      return;
1961    }
1962    if (nRefSegs == 1) {
1963 -    if (!(seg = findSegment(refSegs[0])) ||
1964 -       seg->getType() != jbig2SegBitmap) {
1965 +    seg = findSegment(refSegs[0]);
1966 +    if (seg == NULL || seg->getType() != jbig2SegBitmap) {
1967        error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
1968        return;
1969      }
1970 @@ -3143,11 +3242,24 @@
1971    JBIG2Bitmap *bitmap;
1972    GBool ltp;
1973    Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
1974 -  JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
1975 -  JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
1976 +  JBIG2BitmapPtr cxPtr0 = {0};
1977 +  JBIG2BitmapPtr cxPtr1 = {0};
1978 +  JBIG2BitmapPtr cxPtr2 = {0};
1979 +  JBIG2BitmapPtr cxPtr3 = {0};
1980 +  JBIG2BitmapPtr cxPtr4 = {0};
1981 +  JBIG2BitmapPtr cxPtr5 = {0};
1982 +  JBIG2BitmapPtr cxPtr6 = {0};
1983 +  JBIG2BitmapPtr tpgrCXPtr0 = {0};
1984 +  JBIG2BitmapPtr tpgrCXPtr1 = {0};
1985 +  JBIG2BitmapPtr tpgrCXPtr2 = {0};
1986    int x, y, pix;
1987  
1988    bitmap = new JBIG2Bitmap(0, w, h);
1989 +  if (!bitmap->isOk())
1990 +  {
1991 +    delete bitmap;
1992 +    return NULL;
1993 +  }
1994    bitmap->clearToZero();
1995  
1996    // set up the typical row context
1997 @@ -3332,6 +3444,12 @@
1998    }
1999    pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
2000  
2001 +  if (!pageBitmap->isOk()) {
2002 +    delete pageBitmap;
2003 +    pageBitmap = NULL;
2004 +    return;
2005 +  }
2006 +  
2007    // default pixel value
2008    if (pageDefPixel) {
2009      pageBitmap->clearToOne();