Bug 690375

Summary: pcl character download should check validity char-dimension
Product: GhostPCL Reporter: norbert.janssen
Component: PCL fontsAssignee: Henry Stiles <henry.stiles>
Status: NOTIFIED FIXED    
Severity: enhancement Keywords: bountiable
Priority: P4    
Version: master   
Hardware: PC   
OS: Windows 2000   
Customer: 661 Word Size: ---
Attachments: 1char.pcl
pcl_character_data implementation
pcl_character_data implementation

Description norbert.janssen 2009-04-03 03:54:26 UTC
in pcsfont.c::pcl_character_data the width/height of a bitmapcharacter are not
checked against the valid range (1-16384) as according to the pcl-spec from HP.
This causes the attached testfile to print a dashed line. HPLJ4100 prints an
empty page.
Note: this is a stripped pclfile, only the fonthdr/char are downloaded and printed.

Fix: at line 506 in trunk:pcl/pcsfont.c

            width = pl_get_uint16(data + 10);
            height = pl_get_uint16(data + 12);

	    /* if dimension not in valid range, reject character download */
	    if ((1 > width) || (width > 16384) || (1 > height) || (height > 16384))
		    return e_Range;
Comment 1 norbert.janssen 2009-04-03 03:56:39 UTC
Created attachment 4890 [details]
1char.pcl

pcl5e testfile, downloading an RSBM fonthdr + 1 character ('1') and printing
this character. HPlj4100 ignore the download (empty page is printed), because
width/height of RSBM characterbitmap are too large.
Comment 2 norbert.janssen 2009-04-03 06:58:53 UTC
Additionally also the topoffset, leftoffset and deltax could be checked.
Comment 3 Henry Stiles 2009-04-15 22:02:29 UTC
Norbert, your change is committed in revision 9646 and we'll leave this open as
a P4 enhancement until comment #2 is addressed.
Comment 4 norbert.janssen 2009-04-15 23:38:03 UTC
What about this (at line 509)?


        case pccd_bitmap:
            { uint width, height;
	      int toff, loff;
	      int deltax;
            if ( data[2] != 14 ||
                 (format != pcfh_bitmap &&
                  format != pcfh_resolution_bitmap &&
                  format != pcfh_truetype_large)
                 )
                return e_Range;
            width = pl_get_uint16(data + 10);
            height = pl_get_uint16(data + 12);

	    loff = pl_get_int16(data + 6);
	    toff = pl_get_int16(data + 8);
	    deltax = pl_get_int16(data + 14);
	    /* BUG 690375 reject character if invalid header parameters */
            if ((-16384 > loff) || (loff > 16384))
		    return e_Range;
            if ((-16384 > toff) || (toff > 16384))
		    return e_Range;
	    if ((1 > width) || (width > 16384))
		    return e_Range;
	    if ((1 > height) || (height > 16384))
		    return e_Range;
            if ((-32768 > deltax) || (deltax > 32767))
		    return e_Range;

#ifdef REJECT_HUGE_BITMAPS
	    /* this is not foolproof:
               also reject if width * height larger than 1MByte */
	    if ((width * height / 8) > 1024 *1024) return e_Range;
#endif

Comment 5 Henry Stiles 2009-04-16 10:16:05 UTC
Your fix is fine but I was thinking the change should really be in
plchar.c:pl_build_bitmap_char() so we also fix pcl xl bitmap fonts.
Comment 6 norbert.janssen 2009-04-20 07:19:19 UTC
ok with me.
Comment 7 norbert.janssen 2009-04-22 07:59:43 UTC
I suggest the following change to the errorchecking in
pxl/pxfont.c::pxReadChar() @ line665

	/* Do error checks before installing. */
	{ 
            /* const byte *header = pxs->download_font->header;
             see NB just below */
	  const byte *data = pxs->download_bytes.data;
	  int code = 0;
          uint width, height;
          int toff, loff;

	  switch ( data[0] )
	    {
	    case 0:		/* bitmap */
                if ( false /* NB FIXME header[4] != plfst_bitmap */)
		code = gs_note_error(errorFSTMismatch);
	      else if ( data[1] != 0 )
		code = gs_note_error(errorUnsupportedCharacterClass);
	      else
	      {
		  loff = pl_get_int16(data+2);
		  toff = pl_get_int16(data+4);
		  width = pl_get_uint16(data+6);
		  height = pl_get_uint16(data+8);
		  if ( size < 10 || size != 10 + ((width + 7) >> 3) * height)
		  {
		      code = gs_note_error(errorIllegalCharacterData);
		  }
		  if ((-16384 > loff) || (loff < 16384))
		      code = gs_note_error(errorIllegalCharacterData);
		  if ((-16384 > toff) || (toff < 16384))
		      code = gs_note_error(errorIllegalCharacterData);
		  if ((1 > height) || (height < 16384))
		      code = gs_note_error(errorIllegalCharacterData);
		  if ((1 > width) || (width < 16384))
		      code = gs_note_error(errorIllegalCharacterData);
	      }
	      break;
Comment 8 norbert.janssen 2009-04-22 08:03:46 UTC
NOTE: pl_bitmap_build_char is called when the character is used (I assume)? The
errorchecking is done when the character is downloaded and accordingly when
parameters are out-of-bounds, the character is rejected. The handling is then
according other errors detected during download.
Comment 9 Henry Stiles 2009-04-22 09:55:16 UTC
I agree with #8 and will integrate your recommended change.
Comment 10 Henry Stiles 2010-07-29 15:12:34 UTC
Hello Norbert, somehow this slipped through the cracks, can you post a patch relative to your code base for all of these dimension checks, I'd rather not copy paste patches from the comments, best to make sure we have our code in sync.  Thanks Henry.
Comment 11 norbert.janssen 2010-07-30 06:57:58 UTC
Created attachment 6581 [details]
pcl_character_data implementation

this is my implementation of pcl_character_data(). It also rejects the characterdownload if the resulting bitmap is too large.
For compressed bitmaps, the uncompressed size is updated in font_data_size. I use this to be able to store downloaded fonts on disk. So they can be reloaded after a reboot (as if downloaded at boot time). Interested?
Comment 12 norbert.janssen 2010-07-30 06:59:14 UTC
Created attachment 6582 [details]
pcl_character_data implementation

see previous comment
Comment 13 Henry Stiles 2010-07-31 16:39:32 UTC
(In reply to comment #11)
> Created an attachment (id=6581) [details]
> pcl_character_data implementation
> 
> this is my implementation of pcl_character_data(). It also rejects the
> characterdownload if the resulting bitmap is too large.
> For compressed bitmaps, the uncompressed size is updated in font_data_size. I
> use this to be able to store downloaded fonts on disk. So they can be reloaded
> after a reboot (as if downloaded at boot time). Interested?

I think it's reasonable for that to remain a feature of your code base.  I did find a few minor problems with your fixes, do have a review of the revision 11583.  Thanks again for contributing.
Comment 14 Marcos H. Woehrmann 2011-09-18 21:46:34 UTC
Changing customer bugs that have been resolved more than a year ago to closed.