mirror of
https://github.com/postgres/postgres.git
synced 2025-08-24 09:27:52 +03:00
Prevent integer overflows during units conversion when displaying a GUC
variable that has units. Per report from Stefan Kaltenbrunner. Backport to 8.2. I also backported my patch of 2007-06-21 that prevented comparable overflows on the input side, since that now seems to have enough field track record to be back-patched safely. That patch included addition of hints listing the available unit names, which I did not bother to strip out of it --- this will make a little more work for the translators, but they can copy the translation from 8.3, and anyway an untranslated hint is better than no hint.
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.432.2.1 2008/05/26 18:54:36 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.432.2.2 2008/07/06 19:48:53 tgl Exp $
|
||||||
*
|
*
|
||||||
*--------------------------------------------------------------------
|
*--------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@@ -5824,10 +5824,18 @@ _ShowOption(struct config_generic * record, bool use_units)
|
|||||||
val = (*conf->show_hook) ();
|
val = (*conf->show_hook) ();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char unit[4];
|
/*
|
||||||
int result = *conf->variable;
|
* Use int64 arithmetic to avoid overflows in units
|
||||||
|
* conversion. If INT64_IS_BUSTED we might overflow
|
||||||
|
* anyway and print bogus answers, but there are few
|
||||||
|
* enough such machines that it doesn't seem worth
|
||||||
|
* trying harder.
|
||||||
|
*/
|
||||||
|
int64 result = *conf->variable;
|
||||||
|
const char *unit;
|
||||||
|
|
||||||
if (use_units && result > 0 && (record->flags & GUC_UNIT_MEMORY))
|
if (use_units && result > 0 &&
|
||||||
|
(record->flags & GUC_UNIT_MEMORY))
|
||||||
{
|
{
|
||||||
switch (record->flags & GUC_UNIT_MEMORY)
|
switch (record->flags & GUC_UNIT_MEMORY)
|
||||||
{
|
{
|
||||||
@@ -5842,19 +5850,20 @@ _ShowOption(struct config_generic * record, bool use_units)
|
|||||||
if (result % KB_PER_GB == 0)
|
if (result % KB_PER_GB == 0)
|
||||||
{
|
{
|
||||||
result /= KB_PER_GB;
|
result /= KB_PER_GB;
|
||||||
strcpy(unit, "GB");
|
unit = "GB";
|
||||||
}
|
}
|
||||||
else if (result % KB_PER_MB == 0)
|
else if (result % KB_PER_MB == 0)
|
||||||
{
|
{
|
||||||
result /= KB_PER_MB;
|
result /= KB_PER_MB;
|
||||||
strcpy(unit, "MB");
|
unit = "MB";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(unit, "kB");
|
unit = "kB";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (use_units && result > 0 && (record->flags & GUC_UNIT_TIME))
|
else if (use_units && result > 0 &&
|
||||||
|
(record->flags & GUC_UNIT_TIME))
|
||||||
{
|
{
|
||||||
switch (record->flags & GUC_UNIT_TIME)
|
switch (record->flags & GUC_UNIT_TIME)
|
||||||
{
|
{
|
||||||
@@ -5869,33 +5878,33 @@ _ShowOption(struct config_generic * record, bool use_units)
|
|||||||
if (result % MS_PER_D == 0)
|
if (result % MS_PER_D == 0)
|
||||||
{
|
{
|
||||||
result /= MS_PER_D;
|
result /= MS_PER_D;
|
||||||
strcpy(unit, "d");
|
unit = "d";
|
||||||
}
|
}
|
||||||
else if (result % MS_PER_H == 0)
|
else if (result % MS_PER_H == 0)
|
||||||
{
|
{
|
||||||
result /= MS_PER_H;
|
result /= MS_PER_H;
|
||||||
strcpy(unit, "h");
|
unit = "h";
|
||||||
}
|
}
|
||||||
else if (result % MS_PER_MIN == 0)
|
else if (result % MS_PER_MIN == 0)
|
||||||
{
|
{
|
||||||
result /= MS_PER_MIN;
|
result /= MS_PER_MIN;
|
||||||
strcpy(unit, "min");
|
unit = "min";
|
||||||
}
|
}
|
||||||
else if (result % MS_PER_S == 0)
|
else if (result % MS_PER_S == 0)
|
||||||
{
|
{
|
||||||
result /= MS_PER_S;
|
result /= MS_PER_S;
|
||||||
strcpy(unit, "s");
|
unit = "s";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(unit, "ms");
|
unit = "ms";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strcpy(unit, "");
|
unit = "";
|
||||||
|
|
||||||
snprintf(buffer, sizeof(buffer), "%d%s",
|
snprintf(buffer, sizeof(buffer), INT64_FORMAT "%s",
|
||||||
(int) result, unit);
|
result, unit);
|
||||||
val = buffer;
|
val = buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user