JSONScanner.swift 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575
  1. // Sources/SwiftProtobuf/JSONScanner.swift - JSON format decoding
  2. //
  3. // Copyright (c) 2014 - 2019 Apple Inc. and the project authors
  4. // Licensed under Apache License v2.0 with Runtime Library Exception
  5. //
  6. // See LICENSE.txt for license information:
  7. // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
  8. //
  9. // -----------------------------------------------------------------------------
  10. ///
  11. /// JSON format decoding engine.
  12. ///
  13. // -----------------------------------------------------------------------------
  14. import Foundation
  15. private let asciiBell = UInt8(7)
  16. private let asciiBackspace = UInt8(8)
  17. private let asciiTab = UInt8(9)
  18. private let asciiNewLine = UInt8(10)
  19. private let asciiVerticalTab = UInt8(11)
  20. private let asciiFormFeed = UInt8(12)
  21. private let asciiCarriageReturn = UInt8(13)
  22. private let asciiZero = UInt8(ascii: "0")
  23. private let asciiOne = UInt8(ascii: "1")
  24. private let asciiSeven = UInt8(ascii: "7")
  25. private let asciiNine = UInt8(ascii: "9")
  26. private let asciiColon = UInt8(ascii: ":")
  27. private let asciiPeriod = UInt8(ascii: ".")
  28. private let asciiPlus = UInt8(ascii: "+")
  29. private let asciiComma = UInt8(ascii: ",")
  30. private let asciiSemicolon = UInt8(ascii: ";")
  31. private let asciiDoubleQuote = UInt8(ascii: "\"")
  32. private let asciiSingleQuote = UInt8(ascii: "\'")
  33. private let asciiBackslash = UInt8(ascii: "\\")
  34. private let asciiForwardSlash = UInt8(ascii: "/")
  35. private let asciiHash = UInt8(ascii: "#")
  36. private let asciiEqualSign = UInt8(ascii: "=")
  37. private let asciiUnderscore = UInt8(ascii: "_")
  38. private let asciiQuestionMark = UInt8(ascii: "?")
  39. private let asciiSpace = UInt8(ascii: " ")
  40. private let asciiOpenSquareBracket = UInt8(ascii: "[")
  41. private let asciiCloseSquareBracket = UInt8(ascii: "]")
  42. private let asciiOpenCurlyBracket = UInt8(ascii: "{")
  43. private let asciiCloseCurlyBracket = UInt8(ascii: "}")
  44. private let asciiOpenAngleBracket = UInt8(ascii: "<")
  45. private let asciiCloseAngleBracket = UInt8(ascii: ">")
  46. private let asciiMinus = UInt8(ascii: "-")
  47. private let asciiLowerA = UInt8(ascii: "a")
  48. private let asciiUpperA = UInt8(ascii: "A")
  49. private let asciiLowerB = UInt8(ascii: "b")
  50. private let asciiLowerE = UInt8(ascii: "e")
  51. private let asciiUpperE = UInt8(ascii: "E")
  52. private let asciiLowerF = UInt8(ascii: "f")
  53. private let asciiUpperI = UInt8(ascii: "I")
  54. private let asciiLowerL = UInt8(ascii: "l")
  55. private let asciiLowerN = UInt8(ascii: "n")
  56. private let asciiUpperN = UInt8(ascii: "N")
  57. private let asciiLowerR = UInt8(ascii: "r")
  58. private let asciiLowerS = UInt8(ascii: "s")
  59. private let asciiLowerT = UInt8(ascii: "t")
  60. private let asciiLowerU = UInt8(ascii: "u")
  61. private let asciiLowerZ = UInt8(ascii: "z")
  62. private let asciiUpperZ = UInt8(ascii: "Z")
  63. private func fromHexDigit(_ c: UnicodeScalar) -> UInt32? {
  64. let n = c.value
  65. if n >= 48 && n <= 57 {
  66. return UInt32(n - 48)
  67. }
  68. switch n {
  69. case 65, 97: return 10
  70. case 66, 98: return 11
  71. case 67, 99: return 12
  72. case 68, 100: return 13
  73. case 69, 101: return 14
  74. case 70, 102: return 15
  75. default:
  76. return nil
  77. }
  78. }
  79. // Decode both the RFC 4648 section 4 Base 64 encoding and the RFC
  80. // 4648 section 5 Base 64 variant. The section 5 variant is also
  81. // known as "base64url" or the "URL-safe alphabet".
  82. // Note that both "-" and "+" decode to 62 and "/" and "_" both
  83. // decode as 63.
  84. // swift-format-ignore: NoBlockComments
  85. let base64Values: [Int] = [
  86. /* 0x00 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  87. /* 0x10 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  88. /* 0x20 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63,
  89. /* 0x30 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
  90. /* 0x40 */ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  91. /* 0x50 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
  92. /* 0x60 */ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  93. /* 0x70 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
  94. /* 0x80 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  95. /* 0x90 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  96. /* 0xa0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  97. /* 0xb0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  98. /* 0xc0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  99. /* 0xd0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  100. /* 0xe0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  101. /* 0xf0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  102. ]
  103. /// Returns a `Data` value containing bytes equivalent to the given
  104. /// Base64-encoded string, or nil if the conversion fails.
  105. ///
  106. /// Notes on Google's implementation (Base64Unescape() in strutil.cc):
  107. /// * Google's C++ implementation accepts arbitrary whitespace
  108. /// mixed in with the base-64 characters
  109. /// * Google's C++ implementation ignores missing '=' characters
  110. /// but if present, there must be the exact correct number of them.
  111. /// * The conformance test requires us to accept both standard RFC4648
  112. /// Base 64 encoding and the "URL and Filename Safe Alphabet" variant.
  113. ///
  114. private func parseBytes(
  115. source: UnsafeRawBufferPointer,
  116. index: inout UnsafeRawBufferPointer.Index,
  117. end: UnsafeRawBufferPointer.Index
  118. ) throws -> Data {
  119. let c = source[index]
  120. if c != asciiDoubleQuote {
  121. throw JSONDecodingError.malformedString
  122. }
  123. source.formIndex(after: &index)
  124. // Count the base-64 digits
  125. // Ignore most unrecognized characters in this first pass,
  126. // stop at the closing double quote.
  127. let digitsStart = index
  128. var rawChars = 0
  129. var sawSection4Characters = false
  130. var sawSection5Characters = false
  131. while index != end {
  132. var digit = source[index]
  133. if digit == asciiDoubleQuote {
  134. break
  135. }
  136. if digit == asciiBackslash {
  137. source.formIndex(after: &index)
  138. if index == end {
  139. throw JSONDecodingError.malformedString
  140. }
  141. let escaped = source[index]
  142. switch escaped {
  143. case asciiLowerU:
  144. // TODO: Parse hex escapes such as \u0041. Note that
  145. // such escapes are going to be extremely rare, so
  146. // there's little point in optimizing for them.
  147. throw JSONDecodingError.malformedString
  148. case asciiForwardSlash:
  149. digit = escaped
  150. default:
  151. // Reject \b \f \n \r \t \" or \\ and all illegal escapes
  152. throw JSONDecodingError.malformedString
  153. }
  154. }
  155. if digit == asciiPlus || digit == asciiForwardSlash {
  156. sawSection4Characters = true
  157. } else if digit == asciiMinus || digit == asciiUnderscore {
  158. sawSection5Characters = true
  159. }
  160. let k = base64Values[Int(digit)]
  161. if k >= 0 {
  162. rawChars += 1
  163. }
  164. source.formIndex(after: &index)
  165. }
  166. // We reached the end without seeing the close quote
  167. if index == end {
  168. throw JSONDecodingError.malformedString
  169. }
  170. // Reject mixed encodings.
  171. if sawSection4Characters && sawSection5Characters {
  172. throw JSONDecodingError.malformedString
  173. }
  174. // Allocate a Data object of exactly the right size
  175. var value = Data(count: rawChars * 3 / 4)
  176. // Scan the digits again and populate the Data object.
  177. // In this pass, we check for (and fail) if there are
  178. // unexpected characters. But we don't check for end-of-input,
  179. // because the loop above already verified that there was
  180. // a closing double quote.
  181. index = digitsStart
  182. try value.withUnsafeMutableBytes {
  183. (body: UnsafeMutableRawBufferPointer) in
  184. if var p = body.baseAddress, body.count > 0 {
  185. var n = 0
  186. var chars = 0 // # chars in current group
  187. var padding = 0 // # padding '=' chars
  188. digits: while true {
  189. let digit = source[index]
  190. var k = base64Values[Int(digit)]
  191. if k < 0 {
  192. switch digit {
  193. case asciiDoubleQuote:
  194. break digits
  195. case asciiBackslash:
  196. source.formIndex(after: &index)
  197. let escaped = source[index]
  198. switch escaped {
  199. case asciiForwardSlash:
  200. k = base64Values[Int(escaped)]
  201. default:
  202. // Note: Invalid backslash escapes were caught
  203. // above; we should never get here.
  204. throw JSONDecodingError.malformedString
  205. }
  206. case asciiSpace:
  207. source.formIndex(after: &index)
  208. continue digits
  209. case asciiEqualSign: // Count padding
  210. while true {
  211. switch source[index] {
  212. case asciiDoubleQuote:
  213. break digits
  214. case asciiSpace:
  215. break
  216. case 61:
  217. padding += 1
  218. default: // Only '=' and whitespace permitted
  219. throw JSONDecodingError.malformedString
  220. }
  221. source.formIndex(after: &index)
  222. }
  223. default:
  224. throw JSONDecodingError.malformedString
  225. }
  226. }
  227. n <<= 6
  228. n |= k
  229. chars += 1
  230. if chars == 4 {
  231. p[0] = UInt8(truncatingIfNeeded: n >> 16)
  232. p[1] = UInt8(truncatingIfNeeded: n >> 8)
  233. p[2] = UInt8(truncatingIfNeeded: n)
  234. p += 3
  235. chars = 0
  236. n = 0
  237. }
  238. source.formIndex(after: &index)
  239. }
  240. switch chars {
  241. case 3:
  242. p[0] = UInt8(truncatingIfNeeded: n >> 10)
  243. p[1] = UInt8(truncatingIfNeeded: n >> 2)
  244. if padding == 1 || padding == 0 {
  245. return
  246. }
  247. case 2:
  248. p[0] = UInt8(truncatingIfNeeded: n >> 4)
  249. if padding == 2 || padding == 0 {
  250. return
  251. }
  252. case 0:
  253. if padding == 0 {
  254. return
  255. }
  256. default:
  257. break
  258. }
  259. throw JSONDecodingError.malformedString
  260. }
  261. }
  262. source.formIndex(after: &index)
  263. return value
  264. }
  265. // JSON encoding allows a variety of \-escapes, including
  266. // escaping UTF-16 code points (which may be surrogate pairs).
  267. private func decodeString(_ s: String) -> String? {
  268. var out = String.UnicodeScalarView()
  269. var chars = s.unicodeScalars.makeIterator()
  270. while let c = chars.next() {
  271. switch c.value {
  272. case UInt32(asciiBackslash): // backslash
  273. if let escaped = chars.next() {
  274. switch escaped.value {
  275. case UInt32(asciiLowerU): // "\u"
  276. // Exactly 4 hex digits:
  277. if let digit1 = chars.next(),
  278. let d1 = fromHexDigit(digit1),
  279. let digit2 = chars.next(),
  280. let d2 = fromHexDigit(digit2),
  281. let digit3 = chars.next(),
  282. let d3 = fromHexDigit(digit3),
  283. let digit4 = chars.next(),
  284. let d4 = fromHexDigit(digit4)
  285. {
  286. let codePoint = ((d1 * 16 + d2) * 16 + d3) * 16 + d4
  287. if let scalar = UnicodeScalar(codePoint) {
  288. out.append(scalar)
  289. } else if codePoint < 0xD800 || codePoint >= 0xE000 {
  290. // Not a valid Unicode scalar.
  291. return nil
  292. } else if codePoint >= 0xDC00 {
  293. // Low surrogate without a preceding high surrogate.
  294. return nil
  295. } else {
  296. // We have a high surrogate (in the range 0xD800..<0xDC00), so
  297. // verify that it is followed by a low surrogate.
  298. guard chars.next() == "\\", chars.next() == "u" else {
  299. // High surrogate was not followed by a Unicode escape sequence.
  300. return nil
  301. }
  302. if let digit1 = chars.next(),
  303. let d1 = fromHexDigit(digit1),
  304. let digit2 = chars.next(),
  305. let d2 = fromHexDigit(digit2),
  306. let digit3 = chars.next(),
  307. let d3 = fromHexDigit(digit3),
  308. let digit4 = chars.next(),
  309. let d4 = fromHexDigit(digit4)
  310. {
  311. let follower = ((d1 * 16 + d2) * 16 + d3) * 16 + d4
  312. guard 0xDC00 <= follower && follower < 0xE000 else {
  313. // High surrogate was not followed by a low surrogate.
  314. return nil
  315. }
  316. let high = codePoint - 0xD800
  317. let low = follower - 0xDC00
  318. let composed = 0x10000 | high << 10 | low
  319. guard let composedScalar = UnicodeScalar(composed) else {
  320. // Composed value is not a valid Unicode scalar.
  321. return nil
  322. }
  323. out.append(composedScalar)
  324. } else {
  325. // Malformed \u escape for low surrogate
  326. return nil
  327. }
  328. }
  329. } else {
  330. // Malformed \u escape
  331. return nil
  332. }
  333. case UInt32(asciiLowerB): // \b
  334. out.append("\u{08}")
  335. case UInt32(asciiLowerF): // \f
  336. out.append("\u{0c}")
  337. case UInt32(asciiLowerN): // \n
  338. out.append("\u{0a}")
  339. case UInt32(asciiLowerR): // \r
  340. out.append("\u{0d}")
  341. case UInt32(asciiLowerT): // \t
  342. out.append("\u{09}")
  343. case UInt32(asciiDoubleQuote), UInt32(asciiBackslash),
  344. UInt32(asciiForwardSlash): // " \ /
  345. out.append(escaped)
  346. default:
  347. return nil // Unrecognized escape
  348. }
  349. } else {
  350. return nil // Input ends with backslash
  351. }
  352. default:
  353. out.append(c)
  354. }
  355. }
  356. return String(out)
  357. }
  358. ///
  359. /// The basic scanner support is entirely private
  360. ///
  361. /// For performance, it works directly against UTF-8 bytes in memory.
  362. internal struct JSONScanner {
  363. private let source: UnsafeRawBufferPointer
  364. private var index: UnsafeRawBufferPointer.Index
  365. private var numberParser = DoubleParser()
  366. internal let options: JSONDecodingOptions
  367. internal let extensions: any ExtensionMap
  368. internal var recursionBudget: Int
  369. /// True if the scanner has read all of the data from the source, with the
  370. /// exception of any trailing whitespace (which is consumed by reading this
  371. /// property).
  372. internal var complete: Bool {
  373. mutating get {
  374. skipWhitespace()
  375. return !hasMoreContent
  376. }
  377. }
  378. /// True if the scanner has not yet reached the end of the source.
  379. private var hasMoreContent: Bool {
  380. index != source.endIndex
  381. }
  382. /// The byte (UTF-8 code unit) at the scanner's current position.
  383. private var currentByte: UInt8 {
  384. source[index]
  385. }
  386. internal init(
  387. source: UnsafeRawBufferPointer,
  388. options: JSONDecodingOptions,
  389. extensions: (any ExtensionMap)?
  390. ) {
  391. self.source = source
  392. self.index = source.startIndex
  393. self.recursionBudget = options.messageDepthLimit
  394. self.options = options
  395. self.extensions = extensions ?? SimpleExtensionMap()
  396. }
  397. internal mutating func incrementRecursionDepth() throws {
  398. recursionBudget -= 1
  399. if recursionBudget < 0 {
  400. throw JSONDecodingError.messageDepthLimit
  401. }
  402. }
  403. internal mutating func decrementRecursionDepth() {
  404. recursionBudget += 1
  405. // This should never happen, if it does, something is probably corrupting memory, and
  406. // simply throwing doesn't make much sense.
  407. if recursionBudget > options.messageDepthLimit {
  408. fatalError("Somehow JSONDecoding unwound more objects than it started")
  409. }
  410. }
  411. /// Advances the scanner to the next position in the source.
  412. private mutating func advance() {
  413. source.formIndex(after: &index)
  414. }
  415. /// Skip whitespace.
  416. private mutating func skipWhitespace() {
  417. while hasMoreContent {
  418. let u = currentByte
  419. switch u {
  420. case asciiSpace, asciiTab, asciiNewLine, asciiCarriageReturn:
  421. advance()
  422. default:
  423. return
  424. }
  425. }
  426. }
  427. /// Returns (but does not consume) the next non-whitespace
  428. /// character. This is used by google.protobuf.Value, for
  429. /// example, for custom JSON parsing.
  430. internal mutating func peekOneCharacter() throws -> Character {
  431. skipWhitespace()
  432. guard hasMoreContent else {
  433. throw JSONDecodingError.truncated
  434. }
  435. return Character(UnicodeScalar(UInt32(currentByte))!)
  436. }
  437. // Parse the leading UInt64 from the provided utf8 bytes.
  438. //
  439. // This is called in three different situations:
  440. //
  441. // * Unquoted number.
  442. //
  443. // * Simple quoted number. If a number is quoted but has no
  444. // backslashes, the caller can use this directly on the UTF8 by
  445. // just verifying the quote marks. This code returns `nil` if it
  446. // sees a backslash, in which case the caller will need to handle ...
  447. //
  448. // * Complex quoted number. In this case, the caller must parse the
  449. // quoted value as a string, then convert the string to utf8 and
  450. // use this to parse the result. This is slow but fortunately
  451. // rare.
  452. //
  453. // In the common case where the number is written in integer form,
  454. // this code does a simple straight conversion. If the number is in
  455. // floating-point format, this uses a slower and less accurate
  456. // approach: it identifies a substring comprising a float, and then
  457. // uses Double() and UInt64() to convert that string to an unsigned
  458. // integer. In particular, it cannot preserve full 64-bit integer
  459. // values when they are written in floating-point format.
  460. //
  461. // If it encounters a "\" backslash character, it returns a nil. This
  462. // is used by callers that are parsing quoted numbers. See nextSInt()
  463. // and nextUInt() below.
  464. private func parseBareUInt64(
  465. source: UnsafeRawBufferPointer,
  466. index: inout UnsafeRawBufferPointer.Index,
  467. end: UnsafeRawBufferPointer.Index
  468. ) throws -> UInt64? {
  469. if index == end {
  470. throw JSONDecodingError.truncated
  471. }
  472. let start = index
  473. let c = source[index]
  474. switch c {
  475. case asciiZero: // 0
  476. source.formIndex(after: &index)
  477. if index != end {
  478. let after = source[index]
  479. switch after {
  480. case asciiZero...asciiNine: // 0...9
  481. // leading '0' forbidden unless it is the only digit
  482. throw JSONDecodingError.leadingZero
  483. case asciiPeriod, asciiLowerE, asciiUpperE: // . e
  484. // Slow path: JSON numbers can be written in floating-point notation
  485. index = start
  486. if let d = try parseBareDouble(
  487. source: source,
  488. index: &index,
  489. end: end
  490. ) {
  491. if let u = UInt64(exactly: d) {
  492. return u
  493. }
  494. }
  495. throw JSONDecodingError.malformedNumber
  496. case asciiBackslash:
  497. return nil
  498. default:
  499. return 0
  500. }
  501. }
  502. return 0
  503. case asciiOne...asciiNine: // 1...9
  504. var n = 0 as UInt64
  505. while index != end {
  506. let digit = source[index]
  507. switch digit {
  508. case asciiZero...asciiNine: // 0...9
  509. let val = UInt64(digit - asciiZero)
  510. if n > UInt64.max / 10 || n * 10 > UInt64.max - val {
  511. throw JSONDecodingError.numberRange
  512. }
  513. source.formIndex(after: &index)
  514. n = n * 10 + val
  515. case asciiPeriod, asciiLowerE, asciiUpperE: // . e
  516. // Slow path: JSON allows floating-point notation for integers
  517. index = start
  518. if let d = try parseBareDouble(
  519. source: source,
  520. index: &index,
  521. end: end
  522. ) {
  523. if let u = UInt64(exactly: d) {
  524. return u
  525. }
  526. }
  527. throw JSONDecodingError.malformedNumber
  528. case asciiBackslash:
  529. return nil
  530. default:
  531. return n
  532. }
  533. }
  534. return n
  535. case asciiBackslash:
  536. return nil
  537. default:
  538. throw JSONDecodingError.malformedNumber
  539. }
  540. }
  541. // Parse the leading Int64 from the provided utf8.
  542. //
  543. // This uses parseBareUInt64() to do the heavy lifting;
  544. // we just check for a leading minus and negate the result
  545. // as necessary.
  546. //
  547. // As with parseBareUInt64(), if it encounters a "\" backslash
  548. // character, it returns a nil. This allows callers to use this to
  549. // do a "fast-path" decode of simple quoted numbers by parsing the
  550. // UTF8 directly, only falling back to a full String decode when
  551. // absolutely necessary.
  552. private func parseBareSInt64(
  553. source: UnsafeRawBufferPointer,
  554. index: inout UnsafeRawBufferPointer.Index,
  555. end: UnsafeRawBufferPointer.Index
  556. ) throws -> Int64? {
  557. if index == end {
  558. throw JSONDecodingError.truncated
  559. }
  560. let c = source[index]
  561. if c == asciiMinus { // -
  562. source.formIndex(after: &index)
  563. if index == end {
  564. throw JSONDecodingError.truncated
  565. }
  566. // character after '-' must be digit
  567. let digit = source[index]
  568. if digit < asciiZero || digit > asciiNine {
  569. throw JSONDecodingError.malformedNumber
  570. }
  571. if let n = try parseBareUInt64(source: source, index: &index, end: end) {
  572. let limit: UInt64 = 0x8000_0000_0000_0000 // -Int64.min
  573. if n >= limit {
  574. if n > limit {
  575. // Too large negative number
  576. throw JSONDecodingError.numberRange
  577. } else {
  578. return Int64.min // Special case for Int64.min
  579. }
  580. }
  581. return -Int64(bitPattern: n)
  582. } else {
  583. return nil
  584. }
  585. } else if let n = try parseBareUInt64(source: source, index: &index, end: end) {
  586. if n > UInt64(bitPattern: Int64.max) {
  587. throw JSONDecodingError.numberRange
  588. }
  589. return Int64(bitPattern: n)
  590. } else {
  591. return nil
  592. }
  593. }
  594. // Identify a floating-point token in the upcoming UTF8 bytes.
  595. //
  596. // This implements the full grammar defined by the JSON RFC 7159.
  597. // Note that Swift's string-to-number conversions are much more
  598. // lenient, so this is necessary if we want to accurately reject
  599. // malformed JSON numbers.
  600. //
  601. // This is used by nextDouble() and nextFloat() to parse double and
  602. // floating-point values, including values that happen to be in quotes.
  603. // It's also used by the slow path in parseBareSInt64() and parseBareUInt64()
  604. // above to handle integer values that are written in float-point notation.
  605. private func parseBareDouble(
  606. source: UnsafeRawBufferPointer,
  607. index: inout UnsafeRawBufferPointer.Index,
  608. end: UnsafeRawBufferPointer.Index
  609. ) throws -> Double? {
  610. // RFC 7159 defines the grammar for JSON numbers as:
  611. // number = [ minus ] int [ frac ] [ exp ]
  612. if index == end {
  613. throw JSONDecodingError.truncated
  614. }
  615. let start = index
  616. var c = source[index]
  617. if c == asciiBackslash {
  618. return nil
  619. }
  620. // Optional leading minus sign
  621. if c == asciiMinus { // -
  622. source.formIndex(after: &index)
  623. if index == end {
  624. index = start
  625. throw JSONDecodingError.truncated
  626. }
  627. c = source[index]
  628. if c == asciiBackslash {
  629. return nil
  630. }
  631. } else if c == asciiUpperN { // Maybe NaN?
  632. // Return nil, let the caller deal with it.
  633. return nil
  634. }
  635. if c == asciiUpperI { // Maybe Infinity, Inf, -Infinity, or -Inf ?
  636. // Return nil, let the caller deal with it.
  637. return nil
  638. }
  639. // Integer part can be zero or a series of digits not starting with zero
  640. // int = zero / (digit1-9 *DIGIT)
  641. switch c {
  642. case asciiZero:
  643. // First digit can be zero only if not followed by a digit
  644. source.formIndex(after: &index)
  645. if index == end {
  646. return 0.0
  647. }
  648. c = source[index]
  649. if c == asciiBackslash {
  650. return nil
  651. }
  652. if c >= asciiZero && c <= asciiNine {
  653. throw JSONDecodingError.leadingZero
  654. }
  655. case asciiOne...asciiNine:
  656. while c >= asciiZero && c <= asciiNine {
  657. source.formIndex(after: &index)
  658. if index == end {
  659. if let d = numberParser.utf8ToDouble(bytes: source, start: start, end: index) {
  660. return d
  661. } else {
  662. throw JSONDecodingError.invalidUTF8
  663. }
  664. }
  665. c = source[index]
  666. if c == asciiBackslash {
  667. return nil
  668. }
  669. }
  670. default:
  671. // Integer part cannot be empty
  672. throw JSONDecodingError.malformedNumber
  673. }
  674. // frac = decimal-point 1*DIGIT
  675. if c == asciiPeriod {
  676. source.formIndex(after: &index)
  677. if index == end {
  678. // decimal point must have a following digit
  679. throw JSONDecodingError.truncated
  680. }
  681. c = source[index]
  682. switch c {
  683. case asciiZero...asciiNine: // 0...9
  684. while c >= asciiZero && c <= asciiNine {
  685. source.formIndex(after: &index)
  686. if index == end {
  687. if let d = numberParser.utf8ToDouble(bytes: source, start: start, end: index) {
  688. return d
  689. } else {
  690. throw JSONDecodingError.invalidUTF8
  691. }
  692. }
  693. c = source[index]
  694. if c == asciiBackslash {
  695. return nil
  696. }
  697. }
  698. case asciiBackslash:
  699. return nil
  700. default:
  701. // decimal point must be followed by at least one digit
  702. throw JSONDecodingError.malformedNumber
  703. }
  704. }
  705. // exp = e [ minus / plus ] 1*DIGIT
  706. if c == asciiLowerE || c == asciiUpperE {
  707. source.formIndex(after: &index)
  708. if index == end {
  709. // "e" must be followed by +,-, or digit
  710. throw JSONDecodingError.truncated
  711. }
  712. c = source[index]
  713. if c == asciiBackslash {
  714. return nil
  715. }
  716. if c == asciiPlus || c == asciiMinus { // + -
  717. source.formIndex(after: &index)
  718. if index == end {
  719. // must be at least one digit in exponent
  720. throw JSONDecodingError.truncated
  721. }
  722. c = source[index]
  723. if c == asciiBackslash {
  724. return nil
  725. }
  726. }
  727. switch c {
  728. case asciiZero...asciiNine:
  729. while c >= asciiZero && c <= asciiNine {
  730. source.formIndex(after: &index)
  731. if index == end {
  732. if let d = numberParser.utf8ToDouble(bytes: source, start: start, end: index) {
  733. return d
  734. } else {
  735. throw JSONDecodingError.invalidUTF8
  736. }
  737. }
  738. c = source[index]
  739. if c == asciiBackslash {
  740. return nil
  741. }
  742. }
  743. default:
  744. // must be at least one digit in exponent
  745. throw JSONDecodingError.malformedNumber
  746. }
  747. }
  748. if let d = numberParser.utf8ToDouble(bytes: source, start: start, end: index) {
  749. return d
  750. } else {
  751. throw JSONDecodingError.invalidUTF8
  752. }
  753. }
  754. /// Returns a fully-parsed string with all backslash escapes
  755. /// correctly processed, or nil if next token is not a string.
  756. ///
  757. /// Assumes the leading quote has been verified (but not consumed)
  758. private mutating func parseOptionalQuotedString() -> String? {
  759. // Caller has already asserted that currentByte == quote here
  760. var sawBackslash = false
  761. advance()
  762. let start = index
  763. while hasMoreContent {
  764. switch currentByte {
  765. case asciiDoubleQuote: // "
  766. let s = utf8ToString(bytes: source, start: start, end: index)
  767. advance()
  768. if let t = s {
  769. if sawBackslash {
  770. return decodeString(t)
  771. } else {
  772. return t
  773. }
  774. } else {
  775. return nil // Invalid UTF8
  776. }
  777. case asciiBackslash: // \
  778. advance()
  779. guard hasMoreContent else {
  780. return nil // Unterminated escape
  781. }
  782. sawBackslash = true
  783. default:
  784. break
  785. }
  786. advance()
  787. }
  788. return nil // Unterminated quoted string
  789. }
  790. /// Parse an unsigned integer, whether or not its quoted.
  791. /// This also handles cases such as quoted numbers that have
  792. /// backslash escapes in them.
  793. ///
  794. /// This supports the full range of UInt64 (whether quoted or not)
  795. /// unless the number is written in floating-point format. In that
  796. /// case, we decode it with only Double precision.
  797. internal mutating func nextUInt() throws -> UInt64 {
  798. skipWhitespace()
  799. guard hasMoreContent else {
  800. throw JSONDecodingError.truncated
  801. }
  802. let c = currentByte
  803. if c == asciiDoubleQuote {
  804. let start = index
  805. advance()
  806. if let u = try parseBareUInt64(
  807. source: source,
  808. index: &index,
  809. end: source.endIndex
  810. ) {
  811. guard hasMoreContent else {
  812. throw JSONDecodingError.truncated
  813. }
  814. if currentByte != asciiDoubleQuote {
  815. throw JSONDecodingError.malformedNumber
  816. }
  817. advance()
  818. return u
  819. } else {
  820. // Couldn't parse because it had a "\" in the string,
  821. // so parse out the quoted string and then reparse
  822. // the result to get a UInt.
  823. index = start
  824. let s = try nextQuotedString()
  825. let raw = s.data(using: String.Encoding.utf8)!
  826. let n = try raw.withUnsafeBytes {
  827. (body: UnsafeRawBufferPointer) -> UInt64? in
  828. if body.count > 0 {
  829. var index = body.startIndex
  830. let end = body.endIndex
  831. if let u = try parseBareUInt64(
  832. source: body,
  833. index: &index,
  834. end: end
  835. ) {
  836. if index == end {
  837. return u
  838. }
  839. }
  840. }
  841. return nil
  842. }
  843. if let n = n {
  844. return n
  845. }
  846. }
  847. } else if let u = try parseBareUInt64(
  848. source: source,
  849. index: &index,
  850. end: source.endIndex
  851. ) {
  852. return u
  853. }
  854. throw JSONDecodingError.malformedNumber
  855. }
  856. /// Parse a signed integer, quoted or not, including handling
  857. /// backslash escapes for quoted values.
  858. ///
  859. /// This supports the full range of Int64 (whether quoted or not)
  860. /// unless the number is written in floating-point format. In that
  861. /// case, we decode it with only Double precision.
  862. internal mutating func nextSInt() throws -> Int64 {
  863. skipWhitespace()
  864. guard hasMoreContent else {
  865. throw JSONDecodingError.truncated
  866. }
  867. let c = currentByte
  868. if c == asciiDoubleQuote {
  869. let start = index
  870. advance()
  871. if let s = try parseBareSInt64(
  872. source: source,
  873. index: &index,
  874. end: source.endIndex
  875. ) {
  876. guard hasMoreContent else {
  877. throw JSONDecodingError.truncated
  878. }
  879. if currentByte != asciiDoubleQuote {
  880. throw JSONDecodingError.malformedNumber
  881. }
  882. advance()
  883. return s
  884. } else {
  885. // Couldn't parse because it had a "\" in the string,
  886. // so parse out the quoted string and then reparse
  887. // the result as an SInt.
  888. index = start
  889. let s = try nextQuotedString()
  890. let raw = s.data(using: String.Encoding.utf8)!
  891. let n = try raw.withUnsafeBytes {
  892. (body: UnsafeRawBufferPointer) -> Int64? in
  893. if body.count > 0 {
  894. var index = body.startIndex
  895. let end = body.endIndex
  896. if let s = try parseBareSInt64(
  897. source: body,
  898. index: &index,
  899. end: end
  900. ) {
  901. if index == end {
  902. return s
  903. }
  904. }
  905. }
  906. return nil
  907. }
  908. if let n = n {
  909. return n
  910. }
  911. }
  912. } else if let s = try parseBareSInt64(
  913. source: source,
  914. index: &index,
  915. end: source.endIndex
  916. ) {
  917. return s
  918. }
  919. throw JSONDecodingError.malformedNumber
  920. }
  921. /// Parse the next Float value, regardless of whether it
  922. /// is quoted, including handling backslash escapes for
  923. /// quoted strings.
  924. internal mutating func nextFloat() throws -> Float {
  925. skipWhitespace()
  926. guard hasMoreContent else {
  927. throw JSONDecodingError.truncated
  928. }
  929. let c = currentByte
  930. if c == asciiDoubleQuote { // "
  931. let start = index
  932. advance()
  933. if let d = try parseBareDouble(
  934. source: source,
  935. index: &index,
  936. end: source.endIndex
  937. ) {
  938. guard hasMoreContent else {
  939. throw JSONDecodingError.truncated
  940. }
  941. if currentByte != asciiDoubleQuote {
  942. throw JSONDecodingError.malformedNumber
  943. }
  944. advance()
  945. return Float(d)
  946. } else {
  947. // Slow Path: parseBareDouble returned nil: It might be
  948. // a valid float, but had something that
  949. // parseBareDouble cannot directly handle. So we reset,
  950. // try a full string parse, then examine the result:
  951. index = start
  952. let s = try nextQuotedString()
  953. switch s {
  954. case "NaN": return Float.nan
  955. case "Inf": return Float.infinity
  956. case "-Inf": return -Float.infinity
  957. case "Infinity": return Float.infinity
  958. case "-Infinity": return -Float.infinity
  959. default:
  960. let raw = s.data(using: String.Encoding.utf8)!
  961. let n = try raw.withUnsafeBytes {
  962. (body: UnsafeRawBufferPointer) -> Float? in
  963. if body.count > 0 {
  964. var index = body.startIndex
  965. let end = body.endIndex
  966. if let d = try parseBareDouble(
  967. source: body,
  968. index: &index,
  969. end: end
  970. ) {
  971. let f = Float(d)
  972. if index == end && f.isFinite {
  973. return f
  974. }
  975. }
  976. }
  977. return nil
  978. }
  979. if let n = n {
  980. return n
  981. }
  982. }
  983. }
  984. } else {
  985. if let d = try parseBareDouble(
  986. source: source,
  987. index: &index,
  988. end: source.endIndex
  989. ) {
  990. let f = Float(d)
  991. if f.isFinite {
  992. return f
  993. }
  994. }
  995. }
  996. throw JSONDecodingError.malformedNumber
  997. }
  998. /// Parse the next Double value, regardless of whether it
  999. /// is quoted, including handling backslash escapes for
  1000. /// quoted strings.
  1001. internal mutating func nextDouble() throws -> Double {
  1002. skipWhitespace()
  1003. guard hasMoreContent else {
  1004. throw JSONDecodingError.truncated
  1005. }
  1006. let c = currentByte
  1007. if c == asciiDoubleQuote { // "
  1008. let start = index
  1009. advance()
  1010. if let d = try parseBareDouble(
  1011. source: source,
  1012. index: &index,
  1013. end: source.endIndex
  1014. ) {
  1015. guard hasMoreContent else {
  1016. throw JSONDecodingError.truncated
  1017. }
  1018. if currentByte != asciiDoubleQuote {
  1019. throw JSONDecodingError.malformedNumber
  1020. }
  1021. advance()
  1022. return d
  1023. } else {
  1024. // Slow Path: parseBareDouble returned nil: It might be
  1025. // a valid float, but had something that
  1026. // parseBareDouble cannot directly handle. So we reset,
  1027. // try a full string parse, then examine the result:
  1028. index = start
  1029. let s = try nextQuotedString()
  1030. switch s {
  1031. case "NaN": return Double.nan
  1032. case "Inf": return Double.infinity
  1033. case "-Inf": return -Double.infinity
  1034. case "Infinity": return Double.infinity
  1035. case "-Infinity": return -Double.infinity
  1036. default:
  1037. let raw = s.data(using: String.Encoding.utf8)!
  1038. let n = try raw.withUnsafeBytes {
  1039. (body: UnsafeRawBufferPointer) -> Double? in
  1040. if body.count > 0 {
  1041. var index = body.startIndex
  1042. let end = body.endIndex
  1043. if let d = try parseBareDouble(
  1044. source: body,
  1045. index: &index,
  1046. end: end
  1047. ) {
  1048. if index == end {
  1049. return d
  1050. }
  1051. }
  1052. }
  1053. return nil
  1054. }
  1055. if let n = n {
  1056. return n
  1057. }
  1058. }
  1059. }
  1060. } else {
  1061. if let d = try parseBareDouble(
  1062. source: source,
  1063. index: &index,
  1064. end: source.endIndex
  1065. ) {
  1066. return d
  1067. }
  1068. }
  1069. throw JSONDecodingError.malformedNumber
  1070. }
  1071. /// Return the contents of the following quoted string,
  1072. /// or throw an error if the next token is not a string.
  1073. internal mutating func nextQuotedString() throws -> String {
  1074. skipWhitespace()
  1075. guard hasMoreContent else {
  1076. throw JSONDecodingError.truncated
  1077. }
  1078. let c = currentByte
  1079. if c != asciiDoubleQuote {
  1080. throw JSONDecodingError.malformedString
  1081. }
  1082. if let s = parseOptionalQuotedString() {
  1083. return s
  1084. } else {
  1085. throw JSONDecodingError.malformedString
  1086. }
  1087. }
  1088. /// Return the contents of the following quoted string,
  1089. /// or nil if the next token is not a string.
  1090. /// This will only throw an error if the next token starts
  1091. /// out as a string but is malformed in some way.
  1092. internal mutating func nextOptionalQuotedString() throws -> String? {
  1093. skipWhitespace()
  1094. guard hasMoreContent else {
  1095. return nil
  1096. }
  1097. let c = currentByte
  1098. if c != asciiDoubleQuote {
  1099. return nil
  1100. }
  1101. return try nextQuotedString()
  1102. }
  1103. /// Return a Data with the decoded contents of the
  1104. /// following base-64 string.
  1105. ///
  1106. /// Notes on Google's implementation:
  1107. /// * Google's C++ implementation accepts arbitrary whitespace
  1108. /// mixed in with the base-64 characters
  1109. /// * Google's C++ implementation ignores missing '=' characters
  1110. /// but if present, there must be the exact correct number of them.
  1111. /// * Google's C++ implementation accepts both "regular" and
  1112. /// "web-safe" base-64 variants (it seems to prefer the
  1113. /// web-safe version as defined in RFC 4648
  1114. internal mutating func nextBytesValue() throws -> Data {
  1115. skipWhitespace()
  1116. guard hasMoreContent else {
  1117. throw JSONDecodingError.truncated
  1118. }
  1119. return try parseBytes(source: source, index: &index, end: source.endIndex)
  1120. }
  1121. /// Private function to help parse keywords.
  1122. private mutating func skipOptionalKeyword(bytes: [UInt8]) -> Bool {
  1123. let start = index
  1124. for b in bytes {
  1125. guard hasMoreContent else {
  1126. index = start
  1127. return false
  1128. }
  1129. let c = currentByte
  1130. if c != b {
  1131. index = start
  1132. return false
  1133. }
  1134. advance()
  1135. }
  1136. if hasMoreContent {
  1137. let c = currentByte
  1138. if (c >= asciiUpperA && c <= asciiUpperZ) || (c >= asciiLowerA && c <= asciiLowerZ) {
  1139. index = start
  1140. return false
  1141. }
  1142. }
  1143. return true
  1144. }
  1145. /// If the next token is the identifier "null", consume it and return true.
  1146. internal mutating func skipOptionalNull() -> Bool {
  1147. skipWhitespace()
  1148. if hasMoreContent && currentByte == asciiLowerN {
  1149. return skipOptionalKeyword(bytes: [
  1150. asciiLowerN, asciiLowerU, asciiLowerL, asciiLowerL,
  1151. ])
  1152. }
  1153. return false
  1154. }
  1155. /// Return the following Bool "true" or "false", including
  1156. /// full processing of quoted boolean values. (Used in map
  1157. /// keys, for instance.)
  1158. internal mutating func nextBool() throws -> Bool {
  1159. skipWhitespace()
  1160. guard hasMoreContent else {
  1161. throw JSONDecodingError.truncated
  1162. }
  1163. let c = currentByte
  1164. switch c {
  1165. case asciiLowerF: // f
  1166. if skipOptionalKeyword(bytes: [
  1167. asciiLowerF, asciiLowerA, asciiLowerL, asciiLowerS, asciiLowerE,
  1168. ]) {
  1169. return false
  1170. }
  1171. case asciiLowerT: // t
  1172. if skipOptionalKeyword(bytes: [
  1173. asciiLowerT, asciiLowerR, asciiLowerU, asciiLowerE,
  1174. ]) {
  1175. return true
  1176. }
  1177. default:
  1178. break
  1179. }
  1180. throw JSONDecodingError.malformedBool
  1181. }
  1182. /// Return the following Bool "true" or "false", including
  1183. /// full processing of quoted boolean values. (Used in map
  1184. /// keys, for instance.)
  1185. internal mutating func nextQuotedBool() throws -> Bool {
  1186. skipWhitespace()
  1187. guard hasMoreContent else {
  1188. throw JSONDecodingError.truncated
  1189. }
  1190. if currentByte != asciiDoubleQuote {
  1191. throw JSONDecodingError.unquotedMapKey
  1192. }
  1193. if let s = parseOptionalQuotedString() {
  1194. switch s {
  1195. case "false": return false
  1196. case "true": return true
  1197. default: break
  1198. }
  1199. }
  1200. throw JSONDecodingError.malformedBool
  1201. }
  1202. /// Returns pointer/count spanning the UTF8 bytes of the next regular
  1203. /// key or nil if the key contains a backslash (and therefore requires
  1204. /// the full string-parsing logic to properly parse).
  1205. private mutating func nextOptionalKey() throws -> UnsafeRawBufferPointer? {
  1206. skipWhitespace()
  1207. let stringStart = index
  1208. guard hasMoreContent else {
  1209. throw JSONDecodingError.truncated
  1210. }
  1211. if currentByte != asciiDoubleQuote {
  1212. return nil
  1213. }
  1214. advance()
  1215. let nameStart = index
  1216. while hasMoreContent && currentByte != asciiDoubleQuote {
  1217. if currentByte == asciiBackslash {
  1218. index = stringStart // Reset to open quote
  1219. return nil
  1220. }
  1221. advance()
  1222. }
  1223. guard hasMoreContent else {
  1224. throw JSONDecodingError.truncated
  1225. }
  1226. let buff = UnsafeRawBufferPointer(
  1227. start: source.baseAddress! + nameStart,
  1228. count: index - nameStart
  1229. )
  1230. advance()
  1231. return buff
  1232. }
  1233. /// Parse a field name, look it up in the provided field name map,
  1234. /// and return the corresponding field number.
  1235. ///
  1236. /// Throws if field name cannot be parsed.
  1237. /// If it encounters an unknown field name, it throws
  1238. /// unless `options.ignoreUnknownFields` is set, in which case
  1239. /// it silently skips it.
  1240. internal mutating func nextFieldNumber(
  1241. names: _NameMap,
  1242. messageType: any Message.Type
  1243. ) throws -> Int? {
  1244. while true {
  1245. var fieldName: String
  1246. if let key = try nextOptionalKey() {
  1247. // Fast path: We parsed it as UTF8 bytes...
  1248. try skipRequiredCharacter(asciiColon) // :
  1249. if let fieldNumber = names.number(forJSONName: key) {
  1250. return fieldNumber
  1251. }
  1252. if let s = utf8ToString(bytes: key.baseAddress!, count: key.count) {
  1253. fieldName = s
  1254. } else {
  1255. throw JSONDecodingError.invalidUTF8
  1256. }
  1257. } else {
  1258. // Slow path: We parsed a String; lookups from String are slower.
  1259. fieldName = try nextQuotedString()
  1260. try skipRequiredCharacter(asciiColon) // :
  1261. if let fieldNumber = names.number(forJSONName: fieldName) {
  1262. return fieldNumber
  1263. }
  1264. }
  1265. if let first = fieldName.utf8.first, first == UInt8(ascii: "["),
  1266. let last = fieldName.utf8.last, last == UInt8(ascii: "]")
  1267. {
  1268. fieldName.removeFirst()
  1269. fieldName.removeLast()
  1270. if let fieldNumber = extensions.fieldNumberForProto(messageType: messageType, protoFieldName: fieldName)
  1271. {
  1272. return fieldNumber
  1273. }
  1274. }
  1275. if !options.ignoreUnknownFields {
  1276. throw JSONDecodingError.unknownField(fieldName)
  1277. }
  1278. // Unknown field, skip it and try to parse the next field name
  1279. try skipValue()
  1280. if skipOptionalObjectEnd() {
  1281. return nil
  1282. }
  1283. try skipRequiredComma()
  1284. }
  1285. }
  1286. /// Parse the next token as a string or numeric enum value. Throws
  1287. /// unrecognizedEnumValue if the string/number can't initialize the
  1288. /// enum. Will throw other errors if the JSON is malformed.
  1289. internal mutating func nextEnumValue<E: Enum>() throws -> E? {
  1290. func throwOrIgnore() throws -> E? {
  1291. if options.ignoreUnknownFields {
  1292. return nil
  1293. } else {
  1294. throw JSONDecodingError.unrecognizedEnumValue
  1295. }
  1296. }
  1297. skipWhitespace()
  1298. guard hasMoreContent else {
  1299. throw JSONDecodingError.truncated
  1300. }
  1301. if currentByte == asciiDoubleQuote {
  1302. if let name = try nextOptionalKey() {
  1303. if let e = E(rawUTF8: name) {
  1304. return e
  1305. } else {
  1306. return try throwOrIgnore()
  1307. }
  1308. }
  1309. let name = try nextQuotedString()
  1310. if let e = E(name: name) {
  1311. return e
  1312. } else {
  1313. return try throwOrIgnore()
  1314. }
  1315. } else {
  1316. let n = try nextSInt()
  1317. if let i = Int(exactly: n) {
  1318. if let e = E(rawValue: i) {
  1319. return e
  1320. } else {
  1321. return try throwOrIgnore()
  1322. }
  1323. } else {
  1324. throw JSONDecodingError.numberRange
  1325. }
  1326. }
  1327. }
  1328. /// Helper for skipping a single-character token.
  1329. private mutating func skipRequiredCharacter(_ required: UInt8) throws {
  1330. skipWhitespace()
  1331. guard hasMoreContent else {
  1332. throw JSONDecodingError.truncated
  1333. }
  1334. let next = currentByte
  1335. if next == required {
  1336. advance()
  1337. return
  1338. }
  1339. throw JSONDecodingError.failure
  1340. }
  1341. /// Skip "{", throw if that's not the next character.
  1342. internal mutating func skipRequiredObjectStart() throws {
  1343. try skipRequiredCharacter(asciiOpenCurlyBracket) // {
  1344. try incrementRecursionDepth()
  1345. }
  1346. /// Skip ",", throw if that's not the next character.
  1347. internal mutating func skipRequiredComma() throws {
  1348. try skipRequiredCharacter(asciiComma)
  1349. }
  1350. /// Skip ":", throw if that's not the next character.
  1351. internal mutating func skipRequiredColon() throws {
  1352. try skipRequiredCharacter(asciiColon)
  1353. }
  1354. /// Skip "[", throw if that's not the next character.
  1355. internal mutating func skipRequiredArrayStart() throws {
  1356. try skipRequiredCharacter(asciiOpenSquareBracket) // [
  1357. }
  1358. /// Helper for skipping optional single-character tokens.
  1359. private mutating func skipOptionalCharacter(_ c: UInt8) -> Bool {
  1360. skipWhitespace()
  1361. if hasMoreContent && currentByte == c {
  1362. advance()
  1363. return true
  1364. }
  1365. return false
  1366. }
  1367. /// If the next non-whitespace character is "[", skip it
  1368. /// and return true. Otherwise, return false.
  1369. internal mutating func skipOptionalArrayStart() -> Bool {
  1370. skipOptionalCharacter(asciiOpenSquareBracket)
  1371. }
  1372. /// If the next non-whitespace character is "]", skip it
  1373. /// and return true. Otherwise, return false.
  1374. internal mutating func skipOptionalArrayEnd() -> Bool {
  1375. skipOptionalCharacter(asciiCloseSquareBracket) // ]// ]
  1376. }
  1377. /// If the next non-whitespace character is "}", skip it
  1378. /// and return true. Otherwise, return false.
  1379. internal mutating func skipOptionalObjectEnd() -> Bool {
  1380. let result = skipOptionalCharacter(asciiCloseCurlyBracket) // }
  1381. if result {
  1382. decrementRecursionDepth()
  1383. }
  1384. return result
  1385. }
  1386. /// Return the next complete JSON structure as a string.
  1387. /// For example, this might return "true", or "123.456",
  1388. /// or "{\"foo\": 7, \"bar\": [8, 9]}"
  1389. ///
  1390. /// Used by Any to get the upcoming JSON value as a string.
  1391. /// Note: The value might be an object or array.
  1392. internal mutating func skip() throws -> String {
  1393. skipWhitespace()
  1394. let start = index
  1395. try skipValue()
  1396. if let s = utf8ToString(bytes: source, start: start, end: index) {
  1397. return s
  1398. } else {
  1399. throw JSONDecodingError.invalidUTF8
  1400. }
  1401. }
  1402. /// Advance index past the next value. This is used
  1403. /// by skip() and by unknown field handling.
  1404. /// Note: This handles objects {...} recursively but arrays [...] non-recursively
  1405. /// This avoids us requiring excessive stack space for deeply nested
  1406. /// arrays (which are not included in the recursion budget check).
  1407. private mutating func skipValue() throws {
  1408. skipWhitespace()
  1409. var totalArrayDepth = 0
  1410. while true {
  1411. var arrayDepth = 0
  1412. while skipOptionalArrayStart() {
  1413. arrayDepth += 1
  1414. }
  1415. guard hasMoreContent else {
  1416. throw JSONDecodingError.truncated
  1417. }
  1418. switch currentByte {
  1419. case asciiDoubleQuote: // " begins a string
  1420. try skipString()
  1421. case asciiOpenCurlyBracket: // { begins an object
  1422. try skipObject()
  1423. case asciiCloseSquareBracket: // ] ends an empty array
  1424. if arrayDepth == 0 {
  1425. throw JSONDecodingError.failure
  1426. }
  1427. // We also close out [[]] or [[[]]] here
  1428. while arrayDepth > 0 && skipOptionalArrayEnd() {
  1429. arrayDepth -= 1
  1430. }
  1431. case asciiLowerN: // n must be null
  1432. if !skipOptionalKeyword(bytes: [
  1433. asciiLowerN, asciiLowerU, asciiLowerL, asciiLowerL,
  1434. ]) {
  1435. throw JSONDecodingError.truncated
  1436. }
  1437. case asciiLowerF: // f must be false
  1438. if !skipOptionalKeyword(bytes: [
  1439. asciiLowerF, asciiLowerA, asciiLowerL, asciiLowerS, asciiLowerE,
  1440. ]) {
  1441. throw JSONDecodingError.truncated
  1442. }
  1443. case asciiLowerT: // t must be true
  1444. if !skipOptionalKeyword(bytes: [
  1445. asciiLowerT, asciiLowerR, asciiLowerU, asciiLowerE,
  1446. ]) {
  1447. throw JSONDecodingError.truncated
  1448. }
  1449. default: // everything else is a number token
  1450. _ = try nextDouble()
  1451. }
  1452. totalArrayDepth += arrayDepth
  1453. while totalArrayDepth > 0 && skipOptionalArrayEnd() {
  1454. totalArrayDepth -= 1
  1455. }
  1456. if totalArrayDepth > 0 {
  1457. try skipRequiredComma()
  1458. } else {
  1459. return
  1460. }
  1461. }
  1462. }
  1463. /// Advance the index past the next complete {...} construct.
  1464. private mutating func skipObject() throws {
  1465. try skipRequiredObjectStart()
  1466. if skipOptionalObjectEnd() {
  1467. return
  1468. }
  1469. while true {
  1470. skipWhitespace()
  1471. try skipString()
  1472. try skipRequiredColon()
  1473. try skipValue()
  1474. if skipOptionalObjectEnd() {
  1475. return
  1476. }
  1477. try skipRequiredComma()
  1478. }
  1479. }
  1480. /// Advance the index past the next complete quoted string.
  1481. ///
  1482. // Caveat: This does not fully validate; it will accept
  1483. // strings that have malformed \ escapes.
  1484. //
  1485. // It would be nice to do better, but I don't think it's critical,
  1486. // since there are many reasons that strings (and other tokens for
  1487. // that matter) may be skippable but not parsable. For example:
  1488. // Old clients that don't know new field types will skip fields
  1489. // they don't know; newer clients may reject the same input due to
  1490. // schema mismatches or other issues.
  1491. private mutating func skipString() throws {
  1492. guard hasMoreContent else {
  1493. throw JSONDecodingError.truncated
  1494. }
  1495. if currentByte != asciiDoubleQuote {
  1496. throw JSONDecodingError.malformedString
  1497. }
  1498. advance()
  1499. while hasMoreContent {
  1500. let c = currentByte
  1501. switch c {
  1502. case asciiDoubleQuote:
  1503. advance()
  1504. return
  1505. case asciiBackslash:
  1506. advance()
  1507. guard hasMoreContent else {
  1508. throw JSONDecodingError.truncated
  1509. }
  1510. advance()
  1511. default:
  1512. advance()
  1513. }
  1514. }
  1515. throw JSONDecodingError.truncated
  1516. }
  1517. }