Skip to content

Commit

Permalink
Fixed|libcore: Iterating a string with invalid characters
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Sep 1, 2019
1 parent e198bd8 commit 697b9f9
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 11 deletions.
2 changes: 1 addition & 1 deletion doomsday/libs/core/include/de/data/string.h
Expand Up @@ -117,7 +117,7 @@ struct DE_PUBLIC mb_iterator
const char *i;
const char *start;
mutable mbstate_t mb{};
mutable dsize curCharLen = 0;
mutable int curCharLen = 0;

mb_iterator() : i{nullptr}, start{nullptr} {}
mb_iterator(const char *p) : i{p}, start{p} {}
Expand Down
4 changes: 2 additions & 2 deletions doomsday/libs/core/src/core/timer.cpp
Expand Up @@ -232,8 +232,8 @@ void Timer::post()
}
else
{
warning("[TimerScheduler] Pending timer %p triggered with no event loop running (event "
"not posted)", this);
// warning("[TimerScheduler] Pending timer %p triggered with no event loop running (event "
// "not posted)", this);
}
}
}
Expand Down
21 changes: 13 additions & 8 deletions doomsday/libs/core/src/data/string.cpp
Expand Up @@ -1044,7 +1044,7 @@ Block String::toLatin1() const
{
// Non-8-bit characters are simply filtered out.
Block latin;
for (iChar ch : *this)
for (Char ch : *this)
{
if (ch < 256) latin.append(Block::Byte(ch));
}
Expand Down Expand Up @@ -1106,8 +1106,8 @@ String::const_reverse_iterator::const_reverse_iterator(const Range<const char *>
: iter(range.end, range.start)
{
--iter;

}

String::const_reverse_iterator::const_reverse_iterator(const CString &cstr)
: iter(cstr.end(), cstr.begin())
{
Expand Down Expand Up @@ -1135,16 +1135,21 @@ Char mb_iterator::operator*() const
Char mb_iterator::decode() const
{
wchar_t ch = 0;
const char *end = i;
for (int j = 0; *end && j < MB_CUR_MAX; ++j, ++end) {}
curCharLen = std::mbrtowc(&ch, i, end - i, &mb);
curCharLen = std::mbrtowc(&ch, i, MB_CUR_MAX, &mb);
if (curCharLen < 0)
{
// Multibyte decoding failed. Let's return something valid, though, so the iterator
// doesn't hang due to never reaching the end of the string.
ch = '?';
curCharLen = 1;
}
return ch;
}

mb_iterator &mb_iterator::operator++()
{
if (!curCharLen) decode();
i += de::max(curCharLen, dsize(1));
if (curCharLen == 0) decode();
i += curCharLen;
curCharLen = 0;
return *this;
}
Expand Down Expand Up @@ -1201,8 +1206,8 @@ mb_iterator &mb_iterator::operator+=(int offset)
while (offset-- > 0) ++(*this);
}
return *this;

}

mb_iterator mb_iterator::operator-(int offset) const
{
mb_iterator i = *this;
Expand Down
4 changes: 4 additions & 0 deletions doomsday/tests/test_string/main.cpp
Expand Up @@ -31,6 +31,10 @@ int main(int argc, char **argv)
// Iterators.
{
const String str = u8"H★llo Wörld";
for (Char ch : str)
{
debug("Char: %x %lc", unsigned(ch), ch);
}
for (auto i = str.begin(); i != str.end(); ++i)
{
debug("Char %u: %x %lc", i.pos().index, unsigned(*i), *i);
Expand Down

0 comments on commit 697b9f9

Please sign in to comment.