/// <summary> /// Reads an embedded message field value from the stream. /// </summary> public void ReadMessage(Action <CodedInputStream> decoder) { int length = ReadLength(); if (length == 0) { return; } if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } int oldLimit = PushLimit(length); ++recursionDepth; decoder.Invoke(this); CheckReadEndOfStreamTag(); // Check that we've read exactly as much data as expected. if (!ReachedLimit) { throw InvalidProtocolBufferException.TruncatedMessage(); } --recursionDepth; PopLimit(oldLimit); }
private void SkipGroup(uint startGroupTag) { // Note: Currently we expect this to be the way that groups are read. We could put the recursion // depth changes into the ReadTag method instead, potentially... recursionDepth++; if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } uint tag; while (true) { tag = ReadTag(); if (tag == 0) { throw InvalidProtocolBufferException.TruncatedMessage(); } // Can't call SkipLastField for this case- that would throw. if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup) { break; } // This recursion will allow us to handle nested groups. SkipLastField(); } int startField = WireFormat.GetTagFieldNumber(startGroupTag); int endField = WireFormat.GetTagFieldNumber(tag); if (startField != endField) { throw new InvalidProtocolBufferException("Mismatched end-group tag. Started with field " + startField + "; ended with field " + endField); } recursionDepth--; }
/// <summary> /// Reads an embedded group field from the stream. /// </summary> public void ReadGroup(IMessage builder) { if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } ++recursionDepth; builder.MergeFrom(this); --recursionDepth; }
public static void ReadGroup(ref ParseContext ctx, int fieldNumber, UnknownFieldSet set) { if (ctx.state.recursionDepth >= ctx.state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } ++ctx.state.recursionDepth; set.MergeGroupFrom(ref ctx); CheckLastTagWas(ref ctx.state, WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup)); --ctx.state.recursionDepth; }
public static void ReadGroup(ref ParseContext ctx, IMessage message) { if (ctx.state.recursionDepth >= ctx.state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } ++ctx.state.recursionDepth; uint tag = ctx.state.lastTag; int fieldNumber = WireFormat.GetTagFieldNumber(tag); ReadRawMessage(ref ctx, message); CheckLastTagWas(ref ctx.state, WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup)); --ctx.state.recursionDepth; }
/// <summary> /// Reads an embedded message field value from the stream. /// </summary> public void ReadMessage(IMessage builder) { int length = ReadLength(); if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } int oldLimit = PushLimit(length); ++recursionDepth; builder.MergeFrom(this); CheckLastTagWas(0); --recursionDepth; PopLimit(oldLimit); }
public void ReadMapItor(Action <CodedInputStream> decoder) { int length = ReadLength(); if (length == 0) { return; } if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } int oldLimit = PushLimit(length); ++recursionDepth; decoder.Invoke(this); --recursionDepth; PopLimit(oldLimit); }
/// <summary> /// Reads an embedded message field value from the stream. /// </summary> public void ReadMessage(IMessage builder) { int length = ReadLength(); if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } int oldLimit = PushLimit(length); ++recursionDepth; builder.MergeFrom(this); CheckReadEndOfStreamTag(); // Check that we've read exactly as much data as expected. if (!ReachedLimit) { throw InvalidProtocolBufferException.TruncatedMessage(); } --recursionDepth; PopLimit(oldLimit); }
private void SkipGroup() { // Note: Currently we expect this to be the way that groups are read. We could put the recursion // depth changes into the ReadTag method instead, potentially... recursionDepth++; if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } uint tag; do { tag = ReadTag(); if (tag == 0) { throw InvalidProtocolBufferException.TruncatedMessage(); } // This recursion will allow us to handle nested groups. SkipLastField(); } while (WireFormat.GetTagWireType(tag) != WireFormat.WireType.EndGroup); recursionDepth--; }
public static void ReadMessage(ref ParseContext ctx, IMessage message) { int length = ParsingPrimitives.ParseLength(ref ctx.buffer, ref ctx.state); if (ctx.state.recursionDepth >= ctx.state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, length); ++ctx.state.recursionDepth; ReadRawMessage(ref ctx, message); CheckReadEndOfStreamTag(ref ctx.state); // Check that we've read exactly as much data as expected. if (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state)) { throw InvalidProtocolBufferException.TruncatedMessage(); } --ctx.state.recursionDepth; SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); }
/// <summary> /// Skip a group. /// </summary> public static void SkipGroup(ref ReadOnlySpan <byte> buffer, ref ParserInternalState state, uint startGroupTag) { // Note: Currently we expect this to be the way that groups are read. We could put the recursion // depth changes into the ReadTag method instead, potentially... state.recursionDepth++; if (state.recursionDepth >= state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } uint tag; while (true) { tag = ParsingPrimitives.ParseTag(ref buffer, ref state); if (tag == 0) { throw InvalidProtocolBufferException.TruncatedMessage(); } // Can't call SkipLastField for this case- that would throw. if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup) { break; } // This recursion will allow us to handle nested groups. SkipLastField(ref buffer, ref state); } int startField = WireFormat.GetTagFieldNumber(startGroupTag); int endField = WireFormat.GetTagFieldNumber(tag); if (startField != endField) { throw new InvalidProtocolBufferException( $"Mismatched end-group tag. Started with field {startField}; ended with field {endField}"); } state.recursionDepth--; }
public static KeyValuePair <TKey, TValue> ReadMapEntry <TKey, TValue>(ref ParseContext ctx, MapField <TKey, TValue> .Codec codec) { int length = ParsingPrimitives.ParseLength(ref ctx.buffer, ref ctx.state); if (ctx.state.recursionDepth >= ctx.state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, length); ++ctx.state.recursionDepth; TKey key = codec.KeyCodec.DefaultValue; TValue value = codec.ValueCodec.DefaultValue; uint tag; while ((tag = ctx.ReadTag()) != 0) { if (tag == codec.KeyCodec.Tag) { key = codec.KeyCodec.Read(ref ctx); } else if (tag == codec.ValueCodec.Tag) { value = codec.ValueCodec.Read(ref ctx); } else { SkipLastField(ref ctx.buffer, ref ctx.state); } } // Corner case: a map entry with a key but no value, where the value type is a message. // Read it as if we'd seen input with no data (i.e. create a "default" message). if (value == null) { if (ctx.state.CodedInputStream != null) { // the decoded message might not support parsing from ParseContext, so // we need to allow fallback to the legacy MergeFrom(CodedInputStream) parsing. value = codec.ValueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData)); } else { ParseContext.Initialize(new ReadOnlySequence <byte>(ZeroLengthMessageStreamData), out ParseContext zeroLengthCtx); value = codec.ValueCodec.Read(ref zeroLengthCtx); } } CheckReadEndOfStreamTag(ref ctx.state); // Check that we've read exactly as much data as expected. if (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state)) { throw InvalidProtocolBufferException.TruncatedMessage(); } --ctx.state.recursionDepth; SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); return(new KeyValuePair <TKey, TValue>(key, value)); }