diff --git a/obj_context.c b/obj_context.c index 8f28a81..5a18801 100644 --- a/obj_context.c +++ b/obj_context.c @@ -229,7 +229,9 @@ cr_get_dash (lua_State *L) { cnt = cairo_get_dash_count(*obj); if (cnt > 0) { dashes = malloc(sizeof(double) * cnt); - assert(dashes); + if (!dashes) { + return luaL_error(L, "out of memory"); + } } cairo_get_dash(*obj, dashes, &offset); @@ -642,7 +644,9 @@ cr_set_dash (lua_State *L) { num_dashes = lua_objlen(L, 2); if (num_dashes > 0) { dashes = malloc(sizeof(double) * num_dashes); - assert(dashes); + if (!dashes) { + return luaL_error(L, "out of memory"); + } dashtotal = 0; for (i = 0; i < num_dashes; ++i) { diff --git a/obj_font_face.c b/obj_font_face.c index 1aeb13f..016b6d9 100644 --- a/obj_font_face.c +++ b/obj_font_face.c @@ -197,7 +197,9 @@ user_font_face_create (lua_State *L) { lua_createtable(L, 4, 0); info = malloc(sizeof(UserFontInfo)); - assert(info); + if (!info) { + return luaL_error(L, "out of memory"); + } info->L = L; info->ref = LUA_NOREF; diff --git a/obj_region.c b/obj_region.c index 32f6a7d..e8b771a 100644 --- a/obj_region.c +++ b/obj_region.c @@ -39,23 +39,20 @@ region_create_rectangle (lua_State *L) { static int region_create_rectangles (lua_State *L) { - size_t max_entries = lua_objlen (L, 1); - cairo_rectangle_int_t *rects = calloc(max_entries, sizeof(*rects)); - size_t i = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* discard other args */ + size_t max_entries = lua_objlen (L, 1); + cairo_rectangle_int_t *rects = lua_newuserdata(L, max_entries * sizeof(cairo_rectangle_int_t)); + size_t i; + /* Now iterate over the table */ - lua_pushnil(L); - while (lua_next(L, 1) != 0) { - if (i >= max_entries) - return luaL_error(L, "Cairo.region_create_rectangles(): Internal error, table larger than table?!"); - from_lua_rectangle (L, &rects[i], 3); - i++; - lua_pop(L, 1); + for (i = 0; i < max_entries; ++i) { + from_lua_rectangle_list_element(L, &rects[i], 1, i+1); } cairo_region_t **reg = create_region_userdata(L); *reg = cairo_region_create_rectangles(rects, i); - free(rects); return 1; } diff --git a/obj_surface.c b/obj_surface.c index 1fbda57..fea6aa8 100644 --- a/obj_surface.c +++ b/obj_surface.c @@ -68,7 +68,9 @@ image_surface_create_from_data (lua_State *L) { surface = create_surface_userdata(L); surface->image_buffer = malloc(data_len); - assert(surface->image_buffer); + if (!surface->image_buffer) { + return luaL_error(L, "out of memory"); + } memcpy(surface->image_buffer, data, data_len); surface->surface = cairo_image_surface_create_for_data( surface->image_buffer, fmt, width, height, stride); @@ -474,7 +476,9 @@ surface_get_gdk_pixbuf (lua_State *L) { strideo = ((3 * width) + 7) & ~7; /* align to 8 bytes */ buffer_len = strideo * height; buffer = malloc(buffer_len); - assert(buffer); + if (!buffer) { + return luaL_error(L, "out of memory"); + } rowpi = (const char *) cairo_image_surface_get_data(*surface); rowpo = buffer; @@ -719,7 +723,7 @@ set_mime_data(lua_State *L) mime_data = luaL_checklstring(L, 3, &data_length); mime_priv = malloc(data_length); if (!mime_priv) { - return push_cairo_status(L, CAIRO_STATUS_NO_MEMORY); + return luaL_error(L, "out of memory"); } memcpy(mime_priv, mime_data, data_length); } diff --git a/oocairo.c b/oocairo.c index 235ccff..6fff917 100644 --- a/oocairo.c +++ b/oocairo.c @@ -53,6 +53,12 @@ static int luaL_typerror (lua_State *L, int narg, const char *tname) { #define lua_rawlen(a, b) do_not_use_lua_rawlen_use_lua_objlen_instead; #endif +#if LUA_VERSION_NUM >= 503 +#define oocairo_lua_isinteger(L, idx) lua_isinteger(L, idx) +#else +#define oocairo_lua_isinteger(L, idx) lua_isnumber(L, idx) +#endif + static const int ENDIANNESS_TEST_VAL = 1; #define IS_BIG_ENDIAN (!(*(const char *) &ENDIANNESS_TEST_VAL)) @@ -363,12 +369,37 @@ from_lua_rectangle (lua_State *L, cairo_rectangle_int_t *rect, int pos) { #define DO(t) \ lua_pushstring(L, #t); \ lua_gettable(L, pos); \ - rect->t = luaL_checkinteger(L, -1); \ + if (!oocairo_lua_isinteger(L, -1)) { \ + luaL_argerror(L, pos, "invalid rectangle: coordinates must be integer values"); \ + } \ + rect->t = lua_tointeger(L, -1); \ + lua_pop(L, 1) + DO(x); + DO(y); + DO(width); + DO(height); +#undef DO +} + +static void +from_lua_rectangle_list_element (lua_State *L, cairo_rectangle_int_t *rect, int list_pos, int element_index) { + lua_rawgeti(L, list_pos, element_index); /* push rectangle from list */ + if (lua_type(L, -1) != LUA_TTABLE) { + luaL_argerror(L, list_pos, "list contains invalid rectangle"); + } +#define DO(t) \ + lua_pushstring(L, #t); \ + lua_gettable(L, -2); \ + if (!oocairo_lua_isinteger(L, -1)) { \ + luaL_argerror(L, list_pos, "list contains invalid rectangle: coordinates must be integer values"); \ + } \ + rect->t = lua_tointeger(L, -1); \ lua_pop(L, 1) DO(x); DO(y); DO(width); DO(height); + lua_pop(L, 1); /* pop rectangle */ #undef DO } #endif @@ -494,7 +525,9 @@ from_lua_glyph_array (lua_State *L, cairo_glyph_t **glyphs, int *num_glyphs, return; } *glyphs = GLYPHS_ALLOC(*num_glyphs); - assert(*glyphs); + if (!*glyphs) { + return luaL_error(L, "out of memory"); + } for (i = 0; i < *num_glyphs; ++i) { lua_rawgeti(L, pos, i + 1); @@ -578,7 +611,9 @@ from_lua_clusters_table (lua_State *L, cairo_text_cluster_t **clusters, return; } *clusters = cairo_text_cluster_allocate(*num); - assert(*clusters); + if (!*clusters) { + return luaL_error(L, "out of memory"); + } for (i = 0; i < *num; ++i) { lua_rawgeti(L, pos, i + 1); @@ -778,8 +813,9 @@ free_surface_userdata (SurfaceUserdata *ud) { static char * my_strdup (const char *s) { char *copy = malloc(strlen(s) + 1); - assert(copy); - strcpy(copy, s); + if (copy) { + strcpy(copy, s); + } return copy; } diff --git a/test/region.lua b/test/region.lua index 7eb8077..c655430 100644 --- a/test/region.lua +++ b/test/region.lua @@ -52,6 +52,11 @@ if Cairo.check_version(1, 10, 0) then assert_equal(reg:contains_rectangle(rect), "overlap-in") rect.width = 8 assert_equal(reg:contains_rectangle(rect), "overlap-part") + local ok, errmsg = pcall(function() + reg:contains_rectangle({ x = 0, y = 0 }) + end) + assert_false(ok) + assert_match("bad argument %#1 to %'contains_rectangle%' %(invalid rectangle%: coordinates must be integer values%)", errmsg) end function module.test_copy () @@ -136,6 +141,55 @@ if Cairo.check_version(1, 10, 0) then assert_equal(rect[2].y, 10) assert_equal(rect[2].width, 1) assert_equal(rect[2].height, 1) + + local reg = Cairo.region_create_rectangles(rects, "unused") + local rect = reg:get_rectangles() + assert_equal(#rect, 2) + assert_equal(rect[1].x, 0) + assert_equal(rect[1].y, 0) + assert_equal(rect[1].width, 1) + assert_equal(rect[1].height, 1) + assert_equal(rect[2].x, 10) + assert_equal(rect[2].y, 10) + assert_equal(rect[2].width, 1) + assert_equal(rect[2].height, 1) + + local rects = { rect1, rect2, unused = true } + local reg = Cairo.region_create_rectangles(rects) + local rect = reg:get_rectangles() + assert_equal(#rect, 2) + assert_equal(rect[1].x, 0) + assert_equal(rect[1].y, 0) + assert_equal(rect[1].width, 1) + assert_equal(rect[1].height, 1) + assert_equal(rect[2].x, 10) + assert_equal(rect[2].y, 10) + assert_equal(rect[2].width, 1) + assert_equal(rect[2].height, 1) + + local rect3 = { x = 0, y = 0 } + local rects = { rect1, rect2, rect3 } + local ok, errmsg = pcall(function() + Cairo.region_create_rectangles(rects) + end) + assert_false(ok) + assert_match("bad argument %#1 to %'region_create_rectangles%' %(list contains invalid rectangle%: coordinates must be integer values%)", errmsg) + + local rect3 = { x = 0, y = 0, width = 10, height = {} } + local rects = { rect1, rect2, rect3 } + local ok, errmsg = pcall(function() + Cairo.region_create_rectangles(rects) + end) + assert_false(ok) + assert_match("bad argument %#1 to %'region_create_rectangles%' %(list contains invalid rectangle%: coordinates must be integer values%)", errmsg) + + local rects = { rect1, rect2, "" } + local ok, errmsg = pcall(function() + Cairo.region_create_rectangles(rects) + end) + assert_false(ok) + assert_match("bad argument %#1 to %'region_create_rectangles%' %(list contains invalid rectangle%)", errmsg) + end end diff --git a/test/surface.lua b/test/surface.lua index baf7006..9c044f2 100644 --- a/test/surface.lua +++ b/test/surface.lua @@ -433,7 +433,9 @@ if Cairo.check_version(1, 10, 0) then test("test/data", "test data") local surface = Cairo.image_surface_create("rgb24", 0, 0) - assert_error(function () surface_set_mime_data(nil, "foo") end) + local ok, errmsg = pcall(function () surface:set_mime_data(nil, "foo") end) + assert_false(ok) + assert_match("bad argument %#1 to %'set_mime_data%' %(string expected%, got nil%)", errmsg) end end