druntime giving wrong line for copy assert?

Rudy Raab TransientResponse at outlook.com
Tue Apr 30 13:59:52 UTC 2019


I didn't want to immediately declare this a compiler/runtime bug 
without making sure I wasn't crazy/misinterpreting things.

Backstory is this: I was writing a library for dealing with some 
special corporate data to (de)serialize to/from a binary format 
and tweaking things to get the output to match a known good 
implementation in C#. I had a unittest set up to round-trip data 
from binary -> class instance -> back to binary and ensure input 
and output match.

At one point I got an assert failure in an odd place; it seemed 
to be coming from inside std.format.format. So I wrote a simple 
test program to recreate the issue:

---
#!/usr/bin/env dub
/+ dub.sdl:
	name "hello"
+/

import std.stdio;
import std.datetime;
import std.regex;
import std.base64;
import std.string;
import std.algorithm;

private immutable string[] months = ["Jan", "Feb", "Mar", "Apr", 
"May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

void main()
{
     string dstr = "29-Apr-2019 11:04";
     SysTime dateProgrammed;

     ubyte[] full = new ubyte[128];

     auto m = matchFirst(dstr, 
regex(r"([0-9]{2})-([A-Z][a-z]{2})-([0-9]{4}) 
([0-9]{2}):([0-9]{2})"));
     assert(m.length > 0, "Date string is invalid");
     import std.conv: to;
     DateTime d = DateTime(1990, 1, 1);
     d.month = to!Month(months.join.indexOf(m[2])/3+1);
     d.year = m[3].to!short;
     d.day = m[1].to!ubyte;
     d.hour = m[4].to!ubyte;
     d.minute = m[5].to!ubyte;
     dateProgrammed = SysTime(d, 0.seconds);

     copy("test_string".representation, full[8..16]);

     import std.format: format;
     string date = format!("%d-%3s-%d 
%02d:%02d")(dateProgrammed.day,
         months[dateProgrammed.month-1], dateProgrammed.year,
     dateProgrammed.hour, dateProgrammed.minute);
     copy(date.representation, full[24..44]);

     Base64.encode(full).writeln;
}
---

The problem is on line 33, the copy of "test_string". The slice 
to copy it into is too short. But when I run it with dub, the 
output is this:
---
core.exception.AssertError at C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\mutation.d(373): Cannot copy a source range into a smaller target range.
----------------
0x0043BE49 in _d_assert_msg
0x0040252B in _Dmain at <snip>\test_format_assert.d(36)
0x0043B96B in void rt.dmain2._d_run_main(int, char**, extern (C) 
int function(char[][])*).runAll().__lambda1()
0x0043B8ED in void rt.dmain2._d_run_main(int, char**, extern (C) 
int function(char[][])*).runAll()
0x0043B787 in _d_run_main
0x0043B518 in main at <snip>\test_format_assert.d(7)
0x0048CED5 in mainCRTStartup
0x767A0419 in BaseThreadInitThunk
0x7730662D in RtlGetAppContainerNamedObjectPath
0x773065FD in RtlGetAppContainerNamedObjectPath
---

The error was on line 36, which is the format, not my bad slice. 
Is there a reason for this, or is it a bug somewhere?


More information about the Digitalmars-d-learn mailing list