luaur_ast/methods/parser_copy_parser_alt_d.rs
1use crate::records::ast_array::AstArray;
2use crate::records::parser::Parser;
3use alloc::string::String;
4
5impl Parser {
6 pub fn copy_string(&mut self, data: &String) -> AstArray<core::ffi::c_char> {
7 // C++ `copy(data.c_str(), data.size() + 1)` reads size()+1 bytes because
8 // std::string::c_str() is NUL-terminated with a readable size()+1 buffer.
9 // Rust's `String` is NOT NUL-terminated and `String::as_ptr()` is a dangling
10 // pointer when the string is empty, so copying `len()+1` bytes from the source
11 // over-reads it (a guaranteed SIGSEGV on empty content, UB otherwise). Allocate
12 // len+1, copy the `len` content bytes, and write the trailing NUL ourselves so
13 // the result keeps c_str() semantics (NUL-terminated, logical size = len).
14 let len = data.len();
15 let mut result: AstArray<core::ffi::c_char> = AstArray {
16 data: core::ptr::null_mut(),
17 size: len,
18 };
19
20 unsafe {
21 let storage =
22 crate::records::allocator::Allocator::allocate(&mut *self.allocator, len + 1)
23 as *mut core::ffi::c_char;
24
25 if len > 0 {
26 core::ptr::copy_nonoverlapping(
27 data.as_ptr() as *const core::ffi::c_char,
28 storage,
29 len,
30 );
31 }
32 *storage.add(len) = 0;
33
34 result.data = storage;
35 }
36
37 result
38 }
39}