diff --git a/ChangeLog b/ChangeLog index fc7d0b3..470a1a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,10 @@ 2011-02-04 Holger Hans Peter Freyther + * libgst/cint.c: Propagate type conversion failures. + +2011-02-04 Holger Hans Peter Freyther + * tests/testsuite.at: Add the Sockets test. 2011-02-04 Holger Hans Peter Freyther diff --git a/libgst/cint.c b/libgst/cint.c index ec6bc18..d16b153 100644 --- a/libgst/cint.c +++ b/libgst/cint.c @@ -7,7 +7,7 @@ /*********************************************************************** * - * Copyright 1988,89,90,91,92,94,95,99,2000,2001,2002,2003,2005,2006,2007,2008,2009 + * Copyright 1988,89,90,91,92,94,95,99,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 * Free Software Foundation, Inc. * Written by Steve Byrne. * @@ -150,9 +150,10 @@ static void marli (int n); static void bad_type (OOP class_oop, cdata_type cType); -/* Determines the appropriate C mapping for OOP and stores it. */ -static void push_smalltalk_obj (OOP oop, - cdata_type cType); +/* Determines the appropriate C mapping for OOP and stores it. This + returns 1 in case the type could not be converted. */ +static int push_smalltalk_obj (OOP oop, + cdata_type cType); /* Converts the return type as stored in RESULT to an OOP, based on the RETURNTYPEOOP that is stored in the descriptor. #void is @@ -852,13 +853,18 @@ _gst_invoke_croutine (OOP cFuncOOP, /* Push the arguments */ for (si = i = 0; i < fixedArgs; i++) { + int res = 0; + cType = IS_OOP (argTypes[i]) ? CDATA_COBJECT : TO_INT (argTypes[i]); if (cType == CDATA_SELF || cType == CDATA_SELF_OOP) - push_smalltalk_obj (receiver, - cType == CDATA_SELF ? CDATA_UNKNOWN : CDATA_OOP); + res = push_smalltalk_obj (receiver, + cType == CDATA_SELF ? CDATA_UNKNOWN : CDATA_OOP); else if (cType != CDATA_VOID) /* Do nothing if it is a void */ - push_smalltalk_obj (args[si++], cType); + res = push_smalltalk_obj (args[si++], cType); + + if (res != 0) + goto cleanup; } /* If the previous call was done through the same function descriptor, @@ -917,6 +923,19 @@ _gst_invoke_croutine (OOP cFuncOOP, INC_RESTORE_POINTER (incPtr); return (oop); + +cleanup: + /* Attempt to cleanup all pushing of arguments. We have tried to + write at si and now need to cleanup up until this point. */ + for (i = 0, arg = local_arg_vec; i < si; i++, arg++) + { + if (!arg->oop) + continue; + + xfree (arg->u.ptrVal); + } + INC_RESTORE_POINTER (incPtr); + return NULL; } ffi_type * @@ -1191,7 +1210,7 @@ smalltalk_to_c (OOP oop, return NULL; } -void +int push_smalltalk_obj (OOP oop, cdata_type cType) { @@ -1201,12 +1220,13 @@ push_smalltalk_obj (OOP oop, if (OOP_INT_CLASS (oop) != _gst_array_class) { bad_type (OOP_INT_CLASS (oop), cType); - return; + return 1; } cType = (cType == CDATA_VARIADIC) ? CDATA_UNKNOWN : CDATA_OOP; for (i = 1; i <= NUM_WORDS (OOP_TO_OBJ (oop)); i++) - push_smalltalk_obj (ARRAY_AT (oop, i), cType); + if (push_smalltalk_obj (ARRAY_AT (oop, i), cType) != 0) + return 1; } else { @@ -1216,7 +1236,11 @@ push_smalltalk_obj (OOP oop, INC_ADD_OOP (cp->oop); if (type) c_func_cur->types[c_func_cur->arg_idx++] = type; + else + return 1; } + + return 0; } OOP @@ -1345,8 +1369,6 @@ bad_type (OOP class_oop, else _gst_errorf ("Attempt to pass an instance of %O as a %s", class_oop, c_type_name[cType]); - - _gst_show_backtrace (stderr); } @@ -1381,10 +1403,9 @@ closure_msg_send (ffi_cif* cif, void* result, void** args, void* userdata) desc = (gst_c_callable) OOP_TO_OBJ (callbackOOP); cType = IS_OOP (desc->returnTypeOOP) ? CDATA_COBJECT : TO_INT (desc->returnTypeOOP); - if (cType != CDATA_VOID) + if (cType != CDATA_VOID && smalltalk_to_c (resultOOP, &cp, cType)) { - smalltalk_to_c (resultOOP, &cp, cType); - memcpy (result, &cp.u, sizeof (ffi_arg)); + memcpy (result, &cp.u, sizeof (ffi_arg)); } } diff --git a/packages/sockets/ChangeLog b/packages/sockets/ChangeLog index 2cb65f7..69726c8 100644 --- a/packages/sockets/ChangeLog +++ b/packages/sockets/ChangeLog @@ -1,5 +1,9 @@ 2011-02-04 Holger Hans Peter Freyther + * UnitTest.st: Verify that the primitive are failing. + +2011-02-04 Holger Hans Peter Freyther + * package.xml: Add test section. * UnitTest.st: Add SUnit based testcase. diff --git a/packages/sockets/UnitTest.st b/packages/sockets/UnitTest.st index abd59c2..da19943 100644 --- a/packages/sockets/UnitTest.st +++ b/packages/sockets/UnitTest.st @@ -50,4 +50,19 @@ TestCase subclass: SocketTest [ datagram := Datagram new. socket nextPut: datagram. ] + + testDoNotCrashWithWrongTypes [ + "The objective is to see if wrong types for a cCallout will + make the VM crash or not. It should also check if these calls + raise the appropriate exception." + | socket impl | + + socket := DatagramSocket new. + impl := socket implementation. + + self should: [impl accept: -1 peer: nil addrLen: 0] raise: SystemExceptions.PrimitiveFailed. + self should: [impl getPeerName: -1 addr: nil addrLen: 0] raise: SystemExceptions.PrimitiveFailed. + self should: [impl getSockName: -1 addr: nil addrLen: 0] raise: SystemExceptions.PrimitiveFailed. + self should: [impl receive: -1 buffer: nil size: 0 flags: 0 from: nil size: 0] raise: SystemExceptions.PrimitiveFailed. + ] ]