Index: src/OFMutableUTF8String.m ================================================================== --- src/OFMutableUTF8String.m +++ src/OFMutableUTF8String.m @@ -346,22 +346,23 @@ } } - (void)appendString: (OFString *)string { + const char *UTF8String; size_t UTF8StringLength; if (string == nil) @throw [OFInvalidArgumentException exception]; + UTF8String = string.UTF8String; UTF8StringLength = string.UTF8StringLength; _s->hasHash = false; _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + UTF8StringLength + 1, 1); - memcpy(_s->cString + _s->cStringLength, string.UTF8String, - UTF8StringLength); + memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength); _s->cStringLength += UTF8StringLength; _s->length += string.length; _s->cString[_s->cStringLength] = 0; @@ -368,12 +369,20 @@ if ([string isKindOfClass: [OFUTF8String class]] || [string isKindOfClass: [OFMutableUTF8String class]]) { if (((OFMutableUTF8String *)string)->_s->isUTF8) _s->isUTF8 = true; - } else - _s->isUTF8 = true; + } else { + switch (_OFUTF8StringCheck(UTF8String, UTF8StringLength, + NULL)) { + case 1: + _s->isUTF8 = true; + break; + case -1: + @throw [OFInvalidEncodingException exception]; + } + } } - (void)appendCharacters: (const OFUnichar *)characters length: (size_t)length { char *tmp = OFAllocMemory((length * 4) + 1, 1); @@ -431,38 +440,49 @@ } } - (void)insertString: (OFString *)string atIndex: (size_t)idx { - size_t newCStringLength; + const char *UTF8String; + size_t UTF8StringLength, newCStringLength; if (idx > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) idx = _OFUTF8StringIndexToPosition(_s->cString, idx, _s->cStringLength); - newCStringLength = _s->cStringLength + string.UTF8StringLength; + UTF8String = string.UTF8String; + UTF8StringLength = string.UTF8StringLength; + + newCStringLength = _s->cStringLength + UTF8StringLength; _s->hasHash = false; _s->cString = OFResizeMemory(_s->cString, newCStringLength + 1, 1); - memmove(_s->cString + idx + string.UTF8StringLength, - _s->cString + idx, _s->cStringLength - idx); - memcpy(_s->cString + idx, string.UTF8String, - string.UTF8StringLength); + memmove(_s->cString + idx + UTF8StringLength, _s->cString + idx, + _s->cStringLength - idx); + memcpy(_s->cString + idx, UTF8String, UTF8StringLength); _s->cString[newCStringLength] = '\0'; _s->cStringLength = newCStringLength; _s->length += string.length; if ([string isKindOfClass: [OFUTF8String class]] || [string isKindOfClass: [OFMutableUTF8String class]]) { if (((OFMutableUTF8String *)string)->_s->isUTF8) _s->isUTF8 = true; - } else - _s->isUTF8 = true; + } else { + switch (_OFUTF8StringCheck(UTF8String, UTF8StringLength, + NULL)) { + case 1: + _s->isUTF8 = true; + break; + case -1: + @throw [OFInvalidEncodingException exception]; + } + } } - (void)deleteCharactersInRange: (OFRange)range { size_t start = range.location; @@ -497,10 +517,12 @@ withString: (OFString *)replacement { size_t start = range.location; size_t end = range.location + range.length; size_t newCStringLength, newLength; + const char *replacementString; + size_t replacementLength; if (replacement == nil) @throw [OFInvalidArgumentException exception]; if (range.length > SIZE_MAX - range.location || end > _s->length) @@ -513,12 +535,15 @@ _s->cStringLength); end = _OFUTF8StringIndexToPosition(_s->cString, end, _s->cStringLength); } - newCStringLength = _s->cStringLength - (end - start) + - replacement.UTF8StringLength; + replacementString = replacement.UTF8String; + replacementLength = replacement.UTF8StringLength; + + newCStringLength = + _s->cStringLength - (end - start) + replacementLength; _s->hasHash = false; /* * If the new string is bigger, we need to resize it first so we can * memmove() the rest of the string to the end. @@ -529,14 +554,13 @@ */ if (newCStringLength > _s->cStringLength) _s->cString = OFResizeMemory(_s->cString, newCStringLength + 1, 1); - memmove(_s->cString + start + replacement.UTF8StringLength, - _s->cString + end, _s->cStringLength - end); - memcpy(_s->cString + start, replacement.UTF8String, - replacement.UTF8StringLength); + memmove(_s->cString + start + replacementLength, _s->cString + end, + _s->cStringLength - end); + memcpy(_s->cString + start, replacementString, replacementLength); _s->cString[newCStringLength] = '\0'; /* * If the new string is smaller, we can safely resize it now as we're * done with memmove(). @@ -550,12 +574,20 @@ if ([replacement isKindOfClass: [OFUTF8String class]] || [replacement isKindOfClass: [OFMutableUTF8String class]]) { if (((OFMutableUTF8String *)replacement)->_s->isUTF8) _s->isUTF8 = true; - } else - _s->isUTF8 = true; + } else { + switch (_OFUTF8StringCheck(replacementString, replacementLength, + NULL)) { + case 1: + _s->isUTF8 = true; + break; + case -1: + @throw [OFInvalidEncodingException exception]; + } + } } - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options @@ -635,12 +667,20 @@ if ([replacement isKindOfClass: [OFUTF8String class]] || [replacement isKindOfClass: [OFMutableUTF8String class]]) { if (((OFMutableUTF8String *)replacement)->_s->isUTF8) _s->isUTF8 = true; - } else - _s->isUTF8 = true; + } else { + switch (_OFUTF8StringCheck(replacementString, replacementLength, + NULL)) { + case 1: + _s->isUTF8 = true; + break; + case -1: + @throw [OFInvalidEncodingException exception]; + } + } } - (void)deleteLeadingWhitespaces { size_t i; Index: src/OFUTF8String+Private.h ================================================================== --- src/OFUTF8String+Private.h +++ src/OFUTF8String+Private.h @@ -29,11 +29,11 @@ @end #ifdef __cplusplus extern "C" { #endif -extern int _OFUTF8StringCheck(const char *, size_t, size_t *) +extern int _OFUTF8StringCheck(const char *, size_t, size_t *_Nullable) OF_VISIBILITY_HIDDEN; extern size_t _OFUTF8StringIndexToPosition(const char *, size_t, size_t) OF_VISIBILITY_HIDDEN; #ifdef __cplusplus } Index: src/OFUTF8String.m ================================================================== --- src/OFUTF8String.m +++ src/OFUTF8String.m @@ -458,22 +458,29 @@ @try { _s = &_storage; _s->cStringLength = string.UTF8StringLength; - - if ([string isKindOfClass: [OFUTF8String class]] || - [string isKindOfClass: [OFMutableUTF8String class]]) - _s->isUTF8 = ((OFUTF8String *)string)->_s->isUTF8; - else - _s->isUTF8 = true; - _s->length = string.length; _s->cString = OFAllocMemory(_s->cStringLength + 1, 1); memcpy(_s->cString, string.UTF8String, _s->cStringLength + 1); _s->freeWhenDone = true; + + if ([string isKindOfClass: [OFUTF8String class]] || + [string isKindOfClass: [OFMutableUTF8String class]]) + _s->isUTF8 = ((OFUTF8String *)string)->_s->isUTF8; + else { + switch (_OFUTF8StringCheck(_s->cString, + _s->cStringLength, NULL)) { + case 1: + _s->isUTF8 = true; + break; + case -1: + @throw [OFInvalidEncodingException exception]; + } + } } @catch (id e) { [self release]; @throw e; }