Bug 11721 – regression: std.utf.toUTFindex throws error instead of exception
Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-12-10T17:03:00Z
Last change time
2013-12-16T11:11:41Z
Assigned to
nobody
Creator
timothee.cour2
Comments
Comment #0 by timothee.cour2 — 2013-12-10T17:03:35Z
(this came up in discussion EMAIL:std.utf: use throw UTFException instead of assert(0) in stride, etc)
063_2: ok
git head/064_2: fails core.exception.AssertError@phobos/std/utf.d(171): Past the end of the UTF-8 sequence
import std.traits;
inout(C)[] slice(C)(inout(C)[] str, size_t i, size_t j) if(isSomeChar!C) {
import std.utf;
immutable first = str.toUTFindex(i);
immutable second = str[first .. $].toUTFindex(j-i) + first;
return str[first .. second];
}
unittest{
auto a = "≈açç√ef";
import std.exception;
import core.exception;
assertThrown!Throwable(a.slice(2,8));//ok
assertThrown!RangeError(a.slice(2,8));//fails
}
Comment #1 by k.hara.pg — 2013-12-14T08:38:56Z
Until 2.063, std.utf.toUTFindex was non-template function. In each release, Phobos library is built with -release switch, so the asserts in non-template code is always removed.
So, std.utf.toUTFindex had called release version of std.utf.stride, and it did not throw AssertError "Past the end of the UTF-8 sequence".
But, stride function is @safe function, so array indexing was always checked boundaries, and could throw RangeError.
In 2.064, std.utf.toUTFindex was changed to template function.
https://github.com/D-Programming-Language/phobos/commit/87a2ee7f4d4e4959cf4db9a1710beac67c00129c#diff-27410a0be96392a06647e61c73131b64L882
So, if you compile your code without -release, the assertion is properly checked and it throws AssertError.
If you compile the code with -release, the whole execution still succeeds with 2.064 and git-head.
The main point is, today most of Phobos funcitons have no specifications against erroneous inputs. In this case, if you give invalid index for std.utf.stride via std.utf.toUTFindex, what happens is "implementation-dependent".
(Note: std.utf.toUTFindex is marked as @safe, so it won't occur "undefined behavior", but it is not relevant with this issue.)
The most better way I think is, changing your unittest code to assertThrown!Error(a.slice(2,8));