Index: src/OFMutableString_UTF8.m ================================================================== --- src/OFMutableString_UTF8.m +++ src/OFMutableString_UTF8.m @@ -107,11 +107,11 @@ while (i < _s->cStringLength) { const of_unichar_t *const *table; size_t tableSize; of_unichar_t c; - size_t cLen; + ssize_t cLen; if (isStart) { table = startTable; tableSize = middleTableSize; } else { @@ -120,11 +120,11 @@ } cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); - if (cLen == 0 || c > 0x10FFFF) { + if (cLen <= 0 || c > 0x10FFFF) { [self freeMemory: unicodeString]; @throw [OFInvalidEncodingException exception]; } switch (c) { @@ -202,11 +202,12 @@ - (void)setCharacter: (of_unichar_t)character atIndex: (size_t)index { char buffer[4]; of_unichar_t c; - size_t lenNew, lenOld; + size_t lenNew; + ssize_t lenOld; if (_s->isUTF8) index = of_string_utf8_get_position(_s->cString, index, _s->cStringLength); @@ -222,18 +223,18 @@ if ((lenNew = of_string_utf8_encode(character, buffer)) == 0) @throw [OFInvalidEncodingException exception]; if ((lenOld = of_string_utf8_decode(_s->cString + index, - _s->cStringLength - index, &c)) == 0) + _s->cStringLength - index, &c)) <= 0) @throw [OFInvalidEncodingException exception]; _s->hashed = false; - if (lenNew == lenOld) + if (lenNew == (size_t)lenOld) memcpy(_s->cString + index, buffer, lenNew); - else if (lenNew > lenOld) { + else if (lenNew > (size_t)lenOld) { _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength - lenOld + lenNew + 1]; memmove(_s->cString + index + lenNew, @@ -245,11 +246,11 @@ _s->cStringLength += lenNew; _s->cString[_s->cStringLength] = '\0'; if (character & 0x80) _s->isUTF8 = true; - } else if (lenNew < lenOld) { + } else if (lenNew < (size_t)lenOld) { memmove(_s->cString + index + lenNew, _s->cString + index + lenOld, _s->cStringLength - index - lenOld); memcpy(_s->cString + index, buffer, lenNew); Index: src/OFStdIOStream_Win32Console.m ================================================================== --- src/OFStdIOStream_Win32Console.m +++ src/OFStdIOStream_Win32Console.m @@ -41,10 +41,11 @@ #include "config.h" #import "OFStdIOStream_Win32Console.h" #import "OFStdIOStream+Private.h" +#import "OFString.h" #import "OFDataArray.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFOutOfRangeException.h" @@ -221,26 +222,26 @@ size_t i = 0, j = 0; DWORD written; while (i < length) { of_unichar_t c; - size_t cLen; + size_t UTF8Len; - cLen = of_string_utf8_decode(buffer + i, length - i, + UTF8Len = of_string_utf8_decode(buffer + i, length - i, &c); - if (cLen == 0 || c > 0x10FFFF) + if (UTF8Len <= 0 || c > 0x10FFFF) @throw [OFInvalidEncodingException exception]; if (c > 0xFFFF) { c -= 0x10000; tmp[j++] = 0xD800 | (c >> 10); tmp[j++] = 0xDC00 | (c & 0x3FF); } else tmp[j++] = c; - i += cLen; + i += UTF8Len; } if (!WriteConsoleW(_handle, tmp, j, &written, NULL) || written != j) @throw [OFWriteFailedException Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -1098,11 +1098,11 @@ #ifdef __cplusplus extern "C" { #endif extern size_t of_string_utf8_encode(of_unichar_t, char*); -extern size_t of_string_utf8_decode(const char*, size_t, of_unichar_t*); +extern ssize_t of_string_utf8_decode(const char*, size_t, of_unichar_t*); extern size_t of_string_utf16_length(const of_char16_t*); extern size_t of_string_utf32_length(const of_char32_t*); #ifdef __cplusplus } #endif Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -126,40 +126,41 @@ } return 0; } -size_t +ssize_t of_string_utf8_decode(const char *buffer_, size_t length, of_unichar_t *ret) { + /* FIXME: Check if the following bytes are indeed surrogates */ const uint8_t *buffer = (const uint8_t*)buffer_; if (!(*buffer & 0x80)) { *ret = buffer[0]; return 1; } if ((*buffer & 0xE0) == 0xC0) { if OF_UNLIKELY (length < 2) - return 0; + return -2; *ret = ((buffer[0] & 0x1F) << 6) | (buffer[1] & 0x3F); return 2; } if ((*buffer & 0xF0) == 0xE0) { if OF_UNLIKELY (length < 3) - return 0; + return -3; *ret = ((buffer[0] & 0x0F) << 12) | ((buffer[1] & 0x3F) << 6) | (buffer[2] & 0x3F); return 3; } if ((*buffer & 0xF8) == 0xF0) { if OF_UNLIKELY (length < 4) - return 0; + return -4; *ret = ((buffer[0] & 0x07) << 18) | ((buffer[1] & 0x3F) << 12) | ((buffer[2] & 0x3F) << 6) | (buffer[3] & 0x3F); return 4; } Index: src/OFString_UTF8.m ================================================================== --- src/OFString_UTF8.m +++ src/OFString_UTF8.m @@ -806,18 +806,18 @@ i = j = 0; while (i < _s->cStringLength && j < otherCStringLength) { of_unichar_t c1, c2; - size_t l1, l2; + ssize_t l1, l2; l1 = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c1); l2 = of_string_utf8_decode(otherCString + j, otherCStringLength - j, &c2); - if (l1 == 0 || l2 == 0 || c1 > 0x10FFFF || c2 > 0x10FFFF) + if (l1 <= 0 || l2 <= 0 || c1 > 0x10FFFF || c2 > 0x10FFFF) @throw [OFInvalidEncodingException exception]; if (c1 >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) { of_unichar_t tc = of_unicode_casefolding_table[c1 >> 8][c1 & 0xFF]; @@ -860,14 +860,14 @@ OF_HASH_INIT(hash); for (size_t i = 0; i < _s->cStringLength; i++) { of_unichar_t c; - size_t length; + ssize_t length; if ((length = of_string_utf8_decode(_s->cString + i, - _s->cStringLength - i, &c)) == 0) + _s->cStringLength - i, &c)) <= 0) @throw [OFInvalidEncodingException exception]; OF_HASH_ADD(hash, (c & 0xFF0000) >> 16); OF_HASH_ADD(hash, (c & 0x00FF00) >> 8); OF_HASH_ADD(hash, c & 0x0000FF); @@ -894,12 +894,12 @@ return _s->cString[index]; index = of_string_utf8_get_position(_s->cString, index, _s->cStringLength); - if (!of_string_utf8_decode(_s->cString + index, - _s->cStringLength - index, &character)) + if (of_string_utf8_decode(_s->cString + index, + _s->cStringLength - index, &character) <= 0) @throw [OFInvalidEncodingException exception]; return character; } @@ -1190,16 +1190,16 @@ i = j = 0; while (i < _s->cStringLength) { of_unichar_t c; - size_t cLen; + ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); - if (cLen == 0 || c > 0x10FFFF) + if (cLen <= 0 || c > 0x10FFFF) @throw [OFInvalidEncodingException exception]; ret[j++] = c; i += cLen; } @@ -1218,16 +1218,16 @@ i = j = 0; while (i < _s->cStringLength) { of_unichar_t c; - size_t cLen; + ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); - if (cLen == 0 || c > 0x10FFFF) + if (cLen <= 0 || c > 0x10FFFF) @throw [OFInvalidEncodingException exception]; if (byteOrder != OF_BYTE_ORDER_NATIVE) ret[j++] = OF_BSWAP32(c); else