mirror of
https://github.com/napi-rs/napi-rs.git
synced 2025-12-08 19:56:07 +00:00
fix(napi): JsStringUtf8 memory leak (#2911)
This commit is contained in:
parent
e633c472e7
commit
3894db5e42
@ -109,13 +109,11 @@ impl<'env> JsString<'env> {
|
||||
)
|
||||
})?;
|
||||
|
||||
// respect '\0' with js string, for example: `let hello = [a,'\0',b,'\0',c].join('')`
|
||||
let mut result = mem::ManuallyDrop::new(result);
|
||||
let buf_ptr = result.as_mut_ptr();
|
||||
let bytes = unsafe { std::slice::from_raw_parts(buf_ptr.cast(), written_char_count) };
|
||||
mem::forget(result);
|
||||
|
||||
Ok(JsStringUtf8 {
|
||||
inner: self,
|
||||
buf: bytes,
|
||||
buf: unsafe { Vec::from_raw_parts(buf_ptr.cast(), written_char_count, written_char_count) },
|
||||
})
|
||||
}
|
||||
|
||||
@ -161,7 +159,9 @@ impl<'env> JsString<'env> {
|
||||
Ok(JsStringLatin1 {
|
||||
inner: self,
|
||||
buf: unsafe { std::slice::from_raw_parts(buf_ptr.cast(), written_char_count) },
|
||||
_inner_buf: vec![],
|
||||
_inner_buf: unsafe {
|
||||
Vec::from_raw_parts(buf_ptr.cast(), written_char_count, written_char_count)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +1,21 @@
|
||||
use std::convert::TryFrom;
|
||||
use std::str;
|
||||
|
||||
use crate::{bindgen_prelude::ToNapiValue, sys, Error, JsString, Result};
|
||||
use crate::{bindgen_prelude::ToNapiValue, sys, Error, JsString, Result, Status};
|
||||
|
||||
pub struct JsStringUtf8<'env> {
|
||||
pub(crate) inner: JsString<'env>,
|
||||
pub(crate) buf: &'env [u8],
|
||||
pub(crate) buf: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'env> JsStringUtf8<'env> {
|
||||
pub fn as_str(&self) -> Result<&str> {
|
||||
Ok(unsafe { str::from_utf8_unchecked(self.buf) })
|
||||
str::from_utf8(self.buf.as_slice())
|
||||
.map_err(|err| Error::new(Status::InvalidArg, err.to_string()))
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
self.buf
|
||||
self.buf.as_slice()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
|
||||
@ -832,6 +832,8 @@ Generated by [AVA](https://avajs.dev).
|
||||
␊
|
||||
export declare function indexSetToRust(set: Set<string>): void␊
|
||||
␊
|
||||
export declare function intoUtf8(s: string): string␊
|
||||
␊
|
||||
export declare function jsErrorCallback(value: unknown): Array<Error>␊
|
||||
␊
|
||||
/** default enum values are continuos i32s start from 0 */␊
|
||||
|
||||
Binary file not shown.
@ -286,6 +286,7 @@ import {
|
||||
arrayParams,
|
||||
indexSetToRust,
|
||||
indexSetToJs,
|
||||
intoUtf8,
|
||||
} from '../index.cjs'
|
||||
// import other stuff in `#[napi(module_exports)]`
|
||||
import nativeAddon from '../index.cjs'
|
||||
@ -337,6 +338,7 @@ test('string', (t) => {
|
||||
t.is(createExternalLatin1String(), 'External Latin1')
|
||||
t.is(createStaticLatin1String(), 'Static Latin1 string')
|
||||
t.is(createStaticUtf16String(), 'Static UTF16')
|
||||
t.is(intoUtf8('Hello'), 'Hello')
|
||||
})
|
||||
|
||||
test('JsStringLatin1::from_external tests', (t) => {
|
||||
|
||||
@ -283,6 +283,7 @@ export const i8ArrayToArray = __napiModule.exports.i8ArrayToArray
|
||||
export const indexmapPassthrough = __napiModule.exports.indexmapPassthrough
|
||||
export const indexSetToJs = __napiModule.exports.indexSetToJs
|
||||
export const indexSetToRust = __napiModule.exports.indexSetToRust
|
||||
export const intoUtf8 = __napiModule.exports.intoUtf8
|
||||
export const jsErrorCallback = __napiModule.exports.jsErrorCallback
|
||||
export const Kind = __napiModule.exports.Kind
|
||||
export const KindInValidate = __napiModule.exports.KindInValidate
|
||||
|
||||
@ -328,6 +328,7 @@ module.exports.i8ArrayToArray = __napiModule.exports.i8ArrayToArray
|
||||
module.exports.indexmapPassthrough = __napiModule.exports.indexmapPassthrough
|
||||
module.exports.indexSetToJs = __napiModule.exports.indexSetToJs
|
||||
module.exports.indexSetToRust = __napiModule.exports.indexSetToRust
|
||||
module.exports.intoUtf8 = __napiModule.exports.intoUtf8
|
||||
module.exports.jsErrorCallback = __napiModule.exports.jsErrorCallback
|
||||
module.exports.Kind = __napiModule.exports.Kind
|
||||
module.exports.KindInValidate = __napiModule.exports.KindInValidate
|
||||
|
||||
@ -728,6 +728,7 @@ module.exports.i8ArrayToArray = nativeBinding.i8ArrayToArray
|
||||
module.exports.indexmapPassthrough = nativeBinding.indexmapPassthrough
|
||||
module.exports.indexSetToJs = nativeBinding.indexSetToJs
|
||||
module.exports.indexSetToRust = nativeBinding.indexSetToRust
|
||||
module.exports.intoUtf8 = nativeBinding.intoUtf8
|
||||
module.exports.jsErrorCallback = nativeBinding.jsErrorCallback
|
||||
module.exports.Kind = nativeBinding.Kind
|
||||
module.exports.KindInValidate = nativeBinding.KindInValidate
|
||||
|
||||
@ -793,6 +793,8 @@ export declare function indexSetToJs(): Set<string>
|
||||
|
||||
export declare function indexSetToRust(set: Set<string>): void
|
||||
|
||||
export declare function intoUtf8(s: string): string
|
||||
|
||||
export declare function jsErrorCallback(value: unknown): Array<Error>
|
||||
|
||||
/** default enum values are continuos i32s start from 0 */
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use napi::{bindgen_prelude::*, JsString, JsStringLatin1, JsStringUtf16};
|
||||
use napi::{bindgen_prelude::*, JsString, JsStringLatin1, JsStringUtf16, JsStringUtf8};
|
||||
|
||||
#[napi(object)]
|
||||
pub struct Latin1MethodsResult {
|
||||
@ -40,6 +40,11 @@ pub fn return_c_string() -> RawCString {
|
||||
RawCString::new(mock_c_string_ptr, NAPI_AUTO_LENGTH)
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn into_utf8(s: JsString) -> Result<JsStringUtf8> {
|
||||
s.into_utf8()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
/// Function to test escaped quotes in comments.
|
||||
/// This comment contains escaped quotes: \\"g+sx\\" and should not break JSON parsing.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user