Fixed undefined behaviour when love exceptions are converted into Lua errors (resolves issue #729)

This commit is contained in:
Alex Szpakowski
2013-09-05 23:17:29 -03:00
parent 389e99bf2c
commit 06f80d5c08
45 changed files with 349 additions and 873 deletions
+5 -16
View File
@@ -46,14 +46,8 @@ int w_Canvas_renderTo(lua_State *L)
Canvas *canvas = luax_checkcanvas(L, 1);
luaL_checktype(L, 2, LUA_TFUNCTION);
try
{
canvas->startGrab();
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(canvas->startGrab();)
lua_settop(L, 2); // make sure the function is on top of the stack
lua_call(L, 0, 0);
canvas->stopGrab();
@@ -76,14 +70,9 @@ int w_Canvas_getPixel(lua_State * L)
int x = luaL_checkint(L, 2);
int y = luaL_checkint(L, 3);
unsigned char c[4];
try
{
canvas->getPixel(c, x, y);
}
catch (love::Exception & e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(canvas->getPixel(c, x, y);)
lua_pushnumber(L, c[0]);
lua_pushnumber(L, c[1]);
lua_pushnumber(L, c[2]);
+9 -31
View File
@@ -44,14 +44,8 @@ int w_Font_getWidth(lua_State *L)
{
Font *t = luax_checkfont(L, 1);
const char *str = luaL_checkstring(L, 2);
try
{
lua_pushinteger(L, t->getWidth(str));
}
catch(love::Exception &e)
{
return luaL_error(L, e.what());
}
EXCEPT_GUARD(lua_pushinteger(L, t->getWidth(str));)
return 1;
}
@@ -61,15 +55,12 @@ int w_Font_getWrap(lua_State *L)
const char *str = luaL_checkstring(L, 2);
float wrap = (float) luaL_checknumber(L, 3);
int max_width = 0, numlines = 0;
try
{
EXCEPT_GUARD(
std::vector<std::string> lines = t->getWrap(str, wrap, &max_width);
numlines = lines.size();
}
catch(love::Exception &e)
{
return luaL_error(L, e.what());
}
)
lua_pushinteger(L, max_width);
lua_pushinteger(L, numlines);
return 2;
@@ -105,15 +96,7 @@ int w_Font_setFilter(lua_State *L)
f.anisotropy = (float) luaL_optnumber(L, 4, 1.0);
try
{
t->setFilter(f);
}
catch(love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(t->setFilter(f);)
return 0;
}
@@ -157,17 +140,12 @@ int w_Font_hasGlyph(lua_State *L)
Font *t = luax_checkfont(L, 1);
bool hasglyph = false;
try
{
EXCEPT_GUARD(
if (lua_type(L, 2) == LUA_TSTRING)
hasglyph = t->hasGlyph(luax_checkstring(L, 2));
else
hasglyph = t->hasGlyph((uint32) luaL_checknumber(L, 2));
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
)
luax_pushboolean(L, hasglyph);
return 1;
+6 -24
View File
@@ -44,9 +44,9 @@ int w_Geometry_getVertexCount(lua_State *L)
int w_Geometry_getVertex(lua_State *L)
{
Geometry *geom = luax_checkgeometry(L, 1);
size_t i = size_t(luaL_checkint(L, 2));
try
{
size_t i = size_t(luaL_checkinteger(L, 2));
EXCEPT_GUARD(
const vertex &v = geom->getVertex(i-1);
lua_pushnumber(L, v.x);
lua_pushnumber(L, v.y);
@@ -56,11 +56,7 @@ int w_Geometry_getVertex(lua_State *L)
lua_pushnumber(L, v.g);
lua_pushnumber(L, v.b);
lua_pushnumber(L, v.a);
}
catch (Exception &e)
{
return luaL_error(L, e.what());
}
)
return 8;
}
@@ -100,14 +96,7 @@ int w_Geometry_setVertex(lua_State *L)
v.a = luaL_optinteger(L, 10, 255);
}
try
{
geom->setVertex(i-1, v);
}
catch (Exception &e)
{
return luaL_error(L, e.what());
}
EXCEPT_GUARD(geom->setVertex(i-1, v);)
if (v.r != 255 || v.g != 255 || v.b != 255 || v.a != 255)
geom->setVertexColors(true);
@@ -198,14 +187,7 @@ int w_Geometry_setVertexMap(lua_State *L)
vertexmap.push_back(luaL_checkinteger(L, i + 2) - 1);
}
try
{
g->setElementArray(&vertexmap[0], vertexmap.size());
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(g->setElementArray(&vertexmap[0], vertexmap.size());)
return 0;
}
+51 -146
View File
@@ -174,29 +174,23 @@ int w_newImage(lua_State *L)
else
data = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
if (!data && !data)
return luaL_error(L, "Error creating image.");
// Create the image.
Image *image = 0;
try
{
EXCEPT_GUARD(
if (cdata)
image = instance->newImage(cdata);
else if (data)
image = instance->newImage(data);
else
throw love::Exception("Error creating image.");
}
catch(love::Exception &e)
{
luaL_error(L, e.what());
}
)
if (image == 0)
return luaL_error(L, "Could not load image.");
// Push the type.
luax_pushtype(L, "Image", GRAPHICS_IMAGE_T, image);
return 1;
}
@@ -321,14 +315,7 @@ int w_newGeometry(lua_State *L)
}
Geometry *geom = 0;
try
{
geom = instance->newGeometry(vertices, vertexmap, mode);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(geom = instance->newGeometry(vertices, vertexmap, mode);)
if (geom == 0)
return luaL_error(L, "Could not create geometry.");
@@ -337,6 +324,7 @@ int w_newGeometry(lua_State *L)
// Note: This should be changed to luax_pushtype if the new Geometry is ever
// expected to be pushed to Lua from another C++ function!
// We're only using rawnewtype instead of pushtype for performance.
luax_rawnewtype(L, "Geometry", GRAPHICS_GEOMETRY_T, geom);
return 1;
}
@@ -354,6 +342,7 @@ int w_newQuad(lua_State *L)
// Note: This should be changed to luax_pushtype if the new Geometry is ever
// expected to be pushed to Lua from another C++ function!
// We're only using rawnewtype instead of pushtype for performance.
luax_rawnewtype(L, "Geometry", GRAPHICS_GEOMETRY_T, quad);
return 1;
}
@@ -373,23 +362,14 @@ int w_newFont(lua_State *L)
love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, "Rasterizer", FONT_RASTERIZER_T);
Font *font = NULL;
try
{
// Create the font.
font = instance->newFont(rasterizer, instance->getDefaultFilter());
}
catch (love::Exception &e)
{
return luaL_error(L, e.what());
}
Font *font = 0;
EXCEPT_GUARD(font = instance->newFont(rasterizer, instance->getDefaultFilter());)
if (font == 0)
return luaL_error(L, "Could not load font.");
// Push the type.
luax_pushtype(L, "Font", GRAPHICS_FONT_T, font);
return 1;
}
@@ -444,15 +424,10 @@ int w_newSpriteBatch(lua_State *L)
if (!SpriteBatch::getConstant(usagestr, usage))
return luaL_error(L, "Invalid SpriteBatch usage hint: %s", usagestr);
}
SpriteBatch *t = NULL;
try
{
t = instance->newSpriteBatch(image, size, usage);
}
catch(love::Exception &e)
{
return luaL_error(L, e.what());
}
SpriteBatch *t = 0;
EXCEPT_GUARD(t = instance->newSpriteBatch(image, size, usage);)
luax_pushtype(L, "SpriteBatch", GRAPHICS_SPRITE_BATCH_T, t);
return 1;
}
@@ -464,14 +439,9 @@ int w_newParticleSystem(lua_State *L)
ParticleSystem *t = 0;
if (size < 1.0 || size > LOVE_UINT32_MAX)
return luaL_error(L, "Invalid ParticleSystem size");
try
{
t = instance->newParticleSystem(image, size);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(t = instance->newParticleSystem(image, size);)
luax_pushtype(L, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T, t);
return 1;
}
@@ -487,17 +457,10 @@ int w_newCanvas(lua_State *L)
if (!Canvas::getConstant(str, texture_type))
return luaL_error(L, "Invalid canvas type: %s", str);
Canvas *canvas = NULL;
try
{
canvas = instance->newCanvas(width, height, texture_type);
}
catch(Exception &e)
{
return luaL_error(L, e.what());
}
Canvas *canvas = 0;
EXCEPT_GUARD(canvas = instance->newCanvas(width, height, texture_type);)
if (NULL == canvas)
if (canvas == 0)
return luaL_error(L, "Canvas not created, but no error thrown. I don't even...");
luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, canvas);
@@ -582,21 +545,25 @@ int w_newShader(lua_State *L)
}
}
bool should_error = false;
try
{
Shader *shader = instance->newShader(sources);
luax_pushtype(L, "Shader", GRAPHICS_SHADER_T, shader);
}
catch (const love::Exception &e)
catch (love::Exception &e)
{
// memory is freed in Graphics::newShader
luax_getfunction(L, "graphics", "_transformGLSLErrorMessages");
lua_pushstring(L, e.what());
// Function pushes the new error string onto the stack.
lua_pcall(L, 1, 1, 0);
const char *err = lua_tostring(L, -1);
return luaL_error(L, "%s", err);
should_error = true;
}
if (should_error)
return lua_error(L);
return 1;
}
@@ -729,32 +696,22 @@ int w_setBlendMode(lua_State *L)
if (!Graphics::getConstant(str, mode))
return luaL_error(L, "Invalid blend mode: %s", str);
try
{
instance->setBlendMode(mode);
}
catch(love::Exception &e)
{
return luaL_error(L, e.what());
}
EXCEPT_GUARD(instance->setBlendMode(mode);)
return 0;
}
int w_getBlendMode(lua_State *L)
{
try
{
Graphics::BlendMode mode = instance->getBlendMode();
const char *str;
if (!Graphics::getConstant(mode, str))
return luaL_error(L, "Unknown blend mode");
lua_pushstring(L, str);
return 1;
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
const char *str;
Graphics::BlendMode mode;
EXCEPT_GUARD(mode = instance->getBlendMode();)
if (!Graphics::getConstant(mode, str))
return luaL_error(L, "Unknown blend mode");
lua_pushstring(L, str);
return 1;
}
int w_setDefaultFilter(lua_State *L)
@@ -933,14 +890,9 @@ int w_newScreenshot(lua_State *L)
love::image::Image *image = luax_getmodule<love::image::Image>(L, "image", MODULE_IMAGE_T);
bool copyAlpha = luax_optboolean(L, 1, false);
love::image::ImageData *i = 0;
try
{
i = instance->newScreenshot(image, copyAlpha);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(i = instance->newScreenshot(image, copyAlpha);)
luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, i);
return 1;
}
@@ -983,17 +935,12 @@ int w_setCanvas(lua_State *L)
attachments.push_back(luax_checkcanvas(L, i));
}
try
{
EXCEPT_GUARD(
if (attachments.size() > 0)
canvas->startGrab(attachments);
else
canvas->startGrab();
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
)
return 0;
}
@@ -1116,15 +1063,7 @@ int w_getRendererInfo(lua_State *L)
if (!Graphics::getConstant(str, infotype))
return luaL_error(L, "Invalid renderer info type: %s", str);
try
{
luax_pushstring(L, instance->getRendererInfo(infotype));
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(luax_pushstring(L, instance->getRendererInfo(infotype));)
return 1;
}
@@ -1177,14 +1116,8 @@ int w_print(lua_State *L)
float oy = (float)luaL_optnumber(L, 8, 0.0f);
float kx = (float)luaL_optnumber(L, 9, 0.0f);
float ky = (float)luaL_optnumber(L, 10, 0.0f);
try
{
instance->print(str, x, y, angle, sx, sy, ox, oy, kx,ky);
}
catch(love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(instance->print(str, x, y, angle, sx, sy, ox, oy, kx,ky);)
return 0;
}
@@ -1220,14 +1153,7 @@ int w_printf(lua_State *L)
ky = (float) luaL_optnumber(L, 12, 0.0f);
}
try
{
instance->printf(str, x, y, wrap, align, angle, sx, sy, ox, oy, kx, ky);
}
catch(love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(instance->printf(str, x, y, wrap, align, angle, sx, sy, ox, oy, kx, ky);)
return 0;
}
@@ -1382,27 +1308,13 @@ int w_polygon(lua_State *L)
int w_push(lua_State *L)
{
try
{
instance->push();
}
catch(love::Exception e)
{
return luaL_error(L, e.what());
}
EXCEPT_GUARD(instance->push();)
return 0;
}
int w_pop(lua_State *L)
{
try
{
instance->pop();
}
catch(love::Exception e)
{
return luaL_error(L, e.what());
}
EXCEPT_GUARD(instance->pop();)
return 0;
}
@@ -1551,14 +1463,7 @@ extern "C" int luaopen_love_graphics(lua_State *L)
{
if (instance == 0)
{
try
{
instance = new Graphics();
}
catch (love::Exception &e)
{
return luaL_error(L, e.what());
}
EXCEPT_GUARD(instance = new Graphics();)
}
else
instance->retain();
+4 -28
View File
@@ -70,15 +70,7 @@ int w_Image_setFilter(lua_State *L)
f.anisotropy = (float) luaL_optnumber(L, 4, 1.0);
try
{
t->setFilter(f);
}
catch(love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(t->setFilter(f);)
return 0;
}
@@ -110,19 +102,11 @@ int w_Image_setMipmapFilter(lua_State *L)
return luaL_error(L, "Invalid filter mode: %s", mipmapstr);
}
try
{
t->setFilter(f);
}
catch(love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(t->setFilter(f);)
float sharpness = luaL_optnumber(L, 3, 0);
t->setMipmapSharpness(sharpness);
return 0;
}
@@ -139,7 +123,6 @@ int w_Image_getMipmapFilter(lua_State *L)
lua_pushnil(L); // only return a mipmap filter if mipmapping is enabled
lua_pushnumber(L, t->getMipmapSharpness());
return 2;
}
@@ -185,14 +168,7 @@ int w_Image_isCompressed(lua_State *L)
int w_Image_refresh(lua_State *L)
{
Image *i = luax_checkimage(L, 1);
try
{
i->refresh();
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(i->refresh();)
return 0;
}
@@ -59,14 +59,8 @@ int w_ParticleSystem_setBufferSize(lua_State *L)
lua_Number arg1 = luaL_checknumber(L, 2);
if (arg1 < 1.0 || arg1 > ParticleSystem::MAX_PARTICLES)
return luaL_error(L, "Invalid buffer size");
try
{
t->setBufferSize((uint32) arg1);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(t->setBufferSize((uint32) arg1);)
return 0;
}
@@ -104,14 +98,7 @@ int w_ParticleSystem_setEmissionRate(lua_State *L)
{
ParticleSystem *t = luax_checkparticlesystem(L, 1);
int arg1 = luaL_checkint(L, 2);
try
{
t->setEmissionRate(arg1);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(t->setEmissionRate(arg1);)
return 0;
}
+22 -24
View File
@@ -130,18 +130,22 @@ int w_Shader_sendInt(lua_State *L)
if (!values)
return luaL_error(L, "Error in arguments.");
bool should_error = false;
try
{
shader->sendInt(name, dimension, values, count);
}
catch (love::Exception &e)
{
delete[] values;
return luaL_error(L, "%s", e.what());
should_error = true;
lua_pushstring(L, e.what());
}
delete[] values;
if (should_error)
return lua_error(L);
return 0;
}
@@ -167,18 +171,22 @@ int w_Shader_sendFloat(lua_State *L)
if (!values)
return luaL_error(L, "Error in arguments.");
bool should_error = false;
try
{
shader->sendFloat(name, dimension, values, count);
}
catch (love::Exception &e)
{
delete[] values;
return luaL_error(L, "%s", e.what());
should_error = true;
lua_pushstring(L, e.what());
}
delete[] values;
if (should_error)
return lua_error(L);
return 0;
}
@@ -225,17 +233,23 @@ int w_Shader_sendMatrix(lua_State *L)
lua_pop(L, 1 + dimension);
}
bool should_error = false;
try
{
shader->sendMatrix(name, dimension, values, count);
}
catch(love::Exception &e)
{
delete[] values;
return luaL_error(L, "%s", e.what());
should_error = true;
lua_pushstring(L, e.what());
}
delete[] values;
if (should_error)
return lua_error(L);
return 0;
}
@@ -245,15 +259,7 @@ int w_Shader_sendImage(lua_State *L)
const char *name = luaL_checkstring(L, 2);
Image *img = luax_checkimage(L, 3);
try
{
shader->sendImage(name, *img);
}
catch(love::Exception &e)
{
luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(shader->sendImage(name, *img);)
return 0;
}
@@ -263,15 +269,7 @@ int w_Shader_sendCanvas(lua_State *L)
const char *name = luaL_checkstring(L, 2);
Canvas *canvas = luax_checkcanvas(L, 3);
try
{
shader->sendCanvas(name, *canvas);
}
catch(love::Exception &e)
{
luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(shader->sendCanvas(name, *canvas);)
return 0;
}
@@ -56,17 +56,12 @@ int w_SpriteBatch_add(lua_State *L)
float ky = (float) luaL_optnumber(L, startidx + 8, 0.0);
int id = 0;
try
{
EXCEPT_GUARD(
if (geom)
id = t->addg(geom, x, y, a, sx, sy, ox, oy, kx, ky);
else
id = t->add(x, y, a, sx, sy, ox, oy, kx, ky);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
)
lua_pushinteger(L, id);
return 1;
@@ -96,17 +91,12 @@ int w_SpriteBatch_set(lua_State *L)
float kx = (float) luaL_optnumber(L, startidx + 7, 0.0);
float ky = (float) luaL_optnumber(L, startidx + 8, 0.0);
try
{
EXCEPT_GUARD(
if (geom)
t->addg(geom, x, y, a, sx, sy, ox, oy, kx, ky, id);
else
t->add(x, y, a, sx, sy, ox, oy, kx, ky, id);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
)
return 0;
}
@@ -121,14 +111,7 @@ int w_SpriteBatch_clear(lua_State *L)
int w_SpriteBatch_bind(lua_State *L)
{
SpriteBatch *t = luax_checkspritebatch(L, 1);
try
{
t->lock();
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(t->lock();)
return 0;
}
@@ -219,14 +202,7 @@ int w_SpriteBatch_setBufferSize(lua_State *L)
{
SpriteBatch *t = luax_checkspritebatch(L, 1);
int size = luaL_checkint(L, 2);
try
{
t->setBufferSize(size);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
EXCEPT_GUARD(t->setBufferSize(size);)
return 0;
}