aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/ChangeLog11
-rw-r--r--common/b64dec.c32
-rw-r--r--common/b64enc.c22
-rw-r--r--common/http.c45
-rw-r--r--common/http.h1
-rw-r--r--common/util.h1
6 files changed, 90 insertions, 22 deletions
diff --git a/common/ChangeLog b/common/ChangeLog
index 3ce80cb1a..3b7506492 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,14 @@
+2011-01-20 Werner Koch <[email protected]>
+
+ * util.h (struct b64state): Add field LASTERR.
+ * b64enc.c (enc_start, b64enc_write, b64enc_finish): Handle
+ LASTERR. This is to make sure that we don't leak strduped data.
+ * b64dec.c (b64dec_start, b64dec_proc, b64dec_finish): Ditto.
+
+ * http.c (escape_data): New.
+ (insert_escapes): Implement using escape_data.
+ (http_escape_data): New.
+
2011-01-18 Werner Koch <[email protected]>
* iobuf.c (file_es_filter_ctx_t): New.
diff --git a/common/b64dec.c b/common/b64dec.c
index af223aef2..137dd7216 100644
--- a/common/b64dec.c
+++ b/common/b64dec.c
@@ -1,5 +1,5 @@
/* b64dec.c - Simple Base64 decoder.
- * Copyright (C) 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2008, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -72,16 +72,19 @@ b64dec_start (struct b64state *state, const char *title)
if (title)
{
if (!strncmp (title, "PGP", 3) && (!title[3] || title[3] == ' '))
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-
- state->title = xtrystrdup (title);
- if (!state->title)
- return gpg_error_from_syserror ();
- state->idx = s_init;
+ state->lasterr = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ else
+ {
+ state->title = xtrystrdup (title);
+ if (!state->title)
+ state->lasterr = gpg_error_from_syserror ();
+ else
+ state->idx = s_init;
+ }
}
else
state->idx = s_b64_0;
- return 0;
+ return state->lasterr;
}
@@ -96,12 +99,18 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length,
int pos = state->quad_count;
char *d, *s;
+ if (state->lasterr)
+ return state->lasterr;
+
if (state->stop_seen)
{
*r_nbytes = 0;
- return gpg_error (GPG_ERR_EOF);
+ state->lasterr = gpg_error (GPG_ERR_EOF);
+ xfree (state->title);
+ state->title = NULL;
+ return state->lasterr;
}
-
+
for (s=d=buffer; length && !state->stop_seen; length--, s++)
{
switch (ds)
@@ -210,6 +219,9 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length,
gpg_error_t
b64dec_finish (struct b64state *state)
{
+ if (state->lasterr)
+ return state->lasterr;
+
xfree (state->title);
state->title = NULL;
return state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0;
diff --git a/common/b64enc.c b/common/b64enc.c
index 1e277f4cb..5d616198e 100644
--- a/common/b64enc.c
+++ b/common/b64enc.c
@@ -1,5 +1,6 @@
/* b64enc.c - Simple Base64 encoder.
- * Copyright (C) 2001, 2003, 2004, 2008, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2004, 2008, 2010,
+ * 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -143,6 +144,7 @@ enc_start (struct b64state *state, FILE *fp, estream_t stream,
memset (state, 0, sizeof *state);
state->fp = fp;
state->stream = stream;
+ state->lasterr = 0;
if (title && !*title)
state->flags |= B64ENC_NO_LINEFEEDS;
else if (title)
@@ -154,9 +156,9 @@ enc_start (struct b64state *state, FILE *fp, estream_t stream,
}
state->title = xtrystrdup (title);
if (!state->title)
- return gpg_error_from_syserror ();
+ state->lasterr = gpg_error_from_syserror ();
}
- return 0;
+ return state->lasterr;
}
@@ -203,6 +205,8 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
int idx, quad_count;
const unsigned char *p;
+ if (state->lasterr)
+ return state->lasterr;
if (!nbytes)
{
@@ -285,7 +289,13 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
return 0;
write_error:
- return gpg_error_from_syserror ();
+ state->lasterr = gpg_error_from_syserror ();
+ if (state->title)
+ {
+ xfree (state->title);
+ state->title = NULL;
+ }
+ return state->lasterr;
}
@@ -297,6 +307,9 @@ b64enc_finish (struct b64state *state)
int idx, quad_count;
char tmp[4];
+ if (state->lasterr)
+ return state->lasterr;
+
if (!(state->flags & B64ENC_DID_HEADER))
goto cleanup;
@@ -404,6 +417,7 @@ b64enc_finish (struct b64state *state)
}
state->fp = NULL;
state->stream = NULL;
+ state->lasterr = err;
return err;
}
diff --git a/common/http.c b/common/http.c
index 3d7c463b5..4d3536114 100644
--- a/common/http.c
+++ b/common/http.c
@@ -1,6 +1,6 @@
/* http.c - HTTP protocol handler
- * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006,
- * 2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010,
+ * 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -742,14 +742,14 @@ remove_escapes (char *string)
}
-static int
-insert_escapes (char *buffer, const char *string,
- const char *special)
+static size_t
+escape_data (char *buffer, const void *data, size_t datalen,
+ const char *special)
{
- const unsigned char *s = (const unsigned char*)string;
- int n = 0;
+ const unsigned char *s;
+ size_t n = 0;
- for (; *s; s++)
+ for (s = data; datalen; s++, datalen--)
{
if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
{
@@ -771,6 +771,14 @@ insert_escapes (char *buffer, const char *string,
}
+static int
+insert_escapes (char *buffer, const char *string,
+ const char *special)
+{
+ return escape_data (buffer, string, strlen (string), special);
+}
+
+
/* Allocate a new string from STRING using standard HTTP escaping as
well as escaping of characters given in SPECIALS. A common pattern
for SPECIALS is "%;?&=". However it depends on the needs, for
@@ -792,6 +800,27 @@ http_escape_string (const char *string, const char *specials)
return buf;
}
+/* Allocate a new string from {DATA,DATALEN} using standard HTTP
+ escaping as well as escaping of characters given in SPECIALS. A
+ common pattern for SPECIALS is "%;?&=". However it depends on the
+ needs, for example "+" and "/: often needs to be escaped too.
+ Returns NULL on failure and sets ERRNO. */
+char *
+http_escape_data (const void *data, size_t datalen, const char *specials)
+{
+ int n;
+ char *buf;
+
+ n = escape_data (NULL, data, datalen, specials);
+ buf = xtrymalloc (n+1);
+ if (buf)
+ {
+ escape_data (buf, data, datalen, specials);
+ buf[n] = 0;
+ }
+ return buf;
+}
+
static uri_tuple_t
diff --git a/common/http.h b/common/http.h
index aaa2d3a13..7eecbc004 100644
--- a/common/http.h
+++ b/common/http.h
@@ -117,6 +117,7 @@ unsigned int http_get_status_code (http_t hd);
const char *http_get_header (http_t hd, const char *name);
char *http_escape_string (const char *string, const char *specials);
+char *http_escape_data (const void *data, size_t datalen, const char *specials);
#endif /*GNUPG_COMMON_HTTP_H*/
diff --git a/common/util.h b/common/util.h
index 1f7964fc4..f06701fc0 100644
--- a/common/util.h
+++ b/common/util.h
@@ -150,6 +150,7 @@ struct b64state
u32 crc;
int stop_seen:1;
int invalid_encoding:1;
+ gpg_error_t lasterr;
};
gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title);