Go Back   ZeroC Forums > Help Center

Reply
 
LinkBack Thread Tools Rate Thread Display Modes
  #1 (permalink)  
Old 06-16-2005
rc_hz rc_hz is offline
Registered User
 
Name: Eric RC
Organization: www.genband.com
Project: No project yet
 
Join Date: Jul 2004
Location: Hangzhou, China
Posts: 189
Send a message via MSN to rc_hz
-->
Questions about sanity-check of sequence sizes during sequence unmarshaling

I have noticed the comments in src/ice/BasicStream.cpp
Quote:
//
// startSeq() and endSeq() sanity-check sequence sizes during
// unmarshaling and prevent malicious messages with incorrect sequence
// sizes from causing the receiver to use up all available memory by
// allocating sequences with an impossibly large number of elements.
//
// The code generator inserts calls to startSeq() and endSeq() around
// the code to unmarshal a sequence of a variable-length type. startSeq()
// is called immediately after reading the sequence size, and endSeq() is
// called after reading the final element of a sequence.
//
// For a sequence of a fixed-length type, the code generator inserts a
// call to checkFixedSeq(), which does not cause any memory allocations.
//
// For sequences that contain constructed types that, in turn, contain
// sequences, the code generator also inserts a call to endElement()
// (inlined in BasicStream.h) after unmarshaling each element.
//
// startSeq() is passed the unmarshaled element count, plus the
// minimum size (in bytes) occupied by the sequence's element
// type. numElements * minSize is the smallest possible number of
// bytes that the sequence will occupy on the wire.
//
// Every time startSeq() is called, it pushes the element count and
// the minimum size on a stack. Every time endSeq() is called, it pops
// the stack.
//
// For an ordinary sequence (one that does not (recursively) contain
// nested sequences), numElements * minSize must be less than the
// number of bytes remaining in the stream.
//
// For a sequence that is nested within some other sequence, there
// must be enough bytes remaining in the stream for this sequence
// (numElements + minSize), plus the sum of the bytes required by the
// remaining elements of all the enclosing sequences.
//
// For the enclosing sequences, numElements - 1 is the number of
// elements for which unmarshaling has not started yet. (The call to
// endElement() in the generated code decrements that number whenever
// a sequence element is unmarshaled.)
//
// For sequences that have variable-length elements, checkSeq() is called
// whenever an element is unmarshaled. checkSeq() also checks whether
// the stream has a sufficient number of bytes remaining. This means
// that, for messages with bogus sequence sizes, unmarshaling is
// aborted at the earliest possible point.
//
We know that Ice has defined the following TYPE hierarcy(Chapter 4.8/4.9)
1)Basic Slice Types
bool/byte/short/int/long/float/double/string

2)User-defined Types
enumeration/structure/sequence/dictionary/

3)class

However, some new concepts appeared in the above quote:
1)a sequence of a variable-length type
2)sequences that contain constructed types
3)a sequence of a fixed-length type
But I can not find the accurate definitions of "variable-length type" or "constructed type" or "fixed-length type" in Ice's manual. Just one example: If a struct has one member of class type, what's its type ?


Another question:
Quote:
// startSeq() is passed the unmarshaled element count, plus the
// minimum size (in bytes) occupied by the sequence's element
// type.
How to know the minimum size of a the sequence's element type?

I have noticed the following:
Code:
-- test/ice/stream/Test.cpp (generated by Test.ice)
void
Test::__read(::IceInternal::BasicStream* __is, ::Test::MyClassS& v, ::Test::__U__MyClassS)
{
    ::Ice::Int sz;
    __is->readSize(sz);
    __is->startSeq(sz, 4);		//4 bytes      v.resize(sz);
    for(int i = 0; i < sz; ++i)
    {
		__is->read(::Test::__patch__MyClassPtr, &v[i]);
		__is->checkSeq();
		__is->endElement();
    }
    __is->endSeq(sz);
}

-- test/ice/operations/Test.cpp (generated by Test.ice)
void
Test::__read(::IceInternal::BasicStream* __is, ::Test::MyClassS& v, ::Test::__U__MyClassS)
{
    ::Ice::Int sz;
    __is->readSize(sz);
    __is->startSeq(sz, 2);		//2 bytes    v.resize(sz);
    for(int i = 0; i < sz; ++i)
    {
		::Test::__read(__is, v[i]);
		__is->checkSeq();
		__is->endElement();
    }
    __is->endSeq(sz);
}
In my understanding, a sequence of Class's minimal element size should be 4 bytes because a Class's Identity is 4 bytes(Int) when marshalling. But why it is just 2 bytes in test/ice/operations/Test.cpp ?

