mirror of
https://github.com/simonask/libyaml-safer
synced 2024-11-14 15:47:14 +00:00
Add CStr that can be lossy formatted without allocation
This commit is contained in:
parent
47ad13e63c
commit
966ef05f32
3 changed files with 66 additions and 30 deletions
47
src/bin/cstr/mod.rs
Normal file
47
src/bin/cstr/mod.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use std::fmt::{self, Display, Write as _};
|
||||
use std::slice;
|
||||
use std::str;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
type c_char = i8;
|
||||
|
||||
pub struct CStr {
|
||||
ptr: *const u8,
|
||||
}
|
||||
|
||||
impl CStr {
|
||||
pub unsafe fn from_ptr(ptr: *const c_char) -> Self {
|
||||
CStr { ptr: ptr.cast() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for CStr {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
let len = unsafe { strlen(self.ptr) };
|
||||
let mut bytes = unsafe { slice::from_raw_parts(self.ptr, len) };
|
||||
loop {
|
||||
match str::from_utf8(bytes) {
|
||||
Ok(valid) => return formatter.write_str(valid),
|
||||
Err(utf8_error) => {
|
||||
let valid_up_to = utf8_error.valid_up_to();
|
||||
let valid = unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) };
|
||||
formatter.write_str(valid)?;
|
||||
formatter.write_char(char::REPLACEMENT_CHARACTER)?;
|
||||
if let Some(error_len) = utf8_error.error_len() {
|
||||
bytes = &bytes[valid_up_to + error_len..];
|
||||
} else {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn strlen(s: *const u8) -> usize {
|
||||
let mut end = s;
|
||||
while *end != 0 {
|
||||
end = end.add(1);
|
||||
}
|
||||
end.offset_from(s) as usize
|
||||
}
|
|
@ -14,9 +14,12 @@
|
|||
clippy::unreadable_literal
|
||||
)]
|
||||
|
||||
mod cstr;
|
||||
|
||||
use self::cstr::CStr;
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::ffi::{c_void, CStr};
|
||||
use std::ffi::c_void;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::mem::MaybeUninit;
|
||||
|
@ -145,11 +148,7 @@ pub(crate) unsafe fn unsafe_main(
|
|||
);
|
||||
} else {
|
||||
yaml_emitter_delete(emitter);
|
||||
return Err(format!(
|
||||
"Unknown event: '{}'",
|
||||
CStr::from_ptr(line).to_string_lossy(),
|
||||
)
|
||||
.into());
|
||||
return Err(format!("Unknown event: '{}'", CStr::from_ptr(line)).into());
|
||||
}
|
||||
if ok == 0 {
|
||||
current_block = 13850764817919632987;
|
||||
|
@ -164,16 +163,8 @@ pub(crate) unsafe fn unsafe_main(
|
|||
13850764817919632987 => Err("Memory error: Not enough memory for creating an event".into()),
|
||||
6684355725484023210 => Err(match (*emitter).error as u32 {
|
||||
1 => "Memory error: Not enough memory for emitting".into(),
|
||||
6 => format!(
|
||||
"Writer error: {}",
|
||||
CStr::from_ptr((*emitter).problem).to_string_lossy(),
|
||||
)
|
||||
.into(),
|
||||
7 => format!(
|
||||
"Emitter error: {}",
|
||||
CStr::from_ptr((*emitter).problem).to_string_lossy(),
|
||||
)
|
||||
.into(),
|
||||
6 => format!("Writer error: {}", CStr::from_ptr((*emitter).problem)).into(),
|
||||
7 => format!("Emitter error: {}", CStr::from_ptr((*emitter).problem)).into(),
|
||||
_ => "Internal error".into(),
|
||||
}),
|
||||
_ => Ok(()),
|
||||
|
|
|
@ -11,9 +11,12 @@
|
|||
clippy::too_many_lines
|
||||
)]
|
||||
|
||||
mod cstr;
|
||||
|
||||
use self::cstr::CStr;
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::ffi::{c_void, CStr};
|
||||
use std::ffi::c_void;
|
||||
use std::fmt::Write as _;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Write};
|
||||
|
@ -59,10 +62,7 @@ pub(crate) unsafe fn unsafe_main(
|
|||
yaml_parser_set_input(parser, Some(read_from_stdio), addr_of_mut!(stdin).cast());
|
||||
loop {
|
||||
if yaml_parser_parse(parser, event) == 0 {
|
||||
let mut error = format!(
|
||||
"Parse error: {}",
|
||||
CStr::from_ptr((*parser).problem).to_string_lossy(),
|
||||
);
|
||||
let mut error = format!("Parse error: {}", CStr::from_ptr((*parser).problem));
|
||||
if (*parser).problem_mark.line != 0 || (*parser).problem_mark.column != 0 {
|
||||
let _ = write!(
|
||||
error,
|
||||
|
@ -99,15 +99,14 @@ pub(crate) unsafe fn unsafe_main(
|
|||
let _ = write!(
|
||||
stdout,
|
||||
" &{}",
|
||||
CStr::from_ptr((*event).data.mapping_start.anchor as *const i8)
|
||||
.to_string_lossy(),
|
||||
CStr::from_ptr((*event).data.mapping_start.anchor as *const i8),
|
||||
);
|
||||
}
|
||||
if !((*event).data.mapping_start.tag).is_null() {
|
||||
let _ = write!(
|
||||
stdout,
|
||||
" <{}>",
|
||||
CStr::from_ptr((*event).data.mapping_start.tag as *const i8).to_string_lossy(),
|
||||
CStr::from_ptr((*event).data.mapping_start.tag as *const i8),
|
||||
);
|
||||
}
|
||||
let _ = writeln!(stdout);
|
||||
|
@ -119,15 +118,14 @@ pub(crate) unsafe fn unsafe_main(
|
|||
let _ = write!(
|
||||
stdout,
|
||||
" &{}",
|
||||
CStr::from_ptr((*event).data.sequence_start.anchor as *const i8)
|
||||
.to_string_lossy(),
|
||||
CStr::from_ptr((*event).data.sequence_start.anchor as *const i8),
|
||||
);
|
||||
}
|
||||
if !((*event).data.sequence_start.tag).is_null() {
|
||||
let _ = write!(
|
||||
stdout,
|
||||
" <{}>",
|
||||
CStr::from_ptr((*event).data.sequence_start.tag as *const i8).to_string_lossy(),
|
||||
CStr::from_ptr((*event).data.sequence_start.tag as *const i8),
|
||||
);
|
||||
}
|
||||
let _ = writeln!(stdout);
|
||||
|
@ -139,14 +137,14 @@ pub(crate) unsafe fn unsafe_main(
|
|||
let _ = write!(
|
||||
stdout,
|
||||
" &{}",
|
||||
CStr::from_ptr((*event).data.scalar.anchor as *const i8).to_string_lossy(),
|
||||
CStr::from_ptr((*event).data.scalar.anchor as *const i8),
|
||||
);
|
||||
}
|
||||
if !((*event).data.scalar.tag).is_null() {
|
||||
let _ = write!(
|
||||
stdout,
|
||||
" <{}>",
|
||||
CStr::from_ptr((*event).data.scalar.tag as *const i8).to_string_lossy(),
|
||||
CStr::from_ptr((*event).data.scalar.tag as *const i8),
|
||||
);
|
||||
}
|
||||
match (*event).data.scalar.style as u32 {
|
||||
|
@ -180,7 +178,7 @@ pub(crate) unsafe fn unsafe_main(
|
|||
let _ = writeln!(
|
||||
stdout,
|
||||
"=ALI *{}",
|
||||
CStr::from_ptr((*event).data.alias.anchor as *const i8).to_string_lossy(),
|
||||
CStr::from_ptr((*event).data.alias.anchor as *const i8),
|
||||
);
|
||||
} else {
|
||||
process::abort();
|
||||
|
|
Loading…
Reference in a new issue