From: Pekka Riikonen Date: Tue, 3 Feb 2004 21:27:21 +0000 (+0000) Subject: Surrogates not allowed in UTF-8 data. Added UTF-8 tests. X-Git-Tag: silc.server.0.9.17~39 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=2b7a31f77765e5900618670061d816e61565bc6a;p=silc.git Surrogates not allowed in UTF-8 data. Added UTF-8 tests. --- diff --git a/CHANGES b/CHANGES index 4f36eee8..0f505a0a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +Tue Feb 3 23:25:17 EET 2004 Pekka Riikonen + + * Surrogates not allowed in UTF-8 strings, updated decoder. + Affected file lib/silcutil/silcstrutil.c. Added UTF-8 + testers in lib/silcutil/tests/ directory. + Wed Jan 14 18:42:44 EET 2004 Pekka Riikonen * Added SILC_CLIENT_CONN_ERROR_KE, ERROR_AUTH, ERROR_RESUME and @@ -16,7 +22,7 @@ Tue Jan 04 12:16:04 CET 2004 Jochen Eisinger * Added DIST_SUBDIRS symbols to include all subdirs in distributions. Affected files lib/silcutil/Makefile.am, lib/silcmath/Makefile.am - * Typofix in Irssi::Silc module. Affected file + * Typofix in Irssi::Silc module. Affected file irssi/src/perl/silc/Silc.xs. Tue Jan 04 02:43:44 CET 2004 Jochen Eisinger @@ -27,12 +33,12 @@ Tue Jan 04 02:43:44 CET 2004 Jochen Eisinger irssi/src/fe-common/silc/module-formats.[ch], fe-silc-messages.c; irssi/src/silc/core/client_ops.c, silc-channels.c, silc-servers.c - * Fixed typo in /ACTION help. Affected file + * Fixed typo in /ACTION help. Affected file irssi/docs/help/in/action.in Mon Jan 03 23:26:38 CET 2004 Jochen Eisinger - * Fixed typo in perl module. Affected file + * Fixed typo in perl module. Affected file irssi/src/perl/silc/Server.xs * Changed the way ACTION flagged messages are treated. Added support diff --git a/lib/silcutil/silcstrutil.c b/lib/silcutil/silcstrutil.c index 61b994a2..f3cfdaad 100644 --- a/lib/silcutil/silcstrutil.c +++ b/lib/silcutil/silcstrutil.c @@ -1,10 +1,10 @@ /* - silcstrutil.c + silcstrutil.c Author: Pekka Riikonen - Copyright (C) 2002 - 2003 Pekka Riikonen + Copyright (C) 2002 - 2004 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -391,10 +391,16 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (i + 2 >= utf8_len) return 0; - if (((utf8[i + 1] & 0xc0) != 0x80) || + if (((utf8[i + 1] & 0xc0) != 0x80) || ((utf8[i + 2] & 0xc0) != 0x80)) return 0; + /* Surrogates not allowed (D800-DFFF) */ + if (utf8[i] == 0xed && + utf8[i + 1] >= 0xa0 && utf8[i + 1] <= 0xbf && + utf8[i + 2] >= 0x80 && utf8[i + 2] <= 0xbf) + return 0; + charval = (utf8[i++] & 0xf) << 12; charval |= (utf8[i++] & 0x3f) << 6; charval |= utf8[i] & 0x3f; @@ -404,7 +410,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (i + 3 >= utf8_len) return 0; - if (((utf8[i + 1] & 0xc0) != 0x80) || + if (((utf8[i + 1] & 0xc0) != 0x80) || ((utf8[i + 2] & 0xc0) != 0x80) || ((utf8[i + 3] & 0xc0) != 0x80)) return 0; @@ -419,7 +425,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (i + 4 >= utf8_len) return 0; - if (((utf8[i + 1] & 0xc0) != 0x80) || + if (((utf8[i + 1] & 0xc0) != 0x80) || ((utf8[i + 2] & 0xc0) != 0x80) || ((utf8[i + 3] & 0xc0) != 0x80) || ((utf8[i + 4] & 0xc0) != 0x80)) @@ -436,7 +442,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (i + 5 >= utf8_len) return 0; - if (((utf8[i + 1] & 0xc0) != 0x80) || + if (((utf8[i + 1] & 0xc0) != 0x80) || ((utf8[i + 2] & 0xc0) != 0x80) || ((utf8[i + 3] & 0xc0) != 0x80) || ((utf8[i + 4] & 0xc0) != 0x80) || @@ -559,13 +565,13 @@ do { \ /* Parses MIME object and MIME header in it. */ -bool +bool silc_mime_parse(const unsigned char *mime, SilcUInt32 mime_len, char *version, SilcUInt32 version_size, char *content_type, SilcUInt32 content_type_size, char *transfer_encoding, SilcUInt32 transfer_encoding_size, unsigned char **mime_data_ptr, SilcUInt32 *mime_data_len) -{ +{ int i; unsigned char *tmp; @@ -582,7 +588,7 @@ silc_mime_parse(const unsigned char *mime, SilcUInt32 mime_len, return FALSE; if (mime_data_ptr) - *mime_data_ptr = (unsigned char *)mime + i + + *mime_data_ptr = (unsigned char *)mime + i + (mime[i] == '\n' ? 2 : 4); if (mime_data_len) *mime_data_len = mime_len - (i + (mime[i] == '\n' ? 2 : 4)); @@ -591,7 +597,7 @@ silc_mime_parse(const unsigned char *mime, SilcUInt32 mime_len, tmp = strstr(mime, MIME_CONTENT_TYPE); if (!tmp || (tmp - mime) >= i) return FALSE; - + /* Get MIME version, Content-Type and Transfer Encoding fields */ MIME_GET_FIELD(mime, mime_len, MIME_VERSION, MIME_VERSION_LEN, diff --git a/lib/silcutil/tests/Makefile.am b/lib/silcutil/tests/Makefile.am new file mode 100644 index 00000000..ec7d5f30 --- /dev/null +++ b/lib/silcutil/tests/Makefile.am @@ -0,0 +1,27 @@ +# +# Makefile.am +# +# Author: Pekka Riikonen +# +# Copyright (C) 2004 Pekka Riikonen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign + +bin_PROGRAMS = test_silcstrutil + +test_silcstrutil_SOURCES = test_silcstrutil.c + +LIBS = $(SILC_COMMON_LIBS) +LDADD = -L.. -L../.. -lsilc + +include $(top_srcdir)/Makefile.defines.in diff --git a/lib/silcutil/tests/test_silcstrutil.c b/lib/silcutil/tests/test_silcstrutil.c new file mode 100644 index 00000000..1e537a63 --- /dev/null +++ b/lib/silcutil/tests/test_silcstrutil.c @@ -0,0 +1,85 @@ +/* UTF-8 decoding tests */ + +#include "silcincludes.h" + +#define utf8fail(n, data, len) \ +const unsigned char u##n[] = (data); \ +int u##n##l = len; + +#define utf8failc(n) \ +do { \ + if (!silc_utf8_valid(u##n, u##n##l)) \ + SILC_LOG_DEBUG(("%d: not valid UTF-8, correctly detected, no error", n)); \ + else { \ + SILC_LOG_DEBUG(("%d: parser did not detect malformed UTF-8, error", n)); \ + goto err; \ + } \ +} while(0) + +/* UTF-8 Test vectors that MUST fail */ +utf8fail(1, "\x80", 1); +utf8fail(2, "\xbf", 1); +utf8fail(3, "\xfe", 1); +utf8fail(4, "\xff", 1); +utf8fail(5, "\xfe\xfe\xff\xff", 4); +utf8fail(6, "\xc0\xa0", 2); +utf8fail(7, "\xe0\x80\xaf", 3); +utf8fail(8, "\xf0\x80\x80\xaf", 4); +utf8fail(9, "\xf8\x80\x80\x80\xaf", 5); +utf8fail(10, "\xfc\x80\x80\x80\x80\xaf", 6); +utf8fail(11, "\xc0\x80", 2); +utf8fail(12, "\xe0\x80\x80", 3); +utf8fail(13, "\xf0\x80\x80\x80", 4); +utf8fail(14, "\xf8\x80\x80\x80\x80", 5); +utf8fail(15, "\xfc\x80\x80\x80\x80\x80", 6); +utf8fail(16, "\xc1\xbf", 2); +utf8fail(17, "\xe0\x9f\xbf", 3); +utf8fail(18, "\xf0\x8f\xbf\xbf", 4); +utf8fail(19, "\xf8\x87\xbf\xbf\xbf", 5); +utf8fail(20, "\xfc\x83\xbf\xbf\xbf\xbf", 6); +utf8fail(21, "\xed\xa0\x80", 3); +utf8fail(22, "\xed\xad\xbf", 3); +utf8fail(23, "\xed\xae\x80", 3); +utf8fail(24, "\xed\xaf\xbf", 3); +utf8fail(25, "\xed\xb0\x80", 3); +utf8fail(26, "\xed\xbe\x80", 3); +utf8fail(27, "\xed\xbf\xbf", 3); +utf8fail(28, "\xfc\x20\xfd\x20", 4); +utf8fail(29, "\xf8\xf9\xfa\xfb", 4); +utf8fail(30, "\xf0\x20\xf9\x20\xfa\x20\xfb\x20", 8); + +int main(int argc, char **argv) +{ + bool success = FALSE; + + if (argc > 1 && !strcmp(argv[1], "-d")) { + silc_debug = 1; + silc_debug_hexdump = 1; + silc_log_set_debug_string("*strutil*"); + } + + /* Failure tests */ + utf8failc(1); utf8failc(2); + utf8failc(3); utf8failc(4); + utf8failc(5); utf8failc(6); + utf8failc(7); utf8failc(8); + utf8failc(9); utf8failc(10); + utf8failc(11); utf8failc(12); + utf8failc(13); utf8failc(14); + utf8failc(15); utf8failc(16); + utf8failc(17); utf8failc(18); + utf8failc(19); utf8failc(20); + utf8failc(21); utf8failc(22); + utf8failc(23); utf8failc(24); + utf8failc(25); utf8failc(26); + utf8failc(27); utf8failc(28); + utf8failc(29); utf8failc(30); + + success = TRUE; + + err: + SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE")); + fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE"); + + return success; +}