summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorNatanael Copa <natanael.copa@gmail.com>2010-10-14 06:35:08 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2010-10-14 15:00:01 +0200
commit2631ae8aab71c350273fa2d7a787bfcbff258029 (patch)
treefdfa842e63a6d36de14edad17f81157d9062b5d7 /libc
parent6e74339e7d762857579169068b060a4fd3f345c4 (diff)
getservice: fix handling of long lines
Don't try to be smart by dynamically realloc buffersize as it doesn't work. Instead, be simple and allocate a buffer big enough. This fixes a memory leak when calling getserv{ent,byname,byport} multiple times. To save memory we reduce number of max aliases. We seldomly will need more than 1 anyways. While here, fix segfault that happened if there were too many aliases. Signed-off-by: Natanael Copa <natanael.copa@gmail.com> Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Diffstat (limited to 'libc')
-rw-r--r--libc/inet/getservice.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c
index c38ff80ac..183099f5c 100644
--- a/libc/inet/getservice.c
+++ b/libc/inet/getservice.c
@@ -28,9 +28,11 @@ aliases: case sensitive optional space or tab separated list of other names
#include <bits/uClibc_mutex.h>
__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
-#define MAXALIASES 35
-#define BUFSZ (80) /* one line */
-#define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXALIASES))
+#define MINTOKENS 3
+#define MAXALIASES 8 /* we seldomly need more than 1 alias */
+#define MAXTOKENS (MINTOKENS + MAXALIASES + 1)
+#define BUFSZ (255) /* one line */
+#define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXTOKENS))
static parser_t *servp = NULL;
static struct servent serve;
@@ -65,10 +67,8 @@ libc_hidden_def(endservent)
int getservent_r(struct servent *result_buf,
char *buf, size_t buflen, struct servent **result)
{
- char **alias;
- char **serv_aliases;
char **tok = NULL;
- const size_t aliaslen = sizeof(*serv_aliases) * MAXALIASES;
+ const size_t aliaslen = sizeof(char *) * MAXTOKENS;
int ret = ERANGE;
*result = NULL;
@@ -87,13 +87,13 @@ int getservent_r(struct servent *result_buf,
servp->data_len = aliaslen;
servp->line_len = buflen - aliaslen;
/* <name>[[:space:]]<port>/<proto>[[:space:]][<aliases>] */
- if (!config_read(servp, &tok, MAXALIASES, 3, "# \t/", PARSE_NORMAL)) {
+ if (!config_read(servp, &tok, MAXTOKENS - 1, MINTOKENS, "# \t/", PARSE_NORMAL)) {
goto DONE;
}
result_buf->s_name = *(tok++);
result_buf->s_port = htons((u_short) atoi(*(tok++)));
result_buf->s_proto = *(tok++);
- result_buf->s_aliases = alias = serv_aliases = tok;
+ result_buf->s_aliases = tok;
*result = result_buf;
ret = 0;
DONE:
@@ -106,9 +106,8 @@ libc_hidden_def(getservent_r)
static void __initbuf(void)
{
- if (servbuf)
- servbuf_sz += BUFSZ;
- servbuf = realloc(servbuf, servbuf_sz);
+ if (!servbuf)
+ servbuf = malloc(SBUFSIZE);
if (!servbuf)
abort();
}
@@ -117,9 +116,8 @@ struct servent *getservent(void)
{
struct servent *result;
- do {
- __initbuf();
- } while (getservent_r(&serve, servbuf, servbuf_sz, &result) == ERANGE);
+ __initbuf();
+ getservent_r(&serve, servbuf, servbuf_sz, &result);
return result;
}
@@ -154,10 +152,8 @@ struct servent *getservbyname(const char *name, const char *proto)
{
struct servent *result;
- do {
- __initbuf();
- } while (getservbyname_r(name, proto, &serve, servbuf, servbuf_sz, &result)
- == ERANGE);
+ __initbuf();
+ getservbyname_r(name, proto, &serve, servbuf, servbuf_sz, &result);
return result;
}
@@ -187,10 +183,8 @@ struct servent *getservbyport(int port, const char *proto)
{
struct servent *result;
- do {
- __initbuf();
- } while (getservbyport_r(port, proto, &serve, servbuf, servbuf_sz, &result)
- == ERANGE);
+ __initbuf();
+ getservbyport_r(port, proto, &serve, servbuf, servbuf_sz, &result);
return result;
}
libc_hidden_def(getservbyport)