diff --git a/src/cups-pdf.c b/src/cups-pdf.c index 9a8a8b1..abda1d5 100644 --- a/src/cups-pdf.c +++ b/src/cups-pdf.c @@ -759,6 +759,32 @@ static char *fgets2(char *fbuffer, int fbufsize, FILE *ffpsrc) { return result; } +/* Fill the buffer with \n in order to be able to process embedded nulls on the line. */ +static char *fgets_with_null(char *fbuffer, int fbufsize, FILE *ffpsrc) { + memset(fbuffer, '\n', BUFSIZE); + return fgets2(fbuffer, fbufsize, ffpsrc); +} + +/* Locate the last null character and write the full line, including embedded nulls. + The line must has been read with fgets_with_null. */ +static void fputs_with_null(const char *restrict s, FILE *restrict stream) { + char *end; + size_t count; + + end = memrchr(s, '\0', BUFSIZE); + if (end == NULL) { + log_event(CPERROR, "failed to find end of string"); + return; + } + + count = end - s; + if (count == 0) { + return; + } + + fwrite(s, sizeof(char), end - s, stream); +} + static int preparespoolfile(FILE *fpsrc, char *spoolfile, char *title, char *cmdtitle, int job, struct passwd *passwd) { cp_string buffer; @@ -787,16 +813,16 @@ static int preparespoolfile(FILE *fpsrc, char *spoolfile, char *title, char *cmd log_event(CPSTATUS, "***Experimental Option: FixNewlines"); else log_event(CPDEBUG, "using traditional fgets"); - while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) { + while (fgets_with_null(buffer, BUFSIZE, fpsrc) != NULL) { if (!strncmp(buffer, "%!", 2) && strncmp(buffer, "%!PS-AdobeFont", 14)) { log_event(CPDEBUG, "found beginning of postscript code: %s", buffer); break; } } log_event(CPDEBUG, "now extracting postscript code"); - (void) fputs(buffer, fpdest); - while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) { - (void) fputs(buffer, fpdest); + (void) fputs_with_null(buffer, fpdest); + while (fgets_with_null(buffer, BUFSIZE, fpsrc) != NULL) { + (void) fputs_with_null(buffer, fpdest); if (!is_title && !rec_depth) { memset(title, 0, BUFSIZE); if (sscanf(buffer, "%%%%Title: %"TBUFSIZE"c", title)==1) {