Skip to content

Commit fe7ec6d

Browse files
committed
avoid integer overflow in ensureSurface
width * height * approxBytesPerPixel was too big Zig found via ubsan
1 parent 4ae26ab commit fe7ec6d

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

src/Canvas.cc

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
using namespace std;
3535

36+
#define CAIRO_MAX_SIZE 32767
37+
3638
/*
3739
* Initialize Canvas.
3840
*/
@@ -79,6 +81,11 @@ Canvas::Canvas(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Canvas>(info),
7981
_surface = nullptr;
8082
_closure = nullptr;
8183
format = CAIRO_FORMAT_ARGB32;
84+
this->width = 0;
85+
this->height = 0;
86+
87+
int32_t width;
88+
int32_t height;
8289

8390
if (info[0].IsNumber()) {
8491
width = info[0].As<Napi::Number>().Int32Value();
@@ -104,6 +111,21 @@ Canvas::Canvas(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Canvas>(info),
104111
type = CANVAS_TYPE_IMAGE;
105112
}
106113

114+
if (width > CAIRO_MAX_SIZE || width < 0) {
115+
std::string msg = "Canvas width must be between 0 and " + std::to_string(CAIRO_MAX_SIZE);
116+
Napi::Error::New(env, msg).ThrowAsJavaScriptException();
117+
return;
118+
}
119+
120+
if (height > CAIRO_MAX_SIZE || height < 0) {
121+
std::string msg = "Canvas height must be between 0 and " + std::to_string(CAIRO_MAX_SIZE);
122+
Napi::Error::New(env, msg).ThrowAsJavaScriptException();
123+
return;
124+
}
125+
126+
this->width = width;
127+
this->height = height;
128+
107129
cairo_status_t status = cairo_surface_status(ensureSurface());
108130

109131
if (status != CAIRO_STATUS_SUCCESS) {
@@ -156,8 +178,11 @@ Canvas::GetWidth(const Napi::CallbackInfo& info) {
156178
void
157179
Canvas::SetWidth(const Napi::CallbackInfo& info, const Napi::Value& value) {
158180
if (value.IsNumber()) {
159-
width = value.As<Napi::Number>().Uint32Value();
160-
resurface(info.This().As<Napi::Object>());
181+
int32_t width = value.As<Napi::Number>().Int32Value();
182+
if (width >= 0 && width <= CAIRO_MAX_SIZE) {
183+
this->width = width;
184+
resurface(info.This().As<Napi::Object>());
185+
}
161186
}
162187
}
163188

@@ -177,8 +202,11 @@ Canvas::GetHeight(const Napi::CallbackInfo& info) {
177202
void
178203
Canvas::SetHeight(const Napi::CallbackInfo& info, const Napi::Value& value) {
179204
if (value.IsNumber()) {
180-
height = value.As<Napi::Number>().Uint32Value();
181-
resurface(info.This().As<Napi::Object>());
205+
int32_t height = value.As<Napi::Number>().Uint32Value();
206+
if (height >= 0 && height <= CAIRO_MAX_SIZE) {
207+
this->height = height;
208+
resurface(info.This().As<Napi::Object>());
209+
}
182210
}
183211
}
184212

0 commit comments

Comments
 (0)