mirror of https://github.com/postgres/postgres
Offer pnstrdup to frontend code
We already had it on the backend. Frontend can also use it now. Discussion: https://postgr.es/m/20191204144021.GA17976@alvherre.pgsql
This commit is contained in:
parent
b1abfec825
commit
0b9466fce2
|
@ -114,8 +114,7 @@ split_path(const char *path, char **dir, char **fname)
|
||||||
/* directory path */
|
/* directory path */
|
||||||
if (sep != NULL)
|
if (sep != NULL)
|
||||||
{
|
{
|
||||||
*dir = pg_strdup(path);
|
*dir = pnstrdup(path, sep - path);
|
||||||
(*dir)[(sep - path) + 1] = '\0'; /* no strndup */
|
|
||||||
*fname = pg_strdup(sep + 1);
|
*fname = pg_strdup(sep + 1);
|
||||||
}
|
}
|
||||||
/* local directory */
|
/* local directory */
|
||||||
|
|
|
@ -270,13 +270,10 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
|
||||||
/* execute command */
|
/* execute command */
|
||||||
case '`':
|
case '`':
|
||||||
{
|
{
|
||||||
FILE *fd;
|
int cmdend = strcspn(p + 1, "`");
|
||||||
char *file = pg_strdup(p + 1);
|
char *file = pnstrdup(p + 1, cmdend);
|
||||||
int cmdend;
|
FILE *fd = popen(file, "r");
|
||||||
|
|
||||||
cmdend = strcspn(file, "`");
|
|
||||||
file[cmdend] = '\0';
|
|
||||||
fd = popen(file, "r");
|
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
if (fgets(buf, sizeof(buf), fd) == NULL)
|
if (fgets(buf, sizeof(buf), fd) == NULL)
|
||||||
|
@ -295,13 +292,10 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
|
||||||
/* interpolate variable */
|
/* interpolate variable */
|
||||||
case ':':
|
case ':':
|
||||||
{
|
{
|
||||||
char *name;
|
int nameend = strcspn(p + 1, ":");
|
||||||
|
char *name = pnstrdup(p + 1, nameend);
|
||||||
const char *val;
|
const char *val;
|
||||||
int nameend;
|
|
||||||
|
|
||||||
name = pg_strdup(p + 1);
|
|
||||||
nameend = strcspn(name, ":");
|
|
||||||
name[nameend] = '\0';
|
|
||||||
val = GetVariable(pset.vars, name);
|
val = GetVariable(pset.vars, name);
|
||||||
if (val)
|
if (val)
|
||||||
strlcpy(buf, val, sizeof(buf));
|
strlcpy(buf, val, sizeof(buf));
|
||||||
|
|
|
@ -353,8 +353,7 @@ splitTableColumnsSpec(const char *spec, int encoding,
|
||||||
else
|
else
|
||||||
cp += PQmblen(cp, encoding);
|
cp += PQmblen(cp, encoding);
|
||||||
}
|
}
|
||||||
*table = pg_strdup(spec);
|
*table = pnstrdup(spec, cp - spec);
|
||||||
(*table)[cp - spec] = '\0'; /* no strndup */
|
|
||||||
*columns = cp;
|
*columns = cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,33 @@ pstrdup(const char *in)
|
||||||
return pg_strdup(in);
|
return pg_strdup(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
pnstrdup(const char *in, Size size)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!in)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
_("cannot duplicate null pointer (internal error)\n"));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strnlen(in, size);
|
||||||
|
tmp = malloc(len + 1);
|
||||||
|
if (tmp == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("out of memory\n"));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tmp, in, len);
|
||||||
|
tmp[len] = '\0';
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
repalloc(void *pointer, Size size)
|
repalloc(void *pointer, Size size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,7 @@ extern void pg_free(void *pointer);
|
||||||
|
|
||||||
/* Equivalent functions, deliberately named the same as backend functions */
|
/* Equivalent functions, deliberately named the same as backend functions */
|
||||||
extern char *pstrdup(const char *in);
|
extern char *pstrdup(const char *in);
|
||||||
|
extern char *pnstrdup(const char *in, Size size);
|
||||||
extern void *palloc(Size size);
|
extern void *palloc(Size size);
|
||||||
extern void *palloc0(Size size);
|
extern void *palloc0(Size size);
|
||||||
extern void *palloc_extended(Size size, int flags);
|
extern void *palloc_extended(Size size, int flags);
|
||||||
|
|
|
@ -175,25 +175,6 @@ deccopy(decimal *src, decimal *target)
|
||||||
memcpy(target, src, sizeof(decimal));
|
memcpy(target, src, sizeof(decimal));
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
|
||||||
ecpg_strndup(const char *str, size_t len)
|
|
||||||
{
|
|
||||||
size_t real_len = strlen(str);
|
|
||||||
int use_len = (int) ((real_len > len) ? len : real_len);
|
|
||||||
|
|
||||||
char *new = malloc(use_len + 1);
|
|
||||||
|
|
||||||
if (new)
|
|
||||||
{
|
|
||||||
memcpy(new, str, use_len);
|
|
||||||
new[use_len] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
errno = ENOMEM;
|
|
||||||
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
deccvasc(const char *cp, int len, decimal *np)
|
deccvasc(const char *cp, int len, decimal *np)
|
||||||
{
|
{
|
||||||
|
@ -205,7 +186,7 @@ deccvasc(const char *cp, int len, decimal *np)
|
||||||
if (risnull(CSTRINGTYPE, cp))
|
if (risnull(CSTRINGTYPE, cp))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
str = ecpg_strndup(cp, len); /* decimal_in always converts the complete
|
str = pnstrdup(cp, len); /* decimal_in always converts the complete
|
||||||
* string */
|
* string */
|
||||||
if (!str)
|
if (!str)
|
||||||
ret = ECPG_INFORMIX_NUM_UNDERFLOW;
|
ret = ECPG_INFORMIX_NUM_UNDERFLOW;
|
||||||
|
|
Loading…
Reference in New Issue