aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOskari Timperi <oskari.timperi@iki.fi>2018-04-02 11:37:07 +0300
committerOskari Timperi <oskari.timperi@iki.fi>2018-04-02 11:39:36 +0300
commit2427dd3c04c37dd78a54a73da41141b74182590a (patch)
treee2024e67ba094566282c05160048ae1f4786f12d
parentc4c34c5974ea373288bd29df25ee5fd50325daa2 (diff)
downloadnimpb-2427dd3c04c37dd78a54a73da41141b74182590a.tar.gz
nimpb-2427dd3c04c37dd78a54a73da41141b74182590a.zip
Multiple fixes to reading data from a stream
- littleEndia32/64 arguments were in wrong order in a few places - add safeReadStr that throws and exception if couldn't read enough data - throw exceptions when not reading enough data
-rw-r--r--generator/protoc_gen_nim.nim8
-rw-r--r--src/protobuf/stream.nim30
2 files changed, 23 insertions, 15 deletions
diff --git a/generator/protoc_gen_nim.nim b/generator/protoc_gen_nim.nim
index 22e3cd7..d371859 100644
--- a/generator/protoc_gen_nim.nim
+++ b/generator/protoc_gen_nim.nim
@@ -638,7 +638,7 @@ iterator genReadMapKVProc(msg: Message): string =
if isMessage(value):
yield indent("let", 12)
yield indent("size = readVarint(stream)", 16)
- yield indent("data = readStr(stream, int(size))", 16)
+ yield indent("data = safeReadStr(stream, int(size))", 16)
yield indent("pbs = newProtobufStream(newStringStream(data))", 16)
yield indent(&"value = read{value.typeName}(pbs)", 12)
else:
@@ -677,7 +677,7 @@ iterator genReadMessageProc(msg: Message): string =
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("data = safeReadStr(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):
@@ -698,7 +698,7 @@ iterator genReadMessageProc(msg: Message): string =
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("data = safeReadStr(stream, int(size))", 16)
yield indent("pbs = newProtobufStream(newStringStream(data))", 16)
yield indent(&"{setter}(result, {reader}(pbs))", 12)
else:
@@ -709,7 +709,7 @@ iterator genReadMessageProc(msg: Message): string =
if isMessage(field):
yield indent("let", 12)
yield indent("size = readVarint(stream)", 16)
- yield indent("data = readStr(stream, int(size))", 16)
+ yield indent("data = safeReadStr(stream, int(size))", 16)
yield indent("pbs = newProtobufStream(newStringStream(data))", 16)
yield indent(&"{setter}(result, {reader}(pbs))", 12)
else:
diff --git a/src/protobuf/stream.nim b/src/protobuf/stream.nim
index d7eeadd..9d843e6 100644
--- a/src/protobuf/stream.nim
+++ b/src/protobuf/stream.nim
@@ -181,7 +181,8 @@ proc writeFixed64*(stream: ProtobufStream, value: uint64) =
proc readFixed64*(stream: ProtobufStream): uint64 =
var tmp: uint64
- discard readData(stream, addr(tmp), sizeof(tmp))
+ if readData(stream, addr(tmp), sizeof(tmp)) != sizeof(tmp):
+ raise newException(IOError, "cannot read from stream")
littleEndian64(addr(result), addr(tmp))
proc writeSFixed64*(stream: ProtobufStream, value: int64) =
@@ -201,8 +202,9 @@ proc writeDouble*(stream: ProtobufStream, value: float64) =
proc readDouble*(stream: ProtobufStream): float64 =
var tmp: uint64
- discard readData(stream, addr(tmp), sizeof(tmp))
- littleEndian64(addr(tmp), addr(result))
+ if readData(stream, addr(tmp), sizeof(tmp)) != sizeof(tmp):
+ raise newException(IOError, "cannot read from stream")
+ littleEndian64(addr(result), addr(tmp))
proc writeFixed32*(stream: ProtobufStream, value: uint32) =
var
@@ -215,8 +217,9 @@ proc writeFixed32*(stream: ProtobufStream, value: uint32) =
proc readFixed32*(stream: ProtobufStream): uint32 =
var tmp: uint32
- discard readData(stream, addr(tmp), sizeof(tmp))
- littleEndian32(addr(tmp), addr(result))
+ if readData(stream, addr(tmp), sizeof(tmp)) != sizeof(tmp):
+ raise newException(IOError, "cannot read from stream")
+ littleEndian32(addr(result), addr(tmp))
proc writeSFixed32*(stream: ProtobufStream, value: int32) =
writeFixed32(stream, cast[uint32](value))
@@ -235,8 +238,9 @@ proc writeFloat*(stream: ProtobufStream, value: float32) =
proc readFloat*(stream: ProtobufStream): float32 =
var tmp: float32
- discard readData(stream, addr(tmp), sizeof(tmp))
- littleEndian32(addr(tmp), addr(result))
+ if readData(stream, addr(tmp), sizeof(tmp)) != sizeof(tmp):
+ raise newException(IOError, "cannot read from stream")
+ littleEndian32(addr(result), addr(tmp))
proc writeString*(stream: ProtobufStream, s: string) =
writeUInt64(stream, len(s).uint64)
@@ -245,10 +249,14 @@ proc writeString*(stream: ProtobufStream, s: string) =
proc writeBytes*(stream: ProtobufStream, s: bytes) =
writeString(stream, string(s))
+proc safeReadStr*(stream: Stream, size: int): string =
+ result = newString(size)
+ if readData(stream, addr(result[0]), size) != size:
+ raise newException(IOError, "cannot read from stream")
+
proc readString*(stream: ProtobufStream): string =
- # TODO: use something else than readStr to get rid of int cast?
- let size = readUInt64(stream).int
- result = readStr(stream, size)
+ let size = int(readUInt64(stream))
+ result = safeReadStr(stream, size)
proc readBytes*(stream: ProtobufStream): bytes =
bytes(readString(stream))
@@ -336,7 +344,7 @@ proc skipField*(stream: ProtobufStream, wiretype: WireType) =
discard readFixed32(stream)
of WireType.LengthDelimited:
let size = readVarint(stream)
- discard readStr(stream, int(size))
+ discard safeReadStr(stream, int(size))
else:
raise newException(Exception, "unsupported wiretype: " & $wiretype)