Fix for 687555, /rangecheck in --array-- when loading some (large) CMaps
Alex Cherepanov <[email protected]> Sun, 08 Aug 2004 06:12:11 -0400
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Organization | Coscript Software |
| Message-ID | <[email protected]> |
Use extra level of nesting instead of concatenating CMap data to accommodate CMap's with >= 64K elements. Fix bug 587555 This patch should not affect anything except the small increase in VM use for CMap resources. I'm running the regression test now. _______________________________________________ gs-code-review mailing list [email protected] http://www.ghostscript.com/mailman/listinfo/gs-code-review
687555.diff
(text/plain, 8.4 KB)
Index: gs/lib/gs_cmap.ps
===================================================================
RCS file: /cvs/ghostscript/gs/lib/gs_cmap.ps,v
retrieving revision 1.17
diff -b -u -r1.17 gs_cmap.ps
--- gs/lib/gs_cmap.ps 12 Apr 2003 18:08:18 -0000 1.17
+++ gs/lib/gs_cmap.ps 8 Aug 2004 09:55:16 -0000
@@ -22,7 +22,7 @@
[
/CMERGE_DEBUG
/USE_CIDCHAR_AS_RANGE
-] {dup where {pop pop} { currentdict exch false def pop } ifelse} forall
+] {dup where {pop pop} { currentdict exch //false def pop } ifelse} forall
% ---------------- Public operators ---------------- %
@@ -65,7 +65,7 @@
} ifelse findresource
} if
exch CMap /FontMatrices get dup length 2 index gt {
- exch get dup null eq { pop } { makefont } ifelse
+ exch get dup //null eq { pop } { makefont } ifelse
} {
pop pop
} ifelse
@@ -85,9 +85,9 @@
% Our internal .CodeMapData structure closely mirrors the structures
% defined in gxfcmap.h (q.v.). () indicate a string, [] indicate an array,
% ? indicates a Boolean, # indicates an integer, {} for grouping.
-% [[(first) (last) ...] % code space ranges
-% [(prefix) (key_size,?is_range,value_type,value_size) (keys...)
-% {(values...) | [value ...]} #font_index % code mappings
+% [[[(first) (last) ...]+] % code space ranges
+% [[(prefix) (key_size,?is_range,value_type,value_size) (keys...)
+% {(values...) | [value ...]} #font_index ]+] % code mappings
% ...]
% <<same>> % notdef mappings
% ]
@@ -106,42 +106,52 @@
% ------ Font-level operators ------ %
/begincmap { % - begincmap -
- /.CodeMapData [[] [] []] def
+ /.CodeMapData [[[]] [[]] [[]]] def
/FontMatrices [] def
/.FontIndex 0 def
/.TempMaps [20 dict 50 dict 50 dict] def
- /CodeMap null def % for .buildcmap
+ /CodeMap //null def % for .buildcmap
} bind def
+
/endcmap { % - endcmap -
.rewriteTempMapsNotDef
+
CMAPDEBUG {
- (*** defined charmap ***\n) print
- .TempMaps 1 get {exch == (\t) print ==} forall
- (*** undefined charmap ***\n) print
- .TempMaps 2 get {exch == (\t) print ==} forall
- } if
- 10 dict begin 0 1 2 {
- /i exch def
- % Append data from .TempMaps to .CodeMapData.
- /t .TempMaps i get def
- .CodeMapData i get length t { exch pop length add } forall
- CMAPDEBUG { (requested array size ) print dup == } if
- array /a exch def
- a 0 .CodeMapData i get .putmore
- 0 1 t length 1 sub {
- t exch get .putmore
- } for pop pop
- .CodeMapData i a put
- } for end
+ 2 (*** undefined charmap ***)
+ 1 (*** defined charmap ***)
+ 0 (*** code space ranges ***)
+ 3 { =
+ .TempMaps exch get
+ 0 1 2 index length 1 sub {
+ dup == (\t) print
+ 1 index exch get ==
+ } for
+ pop
+ } repeat
+ } if
+
+ /.CodeMapData dup load [ exch
+ .TempMaps aload pop begin begin begin
+ {
+ [ exch aload pop
+ 0 1 currentdict length 1 sub {
+ currentdict exch get
+ } for
+ ]
+ end
+ } forall
+ ] .endmap def
+
+ CMAPDEBUG {
+ (*** Content of .CodeMapData ***) =
+ 0 .CodeMapData { exch dup == 1 add exch (\t) print == } forall
+ pop
+ } if
+
currentdict /.TempMaps undef
- /.CodeMapData .CodeMapData .endmap def
/FontMatrices FontMatrices .endmap def
} bind def
-/.putmore { % <array> <i> <array2> .putmore <array> <i+len(array2)>
- 3 copy putinterval length add
-} bind def
-
/.endmap { % <map> .endmap <map>
dup type /arraytype eq {
% This might be a shared read-only array inherited via usecmap.
@@ -164,6 +174,7 @@
/begincodespacerange { % <count> begincodespacerange -
pop mark
} bind def
+
/endcodespacerange { % <code_lo> <code_hi> ... endcodespacerange -
0 .appendmap
} bind def
@@ -186,6 +197,7 @@
/FontMatrices exch def
} if
} bind def
+
/endusematrix { % <matrix> endusematrix -
FontMatrices 3 1 roll put
} bind def
@@ -504,18 +516,18 @@
dup length dict .copydict exch .setglobal
} if
dup gcheck 2 index gcheck not and {
- exch .currentglobal exch true .setglobal
+ exch .currentglobal exch //true .setglobal
dup length string copy exch .setglobal exch
} if dup /CMapName 3 index put
} if
- dup /CodeMap get null eq { .buildcmap } if
+ dup /CodeMap get //null eq { .buildcmap } if
/Generic /Category findresource /DefineResource get exec
} put
/Category defineresource pop
% We might have loaded CID font support already.
/CIDInit /ProcSet 2 copy { findresource } .internalstopped
% An interior `stopped' might have reset VM allocation to local.
-true .setglobal
+//true .setglobal
{ pop pop 3 -1 roll }
{ dup length 4 index length add dict .copydict 4 -1 roll exch .copydict }
ifelse exch defineresource pop
Index: gs/src/zfcmap.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/zfcmap.c,v
retrieving revision 1.14
diff -b -u -r1.14 zfcmap.c
--- gs/src/zfcmap.c 10 Apr 2003 11:58:25 -0000 1.14
+++ gs/src/zfcmap.c 8 Aug 2004 09:55:16 -0000
@@ -63,14 +63,26 @@
private int
acquire_code_ranges(gs_cmap_adobe1_t *cmap, const ref *pref, gs_memory_t *mem)
{
- uint num_ranges;
+ uint num_ranges = 0;
gx_code_space_range_t *ranges;
- uint i;
+ uint i, j, elem_sz;
+ ref elem;
- if (!r_is_array(pref) || (num_ranges = r_size(pref)) == 0 ||
- num_ranges & 1)
+ if (!r_is_array(pref))
+ return_error(e_rangecheck);
+ for (i=0; i < r_size(pref); i++) {
+ int code = array_get(pref, i, &elem);
+ if (code < 0)
+ return code;
+ elem_sz = r_size(&elem);
+ if (elem_sz & 1)
+ return_error(e_rangecheck);
+ num_ranges += elem_sz;
+ }
+ if (num_ranges == 0)
return_error(e_rangecheck);
num_ranges >>= 1;
+
ranges = (gx_code_space_range_t *)
gs_alloc_byte_array(mem, num_ranges, sizeof(gx_code_space_range_t),
"acquire_code_ranges");
@@ -78,12 +90,16 @@
return_error(e_VMerror);
cmap->code_space.ranges = ranges;
cmap->code_space.num_ranges = num_ranges;
- for (i = 0; i < num_ranges; ++i, ++ranges) {
+
+ for (i = 0; i < r_size(pref); i++) {
+ array_get(pref, i, &elem);
+ elem_sz = r_size(&elem);
+ for (j = 0; j < elem_sz; j += 2) {
ref rfirst, rlast;
int size;
- array_get(pref, i * 2L, &rfirst);
- array_get(pref, i * 2L + 1, &rlast);
+ array_get(&elem, j, &rfirst);
+ array_get(&elem, j + 1, &rlast);
if (!r_has_type(&rfirst, t_string) ||
!r_has_type(&rlast, t_string) ||
(size = r_size(&rfirst)) == 0 || size > MAX_CMAP_CODE_SIZE ||
@@ -93,6 +109,8 @@
memcpy(ranges->first, rfirst.value.bytes, size);
memcpy(ranges->last, rlast.value.bytes, size);
ranges->size = size;
+ ++ranges;
+ }
}
return 0;
}
@@ -102,12 +120,23 @@
acquire_code_map(gx_code_map_t *pcmap, const ref *pref, gs_cmap_adobe1_t *root,
gs_memory_t *mem)
{
- uint num_lookup;
+ uint num_lookup = 0;
gx_cmap_lookup_range_t *pclr;
long i;
+ ref elem;
+ uint elem_sz;
- if (!r_is_array(pref) || (num_lookup = r_size(pref)) % 5 != 0)
+ if (!r_is_array(pref))
+ return_error(e_rangecheck);
+ for (i=0; i < r_size(pref); i++) {
+ int code = array_get(pref, i, &elem);
+ if (code < 0)
+ return code;
+ elem_sz = r_size(&elem);
+ if (elem_sz % 5 != 0)
return_error(e_rangecheck);
+ num_lookup += elem_sz;
+ }
num_lookup /= 5;
pclr = gs_alloc_struct_array(mem, num_lookup, gx_cmap_lookup_range_t,
&st_cmap_lookup_range_element,
@@ -117,14 +146,20 @@
memset(pclr, 0, sizeof(*pclr) * num_lookup);
pcmap->lookup = pclr;
pcmap->num_lookup = num_lookup;
- for (i = 0; i < num_lookup * 5; i += 5, ++pclr) {
+
+
+ for (i = 0; i < r_size(pref); i++) {
+ uint j;
+ array_get(pref, i, &elem);
+ elem_sz = r_size(&elem);
+ for (j = 0; j < elem_sz; j += 5) {
ref rprefix, rmisc, rkeys, rvalues, rfxs;
- array_get(pref, i, &rprefix);
- array_get(pref, i + 1, &rmisc);
- array_get(pref, i + 2, &rkeys);
- array_get(pref, i + 3, &rvalues);
- array_get(pref, i + 4, &rfxs);
+ array_get(&elem, j, &rprefix);
+ array_get(&elem, j + 1, &rmisc);
+ array_get(&elem, j + 2, &rkeys);
+ array_get(&elem, j + 3, &rvalues);
+ array_get(&elem, j + 4, &rfxs);
if (!r_has_type(&rprefix, t_string) ||
!r_has_type(&rmisc, t_string) ||
@@ -206,6 +241,8 @@
}
check_int_leu_only(rfxs, 0xff);
pclr->font_index = (int)rfxs.value.intval;
+ ++pclr;
+ }
}
return 0;
}