January 21, 2005
Here's a summary of the toStringz bug cases Anders and I posted on the main newsgroup. Personally I think this blows big holes in D's claim to be a safe programming language, but I don't have the impression Walter is going to do anything or maybe it's that he hasn't understood the issue. I feel badly for the future D programmers who have to debug a failure due to being unlucky enough to happen to write to the byte past a string. So here are the examples:

case 1: variables on the stack abutting a static char array
import std.string;
int main() {
  char* x;
  uint b1;
  char[4] y;
  uint b2;
  x = toStringz(y);
  assert(strlen(x) == y.length); // will pass
  b1 = 0x11223344;
  b2 = 0x11223344;
  assert(strlen(x) == y.length); // will fail
  return 0;
}

case 2: dynamic arrays abutting each other
import std.string;
int main() {
  char* x;
  char[] y = new char[32];
  y[] = 0;
  char[] z = new char[32];
  z[] = 32;
  x = toStringz(z);
  assert(strlen(x) == z.length); // will pass
  y[] = 32;
  assert(strlen(x) == z.length); // will fail
  return 0;
}

An example due to Anders:
import std.string;
void main()
{
  for (int x = 15; x <= 17; x++)
  {
    char[] a = new char[x];
    char[] b = new char[x];
    char[] c = new char[x];
    a[0] = 0;
    b[0] = 0;
    c[0] = 0;
    printf("%d %p\n",a);
    printf("%d %p\n",b);
    printf("%d %p\n",c);
    char *p = &a[0] + a.length;
    if(*p != 0) printf("not 0\n"); else printf("is 0\n");
    for(int i = 0; i < b.length; i++)
      b[i] = 'A' + i;
    char *z = toStringz(b);
    for(int i = 0; i < a.length; i++)
      a[i] = 'X';
    for(int i = 0; i < c.length; i++)
     c[i] = 'X';
    printf("%s\n",z);
  }
}

An example where the strlen(cstr) is implementation dependent and can be
arbitrary:
import std.string;
int main() {
  char[1] str;
  char* cstr = toStringz(str);
  ubyte x = 1;
  assert( strlen(cstr) == 1 ); // unknown behavior
  return 0;
}

-Ben


January 21, 2005
On Thu, 20 Jan 2005 22:40:11 -0500, Ben Hinkle <ben.hinkle@gmail.com> wrote:
> Here's a summary of the toStringz bug cases Anders and I posted on the main
> newsgroup. Personally I think this blows big holes in D's claim to be a safe
> programming language, but I don't have the impression Walter is going to do
> anything or maybe it's that he hasn't understood the issue.

I sincerely hope Walter has miss-understood the issue.

IMO a function cannot rely on data it has no control over, in this case data that is past the end of the variable it is passed. As you have shown if that data changes then bad things happen.

I had not commented earlier on this as I thought it was so obviously broken that it would be fixed, if that's not the case then I want to hear why...

<snip rest of message>

Regan