|
| 1 | +From 74af85c4b62b35e55b0ce9dec55ee10cbc4962a2 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Werner Lemberg <wl@gnu.org> |
| 3 | +Date: Mon, 8 Dec 2014 16:01:50 +0100 |
| 4 | +Subject: [PATCH] [pcf] Fix Savannah bug #43774. |
| 5 | + |
| 6 | +Work around `features' of X11's `pcfWriteFont' and `pcfReadFont' |
| 7 | +functions. Since the PCF format doesn't have an official |
| 8 | +specification, we have to exactly follow these functions' behaviour. |
| 9 | + |
| 10 | +The problem was unveiled with a patch from 2014-11-06, fixing issue #43547. |
| 11 | + |
| 12 | +* src/pcf/pcfread.c (pcf_read_TOC): Don't check table size for last |
| 13 | +element. Instead, assign real size. |
| 14 | +--- |
| 15 | + ChangeLog | 14 ++++++++++++++ |
| 16 | + src/pcf/pcfread.c | 54 +++++++++++++++++++++++++++++++++++++++++++----------- |
| 17 | + 2 files changed, 57 insertions(+), 11 deletions(-) |
| 18 | + |
| 19 | +diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c |
| 20 | +index 998cbed..e3caf82 100644 |
| 21 | +--- src/pcf/pcfread.c |
| 22 | ++++ src/pcf/pcfread.c |
| 23 | +@@ -2,7 +2,7 @@ |
| 24 | + |
| 25 | + FreeType font driver for pcf fonts |
| 26 | + |
| 27 | +- Copyright 2000-2010, 2012, 2013 by |
| 28 | ++ Copyright 2000-2010, 2012-2014 by |
| 29 | + Francesco Zappa Nardelli |
| 30 | + |
| 31 | + Permission is hereby granted, free of charge, to any person obtaining a copy |
| 32 | +@@ -78,7 +78,7 @@ THE SOFTWARE. |
| 33 | + FT_FRAME_START( 16 ), |
| 34 | + FT_FRAME_ULONG_LE( type ), |
| 35 | + FT_FRAME_ULONG_LE( format ), |
| 36 | +- FT_FRAME_ULONG_LE( size ), |
| 37 | ++ FT_FRAME_ULONG_LE( size ), /* rounded up to a multiple of 4 */ |
| 38 | + FT_FRAME_ULONG_LE( offset ), |
| 39 | + FT_FRAME_END |
| 40 | + }; |
| 41 | +@@ -95,9 +95,11 @@ THE SOFTWARE. |
| 42 | + FT_Memory memory = FT_FACE( face )->memory; |
| 43 | + FT_UInt n; |
| 44 | + |
| 45 | ++ FT_ULong size; |
| 46 | + |
| 47 | +- if ( FT_STREAM_SEEK ( 0 ) || |
| 48 | +- FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) ) |
| 49 | ++ |
| 50 | ++ if ( FT_STREAM_SEEK( 0 ) || |
| 51 | ++ FT_STREAM_READ_FIELDS( pcf_toc_header, toc ) ) |
| 52 | + return FT_THROW( Cannot_Open_Resource ); |
| 53 | + |
| 54 | + if ( toc->version != PCF_FILE_VERSION || |
| 55 | +@@ -154,14 +156,35 @@ THE SOFTWARE. |
| 56 | + break; |
| 57 | + } |
| 58 | + |
| 59 | +- /* we now check whether the `size' and `offset' values are reasonable: */ |
| 60 | +- /* `offset' + `size' must not exceed the stream size */ |
| 61 | ++ /* |
| 62 | ++ * We now check whether the `size' and `offset' values are reasonable: |
| 63 | ++ * `offset' + `size' must not exceed the stream size. |
| 64 | ++ * |
| 65 | ++ * Note, however, that X11's `pcfWriteFont' routine (used by the |
| 66 | ++ * `bdftopcf' program to create PDF font files) has two special |
| 67 | ++ * features. |
| 68 | ++ * |
| 69 | ++ * - It always assigns the accelerator table a size of 100 bytes in the |
| 70 | ++ * TOC, regardless of its real size, which can vary between 34 and 72 |
| 71 | ++ * bytes. |
| 72 | ++ * |
| 73 | ++ * - Due to the way the routine is designed, it ships out the last font |
| 74 | ++ * table with its real size, ignoring the TOC's size value. Since |
| 75 | ++ * the TOC size values are always rounded up to a multiple of 4, the |
| 76 | ++ * difference can be up to three bytes for all tables except the |
| 77 | ++ * accelerator table, for which the difference can be as large as 66 |
| 78 | ++ * bytes. |
| 79 | ++ * |
| 80 | ++ */ |
| 81 | ++ |
| 82 | + tables = face->toc.tables; |
| 83 | +- for ( n = 0; n < toc->count; n++ ) |
| 84 | ++ size = stream->size; |
| 85 | ++ |
| 86 | ++ for ( n = 0; n < toc->count - 1; n++ ) |
| 87 | + { |
| 88 | + /* we need two checks to avoid overflow */ |
| 89 | +- if ( ( tables->size > stream->size ) || |
| 90 | +- ( tables->offset > stream->size - tables->size ) ) |
| 91 | ++ if ( ( tables->size > size ) || |
| 92 | ++ ( tables->offset > size - tables->size ) ) |
| 93 | + { |
| 94 | + error = FT_THROW( Invalid_Table ); |
| 95 | + goto Exit; |
| 96 | +@@ -169,6 +192,15 @@ THE SOFTWARE. |
| 97 | + tables++; |
| 98 | + } |
| 99 | + |
| 100 | ++ /* no check of `tables->size' for last table element ... */ |
| 101 | ++ if ( ( tables->offset > size ) ) |
| 102 | ++ { |
| 103 | ++ error = FT_THROW( Invalid_Table ); |
| 104 | ++ goto Exit; |
| 105 | ++ } |
| 106 | ++ /* ... instead, we adjust `tables->size' to the real value */ |
| 107 | ++ tables->size = size - tables->offset; |
| 108 | ++ |
| 109 | + #ifdef FT_DEBUG_LEVEL_TRACE |
| 110 | + |
| 111 | + { |
| 112 | +@@ -733,8 +765,8 @@ THE SOFTWARE. |
| 113 | + |
| 114 | + FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); |
| 115 | + |
| 116 | +- /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ |
| 117 | +- if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) |
| 118 | ++ /* XXX: PCF_Face->nmetrics is signed FT_Long, see pcf.h */ |
| 119 | ++ if ( face->nmetrics < 0 || nbitmaps != (FT_ULong)face->nmetrics ) |
| 120 | + return FT_THROW( Invalid_File_Format ); |
| 121 | + |
| 122 | + if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) |
| 123 | +-- |
| 124 | +2.1.3 |
| 125 | + |
0 commit comments