• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 package com.google.protobuf;
9 
10 import java.io.IOException;
11 
12 /**
13  * Thrown when a protocol message being parsed is invalid in some way. For instance,
14  * it contains a malformed varint or a negative byte length.
15  *
16  * @author kenton@google.com Kenton Varda
17  */
18 public class InvalidProtocolBufferException extends IOException {
19   private static final long serialVersionUID = -1616151763072450476L;
20   private MessageLite unfinishedMessage = null;
21   private boolean wasThrownFromInputStream;
22 
InvalidProtocolBufferException(String description)23   public InvalidProtocolBufferException(String description) {
24     super(description);
25   }
26 
InvalidProtocolBufferException(Exception e)27   public InvalidProtocolBufferException(Exception e) {
28     super(e.getMessage(), e);
29   }
30 
InvalidProtocolBufferException(String description, Exception e)31   public InvalidProtocolBufferException(String description, Exception e) {
32     super(description, e);
33   }
34 
InvalidProtocolBufferException(IOException e)35   public InvalidProtocolBufferException(IOException e) {
36     super(e.getMessage(), e);
37   }
38 
InvalidProtocolBufferException(String description, IOException e)39   public InvalidProtocolBufferException(String description, IOException e) {
40     super(description, e);
41   }
42 
43   /**
44    * Attaches an unfinished message to the exception to support best-effort parsing in {@code
45    * Parser} interface.
46    *
47    * @return this
48    */
setUnfinishedMessage(MessageLite unfinishedMessage)49   public InvalidProtocolBufferException setUnfinishedMessage(MessageLite unfinishedMessage) {
50     this.unfinishedMessage = unfinishedMessage;
51     return this;
52   }
53 
54   /**
55    * Returns the unfinished message attached to the exception, or null if no message is attached.
56    */
getUnfinishedMessage()57   public MessageLite getUnfinishedMessage() {
58     return unfinishedMessage;
59   }
60 
61   /** Set by CodedInputStream */
setThrownFromInputStream()62   void setThrownFromInputStream() {
63     /* This write can be racy if the same exception is stored and then thrown by multiple custom
64      * InputStreams on different threads. But since it only ever moves from false->true, there's no
65      * problem. A thread checking this condition after catching this exception from a delegate
66      * stream of CodedInputStream is guaranteed to always observe true, because a write on the same
67      * thread set the value when the exception left the delegate. A thread checking the same
68      * condition with an exception created by CodedInputStream is guaranteed to always see false,
69      * because the exception has not been exposed to any code that could publish it to other threads
70      * and cause a write.
71      */
72     wasThrownFromInputStream = true;
73   }
74 
75   /**
76    * Allows code catching IOException from CodedInputStream to tell whether this instance was thrown
77    * by a delegate InputStream, rather than directly by a parse failure.
78    */
getThrownFromInputStream()79   boolean getThrownFromInputStream() {
80     return wasThrownFromInputStream;
81   }
82 
83   /**
84    * Unwraps the underlying {@link IOException} if this exception was caused by an I/O problem.
85    * Otherwise, returns {@code this}.
86    */
unwrapIOException()87   public IOException unwrapIOException() {
88     return getCause() instanceof IOException ? (IOException) getCause() : this;
89   }
90 
truncatedMessage()91   static InvalidProtocolBufferException truncatedMessage() {
92     return new InvalidProtocolBufferException(
93         "While parsing a protocol message, the input ended unexpectedly "
94             + "in the middle of a field.  This could mean either that the "
95             + "input has been truncated or that an embedded message "
96             + "misreported its own length.");
97   }
98 
negativeSize()99   static InvalidProtocolBufferException negativeSize() {
100     return new InvalidProtocolBufferException(
101         "CodedInputStream encountered an embedded string or message "
102             + "which claimed to have negative size.");
103   }
104 
malformedVarint()105   static InvalidProtocolBufferException malformedVarint() {
106     return new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint.");
107   }
108 
invalidTag()109   static InvalidProtocolBufferException invalidTag() {
110     return new InvalidProtocolBufferException("Protocol message contained an invalid tag (zero).");
111   }
112 
invalidEndTag()113   static InvalidProtocolBufferException invalidEndTag() {
114     return new InvalidProtocolBufferException(
115         "Protocol message end-group tag did not match expected tag.");
116   }
117 
invalidWireType()118   static InvalidWireTypeException invalidWireType() {
119     return new InvalidWireTypeException("Protocol message tag had invalid wire type.");
120   }
121 
122   /** Exception indicating that an unexpected wire type was encountered for a field. */
123   @ExperimentalApi
124   public static class InvalidWireTypeException extends InvalidProtocolBufferException {
125     private static final long serialVersionUID = 3283890091615336259L;
126 
InvalidWireTypeException(String description)127     public InvalidWireTypeException(String description) {
128       super(description);
129     }
130   }
131 
recursionLimitExceeded()132   static InvalidProtocolBufferException recursionLimitExceeded() {
133     return new InvalidProtocolBufferException(
134         "Protocol message had too many levels of nesting.  May be malicious.  "
135             + "Use setRecursionLimit() to increase the recursion depth limit.");
136   }
137 
sizeLimitExceeded()138   static InvalidProtocolBufferException sizeLimitExceeded() {
139     return new InvalidProtocolBufferException(
140         "Protocol message was too large.  May be malicious.  "
141             + "Use CodedInputStream.setSizeLimit() to increase the size limit.");
142   }
143 
parseFailure()144   static InvalidProtocolBufferException parseFailure() {
145     return new InvalidProtocolBufferException("Failed to parse the message.");
146   }
147 
invalidUtf8()148   static InvalidProtocolBufferException invalidUtf8() {
149     return new InvalidProtocolBufferException("Protocol message had invalid UTF-8.");
150   }
151 }
152