mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Fix JSON read off-by-one error
This commit is contained in:
@@ -71,7 +71,7 @@ namespace SabreTools.Library.DatFiles
|
|||||||
|
|
||||||
// Machine array
|
// Machine array
|
||||||
case "machines":
|
case "machines":
|
||||||
ReadMachines(sr, jtr, filename, indexId);
|
ReadMachines(jtr, filename, indexId);
|
||||||
jtr.Read();
|
jtr.Read();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -109,12 +109,10 @@ namespace SabreTools.Library.DatFiles
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read machine array information
|
/// Read machine array information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sr">StreamReader to use to parse the header</param>
|
|
||||||
/// <param name="itr">JsonTextReader to use to parse the machine</param>
|
/// <param name="itr">JsonTextReader to use to parse the machine</param>
|
||||||
/// <param name="filename">Name of the file to be parsed</param>
|
/// <param name="filename">Name of the file to be parsed</param>
|
||||||
/// <param name="indexId">Index ID for the DAT</param>
|
/// <param name="indexId">Index ID for the DAT</param>
|
||||||
private void ReadMachines(
|
private void ReadMachines(
|
||||||
StreamReader sr,
|
|
||||||
JsonTextReader jtr,
|
JsonTextReader jtr,
|
||||||
|
|
||||||
// Standard Dat parsing
|
// Standard Dat parsing
|
||||||
@@ -125,92 +123,57 @@ namespace SabreTools.Library.DatFiles
|
|||||||
if (jtr == null)
|
if (jtr == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Read in the machine array
|
||||||
jtr.Read();
|
jtr.Read();
|
||||||
while (!sr.EndOfStream)
|
JsonSerializer js = new JsonSerializer();
|
||||||
|
JArray machineArray = js.Deserialize<JArray>(jtr);
|
||||||
|
|
||||||
|
// Loop through each machine object and process
|
||||||
|
foreach (JObject machineObj in machineArray)
|
||||||
{
|
{
|
||||||
// If we hit the end of an array, we want to return
|
ReadMachine(machineObj, filename, indexId);
|
||||||
if (jtr.TokenType == JsonToken.EndArray)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// We don't care about anything except start object
|
|
||||||
if (jtr.TokenType != JsonToken.StartObject)
|
|
||||||
{
|
|
||||||
jtr.Read();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadMachine(sr, jtr, filename, indexId);
|
|
||||||
jtr.Read();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read machine object information
|
/// Read machine object information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sr">StreamReader to use to parse the header</param>
|
/// <param name="machineObj">JObject representing a single machine</param>
|
||||||
/// <param name="itr">JsonTextReader to use to parse the machine</param>
|
|
||||||
/// <param name="filename">Name of the file to be parsed</param>
|
/// <param name="filename">Name of the file to be parsed</param>
|
||||||
/// <param name="indexId">Index ID for the DAT</param>
|
/// <param name="indexId">Index ID for the DAT</param>
|
||||||
private void ReadMachine(
|
private void ReadMachine(
|
||||||
StreamReader sr,
|
JObject machineObj,
|
||||||
JsonTextReader jtr,
|
|
||||||
|
|
||||||
// Standard Dat parsing
|
// Standard Dat parsing
|
||||||
string filename,
|
string filename,
|
||||||
int indexId)
|
int indexId)
|
||||||
{
|
{
|
||||||
// If we have an empty machine, skip it
|
// If object is invalid, skip it
|
||||||
if (jtr == null)
|
if (machineObj == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Prepare internal variables
|
// Prepare internal variables
|
||||||
JsonSerializer js = new JsonSerializer();
|
JsonSerializer js = new JsonSerializer();
|
||||||
Machine machine = null;
|
Machine machine = null;
|
||||||
|
|
||||||
jtr.Read();
|
// Read the machine info, if possible
|
||||||
while (!sr.EndOfStream)
|
if (machineObj.ContainsKey("machine"))
|
||||||
{
|
machine = machineObj["machine"].ToObject<Machine>();
|
||||||
// If we hit the end of the machine, return
|
|
||||||
if (jtr.TokenType == JsonToken.EndObject)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// We don't care about anything except properties
|
// Read items, if possible
|
||||||
if (jtr.TokenType != JsonToken.PropertyName)
|
if (machineObj.ContainsKey("items"))
|
||||||
{
|
ReadItems(machineObj["items"] as JArray, filename, indexId, machine);
|
||||||
jtr.Read();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (jtr.Value)
|
|
||||||
{
|
|
||||||
case "machine":
|
|
||||||
jtr.Read();
|
|
||||||
machine = js.Deserialize<Machine>(jtr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "items":
|
|
||||||
ReadItems(sr, jtr, filename, indexId, machine);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
jtr.Read();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read item array information
|
/// Read item array information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sr">StreamReader to use to parse the header</param>
|
/// <param name="itemsArr">JArray representing the items list</param>
|
||||||
/// <param name="jtr">JsonTextReader to use to parse the machine</param>
|
|
||||||
/// <param name="filename">Name of the file to be parsed</param>
|
/// <param name="filename">Name of the file to be parsed</param>
|
||||||
/// <param name="indexId">Index ID for the DAT</param>
|
/// <param name="indexId">Index ID for the DAT</param>
|
||||||
/// <param name="machine">Machine information to add to the parsed items</param>
|
/// <param name="machine">Machine information to add to the parsed items</param>
|
||||||
private void ReadItems(
|
private void ReadItems(
|
||||||
StreamReader sr,
|
JArray itemsArr,
|
||||||
JsonTextReader jtr,
|
|
||||||
|
|
||||||
// Standard Dat parsing
|
// Standard Dat parsing
|
||||||
string filename,
|
string filename,
|
||||||
@@ -219,40 +182,26 @@ namespace SabreTools.Library.DatFiles
|
|||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
Machine machine)
|
Machine machine)
|
||||||
{
|
{
|
||||||
// If the reader is invalid, skip
|
// If the array is invalid, skip
|
||||||
if (jtr == null)
|
if (itemsArr == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
jtr.Read();
|
// Loop through each datitem object and process
|
||||||
while (!sr.EndOfStream)
|
foreach (JObject itemObj in itemsArr)
|
||||||
{
|
{
|
||||||
// If we hit the end of an array, we want to return
|
ReadItem(itemObj, filename, indexId, machine);
|
||||||
if (jtr.TokenType == JsonToken.EndArray)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// We don't care about anything except start object
|
|
||||||
if (jtr.TokenType != JsonToken.StartObject)
|
|
||||||
{
|
|
||||||
jtr.Read();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadItem(sr, jtr, filename, indexId, machine);
|
|
||||||
jtr.Read();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read item information
|
/// Read item information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sr">StreamReader to use to parse the header</param>
|
/// <param name="machineObj">JObject representing a single datitem</param>
|
||||||
/// <param name="jtr">JsonTextReader to use to parse the machine</param>
|
|
||||||
/// <param name="filename">Name of the file to be parsed</param>
|
/// <param name="filename">Name of the file to be parsed</param>
|
||||||
/// <param name="indexId">Index ID for the DAT</param>
|
/// <param name="indexId">Index ID for the DAT</param>
|
||||||
/// <param name="machine">Machine information to add to the parsed items</param>
|
/// <param name="machine">Machine information to add to the parsed items</param>
|
||||||
private void ReadItem(
|
private void ReadItem(
|
||||||
StreamReader sr,
|
JObject itemObj,
|
||||||
JsonTextReader jtr,
|
|
||||||
|
|
||||||
// Standard Dat parsing
|
// Standard Dat parsing
|
||||||
string filename,
|
string filename,
|
||||||
@@ -261,75 +210,49 @@ namespace SabreTools.Library.DatFiles
|
|||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
Machine machine)
|
Machine machine)
|
||||||
{
|
{
|
||||||
// If we have an empty machine, skip it
|
// If we have an empty item, skip it
|
||||||
if (jtr == null)
|
if (itemObj == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Prepare internal variables
|
// Prepare internal variables
|
||||||
JsonSerializer js = new JsonSerializer();
|
|
||||||
DatItem datItem = null;
|
DatItem datItem = null;
|
||||||
|
|
||||||
jtr.Read();
|
// Read the datitem info, if possible
|
||||||
while (!sr.EndOfStream)
|
if (itemObj.ContainsKey("datitem"))
|
||||||
{
|
{
|
||||||
// If we hit the end of the machine - create, add, and return
|
JToken datItemObj = itemObj["datitem"];
|
||||||
if (jtr.TokenType == JsonToken.EndObject)
|
switch (datItemObj.Value<string>("type").AsItemType())
|
||||||
{
|
{
|
||||||
// If we didn't read something valid, just return
|
case ItemType.Archive:
|
||||||
if (datItem == null)
|
datItem = datItemObj.ToObject<Archive>();
|
||||||
return;
|
|
||||||
|
|
||||||
datItem.CopyMachineInformation(machine);
|
|
||||||
datItem.Source = new Source { Index = indexId, Name = filename };
|
|
||||||
ParseAddHelper(datItem);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't care about anything except properties
|
|
||||||
if (jtr.TokenType != JsonToken.PropertyName)
|
|
||||||
{
|
|
||||||
jtr.Read();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (jtr.Value)
|
|
||||||
{
|
|
||||||
case "datitem":
|
|
||||||
jtr.Read();
|
|
||||||
JObject datItemObj = js.Deserialize<JObject>(jtr);
|
|
||||||
switch (datItemObj.Value<string>("type").AsItemType())
|
|
||||||
{
|
|
||||||
case ItemType.Archive:
|
|
||||||
datItem = datItemObj.ToObject<Archive>();
|
|
||||||
break;
|
|
||||||
case ItemType.BiosSet:
|
|
||||||
datItem = datItemObj.ToObject<BiosSet>();
|
|
||||||
break;
|
|
||||||
case ItemType.Blank:
|
|
||||||
datItem = datItemObj.ToObject<Blank>();
|
|
||||||
break;
|
|
||||||
case ItemType.Disk:
|
|
||||||
datItem = datItemObj.ToObject<Disk>();
|
|
||||||
break;
|
|
||||||
case ItemType.Release:
|
|
||||||
datItem = datItemObj.ToObject<Release>();
|
|
||||||
break;
|
|
||||||
case ItemType.Rom:
|
|
||||||
datItem = datItemObj.ToObject<Rom>();
|
|
||||||
break;
|
|
||||||
case ItemType.Sample:
|
|
||||||
datItem = datItemObj.ToObject<Sample>();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case ItemType.BiosSet:
|
||||||
default:
|
datItem = datItemObj.ToObject<BiosSet>();
|
||||||
|
break;
|
||||||
|
case ItemType.Blank:
|
||||||
|
datItem = datItemObj.ToObject<Blank>();
|
||||||
|
break;
|
||||||
|
case ItemType.Disk:
|
||||||
|
datItem = datItemObj.ToObject<Disk>();
|
||||||
|
break;
|
||||||
|
case ItemType.Release:
|
||||||
|
datItem = datItemObj.ToObject<Release>();
|
||||||
|
break;
|
||||||
|
case ItemType.Rom:
|
||||||
|
datItem = datItemObj.ToObject<Rom>();
|
||||||
|
break;
|
||||||
|
case ItemType.Sample:
|
||||||
|
datItem = datItemObj.ToObject<Sample>();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jtr.Read();
|
// If we got a valid datitem, copy machine info and add
|
||||||
|
if (datItem != null)
|
||||||
|
{
|
||||||
|
datItem.CopyMachineInformation(machine);
|
||||||
|
datItem.Source = new Source { Index = indexId, Name = filename };
|
||||||
|
ParseAddHelper(datItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user