1 /* 2 * Copyright 2021 Google Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import XCTest 18 @testable import FlatBuffers 19 20 final class FlatbuffersVerifierTests: XCTestCase { 21 22 lazy var validStorage: ByteBuffer.Storage = ByteBuffer.Storage( 23 count: Int(FlatBufferMaxSize) - 1, 24 alignment: 1) 25 lazy var errorStorage: ByteBuffer.Storage = ByteBuffer.Storage( 26 count: Int(FlatBufferMaxSize) + 1, 27 alignment: 1) 28 29 var buffer: ByteBuffer! 30 31 var validFlatbuffersObject: ByteBuffer! 32 var invalidFlatbuffersObject: ByteBuffer! 33 setUpnull34 override func setUp() { 35 // swiftformat:disable all 36 buffer = ByteBuffer(initialSize: 32) 37 add(buffer: &buffer, v: 4, p: 16) 38 add(buffer: &buffer, v: 4, p: 20) 39 40 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]) 41 42 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]) 43 44 // swiftformat:enable all 45 } 46 testVeriferInitPassingnull47 func testVeriferInitPassing() { 48 var buffer = ByteBuffer(initialSize: 0) 49 buffer._storage = validStorage 50 XCTAssertNoThrow(try Verifier(buffer: &buffer)) 51 } 52 testVeriferInitFailingnull53 func testVeriferInitFailing() { 54 var buffer = ByteBuffer(initialSize: 0) 55 buffer._storage = errorStorage 56 XCTAssertThrowsError(try Verifier(buffer: &buffer)) 57 } 58 testVerifierCheckAlignmentnull59 func testVerifierCheckAlignment() { 60 var verifier = try! Verifier(buffer: &buffer) 61 do { 62 try verifier.isAligned(position: 20, type: Int.self) 63 } catch { 64 XCTAssertEqual( 65 error as? FlatbuffersErrors, 66 .missAlignedPointer(position: 20, type: "Int")) 67 } 68 XCTAssertNoThrow(try verifier.isAligned(position: 16, type: Int.self)) 69 70 var newVerifer = try! Verifier(buffer: &buffer, checkAlignment: false) 71 XCTAssertNoThrow(try newVerifer.isAligned(position: 16, type: Int.self)) 72 } 73 testRangeInBuffernull74 func testRangeInBuffer() { 75 var verifier = try! Verifier(buffer: &buffer) 76 let size = MemoryLayout<Int64>.size 77 XCTAssertNoThrow(try verifier.rangeInBuffer(position: 24, size: size)) 78 XCTAssertThrowsError(try verifier.rangeInBuffer(position: 26, size: size)) 79 XCTAssertThrowsError(try verifier.rangeInBuffer(position: 26, size: size)) 80 XCTAssertThrowsError(try verifier.rangeInBuffer(position: 30, size: size)) 81 XCTAssertThrowsError(try verifier.rangeInBuffer(position: 32, size: size)) 82 XCTAssertThrowsError(try verifier.rangeInBuffer(position: 34, size: size)) 83 84 verifier = try! Verifier( 85 buffer: &buffer, 86 options: .init(maxDepth: 0, maxTableCount: 0, maxApparentSize: 4)) 87 do { 88 try verifier.rangeInBuffer(position: 24, size: size) 89 } catch { 90 XCTAssertEqual( 91 error as! FlatbuffersErrors, 92 .apparentSizeTooLarge) 93 } 94 } 95 testPositionInBuffernull96 func testPositionInBuffer() { 97 var verifier = try! Verifier(buffer: &buffer) 98 XCTAssertNoThrow(try verifier.inBuffer(position: 0, of: Int64.self)) 99 XCTAssertNoThrow(try verifier.inBuffer(position: 24, of: Int64.self)) 100 XCTAssertThrowsError(try verifier.inBuffer(position: -9, of: Int64.self)) 101 XCTAssertThrowsError(try verifier.inBuffer(position: 25, of: Int64.self)) 102 XCTAssertThrowsError(try verifier.inBuffer(position: 26, of: Int32.self)) 103 XCTAssertThrowsError(try verifier.inBuffer(position: 26, of: Int64.self)) 104 XCTAssertThrowsError(try verifier.inBuffer(position: 30, of: Int64.self)) 105 XCTAssertThrowsError(try verifier.inBuffer(position: 32, of: Int64.self)) 106 XCTAssertThrowsError(try verifier.inBuffer(position: 34, of: Int64.self)) 107 } 108 testVisitTablenull109 func testVisitTable() { 110 var verifier = try! Verifier(buffer: &validFlatbuffersObject) 111 XCTAssertNoThrow(try verifier.visitTable(at: 48)) 112 verifier.reset() 113 } 114 testTableVerifiernull115 func testTableVerifier() { 116 var verifier = try! Verifier(buffer: &validFlatbuffersObject) 117 118 var tableVerifer = try! verifier.visitTable(at: 48) 119 XCTAssertNoThrow(try tableVerifer.visit( 120 field: 4, 121 fieldName: "Vec", 122 required: false, 123 type: Vec3.self)) 124 XCTAssertNoThrow(try tableVerifer.visit( 125 field: 8, 126 fieldName: "hp", 127 required: false, 128 type: Int16.self)) 129 130 XCTAssertNoThrow(try tableVerifer.visit( 131 field: 10, 132 fieldName: "name", 133 required: true, 134 type: ForwardOffset<String>.self)) 135 136 XCTAssertNoThrow(try tableVerifer.visit( 137 field: 14, 138 fieldName: "inventory", 139 required: false, 140 type: ForwardOffset<Vector<UInt8, UInt8>>.self)) 141 142 XCTAssertNoThrow(try tableVerifer.visit( 143 field: 22, 144 fieldName: "test4", 145 required: false, 146 type: ForwardOffset<Vector<MyGame_Example_Test, MyGame_Example_Test>> 147 .self)) 148 149 XCTAssertNoThrow(try tableVerifer.visit( 150 field: 24, 151 fieldName: "Vector of strings", 152 required: false, 153 type: ForwardOffset<Vector<ForwardOffset<String>, String>>.self)) 154 155 do { 156 try tableVerifer.visit( 157 field: 13, 158 fieldName: "notvalid", 159 required: false, 160 type: Int16.self) 161 } catch { 162 XCTAssertEqual( 163 error as! FlatbuffersErrors, 164 .missAlignedPointer(position: 25, type: "UInt16")) 165 } 166 167 do { 168 try tableVerifer.visit( 169 unionKey: 18, 170 unionField: 20, 171 unionKeyName: "testType", 172 fieldName: "test", 173 required: false, 174 completion: { (verifier, key: MyGame_Example_Any_, pos) in 175 switch key { 176 case .none_: 177 break 178 case .monster: 179 try ForwardOffset<MyGame_Example_Monster>.verify( 180 &verifier, 181 at: pos, 182 of: MyGame_Example_Monster.self) 183 184 case .testsimpletablewithenum: 185 break 186 case .mygameExample2Monster: 187 break 188 } 189 }) 190 } catch { 191 XCTAssertEqual( 192 error as! FlatbuffersErrors, 193 .missAlignedPointer(position: 25, type: "UInt16")) 194 } 195 } 196 testVerifyUnionVectorsnull197 func testVerifyUnionVectors() { 198 // swiftformat:disable all 199 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]) 200 // swiftformat:enable all 201 XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &byteBuffer) as Movie) 202 } 203 testErrorWrongFileIdnull204 func testErrorWrongFileId() { 205 // swiftformat:disable all 206 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]) 207 // swiftformat:enable all 208 XCTAssertThrowsError(try getCheckedRoot(byteBuffer: &byteBuffer, fileId: "FLEX") as Movie) 209 } 210 testVerifyPrefixedBuffernull211 func testVerifyPrefixedBuffer() { 212 // swiftformat:disable all 213 var byteBuffer = ByteBuffer(bytes: [0, 0, 0, 1, 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]) 214 // swiftformat:enable all 215 XCTAssertThrowsError( 216 try getCheckedPrefixedSizeRoot(byteBuffer: &byteBuffer) as Movie) 217 } 218 testFullVerifiernull219 func testFullVerifier() { 220 XCTAssertNoThrow( 221 try getCheckedRoot( 222 byteBuffer: &validFlatbuffersObject) as MyGame_Example_Monster) 223 } 224 testFullVerifierWithFileIdnull225 func testFullVerifierWithFileId() { 226 XCTAssertNoThrow( 227 try getCheckedRoot( 228 byteBuffer: &validFlatbuffersObject, 229 fileId: MyGame_Example_Monster.id) as MyGame_Example_Monster) 230 } 231 testInvalidBuffernull232 func testInvalidBuffer() { 233 XCTAssertThrowsError( 234 try getCheckedRoot( 235 byteBuffer: &invalidFlatbuffersObject) as MyGame_Example_Monster) 236 } 237 testValidUnionBuffernull238 func testValidUnionBuffer() { 239 let string = "Awesome \\\\t\t\nstring!" 240 var fb = FlatBufferBuilder() 241 let stringOffset = fb.create(string: string) 242 let characterType: [Character] = [.bookfan, .other] 243 244 let characters = [ 245 fb.create(struct: BookReader(booksRead: 7)), 246 stringOffset, 247 ] 248 let types = fb.createVector(characterType) 249 let characterVector = fb.createVector(ofOffsets: characters) 250 251 let end = Movie.createMovie( 252 &fb, 253 mainCharacterType: .other, 254 mainCharacterOffset: Offset(offset: stringOffset.o), 255 charactersTypeVectorOffset: types, 256 charactersVectorOffset: characterVector) 257 Movie.finish(&fb, end: end) 258 var buf = fb.sizedBuffer 259 XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &buf) as Movie) 260 } 261 addnull262 func add(buffer: inout ByteBuffer, v: Int32, p: Int) { 263 buffer.write(value: v, index: p) 264 } 265 } 266