Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Segmentation fault on aliasing #660

merged 1 commit into from

3 participants

alias_action :show, :to => :show

will cause Segmentation fault.

So we need to validate target names


Anyone? ;)


I wonder if the wording should be changed. I don't like using the terms "real action" because in CanCan all actions are the equal, there are just some default aliases in place. I'll pull this in and maybe change it later.

@ryanb ryanb merged commit cad4db2 into from

This is kind of a big change to slip into a point release. It breaks perfectly fine action aliases that aliased to "real actions", but not recursively.

I'm also dubious that this actually caused a segmentation fault. I could see it causing a SystemStackError, but I'm not convinced it's CanCan's job to prevent people from infinite recursion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 23, 2012
  1. @fl00r
This page is out of date. Refresh to see the latest.
Showing with 10 additions and 0 deletions.
  1. +6 −0 lib/cancan/ability.rb
  2. +4 −0 spec/cancan/ability_spec.rb
6 lib/cancan/ability.rb
@@ -172,10 +172,16 @@ def cannot(action = nil, subject = nil, conditions = nil, &block)
# This way one can use params[:action] in the controller to determine the permission.
def alias_action(*args)
target = args.pop[:to]
+ validate_target(target)
aliased_actions[target] ||= []
aliased_actions[target] += args
+ # User shouldn't specify targets with names of real actions or it will cause Seg fault
+ def validate_target(target)
+ raise Error, "You can't specify target (#{target}) as alias because it is real action name" if aliased_actions.values.flatten.include? target
+ end
# Returns a hash of aliased actions. The key is the target and the value is an array of actions aliasing the key.
def aliased_actions
@aliased_actions ||= default_alias_actions
4 spec/cancan/ability_spec.rb
@@ -87,6 +87,10 @@
@ability.can?(:increment, 123).should be_true
+ it "should raise an Error if alias target is an exist action" do
+ lambda{ @ability.alias_action :show, :to => :show }.should raise_error(CanCan::Error, "You can't specify target (show) as alias because it is real action name")
+ end
it "should always call block with arguments when passing no arguments to can" do
@ability.can do |action, object_class, object|
action.should == :foo
Something went wrong with that request. Please try again.