Joylei / eip-rs

rseip - EIP&CIP client in pure Rust, for generic CIP and AB PLC
MIT License
49 stars 6 forks source link

Undefined Behavior with StreamExt::collect #17

Closed kalkronline closed 1 year ago

kalkronline commented 1 year ago

The following snippet produces undefined behavior.

use std::io;
use rseip::precludes::{AbEipClient, PortSegment, AbService};
use futures::stream::StreamExt;

async fn init() -> io::Result<()> {
    let mut client = AbEipClient::new_host_lookup("10.0.10.70")
        .await
        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
        .with_connection_path(PortSegment::default());

    let tags = client
        .list_tag()
        .call()
        .collect::<Vec<_>>()
        .await
        .into_iter()
        .collect::<Result<Vec<_>, _>>()
        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;

    for tag in tags {
        println!("{tag:?}")
    }
}

Output:

SymbolInstance { id: 0x01, name: "��\0\0\u{c}\0M", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x69 } }
SymbolInstance { id: 0x02, name: "Rev��\0\0\u{c}\0", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0xc4 } }
SymbolInstance { id: 0x03, name: "_Ava��\0\0\u{c}\0M", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x70 } }
SymbolInstance { id: 0x04, name: "Ret�\u{742}\0\0\u{8}\0Man", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x68 } }
SymbolInstance { id: 0x05, name: "\u{2}\0\0\u{c}\0Man_M6_C_Rev��\0\0", symbol_type: SymbolType { type: "struct", dims: 0, instance_id: 0xf83 } }
SymbolInstance { id: 0x06, name: "_C�\u{80}\0\u{c}\0Ma", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0xc4 } }
SymbolInstance { id: 0x07, name: "ev��", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0xc4 } }
SymbolInstance { id: 0x08, name: "8_C_Rev��\0\u{f}\0Man_Palet_OK_L", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0xc4 } }
SymbolInstance { id: 0x09, name: "\0Man_Retroce", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x69 } }
SymbolInstance { id: 0x0a, name: "\0�\0\u{8}\0Marcha_C��\0", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x7e } }
SymbolInstance { id: 0x0b, name: "cuadra_Pla", symbol_type: SymbolType { type: "struct", dims: 0, instance_id: 0xdba } }
SymbolInstance { id: 0x0c, name: "\0\0\u{13}\0Mem_Fi", symbol_type: SymbolType { type: "struct", dims: 0, instance_id: 0xb24 } }
SymbolInstance { id: 0x0d, name: "eta_C��\0\u{f}\0Me", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x69 } }
SymbolInstance { id: 0x0e, name: "OK_L9��\0\u{14}\0Mem_Laye", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x7e } }
SymbolInstance { id: 0x0f, name: "te_C��\0\u{13}\0M", symbol_type: SymbolType { type: "struct", dims: 0, instance_id: 0xb9d } }
thread 'main' panicked at 'byte index 15 is out of bounds of `_Encoder_C��`', library/core/src/fmt/mod.rs:2472:30
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Joylei commented 1 year ago

list_tag() or other methods would keep references to underline bytes.

It's better to iterate the result immediately or convert it to your own data structure.