struct.pack does not allow string as pack parameter

This commit is contained in:
Aviv Palivoda
2019-10-20 10:13:40 +03:00
parent 89566ee07b
commit d0184a7ac2
4 changed files with 67 additions and 132 deletions

23
Cargo.lock generated
View File

@@ -864,6 +864,26 @@ name = "ordermap"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "paste"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "paste-impl"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "petgraph"
version = "0.4.13"
@@ -1302,6 +1322,7 @@ dependencies = [
"num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"pwd 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2224,6 +2245,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49"
"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"

View File

@@ -38,3 +38,6 @@ with assert_raises(Exception):
data = struct.pack('B2B', 65, 66)
data = struct.pack('B1B', 65, 66)
with assert_raises(Exception):
struct.pack('<IH', "14", 12)

View File

@@ -65,6 +65,7 @@ nix = "0.15.0"
wtf8 = "0.0.3"
arr_macro = "0.1.2"
csv = "1.1.1"
paste = "0.1"
flame = { version = "0.2", optional = true }
flamer = { version = "0.3", optional = true }

View File

@@ -13,12 +13,10 @@ use std::io::{Cursor, Read, Write};
use std::iter::Peekable;
use byteorder::{ReadBytesExt, WriteBytesExt};
use num_bigint::BigInt;
use num_traits::ToPrimitive;
use crate::function::PyFuncArgs;
use crate::obj::{objbool, objbytes, objfloat, objint, objstr, objtype};
use crate::pyobject::{PyObjectRef, PyResult};
use crate::obj::{objbytes, objstr, objtype};
use crate::pyobject::{PyObjectRef, PyResult, TryFromObject};
use crate::VirtualMachine;
#[derive(Debug)]
@@ -130,144 +128,54 @@ fn is_supported_format_character(c: char) -> bool {
}
}
fn get_int(vm: &VirtualMachine, arg: &PyObjectRef) -> PyResult<BigInt> {
objint::to_int(vm, arg, &BigInt::from(10))
macro_rules! make_pack_no_endianess {
($T:ty) => {
paste::item! {
fn [<pack_ $T>](vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()> {
let v = $T::try_from_object(vm, arg.clone())?;
data.[<write_$T>](v).unwrap();
Ok(())
}
}
};
}
fn pack_i8(vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()> {
let v = get_int(vm, arg)?.to_i8().unwrap();
data.write_i8(v).unwrap();
Ok(())
macro_rules! make_pack_with_endianess {
($T:ty) => {
paste::item! {
fn [<pack_ $T>]<Endianness>(vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()>
where
Endianness: byteorder::ByteOrder,
{
let v = $T::try_from_object(vm, arg.clone())?;
data.[<write_$T>]::<Endianness>(v).unwrap();
Ok(())
}
}
};
}
fn pack_u8(vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()> {
let v = get_int(vm, arg)?.to_u8().unwrap();
data.write_u8(v).unwrap();
Ok(())
}
make_pack_no_endianess!(i8);
make_pack_no_endianess!(u8);
make_pack_with_endianess!(i16);
make_pack_with_endianess!(u16);
make_pack_with_endianess!(i32);
make_pack_with_endianess!(u32);
make_pack_with_endianess!(i64);
make_pack_with_endianess!(u64);
make_pack_with_endianess!(f32);
make_pack_with_endianess!(f64);
fn pack_bool(vm: &VirtualMachine, arg: &PyObjectRef, data: &mut dyn Write) -> PyResult<()> {
if objtype::isinstance(&arg, &vm.ctx.bool_type()) {
let v = if objbool::get_value(arg) { 1 } else { 0 };
data.write_u8(v).unwrap();
Ok(())
let v = if bool::try_from_object(vm, arg.clone())? {
1
} else {
Err(vm.new_type_error("Expected boolean".to_string()))
}
}
fn pack_i16<Endianness>(
vm: &VirtualMachine,
arg: &PyObjectRef,
data: &mut dyn Write,
) -> PyResult<()>
where
Endianness: byteorder::ByteOrder,
{
let v = get_int(vm, arg)?.to_i16().unwrap();
data.write_i16::<Endianness>(v).unwrap();
0
};
data.write_u8(v).unwrap();
Ok(())
}
fn pack_u16<Endianness>(
vm: &VirtualMachine,
arg: &PyObjectRef,
data: &mut dyn Write,
) -> PyResult<()>
where
Endianness: byteorder::ByteOrder,
{
let v = get_int(vm, arg)?.to_u16().unwrap();
data.write_u16::<Endianness>(v).unwrap();
Ok(())
}
fn pack_i32<Endianness>(
vm: &VirtualMachine,
arg: &PyObjectRef,
data: &mut dyn Write,
) -> PyResult<()>
where
Endianness: byteorder::ByteOrder,
{
let v = get_int(vm, arg)?.to_i32().unwrap();
data.write_i32::<Endianness>(v).unwrap();
Ok(())
}
fn pack_u32<Endianness>(
vm: &VirtualMachine,
arg: &PyObjectRef,
data: &mut dyn Write,
) -> PyResult<()>
where
Endianness: byteorder::ByteOrder,
{
let v = get_int(vm, arg)?.to_u32().unwrap();
data.write_u32::<Endianness>(v).unwrap();
Ok(())
}
fn pack_i64<Endianness>(
vm: &VirtualMachine,
arg: &PyObjectRef,
data: &mut dyn Write,
) -> PyResult<()>
where
Endianness: byteorder::ByteOrder,
{
let v = get_int(vm, arg)?.to_i64().unwrap();
data.write_i64::<Endianness>(v).unwrap();
Ok(())
}
fn pack_u64<Endianness>(
vm: &VirtualMachine,
arg: &PyObjectRef,
data: &mut dyn Write,
) -> PyResult<()>
where
Endianness: byteorder::ByteOrder,
{
let v = get_int(vm, arg)?.to_u64().unwrap();
data.write_u64::<Endianness>(v).unwrap();
Ok(())
}
fn pack_f32<Endianness>(
vm: &VirtualMachine,
arg: &PyObjectRef,
data: &mut dyn Write,
) -> PyResult<()>
where
Endianness: byteorder::ByteOrder,
{
let v = get_float(vm, arg)? as f32;
data.write_f32::<Endianness>(v).unwrap();
Ok(())
}
fn pack_f64<Endianness>(
vm: &VirtualMachine,
arg: &PyObjectRef,
data: &mut dyn Write,
) -> PyResult<()>
where
Endianness: byteorder::ByteOrder,
{
let v = get_float(vm, arg)?;
data.write_f64::<Endianness>(v).unwrap();
Ok(())
}
fn get_float(vm: &VirtualMachine, arg: &PyObjectRef) -> PyResult<f64> {
if objtype::isinstance(&arg, &vm.ctx.float_type()) {
Ok(objfloat::get_value(arg))
} else {
Err(vm.new_type_error("Expected float".to_string()))
}
}
fn pack_item<Endianness>(
vm: &VirtualMachine,
code: &FormatCode,