1
0
Fork 0

fix Slice::findDataOffset for compact arrays and objects (#3257)

This commit is contained in:
Jan 2017-09-15 14:35:30 +02:00 committed by Frank Celler
parent b9d48a4304
commit 8a9b4cd9df
4 changed files with 18 additions and 4 deletions

View File

@ -157,6 +157,7 @@ class ArrayIterator {
_current = nullptr;
if (_size > 0) {
auto h = _slice.head();
VELOCYPACK_ASSERT(h != 0x01); // no empty array allowed here
if (h == 0x13) {
_current = _slice.at(0).start();
} else {
@ -194,6 +195,7 @@ class ObjectIterator {
if (_size > 0) {
auto h = slice.head();
VELOCYPACK_ASSERT(h != 0x0a); // no empty object allowed here
if (h == 0x14) {
_current = slice.keyAt(0, false).start();
} else if (useSequentialIteration) {

View File

@ -379,6 +379,7 @@ class Slice {
// find number of items
if (h <= 0x05) { // No offset table or length, need to compute:
VELOCYPACK_ASSERT(h != 0x00 && h != 0x01);
ValueLength firstSubOffset = findDataOffset(h);
Slice first(_start + firstSubOffset);
ValueLength s = first.byteSize();
@ -848,9 +849,14 @@ class Slice {
}
ValueLength findDataOffset(uint8_t head) const noexcept {
// Must be called for a nonempty array or object at start():
VELOCYPACK_ASSERT(head <= 0x12);
// Must be called for a non-empty array or object at start():
VELOCYPACK_ASSERT(head != 0x01 && head != 0x0a && head <= 0x14);
unsigned int fsm = SliceStaticData::FirstSubMap[head];
if (fsm == 0) {
// need to calculate the offset by reading the dynamic length
VELOCYPACK_ASSERT(head == 0x13 || head == 0x14);
return 1 + readVariableValueLength<false>(_start + 1);
}
if (fsm <= 2 && _start[2] != 0) {
return 2;
}

View File

@ -340,7 +340,9 @@ unsigned int const SliceStaticData::FirstSubMap[32] = {
3, // 0x0f, object with unsorted index table
5, // 0x10, object with unsorted index table
9, // 0x11, object with unsorted index table
9, // 0x12, object with unsorted index table
9, // 0x12, object with unsorted index table,
0, // 0x13, compact array, no index table - note: the offset is dynamic!
0, // 0x14, compact object, no index table - note: the offset is dynamic!
0};
// creates a Slice from Json and adds it to a scope

View File

@ -102,6 +102,10 @@ std::string transaction::helpers::extractIdString(CollectionNameResolver const*
if (slice.isObject()) {
// extract id attribute from object
if (slice.isEmptyObject()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
uint8_t const* p = slice.begin() + slice.findDataOffset(slice.head());
if (*p == basics::VelocyPackHelper::KeyAttribute) {
// skip over attribute name
@ -115,7 +119,7 @@ std::string transaction::helpers::extractIdString(CollectionNameResolver const*
if (id.isCustom()) {
// we should be pointing to a custom value now
TRI_ASSERT(id.head() == 0xf3);
return makeIdFromCustom(resolver, id, key);
}
if (id.isString()) {