main.swift 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Copyright (c) 2014 - 2024 Apple Inc. and the project authors
  2. // Licensed under Apache License v2.0 with Runtime Library Exception
  3. //
  4. // See LICENSE.txt for license information:
  5. // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
  6. //
  7. // -----------------------------------------------------------------------------
  8. import Foundation
  9. import FuzzCommon
  10. import SwiftProtobuf
  11. fileprivate func asyncByteStream(bytes: UnsafeRawBufferPointer) -> AsyncStream<UInt8> {
  12. AsyncStream(UInt8.self) { continuation in
  13. for i in 0..<bytes.count {
  14. continuation.yield(bytes.loadUnaligned(fromByteOffset: i, as: UInt8.self))
  15. }
  16. continuation.finish()
  17. }
  18. }
  19. @_cdecl("LLVMFuzzerTestOneInput")
  20. public func FuzzAsyncMessageSequence(_ start: UnsafeRawPointer, _ count: Int) -> CInt {
  21. // No decoding options here, a leading zero is actually valid (zero length message),
  22. // so we rely on the other Binary fuzz tester to test options, and just let this
  23. // one focus on issue around framing of the messages on the stream.
  24. let bytes = UnsafeRawBufferPointer(start: start, count: count)
  25. let asyncBytes = asyncByteStream(bytes: bytes)
  26. let decoding = asyncBytes.binaryProtobufDelimitedMessages(
  27. of: SwiftProtoTesting_Fuzz_Message.self,
  28. extensions: SwiftProtoTesting_Fuzz_FuzzTesting_Extensions)
  29. let semaphore = DispatchSemaphore(value: 0)
  30. Task {
  31. do {
  32. for try await _ in decoding {
  33. // TODO: Test serialization for completeness.
  34. // We could serialize individual messages like this:
  35. // let _: [UInt8] = try! msg.serializedBytes()
  36. // but we don't have a stream writer which is what
  37. // we really want to exercise here.
  38. // Also, serialization here more than doubles the total
  39. // run time, leading to timeouts for the fuzz tester. :(
  40. }
  41. } catch {
  42. // Error parsing are to be expected since not all input will be well formed.
  43. }
  44. semaphore.signal()
  45. }
  46. semaphore.wait()
  47. return 0
  48. }