diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-11-12 12:22:37 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-11-12 12:22:37 +0100 |
commit | bdefb48e33d15a92f28aeea99b646dbda22acf70 (patch) | |
tree | 6dfac4ece3c764007c398868980fdc03854c9359 | |
parent | b7605d09b28ef9d0ca4a1d7cb7d99581b7e50738 (diff) | |
download | gnunet-bdefb48e33d15a92f28aeea99b646dbda22acf70.tar.gz gnunet-bdefb48e33d15a92f28aeea99b646dbda22acf70.zip |
fix undefined behavior from left-shifting signed chars
-rw-r--r-- | src/lib/util/strings.c | 75 |
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: | 392 | fail: |
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 | |||
448 | enum GNUNET_GenericReturnValue | 449 | enum GNUNET_GenericReturnValue |
449 | GNUNET_STRINGS_utf8_tolower (const char *input, | 450 | GNUNET_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 | ||
1694 | size_t | ||
1695 | GNUNET_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 | |||
1709 | size_t | ||
1710 | GNUNET_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: | 1758 | END: |
1754 | *out = output; | 1759 | *out = output; |
1755 | return ret; | 1760 | return ret; |
1756 | } | 1761 | } |
1757 | 1762 | ||
1758 | 1763 | ||
1764 | #undef CHECK_CRLF | ||
1765 | |||
1766 | |||
1759 | size_t | 1767 | size_t |
1760 | GNUNET_STRINGS_base64url_decode (const char *data, | 1768 | GNUNET_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); |