fix some integer conversions in the Table class

Sizes (x, y, z) are clamped to a non-negative int value.
Use NUM2INT instead of FIX2INT as the argument might not be a Fixnum.
This commit is contained in:
cremno 2014-08-31 04:31:46 +02:00
parent d8bb6aa2fc
commit acf826eb7a
1 changed files with 44 additions and 31 deletions

View File

@ -23,14 +23,39 @@
#include "binding-util.h" #include "binding-util.h"
#include "serializable-binding.h" #include "serializable-binding.h"
static int num2TableSize(VALUE v)
{
int i = NUM2INT(v);
return i >= 0 ? i : 0;
}
static void parseArgsTableSizes(int argc, VALUE *argv, int *x, int *y, int *z)
{
*y = *z = 1;
switch (argc)
{
case 3:
*z = num2TableSize(argv[2]);
/* fall through */
case 2:
*y = num2TableSize(argv[1]);
/* fall through */
case 1:
*x = num2TableSize(argv[0]);
break;
default:
rb_error_arity(argc, 1, 3);
}
}
DEF_TYPE(Table); DEF_TYPE(Table);
RB_METHOD(tableInitialize) RB_METHOD(tableInitialize)
{ {
int x, y, z; int x, y, z;
x = y = z = 1;
rb_get_args(argc, argv, "i|ii", &x, &y, &z RB_ARG_END); parseArgsTableSizes(argc, argv, &x, &y, &z);
Table *t = new Table(x, y, z); Table *t = new Table(x, y, z);
@ -43,24 +68,12 @@ RB_METHOD(tableResize)
{ {
Table *t = getPrivateData<Table>(self); Table *t = getPrivateData<Table>(self);
switch (argc) int x, y, z;
{ parseArgsTableSizes(argc, argv, &x, &y, &z);
default:
case 1:
t->resize(FIX2INT(argv[0]));
return Qnil;
case 2: t->resize(x, y, z);
t->resize(FIX2INT(argv[0]),
FIX2INT(argv[1]));
return Qnil;
case 3:
t->resize(FIX2INT(argv[0]),
FIX2INT(argv[1]),
FIX2INT(argv[2]));
return Qnil; return Qnil;
}
} }
#define TABLE_SIZE(d, D) \ #define TABLE_SIZE(d, D) \
@ -68,7 +81,7 @@ RB_METHOD(tableResize)
{ \ { \
RB_UNUSED_PARAM \ RB_UNUSED_PARAM \
Table *t = getPrivateData<Table>(self); \ Table *t = getPrivateData<Table>(self); \
return rb_int2inum(t->d##Size()); \ return INT2NUM(t->d##Size()); \
} }
TABLE_SIZE(x, X) TABLE_SIZE(x, X)
@ -98,9 +111,9 @@ RB_METHOD(tableGetAt)
return Qnil; return Qnil;
} }
int result = t->get(x, y, z); short result = t->get(x, y, z);
return rb_int2inum(result); return INT2FIX(result); /* short always fits in a Fixnum */
} }
RB_METHOD(tableSetAt) RB_METHOD(tableSetAt)
@ -117,28 +130,28 @@ RB_METHOD(tableSetAt)
{ {
default: default:
case 2 : case 2 :
x = FIX2INT(argv[0]); x = NUM2INT(argv[0]);
value = FIX2INT(argv[1]); value = NUM2INT(argv[1]);
break; break;
case 3 : case 3 :
x = FIX2INT(argv[0]); x = NUM2INT(argv[0]);
y = FIX2INT(argv[1]); y = NUM2INT(argv[1]);
value = FIX2INT(argv[2]); value = NUM2INT(argv[2]);
break; break;
case 4 : case 4 :
x = FIX2INT(argv[0]); x = NUM2INT(argv[0]);
y = FIX2INT(argv[1]); y = NUM2INT(argv[1]);
z = FIX2INT(argv[2]); z = NUM2INT(argv[2]);
value = FIX2INT(argv[3]); value = NUM2INT(argv[3]);
break; break;
} }
t->set(value, x, y, z); t->set(value, x, y, z);
return rb_int2inum(value); return argv[argc - 1];
} }
MARSH_LOAD_FUN(Table) MARSH_LOAD_FUN(Table)