main.swift 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  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. private 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. )
  30. let semaphore = DispatchSemaphore(value: 0)
  31. Task {
  32. do {
  33. for try await _ in decoding {
  34. // TODO: Test serialization for completeness.
  35. // We could serialize individual messages like this:
  36. // let _: [UInt8] = try! msg.serializedBytes()
  37. // but we don't have a stream writer which is what
  38. // we really want to exercise here.
  39. // Also, serialization here more than doubles the total
  40. // run time, leading to timeouts for the fuzz tester. :(
  41. }
  42. } catch {
  43. // Error parsing are to be expected since not all input will be well formed.
  44. }
  45. semaphore.signal()
  46. }
  47. semaphore.wait()
  48. return 0
  49. }