Skip to content

Commit f547771

Browse files
gnpricechrisbobbe
authored andcommitted
api: Fix usage of int.parse that implicitly accepts hexadecimal
Calling just `int.parse(s)`, without a `radix:` argument, invokes a special behavior where `int.parse` not only accepts decimal strings like "42", but also hexadecimal strings like "0x2a". That's a bit unexpected. In any case it's definitely not something we want when interpreting any part of the Zulip API. Fix the one place we had this in our own code. There remain two places it appears in the code generated by `json_serializable`; mark those with TODO comments. It'd be nice to fix those too, but realistically this quirk is unlikely to ever cause a problem, so it's not worth a lot of effort to resolve. (Note that this doesn't affect the bulk of places we have an int in the API types, because most of those are handled by jsonDecode before the `json_serializable`-generated code ever sees them. It only affects the keys of `Map<int, …>` structures.) It looks like there's no existing thread in the `json_serializable` tracker for this issue. The most closely related is from where the handling of `Map<int, …>` types was added in the first place: google/json_serializable.dart#434
1 parent 0847f10 commit f547771

File tree

3 files changed

+5
-1
lines changed

3 files changed

+5
-1
lines changed

lib/api/model/events.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ class UpdateMessageFlagsRemoveEvent extends UpdateMessageFlagsEvent {
503503
String get op => 'remove';
504504

505505
// final bool all; // deprecated, ignore
506+
// TODO(json_serializable): keys use plain `int.parse`, permitting hexadecimal
506507
final Map<int, UpdateMessageFlagsMessageDetail>? messageDetails;
507508

508509
UpdateMessageFlagsRemoveEvent({

lib/api/model/model.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,13 @@ class User {
134134
String timezone;
135135
String? avatarUrl; // TODO distinguish null from missing https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/flutter.3A.20omitted.20vs.2E.20null.20in.20JSON/near/1551759
136136
int avatarVersion;
137+
137138
// null for bots, which don't have custom profile fields.
138139
// If null for a non-bot, equivalent to `{}` (null just written for efficiency.)
140+
// TODO(json_serializable): keys use plain `int.parse`, permitting hexadecimal
139141
@JsonKey(readValue: _readProfileData)
140142
Map<int, ProfileFieldUserData>? profileData;
143+
141144
@JsonKey(readValue: _readIsSystemBot)
142145
bool? isSystemBot; // TODO(server-5)
143146

lib/api/model/narrow.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class ApiNarrowMessageId extends ApiNarrowElement {
110110
ApiNarrowMessageId(int operand, {super.negated}) : operand = operand.toString();
111111

112112
factory ApiNarrowMessageId.fromJson(Map<String, dynamic> json) => ApiNarrowMessageId(
113-
int.parse(json['operand'] as String),
113+
int.parse(json['operand'] as String, radix: 10),
114114
negated: json['negated'] as bool? ?? false,
115115
);
116116
}

0 commit comments

Comments
 (0)