Thanks.
__________________
Eric RC
www.genband.com (telecommunication)
I like ICE (Ice for C++/Java/Python)
Reply With Quote
  #2 (permalink)  
Old 06-17-2005
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 907
Quote:
But I can not find the accurate definitions of "variable-length type" or "constructed type" or "fixed-length type" in Ice's manual. Just one example: If a struct has one member of class type, what's its type ?
A fixed-length type is a type whose values have a size that is known at compile time, such as bool.

A constructed type is a class, struct, sequence, dictionary, or enum type.

A variable-length type is a type whose values have sizes that cannot be known at compile time.

The following rules apply:
  • bool, byte, short, int, long, float, and double are fixed-length types.
  • string, proxies, Object, and types derived from Object are variable-length types.
  • Sequences and dictionaries are variable-length types.
  • Constructed types are fixed-length if they, recursively, only contain fixed-length types.

Quote:
How to know the minimum size of a the sequence's element type?
This code uses the minimum on-the-wire size of the data to determine whether it is possible for the remainder of a request to be unmarshaled within the limits of the request size that was sent in the header. The point of all this is to prevent someone from sending malformed packets with impossibly large sizes and to cause an Ice process to allocate impossibly large amounts of memory during unmarshaling.

In the operations test, MyClassS is a sequence of proxies. The minimum on-the-wire size of a proxy is two bytes for a nil proxy (empty name and empty category).

In the stream test, MyClassS is a sequence of classes, not a sequence of proxies, so a different minimum size applies.

Cheers,

Michi.
Reply With Quote
  #3 (permalink)  
Old 06-17-2005
rc_hz rc_hz is offline
Registered User
 
Name: Eric RC
Organization: www.genband.com
Project: No project yet
 
Join Date: Jul 2004
Location: Hangzhou, China
Posts: 189
Send a message via MSN to rc_hz
-->
Quote:
Originally Posted by michi
  • bool, byte, short, int, long, float, and double are fixed-length types.
  • string, proxies, Object, and types derived from Object are variable-length types.
  • Sequences and dictionaries are variable-length types.
  • Constructed types are fixed-length if they, recursively, only contain fixed-length types.
Thank you, Michi.

How about enum type ? It's a construct type and it contains only fixed-length types, so it is a fixed-length type, right ?
__________________
Eric RC
www.genband.com (telecommunication)
I like ICE (Ice for C++/Java/Python)
Reply With Quote
  #4 (permalink)  
Old 06-22-2005
rc_hz rc_hz is offline
Registered User
 
Name: Eric RC
Organization: www.genband.com
Project: No project yet
 
Join Date: Jul 2004
Location: Hangzhou, China
Posts: 189
Send a message via MSN to rc_hz
-->
A bug ???

Code:
-- src/Ice/BasicStream.cpp
void
IceInternal::BasicStream::startSeq(int numElements, int minSize)
{
    if(numElements == 0) // Optimization to avoid pushing a useless stack frame.
    {
		return;
    }

    //
    // Push the current sequence details on the stack.
    //
    SeqData* sd = new SeqData(numElements, minSize);
    sd->previous = _seqDataStack;
    _seqDataStack = sd;

    int bytesLeft = static_cast<int>(b.end() - i);
    if(_seqDataStack == 0) // Outermost sequence
    { //This is always false
		//
		// The sequence must fit within the message.
		//
		if(numElements * minSize > bytesLeft) 
		{
		    throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
		}
    }
    else // Nested sequence
    {
		checkSeq(bytesLeft);
    }
}
Maybe the red part should be replaced:
Code:
    if (sd->previous == 0) // Outermost sequence
__________________
Eric RC
www.genband.com (telecommunication)
I like ICE (Ice for C++/Java/Python)

Last edited by rc_hz : 06-22-2005 at 08:56 AM.
Reply With Quote
  #5 (permalink)  
Old 06-22-2005
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 907
Thanks very much for pointing this out! I've fixed this for the next release.
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
null sequence in C# chris92 Help Center 3 09-29-2006 09:58 AM
Sequence of classes in Slice? bartley Help Center 2 05-19-2006 11:22 PM
C# and dictionary/sequence problem on ICE 3.0.1 tkrieger Help Center 2 05-18-2006 01:59 PM
Sequence of 'unions'? dwolfe5272 Help Center 6 10-18-2004 05:38 PM
Questions about sequence<byte> in C++? rodrigc Help Center 3 02-24-2003 11:21 PM


All times are GMT -4. The time now is 07:24 AM.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0
(c) 2008 ZeroC, Inc.