forked from extern/nushell
Make json require string and pass around metadata (#7010)
* Make json require string and pass around metadata The json deserializer was accepting any inputs by coercing non-strings into strings. As an example, if the input was `[1, 2]` the coercion would turn into `[12]` and deserialize as a list containing number twelve instead of a list of two numbers, one and two. This could lead to silent data corruption. Aside from that pipeline metadata wasn't passed aroud. This commit fixes the type issue by adding a strict conversion function that errors if the input type is not a string or external stream. It then uses this function instead of the original `collect_string()`. In addition, this function returns the pipeline metadata so it can be passed along. * Make other formats require string The problem with json coercing non-string types to string was present in all other text formats. This reuses the `collect_string_strict` function to fix them. * `IntoPipelineData` cleanup The method `into_pipeline_data_with_metadata` can now be conveniently used.
This commit is contained in:
committed by
GitHub
parent
d01ccd5a54
commit
d9d6cea5a9
@ -211,6 +211,33 @@ impl PipelineData {
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves string from pipline data.
|
||||
///
|
||||
/// As opposed to `collect_string` this raises error rather than converting non-string values.
|
||||
/// The `span` will be used if `ListStream` is encountered since it doesn't carry a span.
|
||||
pub fn collect_string_strict(
|
||||
self,
|
||||
span: Span,
|
||||
) -> Result<(String, Option<PipelineMetadata>), ShellError> {
|
||||
match self {
|
||||
PipelineData::Value(Value::String { val, .. }, metadata) => Ok((val, metadata)),
|
||||
PipelineData::Value(val, _) => {
|
||||
Err(ShellError::TypeMismatch("string".into(), val.span()?))
|
||||
}
|
||||
PipelineData::ListStream(_, _) => Err(ShellError::TypeMismatch("string".into(), span)),
|
||||
PipelineData::ExternalStream {
|
||||
stdout: None,
|
||||
metadata,
|
||||
..
|
||||
} => Ok((String::new(), metadata)),
|
||||
PipelineData::ExternalStream {
|
||||
stdout: Some(stdout),
|
||||
metadata,
|
||||
..
|
||||
} => Ok((stdout.into_string()?.item, metadata)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn follow_cell_path(
|
||||
self,
|
||||
cell_path: &[PathMember],
|
||||
@ -596,7 +623,10 @@ impl Iterator for PipelineIterator {
|
||||
|
||||
pub trait IntoPipelineData {
|
||||
fn into_pipeline_data(self) -> PipelineData;
|
||||
fn into_pipeline_data_with_metadata(self, metadata: PipelineMetadata) -> PipelineData;
|
||||
fn into_pipeline_data_with_metadata(
|
||||
self,
|
||||
metadata: impl Into<Option<PipelineMetadata>>,
|
||||
) -> PipelineData;
|
||||
}
|
||||
|
||||
impl<V> IntoPipelineData for V
|
||||
@ -606,8 +636,11 @@ where
|
||||
fn into_pipeline_data(self) -> PipelineData {
|
||||
PipelineData::Value(self.into(), None)
|
||||
}
|
||||
fn into_pipeline_data_with_metadata(self, metadata: PipelineMetadata) -> PipelineData {
|
||||
PipelineData::Value(self.into(), Some(metadata))
|
||||
fn into_pipeline_data_with_metadata(
|
||||
self,
|
||||
metadata: impl Into<Option<PipelineMetadata>>,
|
||||
) -> PipelineData {
|
||||
PipelineData::Value(self.into(), metadata.into())
|
||||
}
|
||||
}
|
||||
|
||||
@ -615,7 +648,7 @@ pub trait IntoInterruptiblePipelineData {
|
||||
fn into_pipeline_data(self, ctrlc: Option<Arc<AtomicBool>>) -> PipelineData;
|
||||
fn into_pipeline_data_with_metadata(
|
||||
self,
|
||||
metadata: PipelineMetadata,
|
||||
metadata: impl Into<Option<PipelineMetadata>>,
|
||||
ctrlc: Option<Arc<AtomicBool>>,
|
||||
) -> PipelineData;
|
||||
}
|
||||
@ -638,7 +671,7 @@ where
|
||||
|
||||
fn into_pipeline_data_with_metadata(
|
||||
self,
|
||||
metadata: PipelineMetadata,
|
||||
metadata: impl Into<Option<PipelineMetadata>>,
|
||||
ctrlc: Option<Arc<AtomicBool>>,
|
||||
) -> PipelineData {
|
||||
PipelineData::ListStream(
|
||||
@ -646,7 +679,7 @@ where
|
||||
stream: Box::new(self.into_iter().map(Into::into)),
|
||||
ctrlc,
|
||||
},
|
||||
Some(metadata),
|
||||
metadata.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user