diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-03-22 17:33:59 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-03-22 17:33:59 +0000 |
commit | 728a3f8c8a1098dea35732c3ad59fb8d60ee8e0f (patch) | |
tree | 40c5157956a84df91ed09c8d620cf2d83626941e /src/util | |
parent | 8bcc7b48e6e2e07ee5ba4da0e0c93714c6698c4d (diff) |
-fixing string decoder issue for input sizes of a multiple of 5
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/strings.c | 25 | ||||
-rw-r--r-- | src/util/test_strings_to_data.c | 51 |
2 files changed, 44 insertions, 32 deletions
diff --git a/src/util/strings.c b/src/util/strings.c index e9b5b3c210..8bbc904bc2 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -817,7 +817,7 @@ GNUNET_STRINGS_data_to_string (const void *data, size_t size, char *out, size_t * @param enc the encoding * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) * @param out location where to store the decoded data - * @param out_size sizeof the output buffer + * @param out_size size of the output buffer * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding */ int @@ -831,31 +831,40 @@ GNUNET_STRINGS_string_to_data (const char *enc, size_t enclen, int ret; int shift; unsigned char *uout; - int encoded_len = out_size * 8; + unsigned int encoded_len = out_size * 8; + if (0 == enclen) + { + if (0 == out_size) + return GNUNET_OK; + return GNUNET_SYSERR; + } uout = out; - if (encoded_len % 5 > 0) + wpos = out_size; + rpos = enclen; + if ((encoded_len % 5) > 0) { vbit = encoded_len % 5; /* padding! */ shift = 5 - vbit; + bits = (ret = getValue__ (enc[--rpos])) >> (5 - (encoded_len % 5)); } else { - vbit = 0; + vbit = 5; shift = 0; + bits = (ret = getValue__ (enc[--rpos])); } if ((encoded_len + shift) / 5 != enclen) return GNUNET_SYSERR; - - wpos = out_size; - rpos = enclen; - bits = (ret = getValue__ (enc[--rpos])) >> (5 - encoded_len % 5); if (-1 == ret) return GNUNET_SYSERR; while (wpos > 0) { if (0 == rpos) + { + GNUNET_break (0); return GNUNET_SYSERR; + } bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits; if (-1 == ret) return GNUNET_SYSERR; diff --git a/src/util/test_strings_to_data.c b/src/util/test_strings_to_data.c index d98cd85782..7397735583 100644 --- a/src/util/test_strings_to_data.c +++ b/src/util/test_strings_to_data.c @@ -30,30 +30,33 @@ int main (int argc, char *argv[]) { - GNUNET_log_setup ("util", "DEBUG", NULL); - char *conv; - char buf[255]; - char *end; - struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded src; - struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded dest; - - memset (&src, '\1', sizeof (src)); - memset (&dest, '\2', sizeof (dest)); - - end = GNUNET_STRINGS_data_to_string (&src, sizeof (src), buf, sizeof (buf)); - end[0] = '\0'; - fprintf (stderr, "Key `%s'\n",buf); - GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_public_key_from_string (buf, strlen (buf), &dest)); - - conv = GNUNET_CRYPTO_ecc_public_key_to_string (&src); - GNUNET_assert (NULL != conv); - fprintf (stderr, "Key `%s'\n",conv); - - - GNUNET_assert (GNUNET_OK == GNUNET_STRINGS_string_to_data (conv, strlen (conv), (unsigned char *) &dest, sizeof (dest))); - GNUNET_assert (0 == memcmp (&src, &dest, sizeof (dest))); - - return 0; + char buf[1024]; + char *end; + char src[128]; + char dst[128]; + unsigned int i; + int ret = 0; + + GNUNET_log_setup ("util", "DEBUG", NULL); + for (i=0;i<sizeof(src);i++) + { + memset (src, i, sizeof (src)); + memset (dst, i+1, sizeof (dst)); + + end = GNUNET_STRINGS_data_to_string (&src, i, buf, sizeof (buf)); + end[0] = '\0'; + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (buf, strlen (buf), dst, i)) + { + fprintf (stderr, "%u failed decode (%u bytes)\n", i, (unsigned int) strlen (buf)); + ret = 1; + } else if (0 != memcmp (src, dst, i)) + { + fprintf (stderr, "%u wrong decode (%u bytes)\n", i, (unsigned int) strlen (buf)); + ret = 1; + } + } + return ret; } |