make_FuzzBinary_dict 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #!/usr/bin/env swift
  2. import Foundation
  3. enum WireFormat: UInt8 {
  4. case varint = 0
  5. case fixed64 = 1
  6. case lengthDelimited = 2
  7. case startGroup = 3
  8. case endGroup = 4
  9. case fixed32 = 5
  10. }
  11. enum Matchers {
  12. case prefix(String, WireFormat)
  13. case suffix(String, WireFormat, WireFormat)
  14. case contains(String, WireFormat)
  15. case contains2(String, WireFormat, WireFormat)
  16. case containsAndPackable(String, WireFormat)
  17. }
  18. // The order of these matters since it is first match that is used.
  19. let tests: [Matchers] = [
  20. .prefix("wkt", .lengthDelimited),
  21. .prefix("map", .lengthDelimited),
  22. .contains2("Group", .startGroup, .endGroup),
  23. .containsAndPackable("float", .fixed32),
  24. .containsAndPackable("double", .fixed64),
  25. .containsAndPackable("fixed64", .fixed64),
  26. .containsAndPackable("fixed", .fixed32),
  27. .containsAndPackable("int64", .varint),
  28. .containsAndPackable("int32", .varint),
  29. .containsAndPackable("bool", .varint),
  30. .containsAndPackable("enum", .varint),
  31. .contains("bytes", .lengthDelimited),
  32. .contains("string", .lengthDelimited),
  33. .contains("message", .lengthDelimited),
  34. // The single fields in the Groups.
  35. .contains("group_field", .varint),
  36. ]
  37. func escapedVarint(_ x: Int) -> String {
  38. var escaped = String()
  39. var v = x
  40. while v > 127 {
  41. escaped.append(String(format: "\\x%02x", UInt8(v & 0x7f | 0x80)))
  42. v >>= 7
  43. }
  44. escaped.append(String(format: "\\x%02x", UInt8(v)))
  45. return escaped
  46. }
  47. func outputTag(_ fieldNum: Int, as wireformat: WireFormat) {
  48. let tag = UInt32(truncatingIfNeeded: fieldNum) << 3 | UInt32(wireformat.rawValue)
  49. print("\"\(escapedVarint(Int(tag)))\"")
  50. }
  51. if CommandLine.arguments.count != 2 {
  52. print("Expected only to get the proto file path as an argument")
  53. exit(1)
  54. }
  55. print("# Tags for all the fields")
  56. let protoFile = try! String(contentsOfFile: CommandLine.arguments[1], encoding: .utf8)
  57. let re = try NSRegularExpression(pattern: #"^ *.+ +(\w+) += (\d+)"#,
  58. options: [.anchorsMatchLines])
  59. let range = NSRange(protoFile.startIndex..<protoFile.endIndex, in: protoFile)
  60. re.enumerateMatches(in: protoFile, options: [], range: range) { (match, _, _) in
  61. guard let match = match else { return }
  62. guard match.numberOfRanges == 3 else { return }
  63. let fieldName = protoFile[Range(match.range(at: 1), in: protoFile)!]
  64. let fieldNum = Int(protoFile[Range(match.range(at: 2), in: protoFile)!])!
  65. // The regex matches enum cases, so skip those.
  66. guard fieldName.uppercased() != fieldName else { return }
  67. for test in tests {
  68. switch test {
  69. case .prefix(let s, let wf):
  70. if fieldName.hasPrefix(s) {
  71. outputTag(fieldNum, as: wf)
  72. return
  73. }
  74. case .suffix(let s, let wf1, let wf2):
  75. if fieldName.hasSuffix(s) {
  76. outputTag(fieldNum, as: wf1)
  77. outputTag(fieldNum, as: wf2)
  78. return
  79. }
  80. case .contains(let s, let wf):
  81. if fieldName.contains(s) {
  82. outputTag(fieldNum, as: wf)
  83. return
  84. }
  85. case .contains2(let s, let wf1, let wf2):
  86. if fieldName.contains(s) {
  87. outputTag(fieldNum, as: wf1)
  88. outputTag(fieldNum, as: wf2)
  89. return
  90. }
  91. case .containsAndPackable(let s, let wf):
  92. if fieldName.contains(s) {
  93. outputTag(fieldNum, as: wf)
  94. if fieldName.contains("repeated") {
  95. outputTag(fieldNum, as: .lengthDelimited)
  96. }
  97. return
  98. }
  99. }
  100. }
  101. print("Error: failed to match: \(fieldName)")
  102. exit(1)
  103. }
  104. print(#"""
  105. # Include a few example values:
  106. # varint:
  107. "\#(escapedVarint(0))"
  108. "\#(escapedVarint(5000))"
  109. "\#(escapedVarint(50000))"
  110. # fixed32:
  111. "\x01\x02\x03\x04"
  112. "\x05\x06\x07\x08"
  113. # fixed64:
  114. "\x01\x02\x03\x04\x05\x06\x07\x08"
  115. "\x01\x02\x03\x04\x50\x60\x70\x80"
  116. # length delimited:
  117. "\#(escapedVarint(3))abc"
  118. "\#(escapedVarint(7))1234567"
  119. "\#(escapedVarint(26))abcdefghijklmnopqrstuvwxyz"
  120. # start/end group just have tags/values after them, no tag specific payload; so
  121. # nothing to provide as an example.
  122. """#)