Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libs/iovm/source/IoList.c
Original file line number Diff line number Diff line change
Expand Up @@ -1116,14 +1116,14 @@ IO_METHOD(IoList, fromEncodedList) {
}
uint32_t id = *((uint32_t *)(d + index));
IoMessage_setCachedArg_to_(rm, 0, IONUMBER(id));
IoMessage_setCachedArg_to_(rm, 0, IONIL(self));

index += sizeof(uint32_t);

{
IoObject *result = IoObject_perform(locals, locals, rm);
List_append_(list, result);
}
IoMessage_setCachedArg_to_(rm, 0, IONIL(self));
} else {
IOASSERT(0, "unrecognized encoded type");
}
Expand Down
35 changes: 35 additions & 0 deletions libs/iovm/tests/correctness/ListTest.io
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,41 @@ ListTest := UnitTest clone do(
assertEquals(t, t asEncodedList asDecodedList)
)

# Regression for IoList.c REFERENCE decode: objectForReferenceId must receive
# IONUMBER(id) (clear cached arg only after perform). Same id=42 as bug.io.
# Uses manual bytes (IOLIST_ENCODING_TYPE_REFERENCE + uint32 LE) so this test
# does not depend on asEncodedList or Lobby referenceIdForObject under doString.
testEncodedListFromEncodedListReferenceId := method(
ref := Object clone
hadObj := Lobby hasLocalSlot("objectForReferenceId")
hadStash := Lobby hasLocalSlot("referenceRoundTripRef")
prevObj := if(hadObj, Lobby getSlot("objectForReferenceId"), nil)
prevStash := if(hadStash, Lobby getSlot("referenceRoundTripRef"), nil)

Lobby referenceRoundTripRef := ref
Lobby do(
objectForReferenceId := method(id,
if(id isIdenticalTo(42), Lobby getSlot("referenceRoundTripRef"), nil)
)
)

enc := ("" asMutable)
enc appendSeq(3 asCharacter, 0 asCharacter, 0 asCharacter)
enc appendSeq(42 asCharacter, 0 asCharacter, 0 asCharacter, 0 asCharacter)
dec := List fromEncodedList(enc)
assertEquals(1, dec size)
assertTrue(dec first isIdenticalTo(ref))

if(hadObj,
Lobby do(objectForReferenceId := prevObj),
Lobby removeSlot("objectForReferenceId")
)
if(hadStash,
Lobby do(referenceRoundTripRef := prevStash),
Lobby removeSlot("referenceRoundTripRef")
)
)

testSlice := method(
a := list(1, 2, 3, 4, 5, 6)
assertEquals(a, a slice(0))
Expand Down