[stdlib] Fix memory safety with evil collections

A collection whose count changes between traversals could cause a memory
safety problem, as we would measure the collection in one pass and
assume that it was the same length when actually initializing array
elements.  Fix that by always using the initial measurement, which
corresponds exactly to allocated memory.  If the collection wants to
trap because we've gone past its new bounds, that's fine.  If it
doesn't, at least we haven't done anything unsafe.

Swift SVN r22152
This commit is contained in:
Dave Abrahams
2014-09-20 03:35:23 +00:00
parent 070987d365
commit 40e9a0f859
3 changed files with 138 additions and 22 deletions

View File

@@ -458,7 +458,8 @@ public func ~> <
}
public func ~> <
C: protocol<_CollectionType,_Sequence_Type>
C: CollectionType
where C.Generator.Element == C._Element
>(
source: C, _:(_CopyToNativeArrayBuffer, ())
) -> _ContiguousArrayBuffer<C.Generator.Element>
@@ -467,10 +468,11 @@ public func ~> <
}
func _copyCollectionToNativeArrayBuffer<
C: protocol<_CollectionType,_Sequence_Type>
C: CollectionType
where C.Generator.Element == C._Element
>(source: C) -> _ContiguousArrayBuffer<C.Generator.Element>
{
let count = countElements(source)
let count = Int(countElements(source).toIntMax())
if count == 0 {
return _ContiguousArrayBuffer()
}
@@ -481,10 +483,11 @@ func _copyCollectionToNativeArrayBuffer<
)
var p = result.baseAddress
for x in GeneratorSequence(source.generate()) {
(p++).initialize(x)
var i = source.startIndex
for _ in 0..<count {
(p++).initialize(source[i++])
}
_expectEnd(i, source)
return result
}