Skip to content

Commit

Permalink
Handle NUL on import
Browse files Browse the repository at this point in the history
  • Loading branch information
yugui committed Sep 1, 2024
1 parent e26ca9b commit 41c9505
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 4 deletions.
6 changes: 2 additions & 4 deletions ext/jsonnet/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ import_callback_entrypoint(void *ctx, const char *base, const char *rel, char **
if (state) {
VALUE msg = rescue_callback(state, "cannot import %s from %s", rel, base);
#ifdef HAVE_JSONNET_IMPORT_CALLBACK_0_19
*buf = rubyjsonnet_str_to_cstr(vm->vm, msg);
*buflen = RSTRING_LEN(msg);
*buf = rubyjsonnet_str_to_ptr(vm->vm, msg, buflen);
return 1;
#else
*success = 0;
Expand All @@ -142,8 +141,7 @@ import_callback_entrypoint(void *ctx, const char *base, const char *rel, char **
result = rb_Array(result);
*found_here = rubyjsonnet_str_to_cstr(vm->vm, rb_ary_entry(result, 1));
#ifdef HAVE_JSONNET_IMPORT_CALLBACK_0_19
*buf = rubyjsonnet_str_to_cstr(vm->vm, rb_ary_entry(result, 0));
*buflen = RSTRING_LEN(rb_ary_entry(result, 0));
*buf = rubyjsonnet_str_to_ptr(vm->vm, rb_ary_entry(result, 0), buflen);
return 0;
#else
*success = 1;
Expand Down
26 changes: 26 additions & 0 deletions ext/jsonnet/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ rubyjsonnet_assert_asciicompat(VALUE str)

/**
* Allocates a C string whose content is equal to \c str with jsonnet_realloc.
*
* Note that this function does not allow NUL characters in the string.
* You should use rubyjsonnet_str_to_ptr() if you want to handle NUL characters.
*
* @param[in] vm a Jsonnet VM
* @param[in] str a String-like object
* @return the allocated C string
*/
char *
rubyjsonnet_str_to_cstr(struct JsonnetVm *vm, VALUE str)
Expand All @@ -44,6 +51,25 @@ rubyjsonnet_str_to_cstr(struct JsonnetVm *vm, VALUE str)
return buf;
}

/**
* Allocates a byte sequence whose content is equal to \c str with jsonnet_realloc.
*
* @param[in] vm a Jsonnet VM
* @param[in] str a String-like object
* @param[out] buflen the length of the allocated buffer
* @return the allocated buffer
*/
char *
rubyjsonnet_str_to_ptr(struct JsonnetVm *vm, VALUE str, size_t *buflen)
{
StringValue(str);
size_t len = RSTRING_LEN(str);
char *buf = jsonnet_realloc(vm, NULL, len);
memcpy(buf, RSTRING_PTR(str), len);
*buflen = len;
return buf;
}

/**
* @return a human readable string which contains the class name of the
* exception and its message. It might be nil on failure
Expand Down
1 change: 1 addition & 0 deletions ext/jsonnet/ruby_jsonnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct JsonnetJsonValue *rubyjsonnet_obj_to_json(struct JsonnetVm *vm, VALUE obj

rb_encoding *rubyjsonnet_assert_asciicompat(VALUE str);
char *rubyjsonnet_str_to_cstr(struct JsonnetVm *vm, VALUE str);
char *rubyjsonnet_str_to_ptr(struct JsonnetVm *vm, VALUE str, size_t *buflen);
VALUE rubyjsonnet_format_exception(VALUE exc);
int rubyjsonnet_jump_tag(const char *exc_mesg);

Expand Down
20 changes: 20 additions & 0 deletions test/test_vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,26 @@ class TestVM < Test::Unit::TestCase
assert_equal expected, JSON.parse(result)
end

test "Jsonnet::VM#import_callback allows NUL char in Jsonnet v0.19 or later" do
return unless Jsonnet.libversion >= "v0.19"

example_str = "\x0\x1".force_encoding(Encoding::BINARY)

vm = Jsonnet::VM.new
vm.import_callback = ->(base, rel) {
case [base, rel]
when ['/path/to/base/', 'foo.bin']
return "\x0\x1".force_encoding(Encoding::BINARY), '/path/to/base/foo.bin'
else
raise Errno::ENOENT, "#{rel} at #{base}"
end
}
result = vm.evaluate(<<-EOS, filename: "/path/to/base/example.jsonnet")
importbin "foo.bin"
EOS
assert_equal [0, 1], JSON.parse(result)
end

test "Jsonnet::VM#evaluate returns an error if customized import callback raises an exception" do
vm = Jsonnet::VM.new
called = false
Expand Down

0 comments on commit 41c9505

Please sign in to comment.