diff --git a/cmd/protoc-gen-tarantool/internal/gen/gen.go b/cmd/protoc-gen-tarantool/internal/gen/gen.go index 8de1de4023f851622353ddf256776f245521c575..a6861eff4374f29d42808d343ad888b30e7c733a 100644 --- a/cmd/protoc-gen-tarantool/internal/gen/gen.go +++ b/cmd/protoc-gen-tarantool/internal/gen/gen.go @@ -181,6 +181,7 @@ // Hot-path locals used by the inlined tag/length fast paths in each // generated _decode function. Localizing turns the LuaJIT references // into upvalue reads on the trace instead of repeated global lookups. w.line("local string_byte = string.byte") + w.line("local utf8_len = require('utf8').len") w.line("local band = bit.band") w.line("local rshift = bit.rshift") } diff --git a/cmd/protoc-gen-tarantool/internal/gen/inline.go b/cmd/protoc-gen-tarantool/internal/gen/inline.go index 73378569881e359ecfe386a4de1cf8adae46d828..8a0182266237309d26d1f082904a1af5d0ef5eb7 100644 --- a/cmd/protoc-gen-tarantool/internal/gen/inline.go +++ b/cmd/protoc-gen-tarantool/internal/gen/inline.go @@ -505,9 +505,19 @@ w.line(" u, pos = wire.decode_varint(buf, pos)") w.line(" %s = wire.varint_to_int32(u)", luaFieldAccess("result", fname)) default: st := scalarName(f.Desc.Kind()) - w.line(" local val") - w.line(" val, pos = wire.decode_%s(buf, pos)", st) - w.line(" %s = val", luaFieldAccess("result", fname)) + if st == "string" || st == "bytes" { + // Inline the 1-byte LEN fast path (length < 128). Skips the + // `wire.decode_string` / `wire.decode_bytes` function call + // frame for the typical short-string case; the resulting + // straight-line code stays inside the parent JIT trace + // instead of stitching through a child trace. (a6n) + dst := luaFieldAccess("result", fname) + emitInlineStringBytesScalar(w, st, dst) + } else { + w.line(" local val") + w.line(" val, pos = wire.decode_%s(buf, pos)", st) + w.line(" %s = val", luaFieldAccess("result", fname)) + } } // Oneof: clear sibling branches so callers see exactly one set field. @@ -577,11 +587,53 @@ w.line(" val, pos = wire.decode_%s(buf, pos)", st) w.line(" %s = %s + 1; list[%s] = val", cnt, cnt, cnt) w.line(" end") } else { - w.line(" local val") - w.line(" val, pos = wire.decode_%s(buf, pos)", st) - w.line(" %s = %s + 1; list[%s] = val", cnt, cnt, cnt) + // Repeated string/bytes — inline 1-byte LEN fast path. (a6n) + emitInlineStringBytesRepeated(w, st, cnt) } } +} + +// emitInlineStringBytesScalar emits the singular string/bytes decode with the +// 1-byte LEN fast path inlined. Falls back to `wire.decode_` for lengths +// >= 128. UTF-8 validation runs only for `string`, not `bytes`. (a6n) +func emitInlineStringBytesScalar(w *writer, st, dst string) { + w.line(" local _lb = string_byte(buf, pos)") + w.line(" if _lb ~= nil and _lb < 0x80 then") + w.line(" local _np = pos + 1") + w.line(" local _epos = _np + _lb") + w.line(" if _epos - 1 > len then error(\"truncated LEN at offset \" .. pos, 0) end") + w.line(" local _s = buf:sub(_np, _epos - 1)") + if st == "string" { + w.line(" if utf8_len(_s) == nil then error(\"invalid UTF-8 in string field at offset \" .. pos, 0) end") + } + w.line(" %s = _s", dst) + w.line(" pos = _epos") + w.line(" else") + w.line(" local val") + w.line(" val, pos = wire.decode_%s(buf, pos)", st) + w.line(" %s = val", dst) + w.line(" end") +} + +// emitInlineStringBytesRepeated mirrors emitInlineStringBytesScalar but +// appends to the per-field list via the `_n_` counter. (a6n) +func emitInlineStringBytesRepeated(w *writer, st, cnt string) { + w.line(" local _lb = string_byte(buf, pos)") + w.line(" if _lb ~= nil and _lb < 0x80 then") + w.line(" local _np = pos + 1") + w.line(" local _epos = _np + _lb") + w.line(" if _epos - 1 > len then error(\"truncated LEN at offset \" .. pos, 0) end") + w.line(" local _s = buf:sub(_np, _epos - 1)") + if st == "string" { + w.line(" if utf8_len(_s) == nil then error(\"invalid UTF-8 in string field at offset \" .. pos, 0) end") + } + w.line(" %s = %s + 1; list[%s] = _s", cnt, cnt, cnt) + w.line(" pos = _epos") + w.line(" else") + w.line(" local val") + w.line(" val, pos = wire.decode_%s(buf, pos)", st) + w.line(" %s = %s + 1; list[%s] = val", cnt, cnt, cnt) + w.line(" end") } // ---------------------------------------------------------------------------- diff --git a/examples/expected/full/c_int64/c_int64_pb.lua b/examples/expected/full/c_int64/c_int64_pb.lua index e07108a5e499d85305b8f09dafe644ac90a1cfe6..07526794fd6a8a744369ced61636464d733e83d8 100644 --- a/examples/expected/full/c_int64/c_int64_pb.lua +++ b/examples/expected/full/c_int64/c_int64_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/full/c_nested/c_nested_pb.lua b/examples/expected/full/c_nested/c_nested_pb.lua index 7e60060498ba4359343a2ad00ce187bcf60d5187..d3a43772e1cb868856d1b2507cb7c421a47d2400 100644 --- a/examples/expected/full/c_nested/c_nested_pb.lua +++ b/examples/expected/full/c_nested/c_nested_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/full/c_repeated/c_repeated_pb.lua b/examples/expected/full/c_repeated/c_repeated_pb.lua index 1702a9d0c7cf11d5e5f00b13de18f649e138602c..f3c3bc2d561083f1037e9e4da3ca376d5d03d655 100644 --- a/examples/expected/full/c_repeated/c_repeated_pb.lua +++ b/examples/expected/full/c_repeated/c_repeated_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift @@ -175,9 +176,20 @@ local val val, pos = wire.decode_int32(buf, pos) result.v = val elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.s = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.s = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.s = val + end else local _ebid = M.Inner_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil @@ -715,15 +727,36 @@ end elseif id == 30 then local list = result.strings if list == nil then list = {}; result.strings = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_strings = _n_strings + 1; list[_n_strings] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_strings = _n_strings + 1; list[_n_strings] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_strings = _n_strings + 1; list[_n_strings] = val + end elseif id == 31 then local list = result.blobs if list == nil then list = {}; result.blobs = list end - local val - val, pos = wire.decode_bytes(buf, pos) - _n_blobs = _n_blobs + 1; list[_n_blobs] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + _n_blobs = _n_blobs + 1; list[_n_blobs] = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + _n_blobs = _n_blobs + 1; list[_n_blobs] = val + end elseif id == 40 then local list = result.messages if list == nil then list = {}; result.messages = list end diff --git a/examples/expected/full/conformance/conformance_pb.lua b/examples/expected/full/conformance/conformance_pb.lua index 46d4d2df62823a42525ba28e43a8dfa4771d340b..949df2b0759a7437c11423d7b0cc0fe63358b5fd 100644 --- a/examples/expected/full/conformance/conformance_pb.lua +++ b/examples/expected/full/conformance/conformance_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift @@ -295,17 +296,50 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_string(buf, pos) - result.name = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.name = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.name = val + end elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.failure_message = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.failure_message = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.failure_message = val + end elseif id == 3 then - local val - val, pos = wire.decode_string(buf, pos) - result.matched_name = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.matched_name = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.matched_name = val + end else local _ebid = M.TestStatus_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil @@ -614,30 +648,73 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.protobuf_payload = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.protobuf_payload = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.protobuf_payload = val + end result.json_payload = nil result.jspb_payload = nil result.text_payload = nil elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.json_payload = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.json_payload = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.json_payload = val + end result.protobuf_payload = nil result.jspb_payload = nil result.text_payload = nil elseif id == 7 then - local val - val, pos = wire.decode_string(buf, pos) - result.jspb_payload = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.jspb_payload = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.jspb_payload = val + end result.protobuf_payload = nil result.json_payload = nil result.text_payload = nil elseif id == 8 then - local val - val, pos = wire.decode_string(buf, pos) - result.text_payload = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.text_payload = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.text_payload = val + end result.protobuf_payload = nil result.json_payload = nil result.jspb_payload = nil @@ -646,9 +723,20 @@ local u u, pos = wire.decode_varint(buf, pos) result.requested_output_format = wire.varint_to_int32(u) elseif id == 4 then - local val - val, pos = wire.decode_string(buf, pos) - result.message_type = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.message_type = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.message_type = val + end elseif id == 5 then local u u, pos = wire.decode_varint(buf, pos) @@ -872,9 +960,20 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_string(buf, pos) - result.parse_error = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.parse_error = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.parse_error = val + end result.serialize_error = nil result.timeout_error = nil result.runtime_error = nil @@ -884,9 +983,20 @@ result.skipped = nil result.jspb_payload = nil result.text_payload = nil elseif id == 6 then - local val - val, pos = wire.decode_string(buf, pos) - result.serialize_error = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.serialize_error = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.serialize_error = val + end result.parse_error = nil result.timeout_error = nil result.runtime_error = nil @@ -896,9 +1006,20 @@ result.skipped = nil result.jspb_payload = nil result.text_payload = nil elseif id == 9 then - local val - val, pos = wire.decode_string(buf, pos) - result.timeout_error = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.timeout_error = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.timeout_error = val + end result.parse_error = nil result.serialize_error = nil result.runtime_error = nil @@ -908,9 +1029,20 @@ result.skipped = nil result.jspb_payload = nil result.text_payload = nil elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.runtime_error = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.runtime_error = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.runtime_error = val + end result.parse_error = nil result.serialize_error = nil result.timeout_error = nil @@ -920,9 +1052,19 @@ result.skipped = nil result.jspb_payload = nil result.text_payload = nil elseif id == 3 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.protobuf_payload = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.protobuf_payload = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.protobuf_payload = val + end result.parse_error = nil result.serialize_error = nil result.timeout_error = nil @@ -932,9 +1074,20 @@ result.skipped = nil result.jspb_payload = nil result.text_payload = nil elseif id == 4 then - local val - val, pos = wire.decode_string(buf, pos) - result.json_payload = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.json_payload = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.json_payload = val + end result.parse_error = nil result.serialize_error = nil result.timeout_error = nil @@ -944,9 +1097,20 @@ result.skipped = nil result.jspb_payload = nil result.text_payload = nil elseif id == 5 then - local val - val, pos = wire.decode_string(buf, pos) - result.skipped = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.skipped = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.skipped = val + end result.parse_error = nil result.serialize_error = nil result.timeout_error = nil @@ -956,9 +1120,20 @@ result.json_payload = nil result.jspb_payload = nil result.text_payload = nil elseif id == 7 then - local val - val, pos = wire.decode_string(buf, pos) - result.jspb_payload = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.jspb_payload = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.jspb_payload = val + end result.parse_error = nil result.serialize_error = nil result.timeout_error = nil @@ -968,9 +1143,20 @@ result.json_payload = nil result.skipped = nil result.text_payload = nil elseif id == 8 then - local val - val, pos = wire.decode_string(buf, pos) - result.text_payload = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.text_payload = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.text_payload = val + end result.parse_error = nil result.serialize_error = nil result.timeout_error = nil diff --git a/examples/expected/full/hello/hello_pb.lua b/examples/expected/full/hello/hello_pb.lua index 09972e35f3ce51c623b32223b21a51e713ed7876..22688ac6544da3cf842fbcd23d06e7aca403775b 100644 --- a/examples/expected/full/hello/hello_pb.lua +++ b/examples/expected/full/hello/hello_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift @@ -315,9 +316,20 @@ local val val, pos = wire.decode_int32(buf, pos) result.id = val elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.text = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.text = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.text = val + end result.code = nil result.details = nil elseif id == 3 then @@ -437,9 +449,20 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_string(buf, pos) - result.name = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.name = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.name = val + end else local _ebid = M.HelloRequest_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil @@ -540,9 +563,20 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_string(buf, pos) - result.greeting = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.greeting = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.greeting = val + end else local _ebid = M.HelloReply_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil @@ -786,9 +820,20 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_string(buf, pos) - result.title = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.title = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.title = val + end elseif id == 2 then local payload payload, pos = wire.decode_len(buf, pos) @@ -963,21 +1008,54 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_string(buf, pos) - result.street = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.street = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.street = val + end elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.city = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.city = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.city = val + end elseif id == 3 then local val val, pos = wire.decode_int32(buf, pos) result.zip = val elseif id == 4 then - local val - val, pos = wire.decode_string(buf, pos) - result.apartment = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.apartment = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.apartment = val + end else local _ebid = M.Address_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil @@ -1272,9 +1350,20 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_string(buf, pos) - result.name = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.name = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.name = val + end elseif id == 2 then local val val, pos = wire.decode_int32(buf, pos) @@ -1282,9 +1371,20 @@ result.age = val elseif id == 3 then local list = result.emails if list == nil then list = {}; result.emails = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_emails = _n_emails + 1; list[_n_emails] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_emails = _n_emails + 1; list[_n_emails] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_emails = _n_emails + 1; list[_n_emails] = val + end elseif id == 4 then local u u, pos = wire.decode_varint(buf, pos) @@ -1322,9 +1422,19 @@ val, pos = wire.decode_int32(buf, pos) _n_lucky_numbers = _n_lucky_numbers + 1; list[_n_lucky_numbers] = val end elseif id == 8 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.avatar = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.avatar = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.avatar = val + end elseif id == 9 then local val val, pos = wire.decode_fixed64(buf, pos) diff --git a/examples/expected/full/proto2_basic/proto2_basic_pb.lua b/examples/expected/full/proto2_basic/proto2_basic_pb.lua index de656e18247b72d6fc924179769f7e68829e8ecc..6f657eea50f256507e8efbc1cbb9c2abc31db942 100644 --- a/examples/expected/full/proto2_basic/proto2_basic_pb.lua +++ b/examples/expected/full/proto2_basic/proto2_basic_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift @@ -372,9 +373,20 @@ local val val, pos = wire.decode_int32(buf, pos) result.i = val elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.s = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.s = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.s = val + end elseif id == 3 then local val val, pos = wire.decode_bool(buf, pos) @@ -396,9 +408,19 @@ local val val, pos = wire.decode_uint64(buf, pos) result.u64 = val elseif id == 8 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.by = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.by = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.by = val + end elseif id == 9 then local u u, pos = wire.decode_varint(buf, pos) @@ -1121,9 +1143,20 @@ local val val, pos = wire.decode_int32(buf, pos) result.a = val elseif id == 3 then - local val - val, pos = wire.decode_string(buf, pos) - result.s = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.s = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.s = val + end else local _ebid = M.WithGroup_SingleGroup_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil @@ -1408,9 +1441,20 @@ local val val, pos = wire.decode_int32(buf, pos) result.id = val elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.name = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.name = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.name = val + end elseif id == 3 then local val val, pos = wire.decode_int32(buf, pos) @@ -1435,9 +1479,20 @@ end elseif id == 5 then local list = result.tags if list == nil then list = {}; result.tags = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_tags = _n_tags + 1; list[_n_tags] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_tags = _n_tags + 1; list[_n_tags] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_tags = _n_tags + 1; list[_n_tags] = val + end elseif id == 6 then local payload payload, pos = wire.decode_len(buf, pos) @@ -1700,9 +1755,20 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_string(buf, pos) - result.key = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.key = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.key = val + end elseif id == 2 then local val val, pos = wire.decode_int32(buf, pos) diff --git a/examples/expected/full/protobuf_test_messages/proto2/test_messages_proto2_pb.lua b/examples/expected/full/protobuf_test_messages/proto2/test_messages_proto2_pb.lua index 571731cb6693ec45932ce95aa14d2f1bf566bc7b..698bb690b2589109569ed57c0d58cf07d6d8f09f 100644 --- a/examples/expected/full/protobuf_test_messages/proto2/test_messages_proto2_pb.lua +++ b/examples/expected/full/protobuf_test_messages/proto2/test_messages_proto2_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift @@ -2737,13 +2738,34 @@ local val val, pos = wire.decode_bool(buf, pos) result.optional_bool = val elseif id == 14 then - local val - val, pos = wire.decode_string(buf, pos) - result.optional_string = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.optional_string = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.optional_string = val + end elseif id == 15 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.optional_bytes = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.optional_bytes = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.optional_bytes = val + end elseif id == 18 then local payload payload, pos = wire.decode_len(buf, pos) @@ -2771,13 +2793,35 @@ local u u, pos = wire.decode_varint(buf, pos) result.optional_foreign_enum = wire.varint_to_int32(u) elseif id == 24 then - local val - val, pos = wire.decode_string(buf, pos) - result.optional_string_piece = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.optional_string_piece = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.optional_string_piece = val + end elseif id == 25 then - local val - val, pos = wire.decode_string(buf, pos) - result.optional_cord = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.optional_cord = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.optional_cord = val + end elseif id == 27 then local payload payload, pos = wire.decode_len(buf, pos) @@ -3011,15 +3055,36 @@ end elseif id == 44 then local list = result.repeated_string if list == nil then list = {}; result.repeated_string = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_repeated_string = _n_repeated_string + 1; list[_n_repeated_string] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_repeated_string = _n_repeated_string + 1; list[_n_repeated_string] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_repeated_string = _n_repeated_string + 1; list[_n_repeated_string] = val + end elseif id == 45 then local list = result.repeated_bytes if list == nil then list = {}; result.repeated_bytes = list end - local val - val, pos = wire.decode_bytes(buf, pos) - _n_repeated_bytes = _n_repeated_bytes + 1; list[_n_repeated_bytes] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + _n_repeated_bytes = _n_repeated_bytes + 1; list[_n_repeated_bytes] = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + _n_repeated_bytes = _n_repeated_bytes + 1; list[_n_repeated_bytes] = val + end elseif id == 48 then local list = result.repeated_nested_message if list == nil then list = {}; result.repeated_nested_message = list end @@ -3069,15 +3134,37 @@ end elseif id == 54 then local list = result.repeated_string_piece if list == nil then list = {}; result.repeated_string_piece = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_repeated_string_piece = _n_repeated_string_piece + 1; list[_n_repeated_string_piece] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_repeated_string_piece = _n_repeated_string_piece + 1; list[_n_repeated_string_piece] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_repeated_string_piece = _n_repeated_string_piece + 1; list[_n_repeated_string_piece] = val + end elseif id == 55 then local list = result.repeated_cord if list == nil then list = {}; result.repeated_cord = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_repeated_cord = _n_repeated_cord + 1; list[_n_repeated_cord] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_repeated_cord = _n_repeated_cord + 1; list[_n_repeated_cord] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_repeated_cord = _n_repeated_cord + 1; list[_n_repeated_cord] = val + end elseif id == 75 then local list = result.packed_int32 if list == nil then list = {}; result.packed_int32 = list end @@ -4008,9 +4095,20 @@ result.oneof_float = nil result.oneof_double = nil result.oneof_enum = nil elseif id == 113 then - local val - val, pos = wire.decode_string(buf, pos) - result.oneof_string = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.oneof_string = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.oneof_string = val + end result.oneof_uint32 = nil result.oneof_nested_message = nil result.oneof_bytes = nil @@ -4020,9 +4118,19 @@ result.oneof_float = nil result.oneof_double = nil result.oneof_enum = nil elseif id == 114 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.oneof_bytes = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.oneof_bytes = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.oneof_bytes = val + end result.oneof_uint32 = nil result.oneof_nested_message = nil result.oneof_string = nil @@ -4162,13 +4270,34 @@ local val val, pos = wire.decode_bool(buf, pos) result.default_bool = val elseif id == 254 then - local val - val, pos = wire.decode_string(buf, pos) - result.default_string = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.default_string = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.default_string = val + end elseif id == 255 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.default_bytes = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.default_bytes = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.default_bytes = val + end elseif id == 401 then local val val, pos = wire.decode_int32(buf, pos) @@ -5254,9 +5383,20 @@ local val val, pos = wire.decode_int32(buf, pos) result.optional_int32 = val elseif id == 1002 then - local val - val, pos = wire.decode_string(buf, pos) - result.optional_string = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.optional_string = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.optional_string = val + end elseif id == 1003 then local payload payload, pos = wire.decode_len(buf, pos) @@ -5699,9 +5839,20 @@ else id, wt, pos = wire.decode_tag(buf, pos) end if id == 1 then - local val - val, pos = wire.decode_string(buf, pos) - result.data = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.data = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.data = val + end else local _ebid = M.OneStringProto2_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil @@ -5834,15 +5985,37 @@ local val val, pos = wire.decode_int32(buf, pos) result.inline = val elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.concept = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.concept = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.concept = val + end elseif id == 3 then local list = result.requires if list == nil then list = {}; result.requires = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_requires = _n_requires + 1; list[_n_requires] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_requires = _n_requires + 1; list[_n_requires] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_requires = _n_requires + 1; list[_n_requires] = val + end else local _ebid = M.ProtoWithKeywords_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil @@ -6350,13 +6523,34 @@ local val val, pos = wire.decode_bool(buf, pos) result.required_bool = val elseif id == 14 then - local val - val, pos = wire.decode_string(buf, pos) - result.required_string = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.required_string = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.required_string = val + end elseif id == 15 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.required_bytes = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.required_bytes = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.required_bytes = val + end elseif id == 18 then local payload payload, pos = wire.decode_len(buf, pos) @@ -6384,13 +6578,35 @@ local u u, pos = wire.decode_varint(buf, pos) result.required_foreign_enum = wire.varint_to_int32(u) elseif id == 24 then - local val - val, pos = wire.decode_string(buf, pos) - result.required_string_piece = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.required_string_piece = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.required_string_piece = val + end elseif id == 25 then - local val - val, pos = wire.decode_string(buf, pos) - result.required_cord = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.required_cord = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.required_cord = val + end elseif id == 27 then local payload payload, pos = wire.decode_len(buf, pos) @@ -6471,13 +6687,34 @@ local val val, pos = wire.decode_bool(buf, pos) result.default_bool = val elseif id == 254 then - local val - val, pos = wire.decode_string(buf, pos) - result.default_string = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.default_string = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.default_string = val + end elseif id == 255 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.default_bytes = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.default_bytes = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.default_bytes = val + end else local _ebid = M.TestAllRequiredTypesProto2_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil diff --git a/examples/expected/full/protobuf_test_messages/proto3/test_messages_proto3_pb.lua b/examples/expected/full/protobuf_test_messages/proto3/test_messages_proto3_pb.lua index fea5a71521f3081af319159db4f8be60f9f770cd..4128053ce1bf6e97ce51982ccdfcf56fd4a0c2a5 100644 --- a/examples/expected/full/protobuf_test_messages/proto3/test_messages_proto3_pb.lua +++ b/examples/expected/full/protobuf_test_messages/proto3/test_messages_proto3_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift @@ -2908,13 +2909,34 @@ local val val, pos = wire.decode_bool(buf, pos) result.optional_bool = val elseif id == 14 then - local val - val, pos = wire.decode_string(buf, pos) - result.optional_string = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.optional_string = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.optional_string = val + end elseif id == 15 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.optional_bytes = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.optional_bytes = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.optional_bytes = val + end elseif id == 18 then local payload payload, pos = wire.decode_len(buf, pos) @@ -2946,13 +2968,35 @@ local u u, pos = wire.decode_varint(buf, pos) result.optional_aliased_enum = wire.varint_to_int32(u) elseif id == 24 then - local val - val, pos = wire.decode_string(buf, pos) - result.optional_string_piece = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.optional_string_piece = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.optional_string_piece = val + end elseif id == 25 then - local val - val, pos = wire.decode_string(buf, pos) - result.optional_cord = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.optional_cord = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.optional_cord = val + end elseif id == 27 then local payload payload, pos = wire.decode_len(buf, pos) @@ -3186,15 +3230,36 @@ end elseif id == 44 then local list = result.repeated_string if list == nil then list = {}; result.repeated_string = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_repeated_string = _n_repeated_string + 1; list[_n_repeated_string] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_repeated_string = _n_repeated_string + 1; list[_n_repeated_string] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_repeated_string = _n_repeated_string + 1; list[_n_repeated_string] = val + end elseif id == 45 then local list = result.repeated_bytes if list == nil then list = {}; result.repeated_bytes = list end - local val - val, pos = wire.decode_bytes(buf, pos) - _n_repeated_bytes = _n_repeated_bytes + 1; list[_n_repeated_bytes] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + _n_repeated_bytes = _n_repeated_bytes + 1; list[_n_repeated_bytes] = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + _n_repeated_bytes = _n_repeated_bytes + 1; list[_n_repeated_bytes] = val + end elseif id == 48 then local list = result.repeated_nested_message if list == nil then list = {}; result.repeated_nested_message = list end @@ -3244,15 +3309,37 @@ end elseif id == 54 then local list = result.repeated_string_piece if list == nil then list = {}; result.repeated_string_piece = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_repeated_string_piece = _n_repeated_string_piece + 1; list[_n_repeated_string_piece] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_repeated_string_piece = _n_repeated_string_piece + 1; list[_n_repeated_string_piece] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_repeated_string_piece = _n_repeated_string_piece + 1; list[_n_repeated_string_piece] = val + end elseif id == 55 then local list = result.repeated_cord if list == nil then list = {}; result.repeated_cord = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_repeated_cord = _n_repeated_cord + 1; list[_n_repeated_cord] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_repeated_cord = _n_repeated_cord + 1; list[_n_repeated_cord] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_repeated_cord = _n_repeated_cord + 1; list[_n_repeated_cord] = val + end elseif id == 75 then local list = result.packed_int32 if list == nil then list = {}; result.packed_int32 = list end @@ -4145,9 +4232,20 @@ result.oneof_double = nil result.oneof_enum = nil result.oneof_null_value = nil elseif id == 113 then - local val - val, pos = wire.decode_string(buf, pos) - result.oneof_string = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.oneof_string = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.oneof_string = val + end result.oneof_uint32 = nil result.oneof_nested_message = nil result.oneof_bytes = nil @@ -4158,9 +4256,19 @@ result.oneof_double = nil result.oneof_enum = nil result.oneof_null_value = nil elseif id == 114 then - local val - val, pos = wire.decode_bytes(buf, pos) - result.oneof_bytes = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + result.oneof_bytes = _s + pos = _epos + else + local val + val, pos = wire.decode_bytes(buf, pos) + result.oneof_bytes = val + end result.oneof_uint32 = nil result.oneof_nested_message = nil result.oneof_string = nil diff --git a/examples/expected/full/quickstart/quickstart_pb.lua b/examples/expected/full/quickstart/quickstart_pb.lua index 11cf3fb2623635cbb2c1468a6919e491a75060fc..cdb0ce452f3df7d360f09366df54f61b4af0ddb7 100644 --- a/examples/expected/full/quickstart/quickstart_pb.lua +++ b/examples/expected/full/quickstart/quickstart_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift @@ -166,9 +167,20 @@ local val val, pos = wire.decode_int32(buf, pos) result.id = val elseif id == 2 then - local val - val, pos = wire.decode_string(buf, pos) - result.name = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + result.name = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + result.name = val + end elseif id == 3 then local u u, pos = wire.decode_varint(buf, pos) @@ -176,9 +188,20 @@ result.role = wire.varint_to_int32(u) elseif id == 4 then local list = result.emails if list == nil then list = {}; result.emails = list end - local val - val, pos = wire.decode_string(buf, pos) - _n_emails = _n_emails + 1; list[_n_emails] = val + local _lb = string_byte(buf, pos) + if _lb ~= nil and _lb < 0x80 then + local _np = pos + 1 + local _epos = _np + _lb + if _epos - 1 > len then error("truncated LEN at offset " .. pos, 0) end + local _s = buf:sub(_np, _epos - 1) + if utf8_len(_s) == nil then error("invalid UTF-8 in string field at offset " .. pos, 0) end + _n_emails = _n_emails + 1; list[_n_emails] = _s + pos = _epos + else + local val + val, pos = wire.decode_string(buf, pos) + _n_emails = _n_emails + 1; list[_n_emails] = val + end else local _ebid = M.User_descriptor.extensions_by_id local _ext = _ebid and _ebid[id] or nil diff --git a/examples/expected/runtime/c_int64/c_int64_pb.lua b/examples/expected/runtime/c_int64/c_int64_pb.lua index df51cb81c349d1aecdcb8a65baec7067d9ed0d2f..23441b30318c48dda0e947dbd757e9c34ecbdf74 100644 --- a/examples/expected/runtime/c_int64/c_int64_pb.lua +++ b/examples/expected/runtime/c_int64/c_int64_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/runtime/c_nested/c_nested_pb.lua b/examples/expected/runtime/c_nested/c_nested_pb.lua index 17bece7ae171c163c06cf38c278a1ca1e1b57491..707cd31b54e5389f88c493ebf98f17fae792dbe8 100644 --- a/examples/expected/runtime/c_nested/c_nested_pb.lua +++ b/examples/expected/runtime/c_nested/c_nested_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/runtime/c_repeated/c_repeated_pb.lua b/examples/expected/runtime/c_repeated/c_repeated_pb.lua index 693680e1fba9caacc0eb92024ca135288429eb63..1a9339ff85d51038c7ad000c85e39c2e10093f65 100644 --- a/examples/expected/runtime/c_repeated/c_repeated_pb.lua +++ b/examples/expected/runtime/c_repeated/c_repeated_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/runtime/conformance/conformance_pb.lua b/examples/expected/runtime/conformance/conformance_pb.lua index 7c79ece1019f58b0512a24d8b77eb7ec2b310e56..0db005fb1157ae0daef0babf3ae40a0daa92399d 100644 --- a/examples/expected/runtime/conformance/conformance_pb.lua +++ b/examples/expected/runtime/conformance/conformance_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/runtime/hello/hello_pb.lua b/examples/expected/runtime/hello/hello_pb.lua index 41c78290c1d25150f86b354646fe52793a1092be..f74e7a72b36e274f7bd06bfbc8e70b842f37b36a 100644 --- a/examples/expected/runtime/hello/hello_pb.lua +++ b/examples/expected/runtime/hello/hello_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/runtime/proto2_basic/proto2_basic_pb.lua b/examples/expected/runtime/proto2_basic/proto2_basic_pb.lua index 82672b26e02947fcb096395eb5063d414afedf91..a6a904ff4b61e9ff24189c73282648ac8f58121e 100644 --- a/examples/expected/runtime/proto2_basic/proto2_basic_pb.lua +++ b/examples/expected/runtime/proto2_basic/proto2_basic_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/runtime/protobuf_test_messages/proto2/test_messages_proto2_pb.lua b/examples/expected/runtime/protobuf_test_messages/proto2/test_messages_proto2_pb.lua index 53c3542fadf859a8658c1424bc32c7a9b377fd98..95af5739182e6fb4e9c3362e4c9d88cbf9666ef8 100644 --- a/examples/expected/runtime/protobuf_test_messages/proto2/test_messages_proto2_pb.lua +++ b/examples/expected/runtime/protobuf_test_messages/proto2/test_messages_proto2_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/runtime/protobuf_test_messages/proto3/test_messages_proto3_pb.lua b/examples/expected/runtime/protobuf_test_messages/proto3/test_messages_proto3_pb.lua index ff1d5a42ef101cb33bf12cae68f9571e3478c339..9878619f254b079d42575d23717535a10013c96e 100644 --- a/examples/expected/runtime/protobuf_test_messages/proto3/test_messages_proto3_pb.lua +++ b/examples/expected/runtime/protobuf_test_messages/proto3/test_messages_proto3_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift diff --git a/examples/expected/runtime/quickstart/quickstart_pb.lua b/examples/expected/runtime/quickstart/quickstart_pb.lua index b416929f581afa6f713ce20c015e4d103a64dba3..e1ff77f3037f13fe9ce6a5a3f26bd54b448500ff 100644 --- a/examples/expected/runtime/quickstart/quickstart_pb.lua +++ b/examples/expected/runtime/quickstart/quickstart_pb.lua @@ -6,6 +6,7 @@ local pb = require("pb") local wire = pb.wire local string_byte = string.byte +local utf8_len = require('utf8').len local band = bit.band local rshift = bit.rshift