digitalmars.D.bugs - [Issue 2975] New: copy - source may exceed target
- d-bugmail puremagic.com (42/42) May 13 2009 http://d.puremagic.com/issues/show_bug.cgi?id=2975
- d-bugmail puremagic.com (31/31) May 26 2011 http://d.puremagic.com/issues/show_bug.cgi?id=2975
- d-bugmail puremagic.com (18/18) May 26 2011 http://d.puremagic.com/issues/show_bug.cgi?id=2975
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
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
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









d-bugmail puremagic.com 