Bug #3825

ENV.delete raise Exception on Windows

Added by Heesob Park almost 5 years ago. Updated about 4 years ago.

[ruby-core:32353]
Status:Closed
Priority:Normal
Assignee:Usaku NAKAMURA
ruby -v:ruby 1.9.3dev (2010-09-12 trunk 29234) [i386-mswin32_90] Backport:

Description

=begin
ENV.delete raises Invalid argument Exception on Windows.

The error is due to trying SetEnvironmentVariable even if putenv succeeded.

C:>ruby -ve "ENV['foo']='bar';ENV.delete('foo')"
ruby 1.9.3dev (2010-09-12 trunk 29234) [i386-mswin32_90]
-e:1:in delete': Invalid argument - ruby_setenv (Errno::EINVAL)
from -e:1:in
'

The patch is simple as like this:

--- hash.c.org 2010-09-13 11:31:01.000000000 +0900
+++ hash.c 2010-09-13 11:51:08.000000000 +0900
@@ -2156,7 +2156,7 @@
/* even if putenv() failed, clean up and try to delete the
* variable from the system area. /
rb_str_resize(buf, 0);
- if (!value || !value) {
+ if (failed && (!value || !
value)) {
/
putenv() doesn't handle empty value */
if (!SetEnvironmentVariable(name,value)) goto fail;
}
=end

History

#1 Updated by Nobuyoshi Nakada almost 5 years ago

=begin
Hi,

At Mon, 13 Sep 2010 12:05:11 +0900,
Heesob Park wrote in :

ENV.delete raises Invalid argument Exception on Windows.

The error is due to trying SetEnvironmentVariable even if putenv succeeded.

Does test/ruby/test_env.rb fail now? I can't check it now.

--
Nobu Nakada

=end

#2 Updated by Heesob Park almost 5 years ago

=begin
Hi,

2010/9/13 Nobuyoshi Nakada nobu@ruby-lang.org:

Hi,

At Mon, 13 Sep 2010 12:05:11 +0900,
Heesob Park wrote in :

ENV.delete raises Invalid argument Exception on Windows.

The error is due to trying SetEnvironmentVariable even if putenv succeeded.

Does test/ruby/test_env.rb fail now?  I can't check it now.

On Windows XP Home SP3:
Test run options: --seed 1488

Loaded suite test_env
Started
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
Finished in 0.156250 seconds.

1) Error:
test_aset(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

2) Error:
test_assoc(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

3) Error:
test_bracket(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:11:in delete'
test_env.rb:11:in
setup'

4) Error:
test_bracket(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

5) Error:
test_clear(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:223:in clear'
test_env.rb:223:in
test_clear'

6) Error:
test_clear(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

7) Failure:
test_delete(TestEnv) [test_env.rb:92]:
Exception raised:
<#>.

