diff options
author | Tom Lane | 2008-07-23 17:29:53 +0000 |
---|---|---|
committer | Tom Lane | 2008-07-23 17:29:53 +0000 |
commit | 3364c4afafb21d2e6cb4b77256984aad2481c9a4 (patch) | |
tree | 5bc42290c68f73c5299682adcdc64836eadd0271 | |
parent | c8b0d53c711e9ee094f2ba8b04d542021682b1b7 (diff) |
Use guc.c's parse_int() instead of pg_atoi() to parse fillfactor in
default_reloptions(). The previous coding was really a bug because pg_atoi()
will always throw elog on bad input data, whereas default_reloptions is not
supposed to complain about bad input unless its validate parameter is true.
Right now you could only expose the problem by hand-modifying
pg_class.reloptions into an invalid state, so it doesn't seem worth
back-patching; but we should get it right in HEAD because there might be other
situations in future. Noted while studying GIN fast-update patch.
-rw-r--r-- | src/backend/access/common/reloptions.c | 14 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 4 | ||||
-rw-r--r-- | src/include/utils/guc.h | 3 |
3 files changed, 17 insertions, 4 deletions
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 532190abe0..db39d90d02 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -21,6 +21,7 @@ #include "nodes/makefuncs.h" #include "utils/array.h" #include "utils/builtins.h" +#include "utils/guc.h" #include "utils/rel.h" @@ -287,7 +288,7 @@ default_reloptions(Datum reloptions, bool validate, { static const char *const default_keywords[1] = {"fillfactor"}; char *values[1]; - int32 fillfactor; + int fillfactor; StdRdOptions *result; parseRelOptions(reloptions, 1, default_keywords, values, validate); @@ -300,7 +301,16 @@ default_reloptions(Datum reloptions, bool validate, if (values[0] == NULL) return NULL; - fillfactor = pg_atoi(values[0], sizeof(int32), 0); + if (!parse_int(values[0], &fillfactor, 0, NULL)) + { + if (validate) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("fillfactor must be an integer: \"%s\"", + values[0]))); + return NULL; + } + if (fillfactor < minFillfactor || fillfactor > 100) { if (validate) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 56c42eebb2..1615119b6d 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -4115,7 +4115,7 @@ parse_bool(const char *value, bool *result) * If not okay and hintmsg is not NULL, *hintmsg is set to a suitable * HINT message, or NULL if no hint provided. */ -static bool +bool parse_int(const char *value, int *result, int flags, const char **hintmsg) { int64 val; @@ -4322,7 +4322,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg) * If the string parses okay, return true, else false. * If okay and result is not NULL, return the value in *result. */ -static bool +bool parse_real(const char *value, double *result) { double val; diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 004df9fdd2..5c723b2476 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -224,6 +224,9 @@ extern void AtEOXact_GUC(bool isCommit, int nestLevel); extern void BeginReportingGUCOptions(void); extern void ParseLongOption(const char *string, char **name, char **value); extern bool parse_bool(const char *value, bool *result); +extern bool parse_int(const char *value, int *result, int flags, + const char **hintmsg); +extern bool parse_real(const char *value, double *result); extern bool set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal); |