mirror of
https://github.com/simonask/libyaml-safer
synced 2024-11-22 19:33:03 +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::{
|
||||
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_scalar_style_t, yaml_sequence_style_t, yaml_tag_directive_t, yaml_token_t,
|
||||
yaml_mapping_style_t, yaml_mark_t, yaml_node_pair_t, yaml_node_t, yaml_parser_state_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,
|
||||
};
|
||||
use core::ptr;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
pub(crate) const INPUT_RAW_BUFFER_SIZE: usize = 16384;
|
||||
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
|
||||
/// for destroying the object using the yaml_parser_delete() function.
|
||||
pub unsafe fn yaml_parser_initialize(parser: *mut yaml_parser_t) -> Result<(), ()> {
|
||||
__assert!(!parser.is_null());
|
||||
core::ptr::write(parser, yaml_parser_t::default());
|
||||
let parser = &mut *parser;
|
||||
parser.raw_buffer.reserve(INPUT_RAW_BUFFER_SIZE);
|
||||
parser.buffer.reserve(INPUT_BUFFER_SIZE);
|
||||
parser.tokens.reserve(16);
|
||||
parser.indents.reserve(16);
|
||||
parser.simple_keys.reserve(16);
|
||||
parser.states.reserve(16);
|
||||
parser.marks.reserve(16);
|
||||
parser.tag_directives.reserve(16);
|
||||
Ok(())
|
||||
pub fn yaml_parser_new<'r>() -> yaml_parser_t<'r> {
|
||||
yaml_parser_t {
|
||||
read_handler: None,
|
||||
input: Default::default(),
|
||||
eof: false,
|
||||
buffer: VecDeque::with_capacity(INPUT_BUFFER_SIZE),
|
||||
unread: 0,
|
||||
raw_buffer: VecDeque::with_capacity(INPUT_RAW_BUFFER_SIZE),
|
||||
encoding: YAML_ANY_ENCODING,
|
||||
offset: 0,
|
||||
mark: yaml_mark_t::default(),
|
||||
stream_start_produced: false,
|
||||
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.
|
||||
|
|
|
@ -12,27 +12,22 @@
|
|||
)]
|
||||
|
||||
use libyaml_safer::{
|
||||
yaml_parser_delete, yaml_parser_initialize, yaml_parser_parse, yaml_parser_set_input,
|
||||
yaml_parser_t, YamlEventData, YAML_DOUBLE_QUOTED_SCALAR_STYLE, YAML_FOLDED_SCALAR_STYLE,
|
||||
YAML_LITERAL_SCALAR_STYLE, YAML_PLAIN_SCALAR_STYLE, YAML_SINGLE_QUOTED_SCALAR_STYLE,
|
||||
yaml_parser_delete, yaml_parser_new, yaml_parser_parse, yaml_parser_set_input, YamlEventData,
|
||||
YAML_DOUBLE_QUOTED_SCALAR_STYLE, YAML_FOLDED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE,
|
||||
YAML_PLAIN_SCALAR_STYLE, YAML_SINGLE_QUOTED_SCALAR_STYLE,
|
||||
};
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::process::{self, ExitCode};
|
||||
use std::slice;
|
||||
|
||||
pub(crate) unsafe fn unsafe_main(
|
||||
pub(crate) fn test_main(
|
||||
stdin: &mut dyn Read,
|
||||
stdout: &mut dyn Write,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let mut parser = MaybeUninit::<yaml_parser_t>::uninit();
|
||||
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();
|
||||
let mut parser = yaml_parser_new();
|
||||
|
||||
yaml_parser_set_input(&mut parser, stdin);
|
||||
|
||||
|
@ -137,7 +132,7 @@ pub(crate) unsafe fn unsafe_main(
|
|||
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() {
|
||||
let repr = match &ch {
|
||||
b'\\' => b"\\\\",
|
||||
|
@ -161,7 +156,7 @@ fn main() -> ExitCode {
|
|||
for arg in args {
|
||||
let mut stdin = File::open(arg).unwrap();
|
||||
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 {
|
||||
let _ = writeln!(io::stderr(), "{}", err);
|
||||
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_unicode, yaml_emitter_set_width, yaml_event_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_set_input_string, yaml_scalar_event_initialize, yaml_sequence_end_event_initialize,
|
||||
yaml_parser_new, yaml_parser_set_encoding, yaml_parser_set_input, yaml_parser_set_input_string,
|
||||
yaml_scalar_event_initialize, yaml_sequence_end_event_initialize,
|
||||
yaml_sequence_start_event_initialize, yaml_stream_end_event_initialize,
|
||||
yaml_stream_start_event_initialize, yaml_token_delete,
|
||||
};
|
||||
|
@ -150,9 +150,7 @@ mod tests {
|
|||
#[test]
|
||||
fn sanity() {
|
||||
unsafe {
|
||||
let mut parser = core::mem::MaybeUninit::uninit();
|
||||
yaml_parser_initialize(parser.as_mut_ptr()).unwrap();
|
||||
let mut parser = parser.assume_init();
|
||||
let mut parser = yaml_parser_new();
|
||||
// const SANITY_INPUT: &'static str =
|
||||
// "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#"
|
||||
|
@ -199,7 +197,7 @@ foo: bar
|
|||
|
||||
#[test]
|
||||
fn test_case() {
|
||||
let mut parser = parser_new();
|
||||
let mut parser = yaml_parser_new();
|
||||
let mut input = TEST_CASE_QF4Y.as_bytes();
|
||||
yaml_parser_set_input_string(&mut parser, &mut input);
|
||||
let mut doc = yaml_document_t::default();
|
||||
|
@ -298,12 +296,4 @@ foo: bar
|
|||
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::vec::Vec;
|
||||
|
||||
use crate::libc;
|
||||
use crate::{api::yaml_parser_new, libc};
|
||||
use core::ptr;
|
||||
|
||||
pub use self::yaml_encoding_t::*;
|
||||
|
@ -688,32 +688,7 @@ pub struct yaml_parser_t<'r> {
|
|||
|
||||
impl<'r> Default for yaml_parser_t<'r> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
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(),
|
||||
}
|
||||
yaml_parser_new()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue