dtolnay / cxx

Safe interop between Rust and C++
https://cxx.rs
Apache License 2.0
5.68k stars 322 forks source link

panic when trying to build a string from a Windows call #1272

Closed leanmendoza closed 9 months ago

leanmendoza commented 9 months ago

Hey there, I'm getting the panic "data for rust::String is not utf-8" for a string built by Windows, in this particular case the string is mixed between English and Spanish: (stun_port.cc:608): UDP send of 20 bytes to host 168.75.70.x:3478 failed with error 0 : [0x00002743] Se ha intentado una operación de socket en una red no accesible.\n

I think the Spanish part of the message is provided by Windows, here is the memory representation when I caught the panic:

    let raw_bytes_memory: Vec<u8> = vec![
        28, 0x73, 0x74, 0x75, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x63, 0x3a, 0x36,
        0x30, 0x38, 0x29, 0x3a, 0x20, 0x55, 0x44, 0x50, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6f,
        0x66, 0x20, 0x32, 0x30, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x68,
        0x6f, 0x73, 0x74, 0x20, 0x31, 0x36, 0x38, 0x2e, 0x37, 0x35, 0x2e, 0x37, 0x30, 0x2e, 0x78,
        0x3a, 0x33, 0x34, 0x37, 0x38, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x77, 0x69,
        0x74, 0x68, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x30, 0x20, 0x3a, 0x20, 0x5b, 0x30,
        0x78, 0x30, 0x30, 0x30, 0x30, 0x32, 0x37, 0x34, 0x33, 0x5d, 0x20, 0x53, 0x65, 0x20, 0x68,
        0x61, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x61, 0x64, 0x6f, 0x20, 0x75, 0x6e, 0x61,
        0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x63, 0x69, 0xf3, 0x6e, 0x20, 0x64, 0x65, 0x20, 0x73,
        0x6f, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x65, 0x6e, 0x20, 0x75, 0x6e, 0x61, 0x20, 0x72, 0x65,
        0x64, 0x20, 0x6e, 0x6f, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2e,
        0x0a,
    ];

    println!("{:?}", std::str::from_utf8(raw_bytes_memory.as_slice()));

The original crash callstack:

KernelBase.dll!00007ff9a3de531c() (Unknown Source:0)
my_lib.dll!_CxxThrowException(void * pExceptionObject, const _s__ThrowInfo * pThrowInfo) Line 78 (d:\a\_work\1\s\src\vctools\crt\vcruntime\src\eh\throw.cpp:78)
my_lib.dll!rust::cxxbridge1::panic<std::invalid_argument>(const char * msg) Line 85 ($USER\.cargo\registry\src\index.crates.io-6f17d22bba15001f\cxx-1.0.107\src\cxx.cc:85)
my_lib.dll!rust::cxxbridge1::initString(rust::cxxbridge1::String * self, const char * s, unsigned __int64 len) Line 111 ($USER\.cargo\registry\src\index.crates.io-6f17d22bba15001f\cxx-1.0.107\src\cxx.cc:111)
my_lib.dll!rust::cxxbridge1::String::String(const std::string & s) Line 119 ($USER\.cargo\registry\src\index.crates.io-6f17d22bba15001f\cxx-1.0.107\src\cxx.cc:119)
my_lib.dll!livekit::LogSink::OnLogMessage(const std::string & message, rtc::LoggingSeverity severity) Line 164 ($USER\.cargo\git\checkouts\client-sdk-rust-361c57e9d86b28fa\6079dba\webrtc-sys\src\webrtc.cpp:164)
my_lib.dll!rtc::LogSink::OnLogMessage(class rtc::LogLineRef const &) (Unknown Source:0)
my_lib.dll!rtc::LogMessage::~LogMessage(void) (Unknown Source:0)
my_lib.dll!rtc::webrtc_logging_impl::Log(enum rtc::webrtc_logging_impl::LogArgType const *,...) (Unknown Source:0)
my_lib.dll!cricket::UDPPort::OnSendPacket(void const *,unsigned __int64,class cricket::StunRequest *) (Unknown Source:0)
my_lib.dll!std::_Func_class<void,void const *,unsigned __int64,class cricket::StunRequest *>::operator()(void const *,unsigned __int64,class cricket::StunRequest *) (Unknown Source:0)
my_lib.dll!cricket::StunRequest::SendInternal(void) (Unknown Source:0)
my_lib.dll!cricket::StunRequestManager::SendDelayed(class cricket::StunRequest *,int) (Unknown Source:0)
my_lib.dll!cricket::UDPPort::SendStunBindingRequests(void) (Unknown Source:0)
my_lib.dll!cricket::UDPPort::OnLocalAddressReady(class rtc::AsyncPacketSocket *,class rtc::SocketAddress const &) (Unknown Source:0)
my_lib.dll!cricket::UDPPort::PrepareAddress(void) (Unknown Source:0)
my_lib.dll!cricket::BasicPortAllocatorSession::AddAllocatedPort(class cricket::Port *,class cricket::AllocationSequence *) (Unknown Source:0)
my_lib.dll!cricket::AllocationSequence::CreateUDPPorts(void) (Unknown Source:0)
my_lib.dll!cricket::AllocationSequence::Process(int) (Unknown Source:0)
my_lib.dll!rtc::Thread::Dispatch(class absl::AnyInvocable<void >) (Unknown Source:0)

I'm submitting this issue to livekit as well.

dtolnay commented 9 months ago

As far as I can tell, cxx is behaving correctly here. Those bytes are indeed not utf-8. If you want to construct a Rust String from C++ std::string, you'll need to ensure that the contents are utf-8.