validate.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. // Copyright 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package impl
  5. import (
  6. "fmt"
  7. "math"
  8. "math/bits"
  9. "reflect"
  10. "unicode/utf8"
  11. "google.golang.org/protobuf/encoding/protowire"
  12. "google.golang.org/protobuf/internal/encoding/messageset"
  13. "google.golang.org/protobuf/internal/flags"
  14. "google.golang.org/protobuf/internal/genid"
  15. "google.golang.org/protobuf/internal/strs"
  16. "google.golang.org/protobuf/reflect/protoreflect"
  17. "google.golang.org/protobuf/reflect/protoregistry"
  18. "google.golang.org/protobuf/runtime/protoiface"
  19. )
  20. // ValidationStatus is the result of validating the wire-format encoding of a message.
  21. type ValidationStatus int
  22. const (
  23. // ValidationUnknown indicates that unmarshaling the message might succeed or fail.
  24. // The validator was unable to render a judgement.
  25. //
  26. // The only causes of this status are an aberrant message type appearing somewhere
  27. // in the message or a failure in the extension resolver.
  28. ValidationUnknown ValidationStatus = iota + 1
  29. // ValidationInvalid indicates that unmarshaling the message will fail.
  30. ValidationInvalid
  31. // ValidationValid indicates that unmarshaling the message will succeed.
  32. ValidationValid
  33. // ValidationWrongWireType indicates that a validated field does not have
  34. // the expected wire type.
  35. ValidationWrongWireType
  36. )
  37. func (v ValidationStatus) String() string {
  38. switch v {
  39. case ValidationUnknown:
  40. return "ValidationUnknown"
  41. case ValidationInvalid:
  42. return "ValidationInvalid"
  43. case ValidationValid:
  44. return "ValidationValid"
  45. default:
  46. return fmt.Sprintf("ValidationStatus(%d)", int(v))
  47. }
  48. }
  49. // Validate determines whether the contents of the buffer are a valid wire encoding
  50. // of the message type.
  51. //
  52. // This function is exposed for testing.
  53. func Validate(mt protoreflect.MessageType, in protoiface.UnmarshalInput) (out protoiface.UnmarshalOutput, _ ValidationStatus) {
  54. mi, ok := mt.(*MessageInfo)
  55. if !ok {
  56. return out, ValidationUnknown
  57. }
  58. if in.Resolver == nil {
  59. in.Resolver = protoregistry.GlobalTypes
  60. }
  61. if in.Depth == 0 {
  62. in.Depth = protowire.DefaultRecursionLimit
  63. }
  64. o, st := mi.validate(in.Buf, 0, unmarshalOptions{
  65. flags: in.Flags,
  66. resolver: in.Resolver,
  67. depth: in.Depth,
  68. })
  69. if o.initialized {
  70. out.Flags |= protoiface.UnmarshalInitialized
  71. }
  72. return out, st
  73. }
  74. type validationInfo struct {
  75. mi *MessageInfo
  76. typ validationType
  77. keyType, valType validationType
  78. // For non-required fields, requiredBit is 0.
  79. //
  80. // For required fields, requiredBit's nth bit is set, where n is a
  81. // unique index in the range [0, MessageInfo.numRequiredFields).
  82. //
  83. // If there are more than 64 required fields, requiredBit is 0.
  84. requiredBit uint64
  85. }
  86. type validationType uint8
  87. const (
  88. validationTypeOther validationType = iota
  89. validationTypeMessage
  90. validationTypeGroup
  91. validationTypeMap
  92. validationTypeRepeatedVarint
  93. validationTypeRepeatedFixed32
  94. validationTypeRepeatedFixed64
  95. validationTypeVarint
  96. validationTypeFixed32
  97. validationTypeFixed64
  98. validationTypeBytes
  99. validationTypeUTF8String
  100. validationTypeMessageSetItem
  101. )
  102. func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd protoreflect.FieldDescriptor, ft reflect.Type) validationInfo {
  103. var vi validationInfo
  104. switch {
  105. case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
  106. switch fd.Kind() {
  107. case protoreflect.MessageKind:
  108. vi.typ = validationTypeMessage
  109. if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok {
  110. vi.mi = getMessageInfo(ot.Field(0).Type)
  111. }
  112. case protoreflect.GroupKind:
  113. vi.typ = validationTypeGroup
  114. if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok {
  115. vi.mi = getMessageInfo(ot.Field(0).Type)
  116. }
  117. case protoreflect.StringKind:
  118. if strs.EnforceUTF8(fd) {
  119. vi.typ = validationTypeUTF8String
  120. }
  121. }
  122. default:
  123. vi = newValidationInfo(fd, ft)
  124. }
  125. if fd.Cardinality() == protoreflect.Required {
  126. // Avoid overflow. The required field check is done with a 64-bit mask, with
  127. // any message containing more than 64 required fields always reported as
  128. // potentially uninitialized, so it is not important to get a precise count
  129. // of the required fields past 64.
  130. if mi.numRequiredFields < math.MaxUint8 {
  131. mi.numRequiredFields++
  132. vi.requiredBit = 1 << (mi.numRequiredFields - 1)
  133. }
  134. }
  135. return vi
  136. }
  137. func newValidationInfo(fd protoreflect.FieldDescriptor, ft reflect.Type) validationInfo {
  138. var vi validationInfo
  139. switch {
  140. case fd.IsList():
  141. switch fd.Kind() {
  142. case protoreflect.MessageKind:
  143. vi.typ = validationTypeMessage
  144. if ft.Kind() == reflect.Ptr {
  145. // Repeated opaque message fields are *[]*T.
  146. ft = ft.Elem()
  147. }
  148. if ft.Kind() == reflect.Slice {
  149. vi.mi = getMessageInfo(ft.Elem())
  150. }
  151. case protoreflect.GroupKind:
  152. vi.typ = validationTypeGroup
  153. if ft.Kind() == reflect.Ptr {
  154. // Repeated opaque message fields are *[]*T.
  155. ft = ft.Elem()
  156. }
  157. if ft.Kind() == reflect.Slice {
  158. vi.mi = getMessageInfo(ft.Elem())
  159. }
  160. case protoreflect.StringKind:
  161. vi.typ = validationTypeBytes
  162. if strs.EnforceUTF8(fd) {
  163. vi.typ = validationTypeUTF8String
  164. }
  165. default:
  166. switch wireTypes[fd.Kind()] {
  167. case protowire.VarintType:
  168. vi.typ = validationTypeRepeatedVarint
  169. case protowire.Fixed32Type:
  170. vi.typ = validationTypeRepeatedFixed32
  171. case protowire.Fixed64Type:
  172. vi.typ = validationTypeRepeatedFixed64
  173. }
  174. }
  175. case fd.IsMap():
  176. vi.typ = validationTypeMap
  177. switch fd.MapKey().Kind() {
  178. case protoreflect.StringKind:
  179. if strs.EnforceUTF8(fd) {
  180. vi.keyType = validationTypeUTF8String
  181. }
  182. }
  183. switch fd.MapValue().Kind() {
  184. case protoreflect.MessageKind:
  185. vi.valType = validationTypeMessage
  186. if ft.Kind() == reflect.Map {
  187. vi.mi = getMessageInfo(ft.Elem())
  188. }
  189. case protoreflect.StringKind:
  190. if strs.EnforceUTF8(fd) {
  191. vi.valType = validationTypeUTF8String
  192. }
  193. }
  194. default:
  195. switch fd.Kind() {
  196. case protoreflect.MessageKind:
  197. vi.typ = validationTypeMessage
  198. vi.mi = getMessageInfo(ft)
  199. case protoreflect.GroupKind:
  200. vi.typ = validationTypeGroup
  201. vi.mi = getMessageInfo(ft)
  202. case protoreflect.StringKind:
  203. vi.typ = validationTypeBytes
  204. if strs.EnforceUTF8(fd) {
  205. vi.typ = validationTypeUTF8String
  206. }
  207. default:
  208. switch wireTypes[fd.Kind()] {
  209. case protowire.VarintType:
  210. vi.typ = validationTypeVarint
  211. case protowire.Fixed32Type:
  212. vi.typ = validationTypeFixed32
  213. case protowire.Fixed64Type:
  214. vi.typ = validationTypeFixed64
  215. case protowire.BytesType:
  216. vi.typ = validationTypeBytes
  217. }
  218. }
  219. }
  220. return vi
  221. }
  222. func (mi *MessageInfo) validate(b []byte, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, result ValidationStatus) {
  223. mi.init()
  224. type validationState struct {
  225. typ validationType
  226. keyType, valType validationType
  227. endGroup protowire.Number
  228. mi *MessageInfo
  229. tail []byte
  230. requiredMask uint64
  231. }
  232. // Pre-allocate some slots to avoid repeated slice reallocation.
  233. states := make([]validationState, 0, 16)
  234. states = append(states, validationState{
  235. typ: validationTypeMessage,
  236. mi: mi,
  237. })
  238. if groupTag > 0 {
  239. states[0].typ = validationTypeGroup
  240. states[0].endGroup = groupTag
  241. }
  242. if opts.depth--; opts.depth < 0 {
  243. return out, ValidationInvalid
  244. }
  245. initialized := true
  246. start := len(b)
  247. State:
  248. for len(states) > 0 {
  249. st := &states[len(states)-1]
  250. for len(b) > 0 {
  251. // Parse the tag (field number and wire type).
  252. var tag uint64
  253. if b[0] < 0x80 {
  254. tag = uint64(b[0])
  255. b = b[1:]
  256. } else if len(b) >= 2 && b[1] < 128 {
  257. tag = uint64(b[0]&0x7f) + uint64(b[1])<<7
  258. b = b[2:]
  259. } else {
  260. var n int
  261. tag, n = protowire.ConsumeVarint(b)
  262. if n < 0 {
  263. return out, ValidationInvalid
  264. }
  265. b = b[n:]
  266. }
  267. var num protowire.Number
  268. if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) {
  269. return out, ValidationInvalid
  270. } else {
  271. num = protowire.Number(n)
  272. }
  273. wtyp := protowire.Type(tag & 7)
  274. if wtyp == protowire.EndGroupType {
  275. if st.endGroup == num {
  276. goto PopState
  277. }
  278. return out, ValidationInvalid
  279. }
  280. var vi validationInfo
  281. switch {
  282. case st.typ == validationTypeMap:
  283. switch num {
  284. case genid.MapEntry_Key_field_number:
  285. vi.typ = st.keyType
  286. case genid.MapEntry_Value_field_number:
  287. vi.typ = st.valType
  288. vi.mi = st.mi
  289. vi.requiredBit = 1
  290. }
  291. case flags.ProtoLegacy && st.mi.isMessageSet:
  292. switch num {
  293. case messageset.FieldItem:
  294. vi.typ = validationTypeMessageSetItem
  295. }
  296. default:
  297. var f *coderFieldInfo
  298. if int(num) < len(st.mi.denseCoderFields) {
  299. f = st.mi.denseCoderFields[num]
  300. } else {
  301. f = st.mi.coderFields[num]
  302. }
  303. if f != nil {
  304. vi = f.validation
  305. break
  306. }
  307. // Possible extension field.
  308. //
  309. // TODO: We should return ValidationUnknown when:
  310. // 1. The resolver is not frozen. (More extensions may be added to it.)
  311. // 2. The resolver returns preg.NotFound.
  312. // In this case, a type added to the resolver in the future could cause
  313. // unmarshaling to begin failing. Supporting this requires some way to
  314. // determine if the resolver is frozen.
  315. xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), num)
  316. if err != nil && err != protoregistry.NotFound {
  317. return out, ValidationUnknown
  318. }
  319. if err == nil {
  320. vi = getExtensionFieldInfo(xt).validation
  321. }
  322. }
  323. if vi.requiredBit != 0 {
  324. // Check that the field has a compatible wire type.
  325. // We only need to consider non-repeated field types,
  326. // since repeated fields (and maps) can never be required.
  327. ok := false
  328. switch vi.typ {
  329. case validationTypeVarint:
  330. ok = wtyp == protowire.VarintType
  331. case validationTypeFixed32:
  332. ok = wtyp == protowire.Fixed32Type
  333. case validationTypeFixed64:
  334. ok = wtyp == protowire.Fixed64Type
  335. case validationTypeBytes, validationTypeUTF8String, validationTypeMessage:
  336. ok = wtyp == protowire.BytesType
  337. case validationTypeGroup:
  338. ok = wtyp == protowire.StartGroupType
  339. }
  340. if ok {
  341. st.requiredMask |= vi.requiredBit
  342. }
  343. }
  344. switch wtyp {
  345. case protowire.VarintType:
  346. if len(b) >= 10 {
  347. switch {
  348. case b[0] < 0x80:
  349. b = b[1:]
  350. case b[1] < 0x80:
  351. b = b[2:]
  352. case b[2] < 0x80:
  353. b = b[3:]
  354. case b[3] < 0x80:
  355. b = b[4:]
  356. case b[4] < 0x80:
  357. b = b[5:]
  358. case b[5] < 0x80:
  359. b = b[6:]
  360. case b[6] < 0x80:
  361. b = b[7:]
  362. case b[7] < 0x80:
  363. b = b[8:]
  364. case b[8] < 0x80:
  365. b = b[9:]
  366. case b[9] < 0x80 && b[9] < 2:
  367. b = b[10:]
  368. default:
  369. return out, ValidationInvalid
  370. }
  371. } else {
  372. switch {
  373. case len(b) > 0 && b[0] < 0x80:
  374. b = b[1:]
  375. case len(b) > 1 && b[1] < 0x80:
  376. b = b[2:]
  377. case len(b) > 2 && b[2] < 0x80:
  378. b = b[3:]
  379. case len(b) > 3 && b[3] < 0x80:
  380. b = b[4:]
  381. case len(b) > 4 && b[4] < 0x80:
  382. b = b[5:]
  383. case len(b) > 5 && b[5] < 0x80:
  384. b = b[6:]
  385. case len(b) > 6 && b[6] < 0x80:
  386. b = b[7:]
  387. case len(b) > 7 && b[7] < 0x80:
  388. b = b[8:]
  389. case len(b) > 8 && b[8] < 0x80:
  390. b = b[9:]
  391. case len(b) > 9 && b[9] < 2:
  392. b = b[10:]
  393. default:
  394. return out, ValidationInvalid
  395. }
  396. }
  397. continue State
  398. case protowire.BytesType:
  399. var size uint64
  400. if len(b) >= 1 && b[0] < 0x80 {
  401. size = uint64(b[0])
  402. b = b[1:]
  403. } else if len(b) >= 2 && b[1] < 128 {
  404. size = uint64(b[0]&0x7f) + uint64(b[1])<<7
  405. b = b[2:]
  406. } else {
  407. var n int
  408. size, n = protowire.ConsumeVarint(b)
  409. if n < 0 {
  410. return out, ValidationInvalid
  411. }
  412. b = b[n:]
  413. }
  414. if size > uint64(len(b)) {
  415. return out, ValidationInvalid
  416. }
  417. v := b[:size]
  418. b = b[size:]
  419. switch vi.typ {
  420. case validationTypeMessage:
  421. if vi.mi == nil {
  422. return out, ValidationUnknown
  423. }
  424. vi.mi.init()
  425. fallthrough
  426. case validationTypeMap:
  427. if vi.mi != nil {
  428. vi.mi.init()
  429. }
  430. states = append(states, validationState{
  431. typ: vi.typ,
  432. keyType: vi.keyType,
  433. valType: vi.valType,
  434. mi: vi.mi,
  435. tail: b,
  436. })
  437. if vi.typ == validationTypeMessage ||
  438. vi.typ == validationTypeGroup ||
  439. vi.typ == validationTypeMap {
  440. if opts.depth--; opts.depth < 0 {
  441. return out, ValidationInvalid
  442. }
  443. }
  444. b = v
  445. continue State
  446. case validationTypeRepeatedVarint:
  447. // Packed field.
  448. for len(v) > 0 {
  449. _, n := protowire.ConsumeVarint(v)
  450. if n < 0 {
  451. return out, ValidationInvalid
  452. }
  453. v = v[n:]
  454. }
  455. case validationTypeRepeatedFixed32:
  456. // Packed field.
  457. if len(v)%4 != 0 {
  458. return out, ValidationInvalid
  459. }
  460. case validationTypeRepeatedFixed64:
  461. // Packed field.
  462. if len(v)%8 != 0 {
  463. return out, ValidationInvalid
  464. }
  465. case validationTypeUTF8String:
  466. if !utf8.Valid(v) {
  467. return out, ValidationInvalid
  468. }
  469. }
  470. case protowire.Fixed32Type:
  471. if len(b) < 4 {
  472. return out, ValidationInvalid
  473. }
  474. b = b[4:]
  475. case protowire.Fixed64Type:
  476. if len(b) < 8 {
  477. return out, ValidationInvalid
  478. }
  479. b = b[8:]
  480. case protowire.StartGroupType:
  481. switch {
  482. case vi.typ == validationTypeGroup:
  483. if vi.mi == nil {
  484. return out, ValidationUnknown
  485. }
  486. vi.mi.init()
  487. states = append(states, validationState{
  488. typ: validationTypeGroup,
  489. mi: vi.mi,
  490. endGroup: num,
  491. })
  492. if opts.depth--; opts.depth < 0 {
  493. return out, ValidationInvalid
  494. }
  495. continue State
  496. case flags.ProtoLegacy && vi.typ == validationTypeMessageSetItem:
  497. typeid, v, n, err := messageset.ConsumeFieldValue(b, false)
  498. if err != nil {
  499. return out, ValidationInvalid
  500. }
  501. xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), typeid)
  502. switch {
  503. case err == protoregistry.NotFound:
  504. b = b[n:]
  505. case err != nil:
  506. return out, ValidationUnknown
  507. default:
  508. xvi := getExtensionFieldInfo(xt).validation
  509. if xvi.mi != nil {
  510. xvi.mi.init()
  511. }
  512. states = append(states, validationState{
  513. typ: xvi.typ,
  514. mi: xvi.mi,
  515. tail: b[n:],
  516. })
  517. if xvi.typ == validationTypeMessage ||
  518. xvi.typ == validationTypeGroup ||
  519. xvi.typ == validationTypeMap {
  520. if opts.depth--; opts.depth < 0 {
  521. return out, ValidationInvalid
  522. }
  523. }
  524. b = v
  525. continue State
  526. }
  527. default:
  528. n := protowire.ConsumeFieldValue(num, wtyp, b)
  529. if n < 0 {
  530. return out, ValidationInvalid
  531. }
  532. b = b[n:]
  533. }
  534. default:
  535. return out, ValidationInvalid
  536. }
  537. }
  538. if st.endGroup != 0 {
  539. return out, ValidationInvalid
  540. }
  541. if len(b) != 0 {
  542. return out, ValidationInvalid
  543. }
  544. b = st.tail
  545. PopState:
  546. numRequiredFields := 0
  547. switch st.typ {
  548. case validationTypeMessage, validationTypeGroup:
  549. numRequiredFields = int(st.mi.numRequiredFields)
  550. opts.depth++
  551. case validationTypeMap:
  552. // If this is a map field with a message value that contains
  553. // required fields, require that the value be present.
  554. if st.mi != nil && st.mi.numRequiredFields > 0 {
  555. numRequiredFields = 1
  556. }
  557. opts.depth++
  558. }
  559. // If there are more than 64 required fields, this check will
  560. // always fail and we will report that the message is potentially
  561. // uninitialized.
  562. if numRequiredFields > 0 && bits.OnesCount64(st.requiredMask) != numRequiredFields {
  563. initialized = false
  564. }
  565. states = states[:len(states)-1]
  566. }
  567. out.n = start - len(b)
  568. if initialized {
  569. out.initialized = true
  570. }
  571. return out, ValidationValid
  572. }