Skip to content

Commit a07efcb

Browse files
Ranjan Kumartillkamppeter
authored andcommitted
Fix buffer size calculation and bounds checks in ppdEmitString
Update the Pass-1 buffer size estimation in ppdEmitString() to account for the maximum formatted length of floating-point custom parameters emitted by _ppdStrFormatd() ("%.12f"). Additionally, replace the unbounded memcpy() of option code strings in Pass-2 with strlcpy() and guard trailing newline writes against buffer end bounds so bufptr cannot advance past bufend. Signed-off-by: Ranjan Kumar <kumarranja@chromium.org>
1 parent 0598346 commit a07efcb

1 file changed

Lines changed: 12 additions & 10 deletions

File tree

‎ppd/ppd-emit.c‎

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ ppdEmitString(ppd_file_t *ppd, // I - PPD file record
669669
ppd_section_t section, // I - Section to write
670670
float min_order) // I - Lowest OrderDependency
671671
{
672-
int i, j, // Looping vars
672+
int i, // Looping vars
673673
count; // Number of choices
674674
ppd_choice_t **choices; // Choices
675675
ppd_size_t *size; // Custom page size
@@ -736,7 +736,7 @@ ppdEmitString(ppd_file_t *ppd, // I - PPD file record
736736
case PPD_CUSTOM_POINTS :
737737
case PPD_CUSTOM_REAL :
738738
case PPD_CUSTOM_INT :
739-
bufsize += 10;
739+
bufsize += 56; // "%.12f" of ±FLT_MAX <= 53 chars + '\n' + slack
740740
break;
741741

742742
case PPD_CUSTOM_PASSCODE :
@@ -760,7 +760,7 @@ ppdEmitString(ppd_file_t *ppd, // I - PPD file record
760760
DEBUG_puts("2ppdEmitString: Custom size set!");
761761

762762
bufsize += 37; // %%BeginFeature: *CustomPageSize True\n
763-
bufsize += 50; // Five 9-digit numbers + newline
763+
bufsize += 5 * 56; // 5 * ("%.12f" of ±FLT_MAX <= 53 chars + '\n' + slack)
764764
}
765765
else if (!_ppd_strcasecmp(choices[i]->choice, "Custom") &&
766766
(coption = ppdFindCustomOption(ppd,
@@ -785,7 +785,7 @@ ppdEmitString(ppd_file_t *ppd, // I - PPD file record
785785
case PPD_CUSTOM_POINTS :
786786
case PPD_CUSTOM_REAL :
787787
case PPD_CUSTOM_INT :
788-
bufsize += 10;
788+
bufsize += 56; // "%.12f" of ±FLT_MAX <= 53 chars + '\n' + slack
789789
break;
790790

791791
case PPD_CUSTOM_PASSCODE :
@@ -1045,7 +1045,8 @@ ppdEmitString(ppd_file_t *ppd, // I - PPD file record
10451045
for (pos = 0; pos < 5; pos ++)
10461046
{
10471047
bufptr = _ppdStrFormatd(bufptr, bufend, values[pos], loc);
1048-
*bufptr++ = '\n';
1048+
if (bufptr < bufend)
1049+
*bufptr++ = '\n';
10491050
}
10501051

10511052
if (!choices[i]->code)
@@ -1099,7 +1100,8 @@ ppdEmitString(ppd_file_t *ppd, // I - PPD file record
10991100
case PPD_CUSTOM_REAL :
11001101
bufptr = _ppdStrFormatd(bufptr, bufend,
11011102
cparam->current.custom_real, loc);
1102-
*bufptr++ = '\n';
1103+
if (bufptr < bufend)
1104+
*bufptr++ = '\n';
11031105
break;
11041106

11051107
case PPD_CUSTOM_INT :
@@ -1146,11 +1148,11 @@ ppdEmitString(ppd_file_t *ppd, // I - PPD file record
11461148

11471149
if (choices[i]->code && choices[i]->code[0])
11481150
{
1149-
j = (int)strlen(choices[i]->code);
1150-
memcpy(bufptr, choices[i]->code, (size_t)j);
1151-
bufptr += j;
1151+
size_t codelen = strlen(choices[i]->code);
1152+
strlcpy(bufptr, choices[i]->code, (size_t)(bufend - bufptr + 1));
1153+
bufptr += strlen(bufptr);
11521154

1153-
if (choices[i]->code[j - 1] != '\n')
1155+
if (choices[i]->code[codelen - 1] != '\n' && bufptr < bufend)
11541156
*bufptr++ = '\n';
11551157
}
11561158

0 commit comments

Comments
 (0)