www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2975] New: copy - source may exceed target

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2975

           Summary: copy - source may exceed target
           Product: D
           Version: 2.030
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: patch
          Severity: minor
          Priority: P2
         Component: Phobos
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: k-foley onu.edu


Here is the current copy:

Range2 copy(Range1, Range2)(Range1 source, Range2 target)
    if (isInputRange!(Range1)
            && isOutputRange!(Range2, ElementType!(Range1)))
{
    foreach (e; source)
    {
        target.put(e);
    }
    return target;
}

When source has more elements than the target, it's possible to raise an
exception once target.empty is true.  I am unsure whether this is intended
behavior.

Here is what I think it should be:

Range2 copy(Range1, Range2)(Range1 source, Range2 target)
    if (isInputRange!(Range1)
            && isOutputRange!(Range2, ElementType!(Range1)))
{
    while ( !source.empty && !target.empty ) {
      target.put( source.front );
      source.popFront();
    }

    return target;
}

Is there a good reason to let copy proceed once target is exhausted?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 13 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2975


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com



13:21:31 PDT ---
This will be caught in non-release builds, simply because copy calls put(),
which calls front(target), where front() has this assert:
  assert(a.length, "Attempting to fetch the front of an empty array");

The assert goes away in release, which means if you compile the following with
-release the enforce will pass since memory will get overwritten:

import std.algorithm;
import std.exception;

void main()
{
    // compile with -release
    auto a = [1, 2, 3, 4, 5];
    int[] b = new int[3];

    copy(a, b);
    enforce(b[3] == 4);  // oops..
}

If we add your changes it means debug builds will end up doing double checks,
once in copy() where it would check for "!target.empty" (which I think should
actually be expression "target.length"), and once in the call to front() by the
put() function.

I'm not sure what, if anything should be done about this. Personally I would
only expect the possibility of this kind of memory corruption if I pass the
-noboundscheck switch. Anyone else care to share their opinion?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 26 2011
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2975


Jonathan M Davis <jmdavisProg gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |jmdavisProg gmx.com
         Resolution|                            |WONTFIX



PDT ---
Output ranges only require the put function. You can't enquire about their
length or whether they're empty - not unless you're relying on them being
something more specific than just an output range. It's up to the output range
to decide how it deals with calls to put that it can't handle. And it's up to
the caller of copy to make sure that the target has enough space. copy does not
explicitly check and _can't_ check, because output ranges don't give it that
ability.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 26 2011