Skip to content

Commit

Permalink
[GR-18163] Adjust Process.egid= to accept Strings (#2669)
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/3391
  • Loading branch information
eregon committed Jun 16, 2022
2 parents 83e0079 + fe1a8ef commit 242e7a1
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Bug fixes:
* Fix issue with feature loading not detecting a previously loaded feature (#2677, @bjfish).
* Fix `/#{...}/o` to evaluate only once per context when splitting happens (@eregon).
* Fix `Kernel#sprintf` formatting of floats to be like CRuby (@aardvark179).
* Fix `Process.egid=` to accept `String`s (#2615, @ngtban)

Compatibility:

Expand Down
41 changes: 40 additions & 1 deletion spec/ruby/core/process/egid_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,44 @@
end

describe "Process.egid=" do
it "needs to be reviewed for spec completeness"

platform_is_not :windows do
it "raises TypeError if not passed an Integer or String" do
-> { Process.egid = Object.new }.should raise_error(TypeError)
end

it "sets the effective group id to its own gid if given the username corresponding to its own gid" do
raise unless Process.gid == Process.egid

require "etc"
group = Etc.getgrgid(Process.gid).name

Process.egid = group
Process.egid.should == Process.gid
end

as_user do
it "raises Errno::ERPERM if run by a non superuser trying to set the root group id" do
-> { Process.egid = 0 }.should raise_error(Errno::EPERM)
end

platform_is :linux do
it "raises Errno::ERPERM if run by a non superuser trying to set the group id from group name" do
-> { Process.egid = "root" }.should raise_error(Errno::EPERM)
end
end
end

as_superuser do
context "when ran by a superuser" do
it "sets the effective group id for the current process if run by a superuser" do
code = <<-RUBY
Process.egid = 1
puts Process.egid
RUBY
ruby_exe(code).should == "1\n"
end
end
end
end
end
2 changes: 1 addition & 1 deletion spec/ruby/core/process/euid_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

as_user do
it "raises Errno::ERPERM if run by a non superuser trying to set the superuser id" do
-> { (Process.euid = 0)}.should raise_error(Errno::EPERM)
-> { Process.euid = 0 }.should raise_error(Errno::EPERM)
end

it "raises Errno::ERPERM if run by a non superuser trying to set the superuser id from username" do
Expand Down
1 change: 0 additions & 1 deletion spec/tags/core/process/euid_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/tags/core/process/uid_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
fails:Process.uid= raises Errno::ERPERM if run by a non privileged user trying to set the superuser id
fails:Process.uid= raises Errno::ERPERM if run by a non privileged user trying to set the superuser id from username
slow:Process.uid returns the correct uid for the user executing this process
32 changes: 27 additions & 5 deletions src/main/ruby/truffleruby/core/process.rb
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,14 @@ def self.ppid
end

def self.uid=(uid)
uid =
if name = Truffle::Type.rb_check_convert_type(uid, String, :to_str)
require 'etc'
Etc.getpwnam(name).uid
else
Truffle::Type.rb_num2ulong(uid)
end

# the 4 rescue clauses below are needed
# until respond_to? can be used to query the implementation of methods attached via FFI
# atm respond_to returns true if a method is attached but not implemented on the platform
Expand Down Expand Up @@ -395,7 +403,14 @@ def self.uid=(uid)
end

def self.gid=(gid)
gid = Truffle::Type.coerce_to gid, Integer, :to_int
gid =
if name = Truffle::Type.rb_check_convert_type(gid, String, :to_str)
require 'etc'
Etc.getgrnam(name).gid
else
Truffle::Type.rb_num2ulong(gid)
end

Process::Sys.setgid gid
end

Expand All @@ -404,11 +419,11 @@ def self.euid=(uid)
# until respond_to? can be used to query the implementation of methods attached via FFI
# atm respond_to returns true if a method is attached but not implemented on the platform
uid =
if uid.kind_of?(String)
if name = Truffle::Type.rb_check_convert_type(uid, String, :to_str)
require 'etc'
Etc.getpwnam(uid).uid
Etc.getpwnam(name).uid
else
Truffle::Type.coerce_to uid, Integer, :to_int
Truffle::Type.rb_num2ulong(uid)
end

begin
Expand All @@ -435,7 +450,14 @@ def self.euid=(uid)
end

def self.egid=(gid)
gid = Truffle::Type.coerce_to gid, Integer, :to_int
gid =
if name = Truffle::Type.rb_check_convert_type(gid, String, :to_str)
require 'etc'
Etc.getgrnam(name).gid
else
Truffle::Type.rb_num2ulong(gid)
end

Process::Sys.setegid gid
end

Expand Down

0 comments on commit 242e7a1

Please sign in to comment.