fix issue 16090 - popFront generates out-of-bounds array index on corrupted utf-8 strings

This commit is contained in:
anonymous 2016-05-31 17:50:44 +02:00
parent 643823d166
commit e1af1b0b51

View file

@ -2085,6 +2085,8 @@ version(unittest)
void popFront(C)(ref C[] str) @trusted pure nothrow void popFront(C)(ref C[] str) @trusted pure nothrow
if (isNarrowString!(C[])) if (isNarrowString!(C[]))
{ {
import std.algorithm : min;
assert(str.length, "Attempting to popFront() past the end of an array of " ~ C.stringof); assert(str.length, "Attempting to popFront() past the end of an array of " ~ C.stringof);
static if (is(Unqual!C == char)) static if (is(Unqual!C == char))
@ -2104,13 +2106,14 @@ if (isNarrowString!(C[]))
//Invalid UTF-8 //Invalid UTF-8
msbs = 1; msbs = 1;
} }
str = str[msbs .. $]; str = str.ptr[min(msbs, str.length) .. str.length];
} }
} }
else static if (is(Unqual!C == wchar)) else static if (is(Unqual!C == wchar))
{ {
immutable u = str[0]; immutable u = str[0];
str = str[1 + (u >= 0xD800 && u <= 0xDBFF) .. $]; immutable seqLen = 1 + (u >= 0xD800 && u <= 0xDBFF);
str = str.ptr[min(seqLen, str.length) .. str.length];
} }
else static assert(0, "Bad template constraint."); else static assert(0, "Bad template constraint.");
} }
@ -2150,6 +2153,26 @@ if (isNarrowString!(C[]))
static assert(checkCTFEW.empty); static assert(checkCTFEW.empty);
} }
unittest // issue 16090
{
string s = "\u00E4";
assert(s.length == 2);
s = s[0 .. 1];
assert(s.length == 1);
s.popFront;
assert(s.empty);
}
unittest
{
wstring s = "\U00010000";
assert(s.length == 2);
s = s[0 .. 1];
assert(s.length == 1);
s.popFront;
assert(s.empty);
}
/** /**
Implements the range interface primitive $(D popBack) for built-in Implements the range interface primitive $(D popBack) for built-in
arrays. Due to the fact that nonmember functions can be called with arrays. Due to the fact that nonmember functions can be called with