Skip to content

Commit 1841a5f

Browse files
WasmParser: Move data count section validation to the validator
1 parent 2dccaf6 commit 1841a5f

File tree

8 files changed

+31
-44
lines changed

8 files changed

+31
-44
lines changed

Sources/WasmKit/Execution/Instances.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ struct InstanceEntity /* : ~Copyable */ {
8282
var exports: [String: InternalExternalValue]
8383
var functionRefs: Set<InternalFunction>
8484
var features: WasmFeatureSet
85-
var hasDataCount: Bool
85+
var dataCount: UInt32?
8686

8787
static var empty: InstanceEntity {
8888
InstanceEntity(
@@ -96,7 +96,7 @@ struct InstanceEntity /* : ~Copyable */ {
9696
exports: [:],
9797
functionRefs: [],
9898
features: [],
99-
hasDataCount: false
99+
dataCount: nil
100100
)
101101
}
102102

@@ -727,12 +727,6 @@ struct DataSegmentEntity {
727727
}
728728
}
729729

730-
extension DataSegmentEntity: ValidatableEntity {
731-
static func createOutOfBoundsError(index: Int, count: Int) -> Error {
732-
Trap._raw("Data index out of bounds: \(index) (max: \(count))")
733-
}
734-
}
735-
736730
typealias InternalDataSegment = EntityHandle<DataSegmentEntity>
737731

738732
/// > Note:

Sources/WasmKit/Execution/StoreAllocator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ extension StoreAllocator {
452452
exports: exports,
453453
functionRefs: functionRefs,
454454
features: module.features,
455-
hasDataCount: module.hasDataCount
455+
dataCount: module.dataCount
456456
)
457457
instancePointer.initialize(to: instanceEntity)
458458
instanceInitialized = true

Sources/WasmKit/Module.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public struct Module {
6363
let tableTypes: [TableType]
6464
let allocator: ISeqAllocator
6565
let features: WasmFeatureSet
66-
let hasDataCount: Bool
66+
let dataCount: UInt32?
6767

6868
init(
6969
types: [FunctionType],
@@ -79,7 +79,7 @@ public struct Module {
7979
customSections: [CustomSection],
8080
allocator: ISeqAllocator,
8181
features: WasmFeatureSet,
82-
hasDataCount: Bool
82+
dataCount: UInt32?
8383
) {
8484
self.functions = functions
8585
self.elements = elements
@@ -91,7 +91,7 @@ public struct Module {
9191
self.customSections = customSections
9292
self.allocator = allocator
9393
self.features = features
94-
self.hasDataCount = hasDataCount
94+
self.dataCount = dataCount
9595

9696
var importedFunctionTypes: [TypeIndex] = []
9797
var globalTypes: [GlobalType] = []

Sources/WasmKit/ModuleParser.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,6 @@ func parseModule<Stream: ByteStream>(stream: Stream, features: WasmFeatureSet =
123123
customSections: customSections,
124124
allocator: allocator,
125125
features: features,
126-
hasDataCount: dataCount != nil
126+
dataCount: dataCount
127127
)
128128
}

Sources/WasmKit/Translator.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ protocol TranslatorContext {
4545
func resolveCallee(_ index: FunctionIndex) -> InternalFunction?
4646
func isSameInstance(_ instance: InternalInstance) -> Bool
4747
func resolveGlobal(_ index: GlobalIndex) -> InternalGlobal?
48-
func validateDataSegment(_ index: DataIndex) throws
4948
func validateFunctionIndex(_ index: FunctionIndex) throws
49+
var dataCount: UInt32? { get }
5050
}
5151

5252
extension TranslatorContext {
@@ -114,15 +114,15 @@ extension InternalInstance: TranslatorContext {
114114
func isSameInstance(_ instance: InternalInstance) -> Bool {
115115
return instance == self
116116
}
117-
func validateDataSegment(_ index: DataIndex) throws {
118-
_ = try self.dataSegments[validating: Int(index)]
119-
}
120117
func validateFunctionIndex(_ index: FunctionIndex) throws {
121118
let function = try self.functions[validating: Int(index)]
122119
guard self.functionRefs.contains(function) else {
123120
throw ValidationError("Function index \(index) is not declared but referenced as a function reference")
124121
}
125122
}
123+
var dataCount: UInt32? {
124+
self.withValue { $0.dataCount }
125+
}
126126
}
127127

128128
private struct MetaProgramCounter {
@@ -2030,7 +2030,7 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
20302030
}
20312031

20322032
mutating func visitMemoryInit(dataIndex: UInt32) throws -> Output {
2033-
try self.module.validateDataSegment(dataIndex)
2033+
try self.validator.validateDataSegment(dataIndex)
20342034
let addressType = try module.addressType(memoryIndex: 0)
20352035
try pop3Emit((.i32, .i32, addressType)) { values, stack in
20362036
let (size, sourceOffset, destOffset) = values
@@ -2045,7 +2045,7 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
20452045
}
20462046
}
20472047
mutating func visitDataDrop(dataIndex: UInt32) throws -> Output {
2048-
try self.module.validateDataSegment(dataIndex)
2048+
try self.validator.validateDataSegment(dataIndex)
20492049
emit(.memoryDataDrop(Instruction.MemoryDataDropOperand(segmentIndex: dataIndex)))
20502050
}
20512051
mutating func visitMemoryCopy(dstMem: UInt32, srcMem: UInt32) throws -> Output {

Sources/WasmKit/Validator.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ struct InstructionValidator<Context: TranslatorContext> {
5454
func validateRefFunc(functionIndex: UInt32) throws {
5555
try context.validateFunctionIndex(functionIndex)
5656
}
57+
58+
func validateDataSegment(_ dataIndex: DataIndex) throws {
59+
// instruction referring data segment requires data count section
60+
// https://webassembly.github.io/spec/core/binary/modules.html#data-count-section
61+
guard let dataCount = context.dataCount else {
62+
throw ValidationError("Data count section is required but not found")
63+
}
64+
guard dataIndex < dataCount else {
65+
throw ValidationError("Data index out of bounds: \(dataIndex) (max: \(dataCount))")
66+
}
67+
}
5768
}
5869

5970
struct ModuleValidator {

Sources/WasmParser/WasmParser.swift

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import WasmTypes
1212
public struct Parser<Stream: ByteStream> {
1313
@usableFromInline
1414
let stream: Stream
15-
public private(set) var hasDataCount: Bool = false
16-
public let features: WasmFeatureSet
1715
let limits: ParsingLimits
1816
var orderTracking = OrderTracking()
1917

@@ -23,14 +21,14 @@ public struct Parser<Stream: ByteStream> {
2321
}
2422
private var nextParseTarget: NextParseTarget
2523

24+
public let features: WasmFeatureSet
2625
public var offset: Int {
2726
return stream.currentIndex
2827
}
2928

30-
public init(stream: Stream, features: WasmFeatureSet = .default, hasDataCount: Bool = false) {
29+
public init(stream: Stream, features: WasmFeatureSet = .default) {
3130
self.stream = stream
3231
self.features = features
33-
self.hasDataCount = hasDataCount
3432
self.nextParseTarget = .header
3533
self.limits = .default
3634
}
@@ -121,7 +119,7 @@ extension Code {
121119
/// ````
122120
@inlinable
123121
public func parseExpression<V: InstructionVisitor>(visitor: inout V) throws {
124-
let parser = Parser(stream: StaticByteStream(bytes: self.expression), features: self.features, hasDataCount: self.hasDataCount)
122+
let parser = Parser(stream: StaticByteStream(bytes: self.expression), features: self.features)
125123
var lastCode: InstructionCode?
126124
while try !parser.stream.hasReachedEnd() {
127125
lastCode = try parser.parseInstruction(visitor: &visitor)
@@ -153,8 +151,7 @@ public struct ExpressionParser {
153151
public init(code: Code) {
154152
self.parser = Parser(
155153
stream: StaticByteStream(bytes: code.expression),
156-
features: code.features,
157-
hasDataCount: code.hasDataCount
154+
features: code.features
158155
)
159156
self.codeOffset = code.offset
160157
self.initialStreamOffset = self.parser.offset
@@ -166,7 +163,7 @@ public struct ExpressionParser {
166163
let shouldContinue = try !parser.stream.hasReachedEnd()
167164
if !shouldContinue {
168165
guard lastCode == .end else {
169-
throw parser.makeError(.endOpcodeExpected)
166+
throw WasmParserError(.endOpcodeExpected, offset: offset)
170167
}
171168
}
172169
return shouldContinue
@@ -212,6 +209,7 @@ public struct WasmParserError: Swift.Error {
212209
let message: Message
213210
let offset: Int
214211

212+
@usableFromInline
215213
init(_ message: Message, offset: Int) {
216214
self.message = message
217215
self.offset = offset
@@ -300,8 +298,6 @@ extension WasmParserError.Message {
300298

301299
static let sectionOutOfOrder = Self("Sections in the module are out of order")
302300

303-
@usableFromInline static let dataCountSectionRequired = Self("Data count section is required but not found")
304-
305301
static func malformedLimit(_ byte: UInt8) -> Self {
306302
Self("Malformed limit: \(byte)")
307303
}
@@ -874,24 +870,13 @@ extension Parser {
874870
case 7: return try v.visitConversion(.i64TruncSatF64U)
875871
case 8:
876872
let dataIndex: DataIndex = try parseUnsigned()
877-
// memory.init requires data count section
878-
// https://webassembly.github.io/spec/core/binary/modules.html#data-count-section
879-
guard hasDataCount else {
880-
throw makeError(.dataCountSectionRequired)
881-
}
882-
883873
let zero = try stream.consumeAny()
884874
guard zero == 0x00 else {
885875
throw makeError(.zeroExpected(actual: zero))
886876
}
887877

888878
return try v.visitMemoryInit(dataIndex: dataIndex)
889879
case 9:
890-
// memory.drop requires data count section
891-
// https://webassembly.github.io/spec/core/binary/modules.html#data-count-section
892-
guard hasDataCount else {
893-
throw makeError(.dataCountSectionRequired)
894-
}
895880
return try v.visitDataDrop(dataIndex: try parseUnsigned())
896881
case 10:
897882
let (zero1, zero2) = try (stream.consumeAny(), stream.consumeAny())
@@ -1140,7 +1125,7 @@ extension Parser {
11401125
)
11411126
return Code(
11421127
locals: locals, expression: expressionBytes,
1143-
offset: expressionStart, hasDataCount: hasDataCount, features: features
1128+
offset: expressionStart, features: features
11441129
)
11451130
}
11461131
}
@@ -1327,7 +1312,6 @@ extension Parser {
13271312
payload = .dataSection(try parseDataSection())
13281313
case 12:
13291314
order = .dataCount
1330-
hasDataCount = true
13311315
payload = .dataCount(try parseDataCountSection())
13321316
default:
13331317
throw makeError(.malformedSectionID(sectionID))

Sources/WasmParser/WasmTypes.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ public struct Code {
1313
@usableFromInline
1414
internal let offset: Int
1515
@usableFromInline
16-
internal let hasDataCount: Bool
17-
@usableFromInline
1816
internal let features: WasmFeatureSet
1917
}
2018

0 commit comments

Comments
 (0)