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:
Martin Habovštiak
2022-11-21 02:06:09 +01:00
committed by GitHub
parent d01ccd5a54
commit d9d6cea5a9
15 changed files with 104 additions and 95 deletions

View File

@ -268,7 +268,6 @@ fn from_ssv(
call: &Call,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let config = engine_state.get_config();
let name = call.head;
let noheaders = call.has_flag("noheaders");
@ -276,7 +275,7 @@ fn from_ssv(
let minimum_spaces: Option<Spanned<usize>> =
call.get_flag(engine_state, stack, "minimum-spaces")?;
let concat_string = input.collect_string("", config)?;
let (concat_string, metadata) = input.collect_string_strict(name)?;
let split_at = match minimum_spaces {
Some(number) => number.item,
None => DEFAULT_MINIMUM_SPACES,
@ -284,7 +283,7 @@ fn from_ssv(
Ok(
from_ssv_string_to_value(&concat_string, noheaders, aligned_columns, split_at, name)
.into_pipeline_data(),
.into_pipeline_data_with_metadata(metadata),
)
}