Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

neo4j_ustring_value() returns null pointer for empty strings #10

Open
johannessen opened this issue Oct 22, 2024 · 1 comment
Open

neo4j_ustring_value() returns null pointer for empty strings #10

johannessen opened this issue Oct 22, 2024 · 1 comment

Comments

@johannessen
Copy link
Collaborator

johannessen commented Oct 22, 2024

According to the documentation, neo4j_ustring_value() always returns a valid pointer for a string.

https://majensen.github.io/libneo4j-omni/neo4j-client-doxy.html#_CPPv419neo4j_ustring_value13neo4j_value_t

However, for zero-length strings, no memory is allocated for the ustring field upon deserialisation. As a consequence, neo4j_ustring_value() returns a null pointer.

char *ustring = NULL;
if (length > 0)
{
ustring = neo4j_mpool_alloc(pool, length);
if (ustring == NULL)
{
return -1;
}
if (neo4j_ios_read_all(stream, ustring, length, NULL) < 0)
{
return -1;
}
}
*value = neo4j_ustring(ustring, length);

johannessen added a commit to johannessen/perlbolt that referenced this issue Oct 22, 2024
When creating new Perl values through API functions like newSVpv() or hv_store(), const char* values are internally copied into memory that is managed by Perl itself. Manually allocating a buffer isn't necessary. Our neo4j_string_to_alloc_str() function does allocate a buffer and never frees it, causing a leak. neo4j_ustring_value() should be used instead.

However, neo4j_ustring_value() currently doesn't return a valid pointer for empty strings, so we need to special-case that. (majensen/libneo4j-omni#10)

When returning SVs from an XSUB, assigning them to a Perl variable will increment their ref count, which causes a leak unless the SV on the stack is mortal. If the SV* typemap is used, they become mortal automatically when they are returned. However, when instead pushing SVs onto the value stack manually, the SVs need to be mortalised manually as well.
@johannessen
Copy link
Collaborator Author

I was thinking maybe there should be a const char * const with the empty string. neo4j_ustring_value() could then simply return that pointer for a zero-length string. Checking the string length would have a slight overhead though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant