Skip to main content

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}