Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mruby
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
mruby
Commits
a384bcce
Unverified
Commit
a384bcce
authored
8 years ago
by
Francois Chagnon
Committed by
Bouke van der Bijl
8 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix instances where return value of mrb_method_search_vm is unchecked
Reported by @charliesome
parent
a630c4f4
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
68 additions
and
10 deletions
+68
-10
src/vm.c
src/vm.c
+37
-10
test/t/nomethoderror.rb
test/t/nomethoderror.rb
+31
-0
No files found.
src/vm.c
View file @
a384bcce
...
...
@@ -54,6 +54,10 @@ The value below allows about 60000 recursive calls in the simplest case. */
#define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai)
#define CALL_MAXARGS 127
void
mrb_method_missing
(
mrb_state
*
mrb
,
mrb_sym
name
,
mrb_value
self
,
mrb_value
args
);
static
inline
void
stack_clear
(
mrb_value
*
from
,
size_t
count
)
{
...
...
@@ -362,9 +366,13 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
c
=
mrb_class
(
mrb
,
self
);
p
=
mrb_method_search_vm
(
mrb
,
&
c
,
mid
);
if
(
!
p
)
{
mrb_sym
missing
=
mrb_intern_lit
(
mrb
,
"method_missing"
);
p
=
mrb_method_search_vm
(
mrb
,
&
c
,
missing
);
if
(
!
p
)
{
mrb_value
args
=
mrb_ary_new_from_values
(
mrb
,
argc
,
argv
);
mrb_method_missing
(
mrb
,
mid
,
self
,
args
);
}
undef
=
mid
;
mid
=
mrb_intern_lit
(
mrb
,
"method_missing"
);
p
=
mrb_method_search_vm
(
mrb
,
&
c
,
mid
);
n
++
;
argc
++
;
}
ci
=
cipush
(
mrb
);
...
...
@@ -749,10 +757,6 @@ argnum_error(mrb_state *mrb, mrb_int num)
#endif
#define CALL_MAXARGS 127
void
mrb_method_missing
(
mrb_state
*
mrb
,
mrb_sym
name
,
mrb_value
self
,
mrb_value
args
);
MRB_API
mrb_value
mrb_vm_run
(
mrb_state
*
mrb
,
struct
RProc
*
proc
,
mrb_value
self
,
unsigned
int
stack_keep
)
{
...
...
@@ -1290,8 +1294,20 @@ RETRY_TRY_BLOCK:
c
=
mrb
->
c
->
ci
->
target_class
->
super
;
m
=
mrb_method_search_vm
(
mrb
,
&
c
,
mid
);
if
(
!
m
)
{
mid
=
mrb_intern_lit
(
mrb
,
"method_missing"
);
m
=
mrb_method_search_vm
(
mrb
,
&
c
,
mid
);
mrb_sym
missing
=
mrb_intern_lit
(
mrb
,
"method_missing"
);
m
=
mrb_method_search_vm
(
mrb
,
&
c
,
missing
);
if
(
!
m
)
{
mrb_value
args
;
if
(
n
==
CALL_MAXARGS
)
{
args
=
regs
[
a
+
1
];
}
else
{
args
=
mrb_ary_new_from_values
(
mrb
,
n
,
regs
+
a
+
1
);
}
mrb_method_missing
(
mrb
,
mid
,
recv
,
args
);
}
mid
=
missing
;
if
(
n
==
CALL_MAXARGS
)
{
mrb_ary_unshift
(
mrb
,
regs
[
a
+
1
],
mrb_symbol_value
(
ci
->
mid
));
}
...
...
@@ -1681,9 +1697,20 @@ RETRY_TRY_BLOCK:
m
=
mrb_method_search_vm
(
mrb
,
&
c
,
mid
);
if
(
!
m
)
{
mrb_value
sym
=
mrb_symbol_value
(
mid
);
mrb_sym
missing
=
mrb_intern_lit
(
mrb
,
"method_missing"
);
m
=
mrb_method_search_vm
(
mrb
,
&
c
,
missing
);
if
(
!
m
)
{
mrb_value
args
;
mid
=
mrb_intern_lit
(
mrb
,
"method_missing"
);
m
=
mrb_method_search_vm
(
mrb
,
&
c
,
mid
);
if
(
n
==
CALL_MAXARGS
)
{
args
=
regs
[
a
+
1
];
}
else
{
args
=
mrb_ary_new_from_values
(
mrb
,
n
,
regs
+
a
+
1
);
}
mrb_method_missing
(
mrb
,
mid
,
recv
,
args
);
}
mid
=
missing
;
if
(
n
==
CALL_MAXARGS
)
{
mrb_ary_unshift
(
mrb
,
regs
[
a
+
1
],
sym
);
}
...
...
This diff is collapsed.
Click to expand it.
test/t/nomethoderror.rb
View file @
a384bcce
...
...
@@ -20,3 +20,34 @@ assert('NoMethodError#args', '15.2.32.2.1') do
end
end
end
assert
(
'Can still raise when BasicObject#method_missing is removed'
)
do
assert_raise
(
TypeError
)
do
begin
BasicObject
.
alias_method
(
:old_method_missing
,
:method_missing
)
BasicObject
.
remove_method
(
:method_missing
)
1
.
__send__
(
:foo
)
ensure
BasicObject
.
alias_method
(
:method_missing
,
:old_method_missing
)
BasicObject
.
remove_method
(
:old_method_missing
)
end
end
end
assert
(
'Can still call super when BasicObject#method_missing is removed'
)
do
assert_raise
(
TypeError
)
do
class
A
def
foo
super
end
end
begin
BasicObject
.
alias_method
(
:old_method_missing
,
:method_missing
)
BasicObject
.
remove_method
(
:method_missing
)
A
.
new
.
foo
ensure
BasicObject
.
alias_method
(
:method_missing
,
:old_method_missing
)
BasicObject
.
remove_method
(
:old_method_missing
)
end
end
end
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment