mirror of
git://git.proxmox.com/git/perlmod.git
synced 2025-03-13 04:58:16 +03:00
make SvPVbyte safe
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
ccde914a4c
commit
83147b1189
@ -81,7 +81,7 @@ impl Deserializer {
|
||||
use crate::scalar::Flags;
|
||||
|
||||
if flags.contains(Flags::STRING) {
|
||||
visitor.visit_str(value.pv_utf8())
|
||||
visitor.visit_str(value.pv_string_utf8())
|
||||
} else if flags.contains(Flags::DOUBLE) {
|
||||
visitor.visit_f64(value.nv())
|
||||
} else if flags.contains(Flags::INTEGER) {
|
||||
@ -113,7 +113,7 @@ impl Deserializer {
|
||||
} else if flags.contains(Flags::DOUBLE) {
|
||||
visitor.visit_f64(value.nv())
|
||||
} else if flags.contains(Flags::STRING) {
|
||||
visitor.visit_str(value.pv_utf8())
|
||||
visitor.visit_str(value.pv_string_utf8())
|
||||
} else {
|
||||
visitor.visit_unit()
|
||||
}
|
||||
@ -141,7 +141,7 @@ impl Deserializer {
|
||||
} else if flags.contains(Flags::INTEGER) {
|
||||
visitor.visit_i64(value.iv() as i64)
|
||||
} else if flags.contains(Flags::STRING) {
|
||||
visitor.visit_str(value.pv_utf8())
|
||||
visitor.visit_str(value.pv_string_utf8())
|
||||
} else {
|
||||
visitor.visit_unit()
|
||||
}
|
||||
@ -277,11 +277,11 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
|
||||
} else if flags.contains(Flags::DOUBLE) {
|
||||
visitor.visit_f64(value.nv())
|
||||
} else if flags.contains(Flags::STRING) {
|
||||
let s = value.pv_utf8();
|
||||
let s = value.pv_string_utf8();
|
||||
let mut chars = s.chars();
|
||||
match chars.next() {
|
||||
Some(ch) if chars.next().is_none() => visitor.visit_char(ch),
|
||||
_ => visitor.visit_str(value.pv_utf8()),
|
||||
_ => visitor.visit_str(value.pv_string_utf8()),
|
||||
}
|
||||
} else {
|
||||
visitor.visit_unit()
|
||||
|
@ -45,6 +45,7 @@ extern "C" {
|
||||
pub fn RSPL_SvIV(sv: *mut SV) -> isize;
|
||||
pub fn RSPL_SvPVutf8(sv: *mut SV, len: *mut libc::size_t) -> *const libc::c_char;
|
||||
pub fn RSPL_SvPV(sv: *mut SV, len: *mut libc::size_t) -> *const libc::c_char;
|
||||
/// This calls `sv_utf8_downgrade` first to avoid croaking, instead returns `NULL` on error.
|
||||
pub fn RSPL_SvPVbyte(sv: *mut SV, len: *mut libc::size_t) -> *const libc::c_char;
|
||||
pub fn RSPL_sv_2mortal(sv: *mut SV) -> *mut SV;
|
||||
pub fn RSPL_get_undef() -> *mut SV;
|
||||
|
@ -55,8 +55,11 @@ extern const char* RSPL_SvPV(SV *sv, size_t *out_len) {
|
||||
return out;
|
||||
}
|
||||
|
||||
/// SvPVbyte with a downgrade check to avoid croaking!
|
||||
extern const char* RSPL_SvPVbyte(SV *sv, size_t *out_len) {
|
||||
size_t length;
|
||||
if (!sv_utf8_downgrade(sv, true))
|
||||
return NULL;
|
||||
const char *out = SvPVbyte(sv, length);
|
||||
*out_len = length;
|
||||
return out;
|
||||
|
@ -229,7 +229,7 @@ impl ScalarRef {
|
||||
}
|
||||
|
||||
/// Coerce to an utf8 string value. (perlxs `SvPVutf8`)
|
||||
pub fn pv_utf8(&self) -> &str {
|
||||
pub fn pv_string_utf8(&self) -> &str {
|
||||
unsafe {
|
||||
let mut len: libc::size_t = 0;
|
||||
let ptr = ffi::RSPL_SvPVutf8(self.sv(), &mut len) as *const u8;
|
||||
@ -238,7 +238,7 @@ impl ScalarRef {
|
||||
}
|
||||
|
||||
/// Coerce to a string without utf8 encoding. (perlxs `SvPV`)
|
||||
pub fn pv_string_bytes(&self) -> &[u8] {
|
||||
pub fn pv_bytes(&self) -> &[u8] {
|
||||
unsafe {
|
||||
let mut len: libc::size_t = 0;
|
||||
let ptr = ffi::RSPL_SvPV(self.sv(), &mut len) as *const u8;
|
||||
@ -246,12 +246,18 @@ impl ScalarRef {
|
||||
}
|
||||
}
|
||||
|
||||
/// Coerce to a byte-string. (perlxs `SvPVbyte`)
|
||||
pub fn pv_bytes(&self) -> &[u8] {
|
||||
/// Coerce to a byte-string, downgrading from utf-8. (perlxs `SvPVbyte`)
|
||||
///
|
||||
/// May fail if there are values which don't fit into bytes in the contained utf-8 string, in
|
||||
/// which case `None` is returned.
|
||||
pub fn pv_utf8_to_bytes(&self) -> Option<&[u8]> {
|
||||
unsafe {
|
||||
let mut len: libc::size_t = 0;
|
||||
let ptr = ffi::RSPL_SvPVbyte(self.sv(), &mut len) as *const u8;
|
||||
std::slice::from_raw_parts(ptr, len)
|
||||
if ptr.is_null() {
|
||||
return None;
|
||||
}
|
||||
Some(std::slice::from_raw_parts(ptr, len))
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,7 +320,7 @@ impl std::fmt::Debug for ScalarRef {
|
||||
match self.ty() {
|
||||
Type::Scalar(flags) => {
|
||||
if flags.intersects(Flags::STRING) {
|
||||
Debug::fmt(self.pv_utf8(), f)
|
||||
Debug::fmt(self.pv_string_utf8(), f)
|
||||
} else if flags.intersects(Flags::INTEGER) {
|
||||
write!(f, "{}", self.iv())
|
||||
} else if flags.intersects(Flags::DOUBLE) {
|
||||
@ -341,7 +347,7 @@ impl serde::Serialize for Scalar {
|
||||
match self.ty() {
|
||||
Type::Scalar(flags) => {
|
||||
if flags.contains(Flags::STRING) {
|
||||
serializer.serialize_str(self.pv_utf8())
|
||||
serializer.serialize_str(self.pv_string_utf8())
|
||||
} else if flags.contains(Flags::DOUBLE) {
|
||||
serializer.serialize_f64(self.nv())
|
||||
} else if flags.contains(Flags::INTEGER) {
|
||||
|
@ -137,7 +137,7 @@ impl Value {
|
||||
if stash.is_null() {
|
||||
return Err(Error(format!(
|
||||
"failed to find package {:?}",
|
||||
pkgsv.pv_utf8()
|
||||
pkgsv.pv_string_utf8()
|
||||
)));
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ impl Value {
|
||||
if value.is_null() {
|
||||
return Err(Error(format!(
|
||||
"failed to bless value into package {:?}",
|
||||
pkgsv.pv_utf8()
|
||||
pkgsv.pv_string_utf8()
|
||||
)));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user