mirror of
https://github.com/simonask/libyaml-safer
synced 2025-02-17 04:48:29 +00:00
Replace yaml_parser_initialize with safe alternative
This commit is contained in:
parent
47351cfe7c
commit
4a863e1f78
4 changed files with 43 additions and 68 deletions
45
src/api.rs
45
src/api.rs
|
@ -4,11 +4,12 @@ use alloc::vec::Vec;
|
||||||
use crate::yaml::{YamlEventData, YamlNodeData};
|
use crate::yaml::{YamlEventData, YamlNodeData};
|
||||||
use crate::{
|
use crate::{
|
||||||
libc, yaml_break_t, yaml_document_t, yaml_emitter_t, yaml_encoding_t, yaml_event_t,
|
libc, yaml_break_t, yaml_document_t, yaml_emitter_t, yaml_encoding_t, yaml_event_t,
|
||||||
yaml_mapping_style_t, yaml_mark_t, yaml_node_pair_t, yaml_node_t, yaml_parser_t,
|
yaml_mapping_style_t, yaml_mark_t, yaml_node_pair_t, yaml_node_t, yaml_parser_state_t,
|
||||||
yaml_scalar_style_t, yaml_sequence_style_t, yaml_tag_directive_t, yaml_token_t,
|
yaml_parser_t, yaml_scalar_style_t, yaml_sequence_style_t, yaml_tag_directive_t, yaml_token_t,
|
||||||
yaml_version_directive_t, YAML_ANY_ENCODING, YAML_UTF8_ENCODING,
|
yaml_version_directive_t, YAML_ANY_ENCODING, YAML_UTF8_ENCODING,
|
||||||
};
|
};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
pub(crate) const INPUT_RAW_BUFFER_SIZE: usize = 16384;
|
pub(crate) const INPUT_RAW_BUFFER_SIZE: usize = 16384;
|
||||||
pub(crate) const INPUT_BUFFER_SIZE: usize = INPUT_RAW_BUFFER_SIZE;
|
pub(crate) const INPUT_BUFFER_SIZE: usize = INPUT_RAW_BUFFER_SIZE;
|
||||||
|
@ -18,19 +19,33 @@ pub(crate) const OUTPUT_BUFFER_SIZE: usize = 16384;
|
||||||
///
|
///
|
||||||
/// This function creates a new parser object. An application is responsible
|
/// This function creates a new parser object. An application is responsible
|
||||||
/// for destroying the object using the yaml_parser_delete() function.
|
/// for destroying the object using the yaml_parser_delete() function.
|
||||||
pub unsafe fn yaml_parser_initialize(parser: *mut yaml_parser_t) -> Result<(), ()> {
|
pub fn yaml_parser_new<'r>() -> yaml_parser_t<'r> {
|
||||||
__assert!(!parser.is_null());
|
yaml_parser_t {
|
||||||
core::ptr::write(parser, yaml_parser_t::default());
|
read_handler: None,
|
||||||
let parser = &mut *parser;
|
input: Default::default(),
|
||||||
parser.raw_buffer.reserve(INPUT_RAW_BUFFER_SIZE);
|
eof: false,
|
||||||
parser.buffer.reserve(INPUT_BUFFER_SIZE);
|
buffer: VecDeque::with_capacity(INPUT_BUFFER_SIZE),
|
||||||
parser.tokens.reserve(16);
|
unread: 0,
|
||||||
parser.indents.reserve(16);
|
raw_buffer: VecDeque::with_capacity(INPUT_RAW_BUFFER_SIZE),
|
||||||
parser.simple_keys.reserve(16);
|
encoding: YAML_ANY_ENCODING,
|
||||||
parser.states.reserve(16);
|
offset: 0,
|
||||||
parser.marks.reserve(16);
|
mark: yaml_mark_t::default(),
|
||||||
parser.tag_directives.reserve(16);
|
stream_start_produced: false,
|
||||||
Ok(())
|
stream_end_produced: false,
|
||||||
|
flow_level: 0,
|
||||||
|
tokens: VecDeque::with_capacity(16),
|
||||||
|
tokens_parsed: 0,
|
||||||
|
token_available: false,
|
||||||
|
indents: Vec::with_capacity(16),
|
||||||
|
indent: 0,
|
||||||
|
simple_key_allowed: false,
|
||||||
|
simple_keys: Vec::with_capacity(16),
|
||||||
|
states: Vec::with_capacity(16),
|
||||||
|
state: yaml_parser_state_t::default(),
|
||||||
|
marks: Vec::with_capacity(16),
|
||||||
|
tag_directives: Vec::with_capacity(16),
|
||||||
|
aliases: Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroy a parser.
|
/// Destroy a parser.
|
||||||
|
|
|
@ -12,27 +12,22 @@
|
||||||
)]
|
)]
|
||||||
|
|
||||||
use libyaml_safer::{
|
use libyaml_safer::{
|
||||||
yaml_parser_delete, yaml_parser_initialize, yaml_parser_parse, yaml_parser_set_input,
|
yaml_parser_delete, yaml_parser_new, yaml_parser_parse, yaml_parser_set_input, YamlEventData,
|
||||||
yaml_parser_t, YamlEventData, YAML_DOUBLE_QUOTED_SCALAR_STYLE, YAML_FOLDED_SCALAR_STYLE,
|
YAML_DOUBLE_QUOTED_SCALAR_STYLE, YAML_FOLDED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE,
|
||||||
YAML_LITERAL_SCALAR_STYLE, YAML_PLAIN_SCALAR_STYLE, YAML_SINGLE_QUOTED_SCALAR_STYLE,
|
YAML_PLAIN_SCALAR_STYLE, YAML_SINGLE_QUOTED_SCALAR_STYLE,
|
||||||
};
|
};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::mem::MaybeUninit;
|
|
||||||
use std::process::{self, ExitCode};
|
use std::process::{self, ExitCode};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
pub(crate) unsafe fn unsafe_main(
|
pub(crate) fn test_main(
|
||||||
stdin: &mut dyn Read,
|
stdin: &mut dyn Read,
|
||||||
stdout: &mut dyn Write,
|
stdout: &mut dyn Write,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let mut parser = MaybeUninit::<yaml_parser_t>::uninit();
|
let mut parser = yaml_parser_new();
|
||||||
if yaml_parser_initialize(parser.as_mut_ptr()).is_err() {
|
|
||||||
return Err("Could not initialize the parser object".into());
|
|
||||||
}
|
|
||||||
let mut parser = parser.assume_init();
|
|
||||||
|
|
||||||
yaml_parser_set_input(&mut parser, stdin);
|
yaml_parser_set_input(&mut parser, stdin);
|
||||||
|
|
||||||
|
@ -137,7 +132,7 @@ pub(crate) unsafe fn unsafe_main(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn print_escaped(stdout: &mut dyn Write, s: &str) {
|
fn print_escaped(stdout: &mut dyn Write, s: &str) {
|
||||||
for ch in s.bytes() {
|
for ch in s.bytes() {
|
||||||
let repr = match &ch {
|
let repr = match &ch {
|
||||||
b'\\' => b"\\\\",
|
b'\\' => b"\\\\",
|
||||||
|
@ -161,7 +156,7 @@ fn main() -> ExitCode {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
let mut stdin = File::open(arg).unwrap();
|
let mut stdin = File::open(arg).unwrap();
|
||||||
let mut stdout = io::stdout();
|
let mut stdout = io::stdout();
|
||||||
let result = unsafe { unsafe_main(&mut stdin, &mut stdout) };
|
let result = test_main(&mut stdin, &mut stdout);
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
let _ = writeln!(io::stderr(), "{}", err);
|
let _ = writeln!(io::stderr(), "{}", err);
|
||||||
return ExitCode::FAILURE;
|
return ExitCode::FAILURE;
|
||||||
|
|
18
src/lib.rs
18
src/lib.rs
|
@ -116,8 +116,8 @@ pub use crate::api::{
|
||||||
yaml_emitter_set_indent, yaml_emitter_set_output, yaml_emitter_set_output_string,
|
yaml_emitter_set_indent, yaml_emitter_set_output, yaml_emitter_set_output_string,
|
||||||
yaml_emitter_set_unicode, yaml_emitter_set_width, yaml_event_delete,
|
yaml_emitter_set_unicode, yaml_emitter_set_width, yaml_event_delete,
|
||||||
yaml_mapping_end_event_initialize, yaml_mapping_start_event_initialize, yaml_parser_delete,
|
yaml_mapping_end_event_initialize, yaml_mapping_start_event_initialize, yaml_parser_delete,
|
||||||
yaml_parser_initialize, yaml_parser_set_encoding, yaml_parser_set_input,
|
yaml_parser_new, yaml_parser_set_encoding, yaml_parser_set_input, yaml_parser_set_input_string,
|
||||||
yaml_parser_set_input_string, yaml_scalar_event_initialize, yaml_sequence_end_event_initialize,
|
yaml_scalar_event_initialize, yaml_sequence_end_event_initialize,
|
||||||
yaml_sequence_start_event_initialize, yaml_stream_end_event_initialize,
|
yaml_sequence_start_event_initialize, yaml_stream_end_event_initialize,
|
||||||
yaml_stream_start_event_initialize, yaml_token_delete,
|
yaml_stream_start_event_initialize, yaml_token_delete,
|
||||||
};
|
};
|
||||||
|
@ -150,9 +150,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn sanity() {
|
fn sanity() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut parser = core::mem::MaybeUninit::uninit();
|
let mut parser = yaml_parser_new();
|
||||||
yaml_parser_initialize(parser.as_mut_ptr()).unwrap();
|
|
||||||
let mut parser = parser.assume_init();
|
|
||||||
// const SANITY_INPUT: &'static str =
|
// const SANITY_INPUT: &'static str =
|
||||||
// "Mark McGwire:\n hr: 65\n avg: 0.278\nSammy Sosa:\n hr: 63\n avg: 0.288\n";
|
// "Mark McGwire:\n hr: 65\n avg: 0.278\nSammy Sosa:\n hr: 63\n avg: 0.288\n";
|
||||||
const SANITY_INPUT: &'static str = r#"
|
const SANITY_INPUT: &'static str = r#"
|
||||||
|
@ -199,7 +197,7 @@ foo: bar
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_case() {
|
fn test_case() {
|
||||||
let mut parser = parser_new();
|
let mut parser = yaml_parser_new();
|
||||||
let mut input = TEST_CASE_QF4Y.as_bytes();
|
let mut input = TEST_CASE_QF4Y.as_bytes();
|
||||||
yaml_parser_set_input_string(&mut parser, &mut input);
|
yaml_parser_set_input_string(&mut parser, &mut input);
|
||||||
let mut doc = yaml_document_t::default();
|
let mut doc = yaml_document_t::default();
|
||||||
|
@ -298,12 +296,4 @@ foo: bar
|
||||||
emitter.assume_init()
|
emitter.assume_init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parser_new<'w>() -> yaml_parser_t<'w> {
|
|
||||||
unsafe {
|
|
||||||
let mut emitter = core::mem::MaybeUninit::uninit();
|
|
||||||
yaml_parser_initialize(emitter.as_mut_ptr()).unwrap();
|
|
||||||
emitter.assume_init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
29
src/yaml.rs
29
src/yaml.rs
|
@ -2,7 +2,7 @@ use alloc::collections::VecDeque;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use crate::libc;
|
use crate::{api::yaml_parser_new, libc};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
|
||||||
pub use self::yaml_encoding_t::*;
|
pub use self::yaml_encoding_t::*;
|
||||||
|
@ -688,32 +688,7 @@ pub struct yaml_parser_t<'r> {
|
||||||
|
|
||||||
impl<'r> Default for yaml_parser_t<'r> {
|
impl<'r> Default for yaml_parser_t<'r> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
yaml_parser_new()
|
||||||
read_handler: None,
|
|
||||||
input: Default::default(),
|
|
||||||
eof: Default::default(),
|
|
||||||
buffer: Default::default(),
|
|
||||||
unread: Default::default(),
|
|
||||||
raw_buffer: Default::default(),
|
|
||||||
encoding: Default::default(),
|
|
||||||
offset: Default::default(),
|
|
||||||
mark: Default::default(),
|
|
||||||
stream_start_produced: Default::default(),
|
|
||||||
stream_end_produced: Default::default(),
|
|
||||||
flow_level: Default::default(),
|
|
||||||
tokens: Default::default(),
|
|
||||||
tokens_parsed: Default::default(),
|
|
||||||
token_available: Default::default(),
|
|
||||||
indents: Default::default(),
|
|
||||||
indent: Default::default(),
|
|
||||||
simple_key_allowed: Default::default(),
|
|
||||||
simple_keys: Default::default(),
|
|
||||||
states: Default::default(),
|
|
||||||
state: Default::default(),
|
|
||||||
marks: Default::default(),
|
|
||||||
tag_directives: Default::default(),
|
|
||||||
aliases: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue