aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-11-12 12:22:37 +0100
committerChristian Grothoff <christian@grothoff.org>2023-11-12 12:22:37 +0100
commitbdefb48e33d15a92f28aeea99b646dbda22acf70 (patch)
tree6dfac4ece3c764007c398868980fdc03854c9359
parentb7605d09b28ef9d0ca4a1d7cb7d99581b7e50738 (diff)
downloadgnunet-bdefb48e33d15a92f28aeea99b646dbda22acf70.tar.gz
gnunet-bdefb48e33d15a92f28aeea99b646dbda22acf70.zip
fix undefined behavior from left-shifting signed chars
-rw-r--r--src/lib/util/strings.c75
1 files changed, 44 insertions, 31 deletions
diff --git a/src/lib/util/strings.c b/src/lib/util/strings.c
index 86323bc83..e0ae6a2fa 100644
--- a/src/lib/util/strings.c
+++ b/src/lib/util/strings.c
@@ -389,7 +389,7 @@ GNUNET_STRINGS_conv (const char *input,
389 ret[encoded_string_length] = '\0'; 389 ret[encoded_string_length] = '\0';
390 free (encoded_string); 390 free (encoded_string);
391 return ret; 391 return ret;
392 fail: 392fail:
393 LOG (GNUNET_ERROR_TYPE_WARNING, 393 LOG (GNUNET_ERROR_TYPE_WARNING,
394 _ ("Character sets requested were `%s'->`%s'\n"), 394 _ ("Character sets requested were `%s'->`%s'\n"),
395 "UTF-8", 395 "UTF-8",
@@ -445,6 +445,7 @@ GNUNET_STRINGS_utf8_normalize (const char *input)
445 return output; 445 return output;
446} 446}
447 447
448
448enum GNUNET_GenericReturnValue 449enum GNUNET_GenericReturnValue
449GNUNET_STRINGS_utf8_tolower (const char *input, 450GNUNET_STRINGS_utf8_tolower (const char *input,
450 char *output) 451 char *output)
@@ -1608,7 +1609,7 @@ GNUNET_STRINGS_base64_encode (const void *in,
1608 size_t len, 1609 size_t len,
1609 char **output) 1610 char **output)
1610{ 1611{
1611 const char *data = in; 1612 const unsigned char *data = in;
1612 size_t ret; 1613 size_t ret;
1613 char *opt; 1614 char *opt;
1614 1615
@@ -1660,7 +1661,9 @@ GNUNET_STRINGS_base64url_encode (const void *in,
1660 char *enc; 1661 char *enc;
1661 size_t pos; 1662 size_t pos;
1662 1663
1663 GNUNET_STRINGS_base64_encode (in, len, output); 1664 GNUNET_STRINGS_base64_encode (in,
1665 len,
1666 output);
1664 enc = *output; 1667 enc = *output;
1665 /* Replace with correct characters for base64url */ 1668 /* Replace with correct characters for base64url */
1666 pos = 0; 1669 pos = 0;
@@ -1691,24 +1694,26 @@ GNUNET_STRINGS_base64url_encode (const void *in,
1691 : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1) 1694 : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1)
1692 1695
1693 1696
1694size_t
1695GNUNET_STRINGS_base64_decode (const char *data,
1696 size_t len,
1697 void **out)
1698{
1699 char *output;
1700 size_t ret = 0;
1701
1702#define CHECK_CRLF \ 1697#define CHECK_CRLF \
1703 while (data[i] == '\r' || data[i] == '\n') \ 1698 while ( (data[i] == '\r') || (data[i] == '\n') ) \
1704 { \ 1699 { \
1705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, \ 1700 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, \
1706 "ignoring CR/LF\n"); \ 1701 "ignoring CR/LF\n"); \
1707 i++; \ 1702 i++; \
1708 if (i >= len) \ 1703 if (i >= len) { \
1709 goto END; \ 1704 goto END; \
1705 } \
1710 } 1706 }
1711 1707
1708
1709size_t
1710GNUNET_STRINGS_base64_decode (const char *data,
1711 size_t len,
1712 void **out)
1713{
1714 unsigned char *output;
1715 size_t ret = 0;
1716
1712 GNUNET_assert (len / 3 < SIZE_MAX); 1717 GNUNET_assert (len / 3 < SIZE_MAX);
1713 output = GNUNET_malloc ((len * 3 / 4) + 8); 1718 output = GNUNET_malloc ((len * 3 / 4) + 8);
1714 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1719 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1716,16 +1721,16 @@ GNUNET_STRINGS_base64_decode (const char *data,
1716 (int) len); 1721 (int) len);
1717 for (size_t i = 0; i < len; ++i) 1722 for (size_t i = 0; i < len; ++i)
1718 { 1723 {
1719 char c; 1724 unsigned char c;
1720 char c1; 1725 unsigned char c1;
1721 1726
1722 CHECK_CRLF; 1727 CHECK_CRLF;
1723 if (FILLCHAR == data[i]) 1728 if (FILLCHAR == data[i])
1724 break; 1729 break;
1725 c = (char) cvtfind (data[i]); 1730 c = (unsigned char) cvtfind (data[i]);
1726 ++i; 1731 ++i;
1727 CHECK_CRLF; 1732 CHECK_CRLF;
1728 c1 = (char) cvtfind (data[i]); 1733 c1 = (unsigned char) cvtfind (data[i]);
1729 c = (c << 2) | ((c1 >> 4) & 0x3); 1734 c = (c << 2) | ((c1 >> 4) & 0x3);
1730 output[ret++] = c; 1735 output[ret++] = c;
1731 if (++i < len) 1736 if (++i < len)
@@ -1734,7 +1739,7 @@ GNUNET_STRINGS_base64_decode (const char *data,
1734 c = data[i]; 1739 c = data[i];
1735 if (FILLCHAR == c) 1740 if (FILLCHAR == c)
1736 break; 1741 break;
1737 c = (char) cvtfind (c); 1742 c = (unsigned char) cvtfind (c);
1738 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf); 1743 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
1739 output[ret++] = c1; 1744 output[ret++] = c1;
1740 } 1745 }
@@ -1745,17 +1750,20 @@ GNUNET_STRINGS_base64_decode (const char *data,
1745 if (FILLCHAR == c1) 1750 if (FILLCHAR == c1)
1746 break; 1751 break;
1747 1752
1748 c1 = (char) cvtfind (c1); 1753 c1 = (unsigned char) cvtfind (c1);
1749 c = ((c << 6) & 0xc0) | c1; 1754 c = ((c << 6) & 0xc0) | c1;
1750 output[ret++] = c; 1755 output[ret++] = c;
1751 } 1756 }
1752 } 1757 }
1753 END: 1758END:
1754 *out = output; 1759 *out = output;
1755 return ret; 1760 return ret;
1756} 1761}
1757 1762
1758 1763
1764#undef CHECK_CRLF
1765
1766
1759size_t 1767size_t
1760GNUNET_STRINGS_base64url_decode (const char *data, 1768GNUNET_STRINGS_base64url_decode (const char *data,
1761 size_t len, 1769 size_t len,
@@ -1768,9 +1776,10 @@ GNUNET_STRINGS_base64url_decode (const char *data,
1768 /* make enough space for padding */ 1776 /* make enough space for padding */
1769 GNUNET_assert (len < SIZE_MAX - 3); 1777 GNUNET_assert (len < SIZE_MAX - 3);
1770 s = GNUNET_malloc (len + 3); 1778 s = GNUNET_malloc (len + 3);
1771 memcpy (s, data, len); 1779 memcpy (s,
1772 1780 data,
1773 for (int i = 0; i < strlen (s); i++) 1781 len);
1782 for (size_t i = 0; i < strlen (s); i++)
1774 { 1783 {
1775 if (s[i] == '-') 1784 if (s[i] == '-')
1776 s[i] = '+'; 1785 s[i] = '+';
@@ -1796,7 +1805,9 @@ GNUNET_STRINGS_base64url_decode (const char *data,
1796 GNUNET_assert (0); 1805 GNUNET_assert (0);
1797 break; 1806 break;
1798 } 1807 }
1799 ret = GNUNET_STRINGS_base64_decode (s, len, out); 1808 ret = GNUNET_STRINGS_base64_decode (s,
1809 len,
1810 out);
1800 GNUNET_free (s); 1811 GNUNET_free (s);
1801 return ret; 1812 return ret;
1802} 1813}
@@ -1825,7 +1836,9 @@ GNUNET_STRINGS_urldecode (const char *data,
1825 GNUNET_free (*out); 1836 GNUNET_free (*out);
1826 return 0; 1837 return 0;
1827 } 1838 }
1828 if (1 != sscanf (rpos + 1, "%2x", &num)) 1839 if (1 != sscanf (rpos + 1,
1840 "%2x",
1841 &num))
1829 break; 1842 break;
1830 *wpos = (char) ((unsigned char) num); 1843 *wpos = (char) ((unsigned char) num);
1831 wpos++; 1844 wpos++;
@@ -1859,11 +1872,11 @@ GNUNET_STRINGS_urlencode (const char *data,
1859 if (0 == (0x80 & *i8)) 1872 if (0 == (0x80 & *i8))
1860 { 1873 {
1861 /* traditional ASCII */ 1874 /* traditional ASCII */
1862 if ( isalnum (*i8) || 1875 if (isalnum (*i8) ||
1863 (*i8 == '-') || 1876 (*i8 == '-') ||
1864 (*i8 == '_') || 1877 (*i8 == '_') ||
1865 (*i8 == '.') || 1878 (*i8 == '.') ||
1866 (*i8 == '~') ) 1879 (*i8 == '~') )
1867 GNUNET_buffer_write (&buf, 1880 GNUNET_buffer_write (&buf,
1868 (const char*) i8, 1881 (const char*) i8,
1869 1); 1882 1);