Re: About GNU Ghostscript 707
Yannis Calotychos <[email protected]>
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
Ghostscript : all versions
file : dscparse.c
function : dsc_scan_data()
system : Apple PowerBook G4 800/Mac OS X 1.2.6
remarks :
the buffer kept by ghostscript is getting refilled when reading the ps
file.
occasionally the new data combined with the data already in the buffer
causes the parser to enter an infinite loop.
for example the buffer may look like:
ABCDEFGH
after token H is parsed, the buffer may be refilled to
IJKLEFGH
the new buffer can cause the parser to enter an infinite loop whereby
all tokens in "IJKLEFGH" are parsed.
a simple fix that zeros trailing parts of the buffer (to IJKL0000)
fixes this issue.
this issue crashes GS with most sample files provided by the latest
Adobe Illustrator installation (AI10 for Mac OS X).
I hope this makes sense,
Please review, and possibly incorporate the code shown below (change is
bracketed in comments /* Y.Calotychos - iView Multimedia Ltd. */)
We have a few more changes regarding functions mac_find_font_family()
and mac_get_font_encoding() that coould be used to load the correct
fonts. however we are still trying to understand how gs calculates the
metrics of strings as, altgough our corrections work in therms of the
font that is used, the character spacing/kerning is not correct.
I would be glad to send sample code.
------------------------------------
int
dsc_scan_data(CDSC *dsc, const char *data, int length)
{
int bytes_read;
int code = 0;
if (dsc == NULL)
return CDSC_ERROR;
if (dsc->id == CDSC_NOTDSC)
return CDSC_NOTDSC;
dsc->id = CDSC_OK;
if (dsc->eof)
return CDSC_OK; /* ignore */
if (length == 0) {
/* EOF, so process what remains */
dsc->eof = TRUE;
}
do {
if (dsc->id == CDSC_NOTDSC)
break;
if (length != 0) {
/* Y.Calotychos - iView Multimedia Ltd. */
/* OLD CODE --------------
if (dsc->data_length > CDSC_DATA_LENGTH/2) {
memmove(dsc->data, dsc->data + dsc->data_index,
dsc->data_length - dsc->data_index);
dsc->data_offset += dsc->data_index;
dsc->data_length -= dsc->data_index;
dsc->data_index = 0;
} END OF OLD CODE -------- */
if (dsc->data_length > CDSC_DATA_LENGTH/2)
{
// copy the remaining data to the top of the buffer.
// we really nead to clear this array as parsers can get confused
as to where
// this line breaks
long l = dsc->data_length - dsc->data_index;
memmove(dsc->data, dsc->data + dsc->data_index, l);
memset(dsc->data+l, 0, CDSC_DATA_LENGTH-l);
dsc->data_offset += dsc->data_index;
dsc->data_length -= dsc->data_index;
dsc->data_index = 0;
}
/* Y.Calotychos - iView Multimedia Ltd. */
/* append to buffer */
bytes_read = min(length, (int)(CDSC_DATA_LENGTH -
dsc->data_length));
memcpy(dsc->data + dsc->data_length, data, bytes_read);
dsc->data_length += bytes_read;
data += bytes_read;
length -= bytes_read;
}
if (dsc->scan_section == scan_none) {
code = dsc_scan_type(dsc);
if (code == CDSC_NEEDMORE) {
/* need more characters before we can identify type */
code = CDSC_OK;
break;
}
dsc->id = code;
}
if (code == CDSC_NOTDSC) {
dsc->id = CDSC_NOTDSC;
break;
}
while ((code = dsc_read_line(dsc)) > 0) {
if (dsc->id == CDSC_NOTDSC)
break;
if (dsc->file_length &&
(dsc->data_offset + dsc->data_index > dsc->file_length)) {
/* have read past end of where we need to parse. */
return CDSC_OK; /* ignore */
}
if (dsc->doseps_end &&
(dsc->data_offset + dsc->data_index > dsc->doseps_end)) {
/* have read past end of DOS EPS PostScript section */
return CDSC_OK; /* ignore */
}
if (dsc->eof)
return CDSC_OK;
if (dsc->skip_document)
continue; /* embedded document */
if (dsc->skip_lines)
continue; /* embedded lines */
if (IS_DSC(dsc->line, "%%BeginData:"))
continue;
if (IS_DSC(dsc->line, "%%BeginBinary:"))
continue;
if (IS_DSC(dsc->line, "%%EndDocument"))
continue;
if (IS_DSC(dsc->line, "%%EndData"))
continue;
if (IS_DSC(dsc->line, "%%EndBinary"))
continue;
do {
switch (dsc->scan_section) {
case scan_comments:
code = dsc_scan_comments(dsc);
break;
case scan_pre_preview:
case scan_preview:
code = dsc_scan_preview(dsc);
break;
case scan_pre_defaults:
case scan_defaults:
code = dsc_scan_defaults(dsc);
break;
case scan_pre_prolog:
case scan_prolog:
code = dsc_scan_prolog(dsc);
break;
case scan_pre_setup:
case scan_setup:
code = dsc_scan_setup(dsc);
break;
case scan_pre_pages:
case scan_pages:
code = dsc_scan_page(dsc);
break;
case scan_pre_trailer:
case scan_trailer:
code = dsc_scan_trailer(dsc);
break;
case scan_eof:
code = CDSC_OK;
break;
default:
/* invalid state */
code = CDSC_ERROR;
}
/* repeat if line is start of next section */
} while (code == CDSC_PROPAGATE);
/* if DOS EPS header not complete, ask for more */
if (code == CDSC_NEEDMORE) {
code = CDSC_OK;
break;
}
if (code == CDSC_NOTDSC) {
dsc->id = CDSC_NOTDSC;
break;
}
}
} while (length != 0);
return (code < 0) ? code : dsc->id;
}
-------------------------------------
yannis calotychos ph.d.
www.iview-multimedia.com