summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2005-02-04 22:22:10 +0000
committerMark Spruiell <mes@zeroc.com>2005-02-04 22:22:10 +0000
commit38bb8b5c01b05c829194cf115492cbfa2266777f (patch)
tree4fa97b214d0d5ff8f9c4f2ba5a987f7837173bae /cpp/src
parentfixes (diff)
downloadice-38bb8b5c01b05c829194cf115492cbfa2266777f.tar.bz2
ice-38bb8b5c01b05c829194cf115492cbfa2266777f.tar.xz
ice-38bb8b5c01b05c829194cf115492cbfa2266777f.zip
removing call to startSeq/endSeq for sequence of fixed-length type
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Ice/BasicStream.cpp52
-rw-r--r--cpp/src/slice2cpp/Gen.cpp16
2 files changed, 47 insertions, 21 deletions
diff --git a/cpp/src/Ice/BasicStream.cpp b/cpp/src/Ice/BasicStream.cpp
index 265061e5768..7f80c1c1013 100644
--- a/cpp/src/Ice/BasicStream.cpp
+++ b/cpp/src/Ice/BasicStream.cpp
@@ -159,9 +159,12 @@ IceInternal::BasicStream::reserve(Container::size_type sz)
// 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. startSeq() is called immediately
-// after reading the sequence size, and endSeq() is called after
-// reading the final element of a sequence.
+// 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()
@@ -190,7 +193,7 @@ IceInternal::BasicStream::reserve(Container::size_type sz)
// endElement() in the generated code decrements that number whenever
// a sequence element is unmarshaled.)
//
-// For sequence that variable-length elements, checkSeq() is called
+// 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
@@ -276,6 +279,26 @@ IceInternal::BasicStream::endSeq(int sz)
delete oldSeqData;
}
+void
+IceInternal::BasicStream::checkFixedSeq(int numElements, int elemSize)
+{
+ int bytesLeft = b.end() - i;
+ if(_seqDataStack == 0) // Outermost sequence
+ {
+ //
+ // The sequence must fit within the message.
+ //
+ if(numElements * elemSize > bytesLeft)
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ }
+ else // Nested sequence
+ {
+ checkSeq(bytesLeft - numElements * elemSize);
+ }
+}
+
IceInternal::BasicStream::WriteEncaps::WriteEncaps()
: writeIndex(0), toBeMarshaledMap(0), marshaledMap(0), typeIdMap(0), typeIdIndex(0), previous(0)
{
@@ -712,12 +735,11 @@ IceInternal::BasicStream::read(vector<Byte>& v)
{
Int sz;
readSize(sz);
- startSeq(sz, 1);
+ checkFixedSeq(sz, 1);
Container::iterator begin = i;
i += sz;
v.resize(sz);
ice_copy(begin, i, v.begin());
- endSeq(sz);
}
void
@@ -735,12 +757,11 @@ IceInternal::BasicStream::read(vector<bool>& v)
{
Int sz;
readSize(sz);
- startSeq(sz, 1);
+ checkFixedSeq(sz, 1);
Container::iterator begin = i;
i += sz;
v.resize(sz);
ice_copy(begin, i, v.begin());
- endSeq(sz);
}
void
@@ -811,7 +832,7 @@ IceInternal::BasicStream::read(vector<Short>& v)
{
Int sz;
readSize(sz);
- startSeq(sz, sizeof(Short));
+ checkFixedSeq(sz, sizeof(Short));
Container::iterator begin = i;
i += sz * static_cast<int>(sizeof(Short));
v.resize(sz);
@@ -830,7 +851,6 @@ IceInternal::BasicStream::read(vector<Short>& v)
ice_copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
#endif
}
- endSeq(sz);
}
void
@@ -911,7 +931,7 @@ IceInternal::BasicStream::read(vector<Int>& v)
{
Int sz;
readSize(sz);
- startSeq(sz, sizeof(Int));
+ checkFixedSeq(sz, sizeof(Int));
Container::iterator begin = i;
i += sz * static_cast<int>(sizeof(Int));
v.resize(sz);
@@ -932,7 +952,6 @@ IceInternal::BasicStream::read(vector<Int>& v)
ice_copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
#endif
}
- endSeq(sz);
}
void
@@ -1033,7 +1052,7 @@ IceInternal::BasicStream::read(vector<Long>& v)
{
Int sz;
readSize(sz);
- startSeq(sz, sizeof(Long));
+ checkFixedSeq(sz, sizeof(Long));
Container::iterator begin = i;
i += sz * static_cast<int>(sizeof(Long));
v.resize(sz);
@@ -1058,7 +1077,6 @@ IceInternal::BasicStream::read(vector<Long>& v)
ice_copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
#endif
}
- endSeq(sz);
}
void
@@ -1139,7 +1157,7 @@ IceInternal::BasicStream::read(vector<Float>& v)
{
Int sz;
readSize(sz);
- startSeq(sz, sizeof(Float));
+ checkFixedSeq(sz, sizeof(Float));
Container::iterator begin = i;
i += sz * static_cast<int>(sizeof(Float));
v.resize(sz);
@@ -1160,7 +1178,6 @@ IceInternal::BasicStream::read(vector<Float>& v)
ice_copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
#endif
}
- endSeq(sz);
}
void
@@ -1261,7 +1278,7 @@ IceInternal::BasicStream::read(vector<Double>& v)
{
Int sz;
readSize(sz);
- startSeq(sz, sizeof(Double));
+ checkFixedSeq(sz, sizeof(Double));
Container::iterator begin = i;
i += sz * static_cast<int>(sizeof(Double));
v.resize(sz);
@@ -1286,7 +1303,6 @@ IceInternal::BasicStream::read(vector<Double>& v)
ice_copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
#endif
}
- endSeq(sz);
}
//
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index b6e8243cecb..d8ad0f26ab7 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -841,7 +841,14 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
C << sb;
C << nl << "::Ice::Int sz;";
C << nl << "__is->readSize(sz);";
- C << nl << "__is->startSeq(sz, " << type->minWireSize() << ");"; // Protect against bogus sequence sizes.
+ if(type->isVariableLength())
+ {
+ C << nl << "__is->startSeq(sz, " << type->minWireSize() << ");"; // Protect against bogus sequence sizes.
+ }
+ else
+ {
+ C << nl << "__is->checkFixedSeq(sz, " << type->minWireSize() << ");";
+ }
C << nl << "v.resize(sz);";
C << nl << "for(int i = 0; i < sz; ++i)";
C << sb;
@@ -861,7 +868,7 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
if(!SequencePtr::dynamicCast(type))
{
//
- // No need to check for directly nested sequences because, at the at start of each
+ // No need to check for directly nested sequences because, at the start of each
// sequence, we check anyway.
//
C << nl << "__is->checkSeq();";
@@ -869,7 +876,10 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
C << nl << "__is->endElement();";
}
C << eb;
- C << nl << "__is->endSeq(sz);";
+ if(type->isVariableLength())
+ {
+ C << nl << "__is->endSeq(sz);";
+ }
C << eb;
if(_stream)