Skip to content

Commit 742f556

Browse files
authored
Fix rare VectorRecord crash opening rev-tree doc [CBL-7682] (#2398)
When copying the body of a revision from a RevTree-based doc, VectorRecord creates `Doc`s on the `body` and `extra` so that all Fleece operations will work. Unfortunately there are some rare cases where the body of a `Rev` isn't in `body` or `extra` but was copied out; this only happens as a workaround for an old (2.0) bug where the Fleece data might be at an odd address. In those situations, the attempt to create a mutable copy of the Dict failed because it can't be retained and its SharedKeys can't be located. Worked around this by detecting the situation, and when it occurs, creating a Doc for the data.
1 parent d193baa commit 742f556

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

LiteCore/RevTrees/VectorRecord.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,16 @@ namespace litecore {
216216
if ( rev == curRev ) {
217217
nuRev = currentRevision();
218218
} else {
219-
if ( rev->body() ) {
220-
auto props = fleece::ValueFromData(rev->body(), kFLTrusted).asDict();
221-
nuProps = props.mutableCopy(kFLDeepCopyImmutables);
219+
if ( slice revBody = rev->body() ) {
220+
if ( extra.containsAddressRange(revBody) || body.containsAddressRange(revBody) ) {
221+
auto props = fleece::ValueFromData(revBody, kFLTrusted).asDict();
222+
nuProps = props.mutableCopy(kFLDeepCopyImmutables);
223+
} else {
224+
// In rare cases `body` is not inside `extra`, thus not covered by `_extraDoc`,
225+
// so copy it into an alloc_slice and create a Doc on it: [CBL-7681]
226+
Doc revDoc(alloc_slice(revBody), kFLTrusted, sharedKeys());
227+
nuProps = revDoc.asDict().mutableCopy(kFLDeepCopyImmutables);
228+
}
222229
nuRev.properties = nuProps;
223230
}
224231
nuRev.revID = rev->revID;

0 commit comments

Comments
 (0)