diff --git a/src/io/files/juce_File.cpp b/src/io/files/juce_File.cpp index 46fce40b6c..b5607b3ccf 100644 --- a/src/io/files/juce_File.cpp +++ b/src/io/files/juce_File.cpp @@ -1003,7 +1003,7 @@ public: expect (tempFile.exists()); expect (tempFile.getSize() == 10); - expect (std::abs (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds()) < 3000); + expect (std::abs ((int64) (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds())) < 3000); expect (tempFile.loadFileAsString() == "0123456789"); expect (! demoFolder.containsSubDirectories()); @@ -1024,7 +1024,7 @@ public: Time t (Time::getCurrentTime()); tempFile.setLastModificationTime (t); Time t2 = tempFile.getLastModificationTime(); - expect (std::abs (t2.toMilliseconds() - t.toMilliseconds()) <= 1000); + expect (std::abs ((int64) (t2.toMilliseconds() - t.toMilliseconds())) <= 1000); { MemoryBlock mb; diff --git a/src/io/network/juce_URL.cpp b/src/io/network/juce_URL.cpp index c91614977a..a773aa8ab3 100644 --- a/src/io/network/juce_URL.cpp +++ b/src/io/network/juce_URL.cpp @@ -514,55 +514,62 @@ const StringPairArray& URL::getMimeTypesOfUploadFiles() const const String URL::removeEscapeChars (const String& s) { String result (s.replaceCharacter ('+', ' ')); - int nextPercent = 0; - for (;;) - { - nextPercent = result.indexOfChar (nextPercent, '%'); - - if (nextPercent < 0) - break; + if (! result.containsChar ('%')) + return result; - int hexDigit1 = 0, hexDigit2 = 0; + // We need to operate on the string as raw UTF8 chars, and then recombine them into unicode + // after all the replacements have been made, so that multi-byte chars are handled. + Array utf8 (result.toUTF8(), result.getNumBytesAsUTF8()); - if ((hexDigit1 = CharacterFunctions::getHexDigitValue (result [nextPercent + 1])) >= 0 - && (hexDigit2 = CharacterFunctions::getHexDigitValue (result [nextPercent + 2])) >= 0) + for (int i = 0; i < utf8.size(); ++i) + { + if (utf8.getUnchecked(i) == '%') { - const juce_wchar replacementChar = (juce_wchar) ((hexDigit1 << 4) + hexDigit2); - result = result.replaceSection (nextPercent, 3, String::charToString (replacementChar)); - } + const int hexDigit1 = CharacterFunctions::getHexDigitValue (utf8 [i + 1]); + const int hexDigit2 = CharacterFunctions::getHexDigitValue (utf8 [i + 2]); - ++nextPercent; + if (hexDigit1 >= 0 && hexDigit2 >= 0) + { + utf8.set (i, (char) ((hexDigit1 << 4) + hexDigit2)); + utf8.removeRange (i + 1, 2); + } + } } - return result; + return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size()); } const String URL::addEscapeChars (const String& s, const bool isParameter) { - String result; - result.preallocateStorage (s.length() + 8); - const char* utf8 = s.toUTF8(); - const char* legalChars = isParameter ? "_-.*!'()" - : "_-$.*!'(),"; + const char* const legalChars = isParameter ? "_-.*!'()" + : ",$_-.*!'()"; - while (*utf8 != 0) + Array utf8 (s.toUTF8(), s.getNumBytesAsUTF8()); + + for (int i = 0; i < utf8.size(); ++i) { - const char c = *utf8++; + const char c = utf8.getUnchecked(i); - if (CharacterFunctions::isLetterOrDigit (c) - || CharacterFunctions::indexOfChar (legalChars, c, false) >= 0) + if (! (CharacterFunctions::isLetterOrDigit (c) + || CharacterFunctions::indexOfChar (legalChars, c, false) >= 0)) { - result << c; - } - else - { - const int v = (int) (uint8) c; - result << (v < 0x10 ? "%0" : "%") << String::toHexString (v); + if (c == ' ') + { + utf8.set (i, '+'); + } + else + { + static const char* const hexDigits = "0123456789abcdef"; + + utf8.set (i, '%'); + utf8.insert (++i, hexDigits [((uint8) c) >> 4]); + utf8.insert (++i, hexDigits [c & 15]); + } } } - return result; + return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size()); } //==============================================================================