@@ -95,6 +95,20 @@ struct ArenaOffsetHelper {
95
95
PROTOBUF_EXPORT MessageLite* CloneSlow(Arena* arena, const MessageLite& value);
96
96
PROTOBUF_EXPORT std::string* CloneSlow(Arena* arena, const std::string& value);
97
97
98
+
// A utility function for logging that doesn't need any template types.
99
+
PROTOBUF_EXPORT void LogIndexOutOfBounds(int index, int size);
100
+
101
+
// A utility function for logging that doesn't need any template types. Same as
102
+
// LogIndexOutOfBounds, but aborts the program in all cases by logging to FATAL
103
+
// instead of DFATAL.
104
+
[[noreturn]] PROTOBUF_EXPORT void LogIndexOutOfBoundsAndAbort(int index,
105
+
int size);
106
+
PROTOBUF_EXPORT inline void RuntimeAssertInBounds(int index, int size) {
107
+
if (ABSL_PREDICT_FALSE(index < 0 || index >= size)) {
108
+
LogIndexOutOfBoundsAndAbort(index, size);
109
+
}
110
+
}
111
+
98
112
// Defined further below.
99
113
template <typename Type>
100
114
class GenericTypeHandler;
@@ -184,8 +198,12 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase {
184
198
185
199
template <typename TypeHandler>
186
200
Value<TypeHandler>* Mutable(int index) {
187
-
ABSL_DCHECK_GE(index, 0);
188
-
ABSL_DCHECK_LT(index, current_size_);
201
+
if constexpr (GetBoundsCheckMode() == BoundsCheckMode::kAbort) {
202
+
RuntimeAssertInBounds(index, current_size_);
203
+
} else {
204
+
ABSL_DCHECK_GE(index, 0);
205
+
ABSL_DCHECK_LT(index, current_size_);
206
+
}
189
207
return cast<TypeHandler>(element_at(index));
190
208
}
191
209
@@ -251,8 +269,22 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase {
251
269
252
270
template <typename TypeHandler>
253
271
const Value<TypeHandler>& Get(int index) const {
254
-
ABSL_DCHECK_GE(index, 0);
255
-
ABSL_DCHECK_LT(index, current_size_);
272
+
if constexpr (GetBoundsCheckMode() == BoundsCheckMode::kReturnDefault) {
273
+
if (ABSL_PREDICT_FALSE(index < 0 || index >= current_size_)) {
274
+
// `default_instance()` is not supported for MessageLite and Message.
275
+
if constexpr (TypeHandler::has_default_instance()) {
276
+
LogIndexOutOfBounds(index, current_size_);
277
+
return TypeHandler::default_instance();
278
+
}
279
+
}
280
+
} else if constexpr (GetBoundsCheckMode() == BoundsCheckMode::kAbort) {
281
+
// We refactor this to a separate function instead of inlining it so we
282
+
// can measure the performance impact more easily.
283
+
RuntimeAssertInBounds(index, current_size_);
284
+
} else {
285
+
ABSL_DCHECK_GE(index, 0);
286
+
ABSL_DCHECK_LT(index, current_size_);
287
+
}
256
288
return *cast<TypeHandler>(element_at(index));
257
289
}
258
290
@@ -847,19 +879,31 @@ class GenericTypeHandler {
847
879
return *static_cast<const GenericType*>(
848
880
MessageTraits<Type>::default_instance());
849
881
}
882
+
883
+
static constexpr bool has_default_instance() { return true; }
850
884
};
851
885
852
886
template <>
853
887
inline Arena* GenericTypeHandler<MessageLite>::GetArena(MessageLite* value) {
854
888
return value->GetArena();
855
889
}
856
890
891
+
template <>
892
+
inline constexpr bool GenericTypeHandler<MessageLite>::has_default_instance() {
893
+
return false;
894
+
}
895
+
857
896
// Message specialization bodies defined in message.cc. This split is necessary
858
897
// to allow proto2-lite (which includes this header) to be independent of
859
898
// Message.
860
899
template <>
861
900
PROTOBUF_EXPORT Arena* GenericTypeHandler<Message>::GetArena(Message* value);
862
901
902
+
template <>
903
+
inline constexpr bool GenericTypeHandler<Message>::has_default_instance() {
904
+
return false;
905
+
}
906
+
863
907
PROTOBUF_EXPORT void* NewStringElement(Arena* arena);
864
908
865
909
template <>
@@ -887,6 +931,8 @@ class GenericTypeHandler<std::string> {
887
931
static const Type& default_instance() {
888
932
return GetEmptyStringAlreadyInited();
889
933
}
934
+
935
+
static constexpr bool has_default_instance() { return true; }
890
936
};
891
937
892
938
} // namespace internal
@@ -1981,14 +2027,6 @@ class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator {
1981
2027
RepeatedPtrField<T>* field_;
1982
2028
};
1983
2029
1984
-
// A utility function for logging that doesn't need any template types.
1985
-
PROTOBUF_EXPORT void LogIndexOutOfBounds(int index, int size);
1986
-
1987
-
// A utility function for logging that doesn't need any template types. Same as
1988
-
// LogIndexOutOfBounds, but aborts the program in all cases by logging to FATAL
1989
-
// instead of DFATAL.
1990
-
[[noreturn]] PROTOBUF_EXPORT void LogIndexOutOfBoundsAndAbort(int index,
1991
-
int size);
1992
2030
1993
2031
template <typename T>
1994
2032
const T& CheckedGetOrDefault(const RepeatedPtrField<T>& field, int index) {
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4