Skip to content

Commit 24ea53d

Browse files
committed
Avoid overflow in fe_utils' printTable()
The original code would miscalculate the total number of cells when the table to print has more than ~4 billion cells, leading to an unnecessary error. Repair by changing some computations to be 64-bits wide. Add some necessary overflow checks. Author: Hongxu Ma <interma@outlook.com> Discussion: https://postgr.es/m/TYBP286MB0351B057B101C90D7C1239E6B4E2A@TYBP286MB0351.JPNP286.PROD.OUTLOOK.COM
1 parent e83aa9f commit 24ea53d

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

src/fe_utils/print.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,14 +3172,25 @@ void
31723172
printTableInit(printTableContent *const content, const printTableOpt *opt,
31733173
const char *title, const int ncolumns, const int nrows)
31743174
{
3175+
uint64 total_cells;
3176+
31753177
content->opt = opt;
31763178
content->title = title;
31773179
content->ncolumns = ncolumns;
31783180
content->nrows = nrows;
31793181

31803182
content->headers = pg_malloc0((ncolumns + 1) * sizeof(*content->headers));
31813183

3182-
content->cells = pg_malloc0((ncolumns * nrows + 1) * sizeof(*content->cells));
3184+
total_cells = (uint64) ncolumns * nrows;
3185+
/* Catch possible overflow. Using >= here allows adding 1 below */
3186+
if (total_cells >= SIZE_MAX / sizeof(*content->cells))
3187+
{
3188+
fprintf(stderr, _("Cannot print table contents: number of cells %lld is equal to or exceeds maximum %lld.\n"),
3189+
(long long int) total_cells,
3190+
(long long int) (SIZE_MAX / sizeof(*content->cells)));
3191+
exit(EXIT_FAILURE);
3192+
}
3193+
content->cells = pg_malloc0((total_cells + 1) * sizeof(*content->cells));
31833194

31843195
content->cellmustfree = NULL;
31853196
content->footers = NULL;
@@ -3249,15 +3260,17 @@ void
32493260
printTableAddCell(printTableContent *const content, char *cell,
32503261
const bool translate, const bool mustfree)
32513262
{
3263+
uint64 total_cells;
3264+
32523265
#ifndef ENABLE_NLS
32533266
(void) translate; /* unused parameter */
32543267
#endif
32553268

3256-
if (content->cellsadded >= content->ncolumns * content->nrows)
3269+
total_cells = (uint64) content->ncolumns * content->nrows;
3270+
if (content->cellsadded >= total_cells)
32573271
{
3258-
fprintf(stderr, _("Cannot add cell to table content: "
3259-
"total cell count of %d exceeded.\n"),
3260-
content->ncolumns * content->nrows);
3272+
fprintf(stderr, _("Cannot add cell to table content: total cell count of %lld exceeded.\n"),
3273+
(long long int) total_cells);
32613274
exit(EXIT_FAILURE);
32623275
}
32633276

@@ -3273,7 +3286,7 @@ printTableAddCell(printTableContent *const content, char *cell,
32733286
{
32743287
if (content->cellmustfree == NULL)
32753288
content->cellmustfree =
3276-
pg_malloc0((content->ncolumns * content->nrows + 1) * sizeof(bool));
3289+
pg_malloc0((total_cells + 1) * sizeof(bool));
32773290

32783291
content->cellmustfree[content->cellsadded] = true;
32793292
}
@@ -3341,9 +3354,10 @@ printTableCleanup(printTableContent *const content)
33413354
{
33423355
if (content->cellmustfree)
33433356
{
3344-
int i;
3357+
uint64 total_cells;
33453358

3346-
for (i = 0; i < content->nrows * content->ncolumns; i++)
3359+
total_cells = (uint64) content->ncolumns * content->nrows;
3360+
for (uint64 i = 0; i < total_cells; i++)
33473361
{
33483362
if (content->cellmustfree[i])
33493363
free(unconstify(char *, content->cells[i]));

src/include/fe_utils/print.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ typedef struct printTableContent
171171
const char **cells; /* NULL-terminated array of cell content
172172
* strings */
173173
const char **cell; /* Pointer to the last added cell */
174-
long cellsadded; /* Number of cells added this far */
174+
uint64 cellsadded; /* Number of cells added this far */
175175
bool *cellmustfree; /* true for cells that need to be free()d */
176176
printTableFooter *footers; /* Pointer to the first footer */
177177
printTableFooter *footer; /* Pointer to the last added footer */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy