| /* |
| * Copyright 2021 Google Inc. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| import XCTest |
| @testable import FlatBuffers |
| |
| final class FlatbuffersVerifierTests: XCTestCase { |
| |
| lazy var validStorage: ByteBuffer.Storage = ByteBuffer.Storage( |
| count: Int(FlatBufferMaxSize) - 1, |
| alignment: 1) |
| lazy var errorStorage: ByteBuffer.Storage = ByteBuffer.Storage( |
| count: Int(FlatBufferMaxSize) + 1, |
| alignment: 1) |
| |
| var buffer: ByteBuffer! |
| |
| var validFlatbuffersObject: ByteBuffer! |
| var invalidFlatbuffersObject: ByteBuffer! |
| |
| override func setUp() { |
| // swiftformat:disable all |
| buffer = ByteBuffer(initialSize: 32) |
| add(buffer: &buffer, v: 4, p: 16) |
| add(buffer: &buffer, v: 4, p: 20) |
| |
| validFlatbuffersObject = ByteBuffer(bytes: [48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0]) |
| |
| invalidFlatbuffersObject = ByteBuffer(bytes: [0, 48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0]) |
| |
| // swiftformat:enable all |
| } |
| |
| func testVeriferInitPassing() { |
| var buffer = ByteBuffer(initialSize: 0) |
| buffer._storage = validStorage |
| XCTAssertNoThrow(try Verifier(buffer: &buffer)) |
| } |
| |
| func testVeriferInitFailing() { |
| var buffer = ByteBuffer(initialSize: 0) |
| buffer._storage = errorStorage |
| XCTAssertThrowsError(try Verifier(buffer: &buffer)) |
| } |
| |
| func testVerifierCheckAlignment() { |
| var verifier = try! Verifier(buffer: &buffer) |
| do { |
| try verifier.isAligned(position: 20, type: Int.self) |
| } catch { |
| XCTAssertEqual( |
| error as? FlatbuffersErrors, |
| .missAlignedPointer(position: 20, type: "Int")) |
| } |
| XCTAssertNoThrow(try verifier.isAligned(position: 16, type: Int.self)) |
| |
| var newVerifer = try! Verifier(buffer: &buffer, checkAlignment: false) |
| XCTAssertNoThrow(try newVerifer.isAligned(position: 16, type: Int.self)) |
| } |
| |
| func testRangeInBuffer() { |
| var verifier = try! Verifier(buffer: &buffer) |
| let size = MemoryLayout<Int64>.size |
| XCTAssertNoThrow(try verifier.rangeInBuffer(position: 24, size: size)) |
| XCTAssertThrowsError(try verifier.rangeInBuffer(position: 26, size: size)) |
| XCTAssertThrowsError(try verifier.rangeInBuffer(position: 26, size: size)) |
| XCTAssertThrowsError(try verifier.rangeInBuffer(position: 30, size: size)) |
| XCTAssertThrowsError(try verifier.rangeInBuffer(position: 32, size: size)) |
| XCTAssertThrowsError(try verifier.rangeInBuffer(position: 34, size: size)) |
| |
| verifier = try! Verifier( |
| buffer: &buffer, |
| options: .init(maxDepth: 0, maxTableCount: 0, maxApparentSize: 4)) |
| do { |
| try verifier.rangeInBuffer(position: 24, size: size) |
| } catch { |
| XCTAssertEqual( |
| error as! FlatbuffersErrors, |
| .apparentSizeTooLarge) |
| } |
| } |
| |
| func testPositionInBuffer() { |
| var verifier = try! Verifier(buffer: &buffer) |
| XCTAssertNoThrow(try verifier.inBuffer(position: 0, of: Int64.self)) |
| XCTAssertNoThrow(try verifier.inBuffer(position: 24, of: Int64.self)) |
| XCTAssertThrowsError(try verifier.inBuffer(position: -9, of: Int64.self)) |
| XCTAssertThrowsError(try verifier.inBuffer(position: 25, of: Int64.self)) |
| XCTAssertThrowsError(try verifier.inBuffer(position: 26, of: Int32.self)) |
| XCTAssertThrowsError(try verifier.inBuffer(position: 26, of: Int64.self)) |
| XCTAssertThrowsError(try verifier.inBuffer(position: 30, of: Int64.self)) |
| XCTAssertThrowsError(try verifier.inBuffer(position: 32, of: Int64.self)) |
| XCTAssertThrowsError(try verifier.inBuffer(position: 34, of: Int64.self)) |
| } |
| |
| func testVisitTable() { |
| var verifier = try! Verifier(buffer: &validFlatbuffersObject) |
| XCTAssertNoThrow(try verifier.visitTable(at: 48)) |
| verifier.reset() |
| } |
| |
| func testTableVerifier() { |
| var verifier = try! Verifier(buffer: &validFlatbuffersObject) |
| |
| var tableVerifer = try! verifier.visitTable(at: 48) |
| XCTAssertNoThrow(try tableVerifer.visit( |
| field: 4, |
| fieldName: "Vec", |
| required: false, |
| type: Vec3.self)) |
| XCTAssertNoThrow(try tableVerifer.visit( |
| field: 8, |
| fieldName: "hp", |
| required: false, |
| type: Int16.self)) |
| |
| XCTAssertNoThrow(try tableVerifer.visit( |
| field: 10, |
| fieldName: "name", |
| required: true, |
| type: ForwardOffset<String>.self)) |
| |
| XCTAssertNoThrow(try tableVerifer.visit( |
| field: 14, |
| fieldName: "inventory", |
| required: false, |
| type: ForwardOffset<Vector<UInt8, UInt8>>.self)) |
| |
| XCTAssertNoThrow(try tableVerifer.visit( |
| field: 22, |
| fieldName: "test4", |
| required: false, |
| type: ForwardOffset<Vector<MyGame_Example_Test, MyGame_Example_Test>> |
| .self)) |
| |
| XCTAssertNoThrow(try tableVerifer.visit( |
| field: 24, |
| fieldName: "Vector of strings", |
| required: false, |
| type: ForwardOffset<Vector<ForwardOffset<String>, String>>.self)) |
| |
| do { |
| try tableVerifer.visit( |
| field: 13, |
| fieldName: "notvalid", |
| required: false, |
| type: Int16.self) |
| } catch { |
| XCTAssertEqual( |
| error as! FlatbuffersErrors, |
| .missAlignedPointer(position: 25, type: "UInt16")) |
| } |
| |
| do { |
| try tableVerifer.visit( |
| unionKey: 18, |
| unionField: 20, |
| unionKeyName: "testType", |
| fieldName: "test", |
| required: false, |
| completion: { (verifier, key: MyGame_Example_Any_, pos) in |
| switch key { |
| case .none_: |
| break |
| case .monster: |
| try ForwardOffset<MyGame_Example_Monster>.verify( |
| &verifier, |
| at: pos, |
| of: MyGame_Example_Monster.self) |
| |
| case .testsimpletablewithenum: |
| break |
| case .mygameExample2Monster: |
| break |
| } |
| }) |
| } catch { |
| XCTAssertEqual( |
| error as! FlatbuffersErrors, |
| .missAlignedPointer(position: 25, type: "UInt16")) |
| } |
| } |
| |
| func testVerifyUnionVectors() { |
| // swiftformat:disable all |
| var byteBuffer = ByteBuffer(bytes: [20, 0, 0, 0, 77, 79, 86, 73, 12, 0, 12, 0, 0, 0, 0, 0, 8, 0, 4, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 0, 32, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 3, 1, 4, 0, 2, 0, 0, 0, 7, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 8, 0, 0, 0]) |
| // swiftformat:enable all |
| XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &byteBuffer) as Movie) |
| } |
| |
| func testFullVerifier() { |
| XCTAssertNoThrow( |
| try getCheckedRoot( |
| byteBuffer: &validFlatbuffersObject) as MyGame_Example_Monster) |
| } |
| |
| func testInvalidBuffer() { |
| XCTAssertThrowsError( |
| try getCheckedRoot( |
| byteBuffer: &invalidFlatbuffersObject) as MyGame_Example_Monster) |
| } |
| |
| func testValidUnionBuffer() { |
| let string = "Awesome \\\\t\t\nstring!" |
| var fb = FlatBufferBuilder() |
| let stringOffset = fb.create(string: string) |
| let characterType: [Character] = [.bookfan, .other] |
| |
| let characters = [ |
| fb.create(struct: BookReader(booksRead: 7)), |
| stringOffset, |
| ] |
| let types = fb.createVector(characterType) |
| let characterVector = fb.createVector(ofOffsets: characters) |
| |
| let end = Movie.createMovie( |
| &fb, |
| mainCharacterType: .other, |
| mainCharacterOffset: Offset(offset: stringOffset.o), |
| charactersTypeVectorOffset: types, |
| charactersVectorOffset: characterVector) |
| Movie.finish(&fb, end: end) |
| var buf = fb.sizedBuffer |
| XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &buf) as Movie) |
| } |
| |
| func add(buffer: inout ByteBuffer, v: Int32, p: Int) { |
| buffer.write(value: v, index: p) |
| } |
| } |