Skip to content

Commit 2968252

Browse files
author
Simeon
authored
Handle JsonException thrown from JSON parser. (#286)
We were allowing some exceptions to escape, which would cause a crash of the reader.
1 parent 029aeb1 commit 2968252

File tree

2 files changed

+138
-137
lines changed

2 files changed

+138
-137
lines changed

source/LottieReader/Serialization/LottieCompositionReader.cs

Lines changed: 136 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -123,155 +123,163 @@ LottieComposition ParseLottieComposition(ref Reader reader)
123123
var markers = Array.Empty<Marker>();
124124
Dictionary<string, GenericDataObject> extraData = null;
125125

126-
reader.ConsumeToken();
127-
128-
while (reader.Read())
126+
try
129127
{
130-
switch (reader.TokenType)
128+
reader.ConsumeToken();
129+
130+
while (reader.Read())
131131
{
132-
case JsonTokenType.Comment:
133-
// Ignore comments.
134-
reader.ConsumeToken();
135-
break;
132+
switch (reader.TokenType)
133+
{
134+
case JsonTokenType.Comment:
135+
// Ignore comments.
136+
reader.ConsumeToken();
137+
break;
136138

137-
case JsonTokenType.PropertyName:
138-
var currentProperty = reader.GetString();
139+
case JsonTokenType.PropertyName:
140+
var currentProperty = reader.GetString();
139141

140-
reader.ConsumeToken();
142+
reader.ConsumeToken();
141143

142-
switch (currentProperty)
143-
{
144-
case "assets":
145-
assets = ParseArray(ref reader, ParseAsset);
146-
break;
147-
case "chars":
148-
chars = ParseArray(ref reader, ParseChar);
149-
break;
150-
case "ddd":
151-
is3d = reader.ParseBool();
152-
break;
153-
case "fr":
154-
framesPerSecond = reader.ParseDouble();
155-
break;
156-
case "fonts":
157-
fonts = ParseFonts(ref reader);
158-
break;
159-
case "layers":
160-
layers = ParseArray(ref reader, ParseLayer);
161-
break;
162-
case "h":
163-
height = reader.ParseDouble();
164-
break;
165-
case "ip":
166-
inPoint = reader.ParseDouble();
167-
break;
168-
case "op":
169-
outPoint = reader.ParseDouble();
170-
break;
171-
case "markers":
172-
markers = ParseArray(ref reader, ParseMarker);
173-
break;
174-
case "nm":
175-
name = reader.GetString();
176-
break;
177-
case "v":
178-
version = reader.GetString();
179-
break;
180-
case "w":
181-
width = reader.ParseDouble();
182-
break;
183-
184-
// Treat any other property as an extension of the BodyMovin format.
185-
default:
186-
{
187-
_issues.UnexpectedField(currentProperty);
188-
if (extraData is null)
144+
switch (currentProperty)
145+
{
146+
case "assets":
147+
assets = ParseArray(ref reader, ParseAsset);
148+
break;
149+
case "chars":
150+
chars = ParseArray(ref reader, ParseChar);
151+
break;
152+
case "ddd":
153+
is3d = reader.ParseBool();
154+
break;
155+
case "fr":
156+
framesPerSecond = reader.ParseDouble();
157+
break;
158+
case "fonts":
159+
fonts = ParseFonts(ref reader);
160+
break;
161+
case "layers":
162+
layers = ParseArray(ref reader, ParseLayer);
163+
break;
164+
case "h":
165+
height = reader.ParseDouble();
166+
break;
167+
case "ip":
168+
inPoint = reader.ParseDouble();
169+
break;
170+
case "op":
171+
outPoint = reader.ParseDouble();
172+
break;
173+
case "markers":
174+
markers = ParseArray(ref reader, ParseMarker);
175+
break;
176+
case "nm":
177+
name = reader.GetString();
178+
break;
179+
case "v":
180+
version = reader.GetString();
181+
break;
182+
case "w":
183+
width = reader.ParseDouble();
184+
break;
185+
186+
// Treat any other property as an extension of the BodyMovin format.
187+
default:
189188
{
190-
extraData = new Dictionary<string, GenericDataObject>();
189+
_issues.UnexpectedField(currentProperty);
190+
if (extraData is null)
191+
{
192+
extraData = new Dictionary<string, GenericDataObject>();
193+
}
194+
195+
using var subDocument = reader.ParseElement();
196+
extraData.Add(currentProperty, subDocument.RootElement.ToGenericDataObject());
191197
}
192198

193-
using var subDocument = reader.ParseElement();
194-
extraData.Add(currentProperty, subDocument.RootElement.ToGenericDataObject());
195-
}
196-
197-
break;
198-
}
199+
break;
200+
}
199201

200-
break;
202+
break;
201203

202-
case JsonTokenType.EndObject:
203-
{
204-
// Check that the required properties were found. If any are missing, throw.
205-
if (version is null)
204+
case JsonTokenType.EndObject:
206205
{
207-
throw reader.Throw("Version parameter not found.");
208-
}
206+
// Check that the required properties were found. If any are missing, throw.
207+
if (version is null)
208+
{
209+
throw reader.Throw("Version parameter not found.");
210+
}
209211

210-
if (!width.HasValue)
211-
{
212-
throw reader.Throw("Width parameter not found.");
213-
}
212+
if (!width.HasValue)
213+
{
214+
throw reader.Throw("Width parameter not found.");
215+
}
214216

215-
if (!height.HasValue)
216-
{
217-
throw reader.Throw("Height parameter not found.");
218-
}
217+
if (!height.HasValue)
218+
{
219+
throw reader.Throw("Height parameter not found.");
220+
}
219221

220-
if (!inPoint.HasValue)
221-
{
222-
throw reader.Throw("Start frame parameter not found.");
223-
}
222+
if (!inPoint.HasValue)
223+
{
224+
throw reader.Throw("Start frame parameter not found.");
225+
}
224226

225-
if (!outPoint.HasValue)
226-
{
227-
throw reader.Throw("End frame parameter not found.");
228-
}
227+
if (!outPoint.HasValue)
228+
{
229+
throw reader.Throw("End frame parameter not found.");
230+
}
229231

230-
if (layers is null)
231-
{
232-
throw reader.Throw("No layers found.");
233-
}
232+
if (layers is null)
233+
{
234+
throw reader.Throw("No layers found.");
235+
}
234236

235-
int[] versions;
236-
try
237-
{
238-
versions = version.Split('.').Select(int.Parse).ToArray();
239-
}
240-
catch (FormatException)
241-
{
242-
// Ignore
243-
versions = new[] { 0, 0, 0 };
244-
}
245-
catch (OverflowException)
246-
{
247-
// Ignore
248-
versions = new[] { 0, 0, 0 };
249-
}
237+
int[] versions;
238+
try
239+
{
240+
versions = version.Split('.').Select(int.Parse).ToArray();
241+
}
242+
catch (FormatException)
243+
{
244+
// Ignore
245+
versions = new[] { 0, 0, 0 };
246+
}
247+
catch (OverflowException)
248+
{
249+
// Ignore
250+
versions = new[] { 0, 0, 0 };
251+
}
250252

251-
var result = new LottieComposition(
252-
name: name ?? string.Empty,
253-
width: width ?? 0.0,
254-
height: height ?? 0.0,
255-
inPoint: inPoint ?? 0.0,
256-
outPoint: outPoint ?? 0.0,
257-
framesPerSecond: framesPerSecond ?? 0.0,
258-
is3d: false,
259-
version: new Version(versions[0], versions[1], versions[2]),
260-
assets: new AssetCollection(assets),
261-
chars: chars,
262-
extraData: extraData is null ? GenericDataMap.Empty : GenericDataMap.Create(extraData),
263-
fonts: fonts,
264-
layers: new LayerCollection(layers),
265-
markers: markers);
266-
return result;
267-
}
253+
var result = new LottieComposition(
254+
name: name ?? string.Empty,
255+
width: width ?? 0.0,
256+
height: height ?? 0.0,
257+
inPoint: inPoint ?? 0.0,
258+
outPoint: outPoint ?? 0.0,
259+
framesPerSecond: framesPerSecond ?? 0.0,
260+
is3d: false,
261+
version: new Version(versions[0], versions[1], versions[2]),
262+
assets: new AssetCollection(assets),
263+
chars: chars,
264+
extraData: extraData is null ? GenericDataMap.Empty : GenericDataMap.Create(extraData),
265+
fonts: fonts,
266+
layers: new LayerCollection(layers),
267+
markers: markers);
268+
return result;
269+
}
268270

269-
// Here means the JSON was invalid or our parser got confused. There is no way to
270-
// recover from this, so throw.
271-
default:
272-
throw reader.ThrowUnexpectedToken();
271+
// Here means the JSON was invalid or our parser got confused. There is no way to
272+
// recover from this, so throw.
273+
default:
274+
throw reader.ThrowUnexpectedToken();
275+
}
273276
}
274277
}
278+
catch (JsonException e)
279+
{
280+
// Re-throw errors from the JSON parser using our own exception.
281+
throw Exception(e.Message);
282+
}
275283

276284
throw EofException;
277285
}

source/LottieReader/Serialization/Reader.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,9 @@ internal void ExpectToken(JsonTokenType tokenType)
4949
// Consumes a token from the stream.
5050
internal void ConsumeToken()
5151
{
52-
try
52+
if (!_jsonReader.Read())
5353
{
54-
if (!_jsonReader.Read())
55-
{
56-
throw EofException;
57-
}
58-
}
59-
catch (JsonException e)
60-
{
61-
throw Exception(e.Message);
54+
throw EofException;
6255
}
6356
}
6457

0 commit comments

Comments
 (0)