Skip to content

Instantly share code, notes, and snippets.

@XrXr

XrXr/demo.c Secret

Last active October 22, 2019 19:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XrXr/d7a07623330c244cb3b13bcae5f9530e to your computer and use it in GitHub Desktop.
Save XrXr/d7a07623330c244cb3b13bcae5f9530e to your computer and use it in GitHub Desktop.
TruffleRuby's RSTRING_PTR does not return a pointer that behaves the way one would expect, breaking existing gems such as Google's protobuf.
#include <stdint.h>
#include <stddef.h>
#include <ruby.h>
#include <stdlib.h>
#include <string.h>
static VALUE
read_four_bytes(VALUE _self, VALUE str)
{
Check_Type(str, T_STRING);
const char *content = RSTRING_PTR(str);
const long len = RSTRING_LEN(str);
if (((size_t) len) < sizeof(uint32_t) * 2) rb_raise(rb_eArgError, "string too short");
content += ((uintptr_t) content) % sizeof(uint32_t); // align the pointer
uint32_t *asuint = (uint32_t *) content;
return UINT2NUM(*asuint);
}
void
Init_demo(void)
{
rb_define_global_function("read_four_bytes", read_four_bytes, 1);
}
require 'mkmf'
create_makefile('demo')
bash-4.4$ ruby -v mkmf.rb && make && ruby -v run_demo.rb
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]
creating Makefile
linking shared-object demo.bundle
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]
1735356263
1633771873
---------------------------------------------------------------------
bash-4.4$ ruby -v mkmf.rb && make && ruby -v run_demo.rb
truffleruby 19.1.1, like ruby 2.6.2, GraalVM CE Native [x86_64-darwin]
creating Makefile
compiling demo.c
linking shared-object demo.su
truffleruby 19.1.1, like ruby 2.6.2, GraalVM CE Native [x86_64-darwin]
103
97
require_relative('demo')
p read_four_bytes("google.protobuf.Duration")
p read_four_bytes("aaaaaaaaaa")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment