Fix malformed CSV files causing crashes; fixes #310

This commit is contained in:
Lucien Greathouse
2020-03-30 11:12:20 -07:00
parent def99a9e4d
commit 30a01381be
3 changed files with 22 additions and 7 deletions

View File

@@ -1,6 +1,7 @@
# Rojo Changelog # Rojo Changelog
## Unreleased Changes ## Unreleased Changes
* Fixed crash when malformed CSV files are put into a project. ([#310](https://github.com/rojo-rbx/rojo/issues/310))
## [6.0.0 Release Candidate 1](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.0-rc.1) (March 29, 2020) ## [6.0.0 Release Candidate 1](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.0-rc.1) (March 29, 2020)
This release jumped from 0.6.0 to 6.0.0. Rojo has been in use in production for many users for quite a long times, and so 6.0 is a more accurate reflection of Rojo's version than a pre-1.0 version. This release jumped from 0.6.0 to 6.0.0. Rojo has been in use in production for many users for quite a long times, and so 6.0 is a more accurate reflection of Rojo's version than a pre-1.0 version.

View File

@@ -8,6 +8,7 @@ use serde::Serialize;
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
use super::{ use super::{
error::SnapshotError,
meta_file::AdjacentMetadata, meta_file::AdjacentMetadata,
middleware::{SnapshotInstanceResult, SnapshotMiddleware}, middleware::{SnapshotInstanceResult, SnapshotMiddleware},
util::match_file_name, util::match_file_name,
@@ -29,8 +30,10 @@ impl SnapshotMiddleware for SnapshotCsv {
}; };
let meta_path = path.with_file_name(format!("{}.meta.json", instance_name)); let meta_path = path.with_file_name(format!("{}.meta.json", instance_name));
let contents = vfs.read(path)?;
let table_contents = convert_localization_csv(&vfs.read(path)?); let table_contents = convert_localization_csv(&contents)
.map_err(|source| SnapshotError::malformed_l10n_csv(source, path))?;
let mut snapshot = InstanceSnapshot::new() let mut snapshot = InstanceSnapshot::new()
.name(instance_name) .name(instance_name)
@@ -87,17 +90,15 @@ struct LocalizationEntry<'a> {
/// https://github.com/BurntSushi/rust-csv/issues/151 /// https://github.com/BurntSushi/rust-csv/issues/151
/// ///
/// This function operates in one step in order to minimize data-copying. /// This function operates in one step in order to minimize data-copying.
fn convert_localization_csv(contents: &[u8]) -> String { fn convert_localization_csv(contents: &[u8]) -> Result<String, csv::Error> {
let mut reader = csv::Reader::from_reader(contents); let mut reader = csv::Reader::from_reader(contents);
let headers = reader.headers().expect("TODO: Handle csv errors").clone(); let headers = reader.headers()?.clone();
let mut records = Vec::new(); let mut records = Vec::new();
for record in reader.into_records() { for record in reader.into_records() {
let record = record.expect("TODO: Handle csv errors"); records.push(record?);
records.push(record);
} }
let mut entries = Vec::new(); let mut entries = Vec::new();
@@ -128,7 +129,10 @@ fn convert_localization_csv(contents: &[u8]) -> String {
entries.push(entry); entries.push(entry);
} }
serde_json::to_string(&entries).expect("Could not encode JSON for localization table") let encoded =
serde_json::to_string(&entries).expect("Could not encode JSON for localization table");
Ok(encoded)
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -37,6 +37,9 @@ pub enum SnapshotError {
path: PathBuf, path: PathBuf,
}, },
#[error("malformed CSV localization data at path {}", .path.display())]
MalformedLocalizationCsv { source: csv::Error, path: PathBuf },
#[error(transparent)] #[error(transparent)]
Io { Io {
#[from] #[from]
@@ -89,4 +92,11 @@ impl SnapshotError {
path: path.into(), path: path.into(),
} }
} }
pub(crate) fn malformed_l10n_csv(source: csv::Error, path: impl Into<PathBuf>) -> Self {
Self::MalformedLocalizationCsv {
source,
path: path.into(),
}
}
} }