Skip to content

Commit 50af58b

Browse files
authored
Merge pull request #4030 from jckarter/27671131
Runtime: Fix undersized allocation for out-of-line optional cast result.
2 parents a4cc137 + 2508c46 commit 50af58b

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

stdlib/public/runtime/Casting.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2874,11 +2874,22 @@ static bool _dynamicCastClassToValueViaObjCBridgeable(
28742874
swift_unknownRetain(srcObject);
28752875
}
28762876

2877+
// The extra byte is for the tag.
2878+
auto targetSize = targetType->getValueWitnesses()->size + 1;
2879+
auto targetAlignMask = targetType->getValueWitnesses()->getAlignmentMask();
2880+
28772881
// Object that frees a buffer when it goes out of scope.
28782882
struct FreeBuffer {
28792883
void *Buffer = nullptr;
2880-
~FreeBuffer() { free(Buffer); }
2881-
} freeBuffer;
2884+
size_t size, alignMask;
2885+
FreeBuffer(size_t size, size_t alignMask) :
2886+
size(size), alignMask(alignMask) {}
2887+
2888+
~FreeBuffer() {
2889+
if (Buffer)
2890+
swift_slowDealloc(Buffer, size, alignMask);
2891+
}
2892+
} freeBuffer{targetSize, targetAlignMask};
28822893

28832894
// Allocate a buffer to store the T? returned by bridging.
28842895
// The extra byte is for the tag.
@@ -2890,7 +2901,7 @@ static bool _dynamicCastClassToValueViaObjCBridgeable(
28902901
optDestBuffer = inlineBuffer;
28912902
} else {
28922903
// Allocate a buffer.
2893-
optDestBuffer = malloc(targetType->getValueWitnesses()->size);
2904+
optDestBuffer = swift_slowAlloc(targetSize, targetAlignMask);
28942905
freeBuffer.Buffer = optDestBuffer;
28952906
}
28962907

0 commit comments

Comments
 (0)