Re: Re: About GNU Ghostscript 707
Ray Johnston <[email protected]>
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
Russell,
Looks OK. Please commit. Also please add the bug # in the log
message. If Jack didn't open a bug on this yet, please open one
with Yannis's report (you can leave out his suggested changes),
then close it with your patch.
Regards,
Ray
__________________________________________________________________
Russell Lang wrote:
> Ray, Yannis,
>
> Some updates to the DSC parser, including a fix for the bug
> triggered by the file from Yannis.
>
> Yannis, could you please confirm that this does fix the problem?
> You may need to grab dscparse.c and dscparse.h from GS 8.11 if
> the patch doesn't apply cleanly to 7.07. Your change should not
> be needed. Note that the problem was caused by incorrect DSC
> comments (%%DocumentProcessColors was incorrectly used instead
> of %%DocumentCustomColors), but could still have been triggered
> if the correct comments were used.
>
> Proposed log message:
> Report (atend) in the trailer as being unknown.
> Recognise %%DocumentProcessColors and %%DocumentCustomColors
> in the trailer.
> Fix crash caused by dsc_copy_string not stopping at the end
> of a string occasionally.
> Allocate colour details using the correct allocator so they
> will be freed correctly.
>
> Russell
>
>
> On 11 Sep 2003 at 0:53, Yannis Calotychos wrote:
>
>
>>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
>>
>>_______________________________________________
>>gs-code-review mailing list
>>[email protected]
>>http://www.ghostscript.com/mailman/listinfo/gs-code-review
>
>
>
> Russell Lang [email protected]
> Ghostgum Software Pty Ltd http://www.ghostgum.com.au/
>
>
>
>
>
> ------------------------------------------------------------------------
>
> diff -u l:/cvs/gsview/src/dscparse.c src/dscparse.c
> --- l:/cvs/gsview/src/dscparse.c Thu Sep 11 10:59:20 2003
> +++ src/dscparse.c Fri Sep 12 05:47:12 2003
> @@ -1437,20 +1437,27 @@
> n++;
> p = dsc->line + n;
> if (COMPARE(p, "atend")) {
> - int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
> - switch (rc) {
> - case CDSC_RESPONSE_OK:
> - /* assume (atend) */
> - /* we should mark it as deferred */
> - break;
> - case CDSC_RESPONSE_CANCEL:
> - /* ignore it */
> - break;
> - case CDSC_RESPONSE_IGNORE_ALL:
> - return CDSC_NOTDSC;
> + if (dsc->scan_section != scan_comments)
> + dsc_unknown(dsc);
> + else {
> + int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND,
> + dsc->line, dsc->line_length);
> + switch (rc) {
> + case CDSC_RESPONSE_OK:
> + /* assume (atend) */
> + /* we should mark it as deferred */
> + break;
> + case CDSC_RESPONSE_CANCEL:
> + /* ignore it */
> + break;
> + case CDSC_RESPONSE_IGNORE_ALL:
> + return CDSC_NOTDSC;
> + }
> }
> }
> else if (COMPARE(p, "(atend)")) {
> + if (dsc->scan_section != scan_comments)
> + dsc_unknown(dsc);
> /* do nothing */
> /* we should mark it as deferred */
> }
> @@ -1546,21 +1553,27 @@
> p = dsc->line + offset;
>
> if (COMPARE(p, "atend")) {
> - int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
> - dsc->line_length);
> - switch (rc) {
> - case CDSC_RESPONSE_OK:
> - /* assume (atend) */
> - /* we should mark it as deferred */
> - break;
> - case CDSC_RESPONSE_CANCEL:
> - /* ignore it */
> - break;
> - case CDSC_RESPONSE_IGNORE_ALL:
> - return CDSC_NOTDSC;
> + if (dsc->scan_section == scan_trailer)
> + dsc_unknown(dsc);
> + else {
> + int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
> + dsc->line_length);
> + switch (rc) {
> + case CDSC_RESPONSE_OK:
> + /* assume (atend) */
> + /* we should mark it as deferred */
> + break;
> + case CDSC_RESPONSE_CANCEL:
> + /* ignore it */
> + break;
> + case CDSC_RESPONSE_IGNORE_ALL:
> + return CDSC_NOTDSC;
> + }
> }
> }
> else if (COMPARE(p, "(atend)")) {
> + if (dsc->scan_section == scan_trailer)
> + dsc_unknown(dsc);
> /* do nothing */
> /* we should mark it as deferred */
> }
> @@ -1678,21 +1691,27 @@
> p = dsc->line + offset;
>
> if (COMPARE(p, "atend")) {
> - int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
> - dsc->line_length);
> - switch (rc) {
> - case CDSC_RESPONSE_OK:
> - /* assume (atend) */
> - /* we should mark it as deferred */
> - break;
> - case CDSC_RESPONSE_CANCEL:
> - /* ignore it */
> - break;
> - case CDSC_RESPONSE_IGNORE_ALL:
> - return CDSC_NOTDSC;
> + if (dsc->scan_section == scan_trailer)
> + dsc_unknown(dsc);
> + else {
> + int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
> + dsc->line_length);
> + switch (rc) {
> + case CDSC_RESPONSE_OK:
> + /* assume (atend) */
> + /* we should mark it as deferred */
> + break;
> + case CDSC_RESPONSE_CANCEL:
> + /* ignore it */
> + break;
> + case CDSC_RESPONSE_IGNORE_ALL:
> + return CDSC_NOTDSC;
> + }
> }
> }
> else if (COMPARE(p, "(atend)")) {
> + if (dsc->scan_section == scan_trailer)
> + dsc_unknown(dsc);
> /* do nothing */
> /* we should mark it as deferred */
> }
> @@ -1754,20 +1773,27 @@
> while (IS_WHITE(*p))
> p++;
> if (COMPARE(p, "atend")) {
> - int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, dsc->line_length);
> - switch (rc) {
> - case CDSC_RESPONSE_OK:
> - /* assume (atend) */
> - /* we should mark it as deferred */
> - break;
> - case CDSC_RESPONSE_CANCEL:
> - /* ignore it */
> - break;
> - case CDSC_RESPONSE_IGNORE_ALL:
> - return CDSC_NOTDSC;
> + if (dsc->scan_section == scan_trailer)
> + dsc_unknown(dsc);
> + else {
> + int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND,
> + dsc->line, dsc->line_length);
> + switch (rc) {
> + case CDSC_RESPONSE_OK:
> + /* assume (atend) */
> + /* we should mark it as deferred */
> + break;
> + case CDSC_RESPONSE_CANCEL:
> + /* ignore it */
> + break;
> + case CDSC_RESPONSE_IGNORE_ALL:
> + return CDSC_NOTDSC;
> + }
> }
> }
> else if (COMPARE(p, "(atend)")) {
> + if (dsc->scan_section == scan_trailer)
> + dsc_unknown(dsc);
> /* do nothing */
> /* we should mark it as deferred */
> }
> @@ -1816,21 +1842,27 @@
> while (IS_WHITE(*p))
> p++;
> if (COMPARE(p, "atend")) {
> - int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
> - dsc->line_length);
> - switch (rc) {
> - case CDSC_RESPONSE_OK:
> - /* assume (atend) */
> - /* we should mark it as deferred */
> - break;
> - case CDSC_RESPONSE_CANCEL:
> - /* ignore it */
> - break;
> - case CDSC_RESPONSE_IGNORE_ALL:
> - return CDSC_NOTDSC;
> + if (dsc->scan_section == scan_trailer)
> + dsc_unknown(dsc);
> + else {
> + int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line,
> + dsc->line_length);
> + switch (rc) {
> + case CDSC_RESPONSE_OK:
> + /* assume (atend) */
> + /* we should mark it as deferred */
> + break;
> + case CDSC_RESPONSE_CANCEL:
> + /* ignore it */
> + break;
> + case CDSC_RESPONSE_IGNORE_ALL:
> + return CDSC_NOTDSC;
> + }
> }
> }
> else if (COMPARE(p, "(atend)")) {
> + if (dsc->scan_section == scan_trailer)
> + dsc_unknown(dsc);
> /* do nothing */
> /* we should mark it as deferred */
> }
> @@ -3266,6 +3298,10 @@
> * %%Trailer
> * %%EOF
> * %%BoundingBox:
> + * %%CropBox:
> + * %%HiResBoundingBox:
> + * %%DocumentCustomColors:
> + * %%DocumentProcessColors:
> * %%Orientation:
> * %%Pages:
> * %%PageOrder:
> @@ -3416,6 +3452,16 @@
> dsc->id = CDSC_DOCUMENTSUPPLIEDFONTS;
> /* ignore */
> }
> + else if (IS_DSC(line, "%%DocumentProcessColors:")) {
> + dsc->id = CDSC_DOCUMENTPROCESSCOLORS;
> + if (dsc_parse_process_colours(dsc) != CDSC_OK)
> + dsc->id = CDSC_UNKNOWNDSC;
> + }
> + else if (IS_DSC(line, "%%DocumentCustomColors:")) {
> + dsc->id = CDSC_DOCUMENTCUSTOMCOLORS;
> + if (dsc_parse_custom_colours(dsc) != CDSC_OK)
> + dsc->id = CDSC_UNKNOWNDSC;
> + }
> else {
> /* All other DSC comments are unknown, but not an error */
> dsc->id = CDSC_UNKNOWNDSC;
> @@ -3521,7 +3567,7 @@
> len = slen-1;
> while ( (i<len) && IS_WHITE(line[i]))
> i++; /* skip leading spaces */
> - if (line[i]=='(') {
> + if ((i < len) && (line[i]=='(')) {
> quoted = TRUE;
> instring++;
> i++; /* don't copy outside () */
> @@ -3691,7 +3737,7 @@
> i--;
> }
> while (i > 0) {
> - if (!isdigit(p[-1]))
> + if (!isdigit((int)p[-1]))
> break;
> p--;
> i--;
> @@ -4153,6 +4199,16 @@
> break;
> }
> }
> + while (IS_WHITE(dsc->line[n]))
> + n++;
> + if (COMPARE(dsc->line+n, "(atend)")) {
> + if (dsc->scan_section == scan_comments)
> + blank_line = TRUE;
> + else {
> + dsc_unknown(dsc);
> + return CDSC_NOTDSC;
> + }
> + }
>
> if (!blank_line) {
> do {
> @@ -4161,7 +4217,8 @@
> n+=i;
> if (i && strlen(colourname)) {
> if ((pcolour = dsc_find_colour(dsc, colourname)) == NULL) {
> - pcolour = (CDSCCOLOUR *)malloc(sizeof(CDSCCOLOUR));
> + pcolour = (CDSCCOLOUR *)
> + dsc_memalloc(dsc, sizeof(CDSCCOLOUR));
> if (pcolour == NULL)
> return CDSC_ERROR; /* out of memory */
> memset(pcolour, 0, sizeof(CDSCCOLOUR));
> @@ -4243,6 +4300,16 @@
> break;
> }
> }
> + while (IS_WHITE(dsc->line[n]))
> + n++;
> + if (COMPARE(dsc->line+n, "(atend)")) {
> + if (dsc->scan_section == scan_comments)
> + blank_line = TRUE;
> + else {
> + dsc_unknown(dsc);
> + return CDSC_NOTDSC;
> + }
> + }
>
> if (!blank_line) {
> do {
> @@ -4251,7 +4318,8 @@
> n+=i;
> if (i && strlen(colourname)) {
> if ((pcolour = dsc_find_colour(dsc, colourname)) == NULL) {
> - pcolour = (CDSCCOLOUR *)malloc(sizeof(CDSCCOLOUR));
> + pcolour = (CDSCCOLOUR *)
> + dsc_memalloc(dsc, sizeof(CDSCCOLOUR));
> if (pcolour == NULL)
> return CDSC_ERROR; /* out of memory */
> memset(pcolour, 0, sizeof(CDSCCOLOUR));
> @@ -4323,7 +4391,8 @@
> n+=i;
> if (i && strlen(colourname)) {
> if ((pcolour = dsc_find_colour(dsc, colourname)) == NULL) {
> - pcolour = (CDSCCOLOUR *)malloc(sizeof(CDSCCOLOUR));
> + pcolour = (CDSCCOLOUR *)
> + dsc_memalloc(dsc, sizeof(CDSCCOLOUR));
> if (pcolour == NULL)
> return CDSC_ERROR; /* out of memory */
> memset(pcolour, 0, sizeof(CDSCCOLOUR));
> @@ -4395,7 +4464,8 @@
> n+=i;
> if (i && strlen(colourname)) {
> if ((pcolour = dsc_find_colour(dsc, colourname)) == NULL) {
> - pcolour = (CDSCCOLOUR *)malloc(sizeof(CDSCCOLOUR));
> + pcolour = (CDSCCOLOUR *)
> + dsc_memalloc(dsc, sizeof(CDSCCOLOUR));
> if (pcolour == NULL)
> return CDSC_ERROR; /* out of memory */
> memset(pcolour, 0, sizeof(CDSCCOLOUR));