8) Error:
test_delete(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

9) Error:
test_each_key(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

10) Error:
test_each_pair(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

11) Error:
test_each_value(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

12) Error:
test_empty_p(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:269:in clear'
test_env.rb:269:in
test_empty_p'

13) Error:
test_empty_p(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

14) Error:
test_fetch(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:104:in delete'
test_env.rb:104:in
test_fetch'

15) Error:
test_fetch(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

16) Error:
test_getenv(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

17) Error:
test_has_key(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

18) Error:
test_has_value(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:11:in delete'
test_env.rb:11:in
setup'

19) Error:
test_has_value(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

20) Error:
test_has_value2(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:297:in clear'
test_env.rb:297:in
test_has_value2'

21) Error:
test_has_value2(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

22) Error:
test_huge_value(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

23) Error:
test_inspect(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:232:in clear'
test_env.rb:232:in
test_inspect'

24) Error:
test_inspect(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

25) Error:
test_invert(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:352:in clear'
test_env.rb:352:in
test_invert'

26) Error:
test_invert(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

27) Error:
test_key(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

28) Error:
test_keys(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:11:in delete'
test_env.rb:11:in
setup'

29) Error:
test_keys(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

30) Error:
test_rassoc(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:304:in clear'
test_env.rb:304:in
test_rassoc'

31) Error:
test_rassoc(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

32) Error:
test_rehash(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

33) Error:
test_reject(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

34) Error:
test_reject_bang(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:11:in delete'
test_env.rb:11:in
setup'

35) Error:
test_reject_bang(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

36) Error:
test_replace(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:360:in replace'
test_env.rb:360:in
test_replace'

37) Error:
test_replace(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

38) Error:
test_select(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

39) Error:
test_select_bang(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:11:in delete'
test_env.rb:11:in
setup'

40) Error:
test_select_bang(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

41) Error:
test_shift(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:342:in clear'
test_env.rb:342:in
test_shift'

42) Error:
test_shift(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

43) Error:
test_size(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

44) Error:
test_to_a(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:11:in delete'
test_env.rb:11:in
setup'

45) Error:
test_to_a(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

46) Error:
test_to_hash(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

47) Error:
test_to_s(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

48) Error:
test_update(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:365:in clear'
test_env.rb:365:in
test_update'

49) Error:
test_update(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

50) Error:
test_values(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

51) Error:
test_values_at(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
test_env.rb:17:in clear'
test_env.rb:17:in
teardown'

34 tests, 209 assertions, 1 failures, 50 errors, 0 skips

Test run options: --seed 1488


BTW, On Windows 7, it works fine:

Test run options: --seed 34498

Loaded suite test_env
Started
..................................
Finished in 0.454000 seconds.

34 tests, 391 assertions, 0 failures, 0 errors, 0 skips

Test run options: --seed 34498

Regards,
Park Heesob

=end

#3 Updated by Peter Weldon almost 5 years ago

=begin
Knowing the value of GetLastError() after SetEnvironmentVariable() fails may give a clue. Can you try get that?

In VS, I would, add "$err,hr" to my watch window and put a break point at the fail: label in hash.c (setenv).
=end

#4 Updated by Heesob Park almost 5 years ago

=begin
2010/9/14 Peter Weldon redmine@ruby-lang.org:

Issue #3825 has been updated by Peter Weldon.

Knowing the value of GetLastError() after SetEnvironmentVariable() fails may give a clue. Can you try get that?

In VS, I would, add "$err,hr" to my watch window and put a break point at the fail: label in hash.c (setenv).

The value of GetLastError() is 203 and which defined as
#define ERROR_ENVVAR_NOT_FOUND 203

I am not sure in which case, SetEnvironmentVariable() with null value fails.

The another possible patch is

--- hash.c 2010-09-14 09:47:12.000000000 +0900
+++ hash.c.new 2010-09-14 09:47:12.000000000 +0900
@@ -2158,7 +2158,7 @@
rb_str_resize(buf, 0);
if (!value || !value) {
/
putenv() doesn't handle empty value */
- if (!SetEnvironmentVariable(name,value)) goto fail;
+ if (!SetEnvironmentVariable(name,value) && GetLastError() !=
ERROR_ENVVAR_NOT_FOUND) goto fail;
}
if (failed) goto fail;
#elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)

=end

#5 Updated by Shyouhei Urabe almost 5 years ago

  • Status changed from Open to Assigned
  • Assignee set to Usaku NAKAMURA

=begin

=end

#6 Updated by Heesob Park almost 5 years ago

=begin
I confirmed this issue occurs on Windows 2000, XP, 2003.

Is there any specific reason for this issue not fixed?

=end

#7 Updated by Usaku NAKAMURA almost 5 years ago

=begin
Does this occur in trunk?
Though I cannot reproduce.
=end

#8 Updated by Heesob Park almost 5 years ago

=begin
2010/9/30 Usaku NAKAMURA redmine@ruby-lang.org:

Issue #3825 has been updated by Usaku NAKAMURA.

Does this occur in trunk?
Though I cannot reproduce.

Yes, it occur in trunk on Windows XP. I know it does not occur on Windows 7.

C:>ruby -ve "ENV['foo']='bar';ENV.delete('foo')"
ruby 1.9.3dev (2010-09-28 trunk 29354) [i386-mswin32_90]
-e:1:in delete': Invalid argument - ruby_setenv (Errno::EINVAL)
from -e:1:in
'

=end

#9 Updated by Usaku NAKAMURA almost 5 years ago

=begin
Hello,

In message " Re: [Ruby 1.9-Bug#3825] ENV.delete raise Exception on Windows"
on Sep.30,2010 10:31:34, phasis@gmail.com wrote:

Yes, it occur in trunk on Windows XP. I know it does not occur on Windows 7.

Oh, I see.
Just merged your patch. thanks!

Regards,
--
U.Nakamura usa@garbagecollect.jp

=end

#10 Updated by Usaku NAKAMURA almost 5 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

=begin
This issue was solved with changeset r29377.
Heesob, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

=end

Also available in: Atom PDF