Skip to content

Commit ac355ba

Browse files
committed
wrap negative values passed to createImageData
instead of crashing
1 parent 9249c02 commit ac355ba

2 files changed

Lines changed: 22 additions & 6 deletions

File tree

src/CanvasRenderingContext2d.cc

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,20 +1219,27 @@ Napi::Value
12191219
Context2d::CreateImageData(const Napi::CallbackInfo& info){
12201220
Canvas *canvas = this->canvas();
12211221
Napi::Number zero = Napi::Number::New(env, 0);
1222-
int32_t width, height;
1222+
uint32_t width, height;
12231223

12241224
if (info[0].IsObject()) {
12251225
Napi::Object obj = info[0].As<Napi::Object>();
1226-
width = obj.Get("width").UnwrapOr(zero).ToNumber().UnwrapOr(zero).Int32Value();
1227-
height = obj.Get("height").UnwrapOr(zero).ToNumber().UnwrapOr(zero).Int32Value();
1226+
width = obj.Get("width").UnwrapOr(zero).ToNumber().UnwrapOr(zero).Uint32Value();
1227+
height = obj.Get("height").UnwrapOr(zero).ToNumber().UnwrapOr(zero).Uint32Value();
12281228
} else {
1229-
width = info[0].ToNumber().UnwrapOr(zero).Int32Value();
1230-
height = info[1].ToNumber().UnwrapOr(zero).Int32Value();
1229+
width = info[0].ToNumber().UnwrapOr(zero).Uint32Value();
1230+
height = info[1].ToNumber().UnwrapOr(zero).Uint32Value();
12311231
}
12321232

12331233
int stride = canvas->stride();
12341234
double Bpp = static_cast<double>(stride) / canvas->getWidth();
1235-
int nBytes = static_cast<int>(Bpp * width * height + .5);
1235+
int64_t nBytes = Bpp * width * height + .5;
1236+
1237+
if (nBytes > INT32_MAX) {
1238+
// INT32_MAX is what Firefox limits the buffer to
1239+
std::string msg = "buffer exceeds " + std::to_string(INT32_MAX) + " bytes";
1240+
Napi::Error::New(env, msg).ThrowAsJavaScriptException();
1241+
return env.Undefined();
1242+
}
12361243

12371244
Napi::ArrayBuffer ab = Napi::ArrayBuffer::New(env, nBytes);
12381245
Napi::Value arr;

test/canvas.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,15 @@ describe('Canvas', function () {
988988
assert.equal(0, imageData.data[0])
989989
assert.equal(0, imageData.data[1])
990990
})
991+
992+
it('wraps negative values', function () {
993+
const canvas = createCanvas(20, 20)
994+
const ctx = canvas.getContext('2d')
995+
// WebIDL says this should throw, but we skip [EnforceRange]
996+
const data = ctx.createImageData(-0xfffffffe, -0xfffffffe);
997+
assert.equal(data.width, 2);
998+
assert.equal(data.height, 2);
999+
})
9911000
})
9921001

9931002
describe('Context2d#measureText()', function () {

0 commit comments

Comments
 (0)