Skip to content

Commit

Permalink
Pass length constrained mrb string to osc-bridge
Browse files Browse the repository at this point in the history
When views are created on mruby strings it's possible that the string
pointer points to a longer string than is visible at the ruby level.
In other words strlen(s.pointer) >= s.length. By copying a string we
avoid this edge case.

In the UI this created a bug where it was impossible to delete
characters from a long string.
In ruby you'd start with a string like "foobar"\0(len 6), delete a
character off the end via creating a string view which at the ruby
level was "fooba", but under the hood it was represented via
"fooba"r\0(len 5).
This specific behavior only occurs for non-embeddable strings which in
mruby's case is about roughly 27 characters (compilation flag
dependent).
  • Loading branch information
fundamental committed May 1, 2023
1 parent bbac205 commit a581036
Showing 1 changed file with 16 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/mruby-widget-lib/src/gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,20 @@ mrb_remote_param_set_value_ar(mrb_state *mrb, mrb_value self)
return self;
}

static char *
mrb_copy_str(mrb_state *mrb, mrb_value value)
{
size_t l = mrb_string_value_len(mrb, value);
const char *s = mrb_string_value_ptr(mrb, value);
char *out = malloc(l+1);

for(int i=0; i<l; ++i)
out[i] = s[i];

This comment has been minimized.

Copy link
@pgervais

pgervais May 2, 2023

Contributor

Just out of curiosity: what's the reason for avoiding memcpy here?

This comment has been minimized.

Copy link
@fundamental

fundamental May 2, 2023

Author Member

I guess I've been doing too much coding outside of C :p


out[l] = 0;
return out;
}

static mrb_value
mrb_remote_param_set_value_str(mrb_state *mrb, mrb_value self)
{
Expand All @@ -1148,8 +1162,9 @@ mrb_remote_param_set_value_str(mrb_state *mrb, mrb_value self)
mrb_assert(param->br);
mrb_assert(param->uri);

const char *str = mrb_string_value_ptr(mrb, value);
const char *str = mrb_copy_str(mrb, value);
br_set_value_string(param->br, param->uri, str);
free(str);
return self;
}

Expand Down

0 comments on commit a581036

Please sign in to comment.