Skip to content

Commit

Permalink
std.signals: check for overflow on allocation sizes
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Jul 29, 2016
1 parent 6db08d3 commit 6f5e869
Showing 1 changed file with 27 additions and 2 deletions.
29 changes: 27 additions & 2 deletions std/signals.d
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,13 @@ mixin template Signal(T1...)
}
else
{
len = len * 2 + 4;
auto p = core.stdc.stdlib.realloc(slots.ptr, slot_t.sizeof * len);
import core.checkedint : addu, mulu;
bool overflow;
len = addu(mulu(len, 2, overflow), 4, overflow); // len = len * 2 + 4
const nbytes = mulu(len, slot_t.sizeof, overflow);
if (overflow) assert(0);

auto p = core.stdc.stdlib.realloc(slots.ptr, nbytes);
if (!p)
core.exception.onOutOfMemoryError();
slots = (cast(slot_t*)p)[0 .. len];
Expand Down Expand Up @@ -240,6 +245,13 @@ mixin template Signal(T1...)
}
}

class Observer2
{ // our slot
void watch(string msg, int value)
{
}
}

class Foo
{
int value() { return _value; }
Expand All @@ -263,12 +275,25 @@ mixin template Signal(T1...)

Foo a = new Foo;
Observer o = new Observer;
auto o2 = new Observer2;
auto o3 = new Observer2;
auto o4 = new Observer2;
auto o5 = new Observer2;

a.value = 3; // should not call o.watch()
a.connect(&o.watch); // o.watch is the slot
a.connect(&o2.watch);
a.connect(&o3.watch);
a.connect(&o4.watch);
a.connect(&o5.watch);
a.value = 4; // should call o.watch()
a.disconnect(&o.watch); // o.watch is no longer a slot
a.disconnect(&o3.watch);
a.disconnect(&o5.watch);
a.disconnect(&o4.watch);
a.disconnect(&o2.watch);
a.value = 5; // so should not call o.watch()
a.connect(&o2.watch);
a.connect(&o.watch); // connect again
a.value = 6; // should call o.watch()
destroy(o); // destroying o should automatically disconnect it
Expand Down

0 comments on commit 6f5e869

Please sign in to comment.