diff options
21 files changed, 651 insertions, 61 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 6b825cc7326..3a81fdf910d 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,49 @@ +Tue Oct 6 09:43:40 UTC 2009 Vladimir Zykov <vz@prismtech.com> + + * tao/Bounded_Sequence_CDR_T.h: + * tao/Bounded_Array_Sequence_T.h: + * tao/Bounded_Basic_String_Sequence_T.h: + * tao/Range_Checking_T.h: + * tao/Valuetype/Bounded_Valuetype_Sequence_T.h: + * tao/Bounded_Value_Sequence_T.h: + * tao/Bounded_Object_Reference_Sequence_T.h: + + Fixed a bug#3746. Now if TAO_CHECKED_SEQUENCE_INDEXING + is defined sequence code will throw BAD_PARAM in case + there is an attempt to access elements above maximum. + Also there will be BAD_PARAM exception in case new sequence's + length is greater than bound and marshaling of bounded + sequences will fail if sequence length is above maximum. + + * tests/Bug_3746_Regression/client.cpp: + * tests/Bug_3746_Regression/Test.idl: + * tests/Bug_3746_Regression/server.cpp: + * tests/Bug_3746_Regression/Test_i.cpp: + * tests/Bug_3746_Regression/Test_i.h: + * tests/Bug_3746_Regression/run_test.pl: + * bin/tao_orb_tests.lst: + + Added a test for bug#3746. + + * tests/Sequence_Unit_Tests/Bounded_String.cpp: + * tests/Sequence_Unit_Tests/Unbounded_String.cpp: + * tests/Sequence_Unit_Tests/Unbounded_Octet.cpp: + * tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp: + * tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp: + + Fixed sequence unit tests for proper testing of code + added with the fix for bug#3746. + + * tests/Sequence_Unit_Tests/string_sequence_tester.hpp: + + Rearranged the code. This fixes stack overflow exception in + standard/inline builds on win32. The problem was related to + incorrect code generation with /O2 optimization level. The + above exception was easy to reproduce when stepping through + assembler code. The exception was thrown by the code preceding + the first line of a test_duplicate_exception_in_assignment() + function. + Mon Oct 5 14:29:52 UTC 2009 Marcel Smit <msmit@remedy.nl> * tests/RTCORBA/Priority_Inversion_With_Bands/run_test.pl: diff --git a/TAO/bin/tao_orb_tests.lst b/TAO/bin/tao_orb_tests.lst index a35d383c0e4..acf843bd175 100644 --- a/TAO/bin/tao_orb_tests.lst +++ b/TAO/bin/tao_orb_tests.lst @@ -166,6 +166,7 @@ TAO/tests/Bug_3683_Regression/run_test.pl: TAO/tests/Bug_3695_Regression/run_test.pl: TAO/tests/Bug_3701_Regression/run_test.pl: TAO/tests/Bug_3743_Regression/run_test.pl: !NO_IFR !LabVIEW_RT !WinCE !FUZZ +TAO/tests/Bug_3746_Regression/run_test.pl: TAO/tests/DIOP/run_test.pl: !ST !NO_DIOP !ACE_FOR_TAO !CORBA_E_MICRO !LabVIEW_RT !WinCE !FUZZ TAO/tests/DIOP/run_test_ipv6.pl: IPV6 !ST !NO_DIOP !ACE_FOR_TAO !CORBA_E_MICRO !LabVIEW_RT !WinCE !FUZZ TAO/tests/RTCORBA/Activate_Object_Multiple_ORBs/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ST diff --git a/TAO/tao/Bounded_Array_Sequence_T.h b/TAO/tao/Bounded_Array_Sequence_T.h index d9961cffa73..3d02cbdafde 100644 --- a/TAO/tao/Bounded_Array_Sequence_T.h +++ b/TAO/tao/Bounded_Array_Sequence_T.h @@ -54,10 +54,8 @@ public: return impl_.length(); } inline void length(CORBA::ULong length) { - if (MAX >= length) - { - impl_.length(length); - } + implementation_type::range::check_length(length, MAX); + impl_.length(length); } inline value_type const & operator[](CORBA::ULong i) const { return impl_[i]; @@ -134,7 +132,7 @@ namespace TAO typedef TAO_FixedArray_Var_T <T_array, T_slice, T_tag> fixed_array; typedef TAO::Array_Traits<forany> array_traits; ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } for(CORBA::ULong i = 0; i < length; ++i) { diff --git a/TAO/tao/Bounded_Basic_String_Sequence_T.h b/TAO/tao/Bounded_Basic_String_Sequence_T.h index 3533c987dcf..dc8e60cc348 100644 --- a/TAO/tao/Bounded_Basic_String_Sequence_T.h +++ b/TAO/tao/Bounded_Basic_String_Sequence_T.h @@ -66,10 +66,7 @@ public: /// @copydoc details::generic_sequence::length inline void length(CORBA::ULong length) { implementation_type::range::check_length(length, MAX); - if (MAX >= length) - { - impl_.length(length); - } + impl_.length(length); } /// @copydoc details::generic_sequence::operator[] inline const_element_type operator[](CORBA::ULong i) const { diff --git a/TAO/tao/Bounded_Object_Reference_Sequence_T.h b/TAO/tao/Bounded_Object_Reference_Sequence_T.h index fe4877c93af..03317510e05 100644 --- a/TAO/tao/Bounded_Object_Reference_Sequence_T.h +++ b/TAO/tao/Bounded_Object_Reference_Sequence_T.h @@ -68,10 +68,7 @@ public: /// @copydoc details::generic_sequence::length inline void length(CORBA::ULong length) { implementation_type::range::check_length(length, MAX); - if (MAX >= length) - { - impl_.length(length); - } + impl_.length(length); } /// @copydoc details::generic_sequence::operator[] inline const_element_type operator[](CORBA::ULong i) const { diff --git a/TAO/tao/Bounded_Sequence_CDR_T.h b/TAO/tao/Bounded_Sequence_CDR_T.h index 08201191eab..e5a4adeb672 100644 --- a/TAO/tao/Bounded_Sequence_CDR_T.h +++ b/TAO/tao/Bounded_Sequence_CDR_T.h @@ -390,7 +390,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::Short, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_short_array (source.get_buffer (), length); @@ -399,7 +399,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::Long, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_long_array (source.get_buffer (), length); @@ -408,7 +408,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::ULong, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_ulong_array (source.get_buffer (), length); @@ -417,7 +417,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::UShort, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_ushort_array (source.get_buffer (), length); @@ -426,7 +426,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::Octet, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_octet_array (source.get_buffer (), length); @@ -435,7 +435,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::Char, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_char_array (source.get_buffer (), length); @@ -445,7 +445,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::WChar, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_wchar_array (source.get_buffer (), length); @@ -455,7 +455,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::Float, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_float_array (source.get_buffer (), length); @@ -464,7 +464,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::Double, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_double_array (source.get_buffer (), length); @@ -473,7 +473,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::LongLong, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_longlong_array (source.get_buffer (), length); @@ -482,7 +482,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::ULongLong, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_ulonglong_array (source.get_buffer (), length); @@ -491,7 +491,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::LongDouble, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_longdouble_array (source.get_buffer (), length); @@ -500,7 +500,7 @@ namespace TAO { template <typename stream, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <CORBA::Boolean, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } return strm.write_boolean_array (source.get_buffer (), length); @@ -509,7 +509,7 @@ namespace TAO { template <typename stream, typename value_t, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_value_sequence <value_t, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } for(CORBA::ULong i = 0; i < length; ++i) { @@ -523,7 +523,7 @@ namespace TAO { template <typename stream, typename charT, CORBA::ULong MAX> bool marshal_sequence(stream & strm, const TAO::bounded_basic_string_sequence <charT, MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } for(CORBA::ULong i = 0; i < length; ++i) { @@ -537,7 +537,7 @@ namespace TAO { template <typename stream, typename charT, CORBA::ULong MAX, CORBA::ULong BD_STR_MAX> bool marshal_sequence(stream & strm, const TAO::bounded_bd_string_sequence <charT, MAX, BD_STR_MAX> & source) { ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } for(CORBA::ULong i = 0; i < length; ++i) { @@ -556,7 +556,7 @@ namespace TAO { bool marshal_sequence(stream & strm, const TAO::bounded_object_reference_sequence<object_t, object_t_var, MAX> & source) { typedef typename TAO::bounded_object_reference_sequence<object_t, object_t_var, MAX>::object_type object_type; ::CORBA::ULong const length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } for(CORBA::ULong i = 0; i < length; ++i) { diff --git a/TAO/tao/Bounded_Value_Sequence_T.h b/TAO/tao/Bounded_Value_Sequence_T.h index fc52674a078..fad27fda923 100644 --- a/TAO/tao/Bounded_Value_Sequence_T.h +++ b/TAO/tao/Bounded_Value_Sequence_T.h @@ -61,10 +61,7 @@ public: /// @copydoc details::generic_sequence::length inline void length(CORBA::ULong length) { implementation_type::range::check_length(length, MAX); - if (MAX >= length) - { - impl_.length(length); - } + impl_.length(length); } /// @copydoc details::generic_sequence::operator[] inline value_type const & operator[](CORBA::ULong i) const { diff --git a/TAO/tao/Range_Checking_T.h b/TAO/tao/Range_Checking_T.h index f5e461ef09f..e6da9645e9a 100644 --- a/TAO/tao/Range_Checking_T.h +++ b/TAO/tao/Range_Checking_T.h @@ -12,6 +12,7 @@ */ #include "tao/Basic_Types.h" +#include "tao/SystemException.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL @@ -118,23 +119,28 @@ struct range_checking typedef T value_type; inline static void check( - CORBA::ULong /* index */, - CORBA::ULong /* length */, + CORBA::ULong index, + CORBA::ULong length, CORBA::ULong /* maximum */, char const * /* function_name */) { // Applications and tests can specialize this function to define // their own behavior +#if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1) + if (length <= index) + throw ::CORBA::BAD_PARAM (); +#else + ACE_UNUSED_ARG (index); + ACE_UNUSED_ARG (length); +#endif // TAO_CHECKED_SEQUENCE_INDEXING } inline static void check_length( - CORBA::ULong & /* new_length */, - CORBA::ULong /* maximum */) + CORBA::ULong &new_length, + CORBA::ULong maximum) { - /* if (maximum < new_length) - new_length = maximum; - */ + throw ::CORBA::BAD_PARAM (); } }; diff --git a/TAO/tao/Valuetype/Bounded_Valuetype_Sequence_T.h b/TAO/tao/Valuetype/Bounded_Valuetype_Sequence_T.h index 8e9504e352c..db3f3f57eb3 100644 --- a/TAO/tao/Valuetype/Bounded_Valuetype_Sequence_T.h +++ b/TAO/tao/Valuetype/Bounded_Valuetype_Sequence_T.h @@ -62,10 +62,7 @@ public: inline void length(CORBA::ULong length) { implementation_type::range::check_length(length, MAX); - if (MAX >= length) - { - impl_.length(length); - } + impl_.length(length); } inline value_type const & operator[](CORBA::ULong i) const { return impl_[i]; @@ -183,7 +180,7 @@ private: bool marshal_sequence(stream & strm, const TAO::bounded_valuetype_sequence<object_t, object_t_var, MAX> & source) { const ::CORBA::ULong length = source.length (); - if (!(strm << length)) { + if (length > source.maximum () || !(strm << length)) { return false; } for(CORBA::ULong i = 0; i < length; ++i) { diff --git a/TAO/tests/Bug_3746_Regression/Test.idl b/TAO/tests/Bug_3746_Regression/Test.idl new file mode 100644 index 00000000000..df0af811264 --- /dev/null +++ b/TAO/tests/Bug_3746_Regression/Test.idl @@ -0,0 +1,20 @@ +// +// $Id$ +// + +/// Put the interfaces in a module, to avoid global namespace pollution +module Test +{ + /// A very simple interface + interface BoundSequences + { + typedef sequence<long, 10> SequenceOf10Long; + unsigned long SendSequenceOf10Long (in unsigned long LengthSent, in SequenceOf10Long inSeq); + + /// A method to shutdown the ORB + /** + * This method is used to simplify the test shutdown process + */ + oneway void shutdown (); + }; +}; diff --git a/TAO/tests/Bug_3746_Regression/Test_i.cpp b/TAO/tests/Bug_3746_Regression/Test_i.cpp new file mode 100644 index 00000000000..684b38099e8 --- /dev/null +++ b/TAO/tests/Bug_3746_Regression/Test_i.cpp @@ -0,0 +1,28 @@ +// +// $Id$ +// +#include "Test_i.h" + +ACE_RCSID(TestLargeSequence, + TestLargeSequence, + "$Id$") + +BoundSequences::BoundSequences (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)) +{ +} + +::CORBA::ULong BoundSequences::SendSequenceOf10Long (const ::CORBA::ULong LengthSent, const ::Test::BoundSequences::SequenceOf10Long &inSeq) +{ + ACE_DEBUG ((LM_DEBUG, + "Server - BoundSequences::SendSequenceOf10Long (%u, length(%u)) is %C\n", + LengthSent, inSeq.length(), + ((LengthSent == inSeq.length())? "Correct" : "**** Incorrect ****"))); + return inSeq.length(); +} + +void +BoundSequences::shutdown (void) +{ + this->orb_->shutdown (0); +} diff --git a/TAO/tests/Bug_3746_Regression/Test_i.h b/TAO/tests/Bug_3746_Regression/Test_i.h new file mode 100644 index 00000000000..5d51398d2f7 --- /dev/null +++ b/TAO/tests/Bug_3746_Regression/Test_i.h @@ -0,0 +1,34 @@ +// +// $Id$ +// + +#ifndef HELLO_H +#define HELLO_H +#include /**/ "ace/pre.h" + +#include "TestS.h" + +/// Implement the Test::TestLargeSequence interface +class BoundSequences + : public virtual POA_Test::BoundSequences +{ +public: + /// Constructor + BoundSequences (CORBA::ORB_ptr orb); + + // = The skeleton methods + virtual ::CORBA::ULong SendSequenceOf10Long ( + ::CORBA::ULong LengthSent, + const ::Test::BoundSequences::SequenceOf10Long &inSeq + ); + + virtual void shutdown (void); + +private: + /// Use an ORB reference to conver strings to objects and shutdown + /// the application. + CORBA::ORB_var orb_; +}; + +#include /**/ "ace/post.h" +#endif /* HELLO_H */ diff --git a/TAO/tests/Bug_3746_Regression/client.cpp b/TAO/tests/Bug_3746_Regression/client.cpp new file mode 100644 index 00000000000..9093c0fa7bb --- /dev/null +++ b/TAO/tests/Bug_3746_Regression/client.cpp @@ -0,0 +1,205 @@ +// $Id$ + +#include "TestC.h" +#include "ace/Get_Opt.h" + +ACE_RCSID(Bug_3746_Regression, + client, + "$Id$") + +const ACE_TCHAR *ior = ACE_TEXT ("file://test.ior"); + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("k:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s -k <ior> \n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + int error= 0; + try + { + CORBA::ORB_var orb = CORBA::ORB_init (argc, argv); + + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::Object_var tmp = orb->string_to_object(ior); + + Test::BoundSequences_var TestThis = + Test::BoundSequences::_narrow(tmp.in ()); + + if (CORBA::is_nil (TestThis.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil Test::BoundSequences reference <%s>\n", + ior), + 1); + } + + //////////////////////////////////////////// + ::Test::BoundSequences::SequenceOf10Long Seq; + ACE_DEBUG ((LM_DEBUG, "Client - Attempting to set length(11)\n")); + try + { + Seq.length (11); + ACE_DEBUG ((LM_DEBUG, + "Client - **FAILED** Incorrectly set length to %u\n", + Seq.length ())); + error= 1; + } + catch (const ::CORBA::BAD_PARAM &) + { + ACE_DEBUG ((LM_DEBUG, "Client - Correctly threw bad_param\n")); + } + catch (const ::CORBA::Exception &ex) + { + ex._tao_print_exception ("Client - **FAILED** Incorrectly threw"); + error= 1; + } + catch (...) + { + ACE_DEBUG ((LM_DEBUG, + "Client - **FAILED** Incorrectly threw something else\n")); + error= 1; + } + + //////////////////////////////////////////// + ACE_DEBUG ((LM_DEBUG, "Client - Attempting to set length(10)\n")); + try + { + Seq.length (10); + ACE_DEBUG ((LM_DEBUG, "Client - %Correctly set length to %u\n", + ((10 == Seq.length ()) ? "C" : "**** Inc"), + Seq.length ())); + if (10 != Seq.length ()) + error= 1; + } + catch (const ::CORBA::Exception &ex) + { + ex._tao_print_exception ("Client - **FAILED** Incorrectly threw"); + error= 1; + } + catch (...) + { + ACE_DEBUG ((LM_DEBUG, + "Client - **FAILED** Incorrectly threw something else\n")); + error= 1; + } + + ////////////////////////////////////////// + ACE_DEBUG ((LM_DEBUG, "Client - Accessing [0]\n")); + try + { + // Just to read access Seq[0] without optimizing away + ACE_DEBUG ((LM_DEBUG, "", Seq[0])); + ACE_DEBUG ((LM_DEBUG, "Client - Correctly allowed access to [0]\n")); + } + catch (const ::CORBA::Exception &ex) + { + ex._tao_print_exception ("Client - **FAILED** Incorrectly threw"); + error= 1; + } + catch (...) + { + ACE_DEBUG ((LM_DEBUG, + "Client - **FAILED** Incorrectly threw something else\n")); + error= 1; + } + + //////////////////////////////////////////// + ACE_DEBUG ((LM_DEBUG, "Client - Accessing [10]\n")); + try + { + // Just to read access Seq[10] without optimizing away + ACE_DEBUG ((LM_DEBUG, "", Seq[10])); +#if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1) + ACE_DEBUG ((LM_DEBUG, + "Client - **** Incorrectly allowed access to [10]\n")); + error= 1; + } + catch (const ::CORBA::BAD_PARAM &) + { + ACE_DEBUG ((LM_DEBUG, "Client - Correctly threw bad_param\n")); +#else + ACE_DEBUG ((LM_DEBUG, "Client - Correctly allowed access to [10]\n")); +#endif // TAO_CHECKED_SEQUENCE_INDEXING + } + catch (const ::CORBA::Exception &ex) + { + ex._tao_print_exception ("Client - **FAILED** Incorrectly threw"); + error= 1; + } + catch (...) + { + ACE_DEBUG ((LM_DEBUG, + "Client - **FAILED** Incorrectly threw something else\n")); + error= 1; + } + + //////////////////////////////////////////// + ACE_DEBUG ((LM_DEBUG, "Client - Sending Seq\n")); + ::CORBA::ULong result; + try + { + result= TestThis->SendSequenceOf10Long (Seq.length (), Seq); + if (result != Seq.length()) + { + ACE_DEBUG ((LM_DEBUG, + "Client - **FAILED** Sent %u longs but " + "server received %u longs\n", + Seq.length(), result)); + error= 1; + } + else + ACE_DEBUG ((LM_DEBUG, + "Client - **SUCCESS** Sent and Server got %u longs\n", + result)); + } + catch (const ::CORBA::Exception &ex) + { + ex._tao_print_exception ("Client - **FAILED** Incorrectly threw"); + error= 1; + } + catch (...) + { + ACE_DEBUG ((LM_DEBUG, + "Client - **FAILED** Incorrectly threw something else\n")); + error= 1; + } + + //////////////////////////////////////////// + ACE_DEBUG ((LM_DEBUG, "Client - Shutting down Server\n")); + TestThis->shutdown (); + + ACE_DEBUG ((LM_DEBUG, "Client - Finishing\n")); + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Client - Exception caught:"); + error= 1; + } + + return error; +} diff --git a/TAO/tests/Bug_3746_Regression/run_test.pl b/TAO/tests/Bug_3746_Regression/run_test.pl new file mode 100755 index 00000000000..ada2dbda5a4 --- /dev/null +++ b/TAO/tests/Bug_3746_Regression/run_test.pl @@ -0,0 +1,75 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::TestTarget; + +$status = 0; +$debug_level = '0'; + +foreach $i (@ARGV) { + if ($i eq '-debug') { + $debug_level = '10'; + } +} + +my $server = PerlACE::TestTarget::create_target (1) || die "Create Client failed\n"; +my $client = PerlACE::TestTarget::create_target (2) || die "Create Server failed\n"; + +my $iorbase = "test.ior"; +my $server_iorfile = $server->LocalFile ($iorbase); +my $client_iorfile = $client->LocalFile ($iorbase); +$server->DeleteFile($iorbase); +$client->DeleteFile($iorbase); + +$SV = $server->CreateProcess ("server", "-ORBdebuglevel $debug_level -o $server_iorfile"); +$CL = $client->CreateProcess ("client", "-k file://$client_iorfile"); + +print "Starting Server\n"; +$server_status = $SV->Spawn (); + +if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + exit 1; +} + +if ($server->WaitForFileTimed ($iorbase, + $server->ProcessStartWaitInterval()) == -1) { + print STDERR "ERROR: cannot find file <$server_iorfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} + +if ($server->GetFile ($iorbase) == -1) { + print STDERR "ERROR: cannot retrieve file <$server_iorfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} +if ($client->PutFile ($iorbase) == -1) { + print STDERR "ERROR: cannot set file <$client_iorfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} +print "Starting Client\n"; +$client_status = $CL->SpawnWaitKill (30); #$client->ProcessStartWaitInterval()); + +if ($client_status != 0) { + print STDERR "ERROR: client returned $client_status\n"; + $status = 1; +} + +$server_status = $SV->WaitKill ($server->ProcessStopWaitInterval()); + +if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + $status = 1; +} + +$server->DeleteFile($iorbase); +$client->DeleteFile($iorbase); + +exit $status; diff --git a/TAO/tests/Bug_3746_Regression/server.cpp b/TAO/tests/Bug_3746_Regression/server.cpp new file mode 100644 index 00000000000..c6f2435e88e --- /dev/null +++ b/TAO/tests/Bug_3746_Regression/server.cpp @@ -0,0 +1,112 @@ +// $Id$ + +#include "Test_i.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID (Bug_3746_Regression, + server, + "$Id$") + +const ACE_TCHAR *ior_output_file = ACE_TEXT ("test.ior"); + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("o:")); + int c; + + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-o <iorfile>" + "\n", + argv [0]), + -1); + } + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +ACE_TMAIN(int argc, ACE_TCHAR *argv[]) +{ + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv); + + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA"); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in ()); + + if (CORBA::is_nil (root_poa.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Panic: nil RootPOA\n"), + 1); + } + + PortableServer::POAManager_var poa_manager = root_poa->the_POAManager (); + + if (parse_args (argc, argv) != 0) + return 1; + + BoundSequences *test_impl = 0; + ACE_NEW_RETURN (test_impl, + BoundSequences (orb.in ()), + 1); + PortableServer::ServantBase_var owner_transfer (test_impl); + + PortableServer::ObjectId_var id = + root_poa->activate_object (test_impl); + + CORBA::Object_var object = root_poa->id_to_reference (id.in ()); + + Test::BoundSequences_var theServer = + Test::BoundSequences::_narrow (object.in ()); + + CORBA::String_var ior = orb->object_to_string (theServer.in ()); + + // Output the IOR to the <ior_output_file> + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Server - Cannot open output file for writing IOR: %s\n", + ior_output_file), + 1); + } + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + + poa_manager->activate (); + + orb->run (); + + ACE_DEBUG ((LM_DEBUG, "Server - Event loop finished\n")); + + root_poa->destroy (1, 1); + + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Server - Exception caught:"); + return 1; + } + + return 0; +} diff --git a/TAO/tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp b/TAO/tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp index 0fc2f94d780..75f2f941112 100644 --- a/TAO/tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp +++ b/TAO/tests/Sequence_Unit_Tests/Bounded_Simple_Types.cpp @@ -39,7 +39,18 @@ int ACE_TMAIN (int, ACE_TCHAR *[]) b[0] = a[0]; int_sequence const & d = a; - c[0] = d[0]; + try + { + c[0] = d[0]; +#if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1) + return 1; +#endif + } + catch (const ::CORBA::BAD_PARAM &) + { + // c has length = 0, so there is an exception when we try + // to access element above length. + } b.replace(0, int_sequence::allocbuf(), true); diff --git a/TAO/tests/Sequence_Unit_Tests/Bounded_String.cpp b/TAO/tests/Sequence_Unit_Tests/Bounded_String.cpp index 7e1846cbd7a..31b9cb38d19 100644 --- a/TAO/tests/Sequence_Unit_Tests/Bounded_String.cpp +++ b/TAO/tests/Sequence_Unit_Tests/Bounded_String.cpp @@ -31,7 +31,18 @@ int ACE_TMAIN (int, ACE_TCHAR *[]) b[0] = a[0]; s_sequence const & d = a; - c[0] = d[0]; + try + { + c[0] = d[0]; +#if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1) + return 1; +#endif + } + catch (const ::CORBA::BAD_PARAM &) + { + // c has length = 0, so there is an exception when we try + // to access element above length. + } b.replace(0, s_sequence::allocbuf(), true); @@ -50,7 +61,18 @@ int ACE_TMAIN (int, ACE_TCHAR *[]) s_sequence e(c); CORBA::String_var w(const_cast<char const*>("World")); - e[0] = w; + try + { + e[0] = w; +#if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1) + return 1; +#endif + } + catch (const ::CORBA::BAD_PARAM &) + { + // e has length = 0, so there is an exception when we try + // to access element above length. + } return 0; } diff --git a/TAO/tests/Sequence_Unit_Tests/Unbounded_Octet.cpp b/TAO/tests/Sequence_Unit_Tests/Unbounded_Octet.cpp index 28710cfcae1..ca0704ea501 100644 --- a/TAO/tests/Sequence_Unit_Tests/Unbounded_Octet.cpp +++ b/TAO/tests/Sequence_Unit_Tests/Unbounded_Octet.cpp @@ -30,7 +30,18 @@ int ACE_TMAIN (int, ACE_TCHAR *[]) b[0] = a[0]; s_sequence const & d = a; - c[0] = d[0]; + try + { + c[0] = d[0]; +#if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1) + return 1; +#endif + } + catch (const ::CORBA::BAD_PARAM &) + { + // c has length = 0, so there is an exception when we try + // to access element above length. + } b.replace(64, 0, s_sequence::allocbuf(64), true); diff --git a/TAO/tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp b/TAO/tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp index 31c2f55b75c..79a93c10ed1 100644 --- a/TAO/tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp +++ b/TAO/tests/Sequence_Unit_Tests/Unbounded_Simple_Types.cpp @@ -35,7 +35,18 @@ int ACE_TMAIN (int, ACE_TCHAR *[]) b[0] = a[0]; int_sequence const & d = a; - c[0] = d[0]; + try + { + c[0] = d[0]; +#if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1) + return 1; +#endif + } + catch (const ::CORBA::BAD_PARAM &) + { + // c has length = 0, so there is an exception when we try + // to access element above length. + } b.replace(64, 0, int_sequence::allocbuf(64), true); diff --git a/TAO/tests/Sequence_Unit_Tests/Unbounded_String.cpp b/TAO/tests/Sequence_Unit_Tests/Unbounded_String.cpp index 2f700900cac..a7e77788021 100644 --- a/TAO/tests/Sequence_Unit_Tests/Unbounded_String.cpp +++ b/TAO/tests/Sequence_Unit_Tests/Unbounded_String.cpp @@ -30,7 +30,18 @@ int ACE_TMAIN (int, ACE_TCHAR *[]) b[0] = a[0]; s_sequence const & d = a; - c[0] = d[0]; + try + { + c[0] = d[0]; +#if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1) + return 1; +#endif + } + catch (const ::CORBA::BAD_PARAM &) + { + // c has length = 0, so there is an exception when we try + // to access element above length. + } b.replace(64, 0, s_sequence::allocbuf(64), true); @@ -49,7 +60,18 @@ int ACE_TMAIN (int, ACE_TCHAR *[]) s_sequence e(c); CORBA::String_var w(const_cast<char const*>("World")); - e[0] = w; + try + { + e[0] = w; +#if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1) + return 1; +#endif + } + catch (const ::CORBA::BAD_PARAM &) + { + // e has length = 0, so there is an exception when we try + // to access element above length. + } return 0; } diff --git a/TAO/tests/Sequence_Unit_Tests/string_sequence_tester.hpp b/TAO/tests/Sequence_Unit_Tests/string_sequence_tester.hpp index cfc5ac0c48e..339c59ada80 100644 --- a/TAO/tests/Sequence_Unit_Tests/string_sequence_tester.hpp +++ b/TAO/tests/Sequence_Unit_Tests/string_sequence_tester.hpp @@ -389,10 +389,10 @@ struct string_sequence_tester { expected_calls f(tested_allocation_traits::freebuf_calls); { - tested_sequence x; x.length(8); + tested_sequence x; x.length(4); f.reset(); - for(CORBA::ULong i = 0; i != 8; ++i) + for(CORBA::ULong i = 0; i != 4; ++i) { x[i] = helper::allocate_test_string(); } @@ -403,8 +403,8 @@ struct string_sequence_tester { - tested_sequence y; y.length(4); - for(CORBA::ULong i = 0; i != 4; ++i) + tested_sequence y; y.length(8); + for(CORBA::ULong i = 0; i != 8; ++i) { y[i] = helper::allocate_test_string(); } @@ -414,14 +414,14 @@ struct string_sequence_tester r.reset(); f.reset(); tested_element_traits::duplicate_calls.failure_countdown(4); - CHECK_THROW(y = x, testing_exception); + CHECK_THROW(x = y, testing_exception); FAIL_RETURN_IF_NOT(a.expect(1), a); FAIL_RETURN_IF_NOT(f.expect(1), f); FAIL_RETURN_IF_NOT(d.expect(4), d); - FAIL_RETURN_IF_NOT(r.expect(x.maximum()), r); + FAIL_RETURN_IF_NOT(r.expect(y.maximum()), r); - CHECK_EQUAL(CORBA::ULong(4), y.length()); - for(CORBA::ULong i = 0; i != 4; ++i) + CHECK_EQUAL(CORBA::ULong(8), y.length()); + for(CORBA::ULong i = 0; i != 8; ++i) { FAIL_RETURN_IF_NOT( helper::compare_test_string(y[i]), |