summaryrefslogtreecommitdiffabout
path: root/lib/slist.c
authorSergey Poznyakoff <gray@gnu.org>2018-08-15 19:22:31 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2018-08-15 19:22:31 (GMT)
commit7a40b7873bd666809183cdd952d6e2a8f1870981 (patch) (side-by-side diff)
tree0ae71532dc78f597b717152b564d6681d1ad832a /lib/slist.c
parent988b8e27f5df26d7e9f6fd7984677873ca1c40cb (diff)
downloadpam-modules-7a40b7873bd666809183cdd952d6e2a8f1870981.tar.gz
pam-modules-7a40b7873bd666809183cdd952d6e2a8f1870981.tar.bz2
Major cleanup
* lib/graypam.h (gray_pam_init) (gray_raise,gray_malloc,gray_zalloc,gray_calloc) (gray_realloc,gray_strdup): Remove. (gray_slist_err,gray_slist_clrerr): New functions. (gray_slist_append,gray_slist_append_char): Return ssize_t. (gray_slist_coalesce): Likewise. (gray_slist_grow_backslash_num) (gray_slist_grow_backslash): Return int. (errno_to_pam): New function. (gray_set_transform_expr): Return int. * lib/mem.c (gray_raise,gray_malloc,gray_zalloc,gray_calloc) (gray_realloc,gray_strdup): Remove. (gray_2nrealloc): Rewrite. * lib/base64.c: Check return from gray_slist_append_char * lib/env.c: Check return values from gray_slist functions * lib/ldappass.c: Likewise. * lib/slist.c (gray_slist_bucket) <ec>: New member. (gray_slist_err,gray_slist_clrerr): New functions. (gray_slist_append,gray_slist_append_char): Return ssize_t. (gray_slist_coalesce): Likewise. (gray_slist_grow_backslash_num) (gray_slist_grow_backslash): Return int. * lib/transform.c: Use standard memory allocation functions. * pam_ldaphome/pam_ldaphome.c: Likewise. * pam_innetgr/pam_innetgr.c: Likewise. * pam_log/pam_log.c: Likewise. * pam_regex/pam_regex.c: Likewise. * pam_sql/pam_mysql.c: Likewise. * pam_sql/pam_pgsql.c: Likewise.
Diffstat (limited to 'lib/slist.c') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/slist.c127
1 files changed, 88 insertions, 39 deletions
diff --git a/lib/slist.c b/lib/slist.c
index b110350..46e516e 100644
--- a/lib/slist.c
+++ b/lib/slist.c
@@ -28,38 +28,47 @@ struct gray_slist_bucket {
struct gray_slist {
struct gray_slist_bucket *head, *tail;
struct gray_slist_bucket *free;
+ int ec; /* error code */
};
static struct gray_slist_bucket *
alloc_bucket(size_t size)
{
- struct gray_slist_bucket *p = gray_malloc(sizeof(*p) + size);
- p->buf = (char*)(p + 1);
- p->level = 0;
- p->size = size;
- p->next = NULL;
+ struct gray_slist_bucket *p = malloc(sizeof(*p) + size);
+ if (p) {
+ p->buf = (char*)(p + 1);
+ p->level = 0;
+ p->size = size;
+ p->next = NULL;
+ }
return p;
}
-static void
+static int
alloc_pool(gray_slist_t slist, size_t size)
{
struct gray_slist_bucket *p = alloc_bucket(GRAY_SLIST_BUCKET_SIZE);
+ if (!p) {
+ slist->ec = errno;
+ return 1;
+ }
if (slist->tail)
slist->tail->next = p;
else
slist->head = p;
slist->tail = p;
+ return 0;
}
-static size_t
+static ssize_t
copy_chars(gray_slist_t slist, const char *str, size_t n)
{
size_t rest;
-
- if (!slist->head || slist->tail->level == slist->tail->size)
- alloc_pool(slist, GRAY_SLIST_BUCKET_SIZE);
+ if (!slist->head || slist->tail->level == slist->tail->size) {
+ if (alloc_pool(slist, GRAY_SLIST_BUCKET_SIZE))
+ return -1;
+ }
rest = slist->tail->size - slist->tail->level;
if (n > rest)
n = rest;
@@ -69,13 +78,28 @@ copy_chars(gray_slist_t slist, const char *str, size_t n)
}
gray_slist_t
-gray_slist_create()
+gray_slist_create(void)
{
- gray_slist_t slist = gray_malloc(sizeof(*slist));
- slist->head = slist->tail = slist->free = 0;
+ gray_slist_t slist = malloc(sizeof(*slist));
+ if (slist) {
+ slist->head = slist->tail = slist->free = 0;
+ slist->ec = 0;
+ }
return slist;
}
+int
+gray_slist_err(gray_slist_t slist)
+{
+ return slist->ec;
+}
+
+void
+gray_slist_clerr(gray_slist_t slist)
+{
+ slist->ec = 0;
+}
+
void
gray_slist_clear(gray_slist_t slist)
{
@@ -84,14 +108,15 @@ gray_slist_clear(gray_slist_t slist)
slist->free = slist->head;
slist->head = slist->tail = NULL;
}
+ gray_slist_clerr(slist);
}
void
gray_slist_free(gray_slist_t *slist)
{
- struct gray_slist_bucket *p;
if (*slist) {
+ struct gray_slist_bucket *p;
gray_slist_clear(*slist);
for (p = (*slist)->free; p; ) {
struct gray_slist_bucket *next = p->next;
@@ -103,21 +128,27 @@ gray_slist_free(gray_slist_t *slist)
*slist = NULL;
}
-void
+ssize_t
gray_slist_append(gray_slist_t slist, const char *str, size_t n)
{
- const char *ptr = str;
- while (n) {
- size_t s = copy_chars(slist, ptr, n);
- ptr += s;
- n -= s;
+ ssize_t total;
+
+ if (slist->ec)
+ return -1;
+ total = 0;
+ while (total < n) {
+ ssize_t s = copy_chars(slist, str + total, n - total);
+ if (s == -1)
+ return -1;
+ total += s;
}
+ return total;
}
-void
+ssize_t
gray_slist_append_char(gray_slist_t slist, char c)
{
- gray_slist_append(slist, &c, 1);
+ return gray_slist_append(slist, &c, 1);
}
size_t
@@ -130,17 +161,22 @@ gray_slist_size(gray_slist_t slist)
return size;
}
-size_t
+ssize_t
gray_slist_coalesce(gray_slist_t slist)
{
size_t size;
- if (slist->head && slist->head->next == NULL)
+ if (slist->ec)
+ return -1;
+ else if (slist->head && slist->head->next == NULL)
size = slist->head->level;
else {
size = gray_slist_size(slist);
- struct gray_slist_bucket *bucket = alloc_bucket(size);
- struct gray_slist_bucket *p;
+ struct gray_slist_bucket *bucket, *p;
+
+ bucket = alloc_bucket(size);
+ if (!bucket)
+ return -1;
for (p = slist->head; p; ) {
struct gray_slist_bucket *next = p->next;
@@ -165,7 +201,10 @@ gray_slist_head(gray_slist_t slist, size_t *psize)
void *
gray_slist_finish(gray_slist_t slist)
{
- gray_slist_coalesce(slist);
+ if (slist->ec)
+ return NULL;
+ if (gray_slist_coalesce(slist) == -1)
+ return NULL;
gray_slist_clear(slist);
return slist->free->buf;
}
@@ -174,14 +213,16 @@ gray_slist_finish(gray_slist_t slist)
#define to_num(c) \
(isdigit(c) ? c - '0' : (isxdigit(c) ? toupper(c) - 'A' + 10 : 255 ))
-void
+int
gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
int len, int base)
{
int i;
int val = 0;
char *start = text;
-
+
+ if (slist->ec)
+ return -1;
if (text[0] == '\\') {
text++;
if (base == 16)
@@ -196,14 +237,17 @@ gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
}
if (i == 0) {
- gray_slist_append(slist, start, 1);
+ if (gray_slist_append(slist, start, 1) != 1)
+ return -1;
if (pend)
*pend = start + 1;
} else {
- gray_slist_append_char(slist, val);
+ if (gray_slist_append_char(slist, val) != 1)
+ return -1;
if (pend)
*pend = text + i;
}
+ return 0;
}
int
@@ -219,22 +263,27 @@ gray_decode_backslash(int c)
return c;
}
-void
+int
gray_slist_grow_backslash(gray_slist_t slist, char *text, char **endp)
{
if (text[1] == '\\' || (unsigned char)text[1] > 127) {
- gray_slist_append_char(slist, text[1]);
+ if (gray_slist_append_char(slist, text[1]) != 1)
+ return -1;
text += 2;
- } else if (isdigit(text[1]))
- gray_slist_grow_backslash_num(slist, text, &text, 3, 8);
- else if (text[1] == 'x' || text[1] == 'X')
- gray_slist_grow_backslash_num(slist, text, &text, 2, 16);
- else {
+ } else if (isdigit(text[1])) {
+ if (gray_slist_grow_backslash_num(slist, text, &text, 3, 8))
+ return -1;
+ } else if (text[1] == 'x' || text[1] == 'X') {
+ if (gray_slist_grow_backslash_num(slist, text, &text, 2, 16))
+ return -1;
+ } else {
int c = gray_decode_backslash(text[1]);
- gray_slist_append_char(slist, c);
+ if (gray_slist_append_char(slist, c) != 1)
+ return -1;
text += 2;
}
*endp = text;
+ return 0;
}

Return to:

Send suggestions and report system problems to the System administrator.