diff options
| author | Oskari Timperi <oskari.timperi@iki.fi> | 2018-04-02 11:32:22 +0300 |
|---|---|---|
| committer | Oskari Timperi <oskari.timperi@iki.fi> | 2018-04-02 11:39:35 +0300 |
| commit | c4c34c5974ea373288bd29df25ee5fd50325daa2 (patch) | |
| tree | 6c430da414c6fe1d2556e6a3076abf4b7b81c291 | |
| parent | f189bb22d71d4e25984c8d1e72c37a4a9823d2b2 (diff) | |
| download | nimpb-c4c34c5974ea373288bd29df25ee5fd50325daa2.tar.gz nimpb-c4c34c5974ea373288bd29df25ee5fd50325daa2.zip | |
Validate wire types
| -rw-r--r-- | generator/protoc_gen_nim.nim | 5 | ||||
| -rw-r--r-- | src/protobuf/stream.nim | 11 |
2 files changed, 16 insertions, 0 deletions
diff --git a/generator/protoc_gen_nim.nim b/generator/protoc_gen_nim.nim index a05172a..22e3cd7 100644 --- a/generator/protoc_gen_nim.nim +++ b/generator/protoc_gen_nim.nim @@ -674,12 +674,14 @@ iterator genReadMessageProc(msg: Message): string = yield indent(&"of {field.number}:", 8) if isRepeated(field): if isMapEntry(field): + yield indent(&"expectWireType(wireType, {field.wiretypeStr})", 12) yield indent("let", 12) yield indent("size = readVarint(stream)", 16) yield indent("data = readStr(stream, int(size))", 16) yield indent("pbs = newProtobufStream(newStringStream(data))", 16) yield indent(&"read{field.typeName}KV(pbs, result.{field.name})", 12) elif isNumeric(field): + yield indent(&"expectWireType(wireType, {field.wiretypeStr}, WireType.LengthDelimited)", 12) yield indent("if wireType == WireType.LengthDelimited:", 12) yield indent("let", 16) yield indent("size = readVarint(stream)", 20) @@ -693,14 +695,17 @@ iterator genReadMessageProc(msg: Message): string = yield indent("else:", 12) yield indent(&"{setter}(result, {reader}(stream))", 16) elif isMessage(field): + yield indent(&"expectWireType(wireType, {field.wiretypeStr})", 12) yield indent("let", 12) yield indent("size = readVarint(stream)", 16) yield indent("data = readStr(stream, int(size))", 16) yield indent("pbs = newProtobufStream(newStringStream(data))", 16) yield indent(&"{setter}(result, {reader}(pbs))", 12) else: + yield indent(&"expectWireType(wireType, {field.wiretypeStr})", 12) yield indent(&"{setter}(result, {reader}(stream))", 12) else: + yield indent(&"expectWireType(wireType, {field.wiretypeStr})", 12) if isMessage(field): yield indent("let", 12) yield indent("size = readVarint(stream)", 16) diff --git a/src/protobuf/stream.nim b/src/protobuf/stream.nim index a0b650d..d7eeadd 100644 --- a/src/protobuf/stream.nim +++ b/src/protobuf/stream.nim @@ -1,5 +1,6 @@ import endians import streams +import strutils import types @@ -22,6 +23,8 @@ type InvalidFieldNumberError* = object of ParseError + UnexpectedWireTypeError* = object of ParseError + proc pbClose(s: Stream) = close(ProtobufStream(s).stream) ProtobufStream(s).stream = nil @@ -336,3 +339,11 @@ proc skipField*(stream: ProtobufStream, wiretype: WireType) = discard readStr(stream, int(size)) else: raise newException(Exception, "unsupported wiretype: " & $wiretype) + +proc expectWireType*(actual: WireType, expected: varargs[WireType]) = + for exp in expected: + if actual == exp: + return + let message = "Got wiretype " & $actual & " but expected: " & + join(expected, ", ") + raise newException(UnexpectedWireTypeError, message) |
