mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Change the way string relopts are allocated.
Don't try to allocate the default value for a string relopt in the same palloc chunk as the relopt_string struct. That didn't work too well if you added a built-in string relopt in the stringRelOpts array, as it's not possible to have an initializer for a variable length struct in C. This makes the code slightly simpler too. While we're at it, move the call to validator function in add_string_reloption to before the allocation, so that if someone does pass a bogus default value, we don't leak memory.
This commit is contained in:
@ -371,8 +371,6 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc)
|
|||||||
size_t size;
|
size_t size;
|
||||||
relopt_gen *newoption;
|
relopt_gen *newoption;
|
||||||
|
|
||||||
Assert(type != RELOPT_TYPE_STRING);
|
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
|
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
@ -386,6 +384,9 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc)
|
|||||||
case RELOPT_TYPE_REAL:
|
case RELOPT_TYPE_REAL:
|
||||||
size = sizeof(relopt_real);
|
size = sizeof(relopt_real);
|
||||||
break;
|
break;
|
||||||
|
case RELOPT_TYPE_STRING:
|
||||||
|
size = sizeof(relopt_string);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "unsupported option type");
|
elog(ERROR, "unsupported option type");
|
||||||
return NULL; /* keep compiler quiet */
|
return NULL; /* keep compiler quiet */
|
||||||
@ -474,45 +475,29 @@ void
|
|||||||
add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
|
add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
|
||||||
validate_string_relopt validator)
|
validate_string_relopt validator)
|
||||||
{
|
{
|
||||||
MemoryContext oldcxt;
|
|
||||||
relopt_string *newoption;
|
relopt_string *newoption;
|
||||||
int default_len = 0;
|
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
|
/* make sure the validator/default combination is sane */
|
||||||
|
if (validator)
|
||||||
|
(validator) (default_val);
|
||||||
|
|
||||||
if (default_val)
|
newoption = (relopt_string *) allocate_reloption(kinds, RELOPT_TYPE_STRING,
|
||||||
default_len = strlen(default_val);
|
name, desc);
|
||||||
|
|
||||||
newoption = palloc0(sizeof(relopt_string) + default_len);
|
|
||||||
|
|
||||||
newoption->gen.name = pstrdup(name);
|
|
||||||
if (desc)
|
|
||||||
newoption->gen.desc = pstrdup(desc);
|
|
||||||
else
|
|
||||||
newoption->gen.desc = NULL;
|
|
||||||
newoption->gen.kinds = kinds;
|
|
||||||
newoption->gen.namelen = strlen(name);
|
|
||||||
newoption->gen.type = RELOPT_TYPE_STRING;
|
|
||||||
newoption->validate_cb = validator;
|
newoption->validate_cb = validator;
|
||||||
if (default_val)
|
if (default_val)
|
||||||
{
|
{
|
||||||
strcpy(newoption->default_val, default_val);
|
newoption->default_val = MemoryContextStrdup(TopMemoryContext,
|
||||||
newoption->default_len = default_len;
|
default_val);
|
||||||
|
newoption->default_len = strlen(default_val);
|
||||||
newoption->default_isnull = false;
|
newoption->default_isnull = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newoption->default_val[0] = '\0';
|
newoption->default_val = "";
|
||||||
newoption->default_len = 0;
|
newoption->default_len = 0;
|
||||||
newoption->default_isnull = true;
|
newoption->default_isnull = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure the validator/default combination is sane */
|
|
||||||
if (newoption->validate_cb)
|
|
||||||
(newoption->validate_cb) (newoption->default_val);
|
|
||||||
|
|
||||||
MemoryContextSwitchTo(oldcxt);
|
|
||||||
|
|
||||||
add_reloption((relopt_gen *) newoption);
|
add_reloption((relopt_gen *) newoption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ typedef struct relopt_string
|
|||||||
int default_len;
|
int default_len;
|
||||||
bool default_isnull;
|
bool default_isnull;
|
||||||
validate_string_relopt validate_cb;
|
validate_string_relopt validate_cb;
|
||||||
char default_val[1]; /* variable length, zero-terminated */
|
char *default_val;
|
||||||
} relopt_string;
|
} relopt_string;
|
||||||
|
|
||||||
/* This is the table datatype for fillRelOptions */
|
/* This is the table datatype for fillRelOptions */
|
||||||
|
Reference in New Issue
Block a user