Issue #6990 has been updated by h.shirosaki (Hiroshi Shirosaki).


=begin
Language of FormatMessage seems not affected by console code page.

Test using locale:
 msg[0, len].force_encoding("locale").tr("\r", '').chomp

"locale" means console code page on Windows ruby.
But changing console code page doesn't affect message language. Message seems always cp932 Japanese on Windows 7.

 > type message.rb 
 require "openssl"
 OpenSSL.send(:remove_const, :Random)
 require "securerandom"

 SecureRandom.random_bytes
 SecureRandom.send(:instance_variable_set, :@hProv, 0)
 SecureRandom.random_bytes

 > chcp 932
 > ruby message.rb
 V:/ruby19_mingw/lib/ruby/2.0.0/securerandom.rb:117:in `random_bytes': unknown error - CryptGenRandom
  failed: ?????????????????????????? (SystemCallError)
         from message.rb:7:in `<main>'

 > chcp 65001
 > ruby message.rb
 V:/ruby19_mingw/lib/ruby/2.0.0/securerandom.rb:264:in `tr': invalid byte sequence in UTF-8 (Argument
 Error)
         from V:/ruby19_mingw/lib/ruby/2.0.0/securerandom.rb:264:in `lastWin32ErrorMessage'
         from V:/ruby19_mingw/lib/ruby/2.0.0/securerandom.rb:117:in `random_bytes'
         from message.rb:7:in `<main>'
 
 > chcp 1252
 > ruby message.rb
 V:/ruby19_mingw/lib/ruby/2.0.0/securerandom.rb:117:in `random_bytes': unknown error - CryptGenRandom
  failed: ?????????????? (SystemCallError)
         from message.rb:7:in `<main>'

But on Windows XP, message language seems determined by console code page. With not 932 code page, message is English.

To avoid `invalid byte sequence` error with String#tr, I would like to set filesystem encoding.
If you know better way, please correct it.

=end

----------------------------------------
Bug #6990: test_s_random_bytes_without_openssl error on Windows x64
https://bugs.ruby-lang.org/issues/6990#change-29278

Author: h.shirosaki (Hiroshi Shirosaki)
Status: Assigned
Priority: Normal
Assignee: h.shirosaki (Hiroshi Shirosaki)
Category: test
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-09-06 trunk 36917) [x64-mingw32]


=begin

TestSecureRandom sometimes has an error on ci.rubyinstaller.

http://ci.rubyinstaller.org/job/ruby-trunk-x64-test-all/41/console


 3) Error:
 test_s_random_bytes_without_openssl(TestSecureRandom):
 SystemCallError: unknown error - CryptGenRandom failed: The parameter is incorrect.
 C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/lib/securerandom.rb:116:in `random_bytes'
 C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/test/test_securerandom.rb:12:in `test_s_random_bytes'
 C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/test/test_securerandom.rb:97:in `block in test_s_random_bytes_without_openssl'
 C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/lib/tmpdir.rb:88:in `mktmpdir'
 C:/Users/Worker/Jenkins/workspace/ruby-trunk-x64-build/test/test_securerandom.rb:85:in `test_s_random_bytes_without_openssl'
 

This error seems to occur only on x64.

I guess the following scenario.

Pointer size of @hProv seems limited to 32bit with x64 ruby.
If the pointer value was larger than 32bit max, it would fail.

https://github.com/ruby/ruby/blob/trunk/lib/securerandom.rb#L106

I don't get the error at test-all on my local box, but I can get same error with the following script.
It takes long time to get the error.


 require "openssl"
 OpenSSL.send(:remove_const, :Random)
 require "securerandom"
 
 i = 0
 loop do
   SecureRandom.random_bytes
   SecureRandom.send(:remove_instance_variable, :@has_win32)
   p SecureRandom.send(:instance_variable_get, :@hProv).to_s(16) if (i % 10000) == 0
   i += 1
 end


I attached a patch. I also fixed encoding error which occurs if error message contains Japanese characters.

=end


-- 
http://bugs.ruby-lang.org/