Windows ENV object being corrupted

I am running in rake ( I have reproduced the problem with a straight
ruby script ) and I read in a batch file that has a few hundred
environment variables in it. At some magic point when 323 entries are
made to the ENV object, suddenly the ENV object gets corrupted.
Suddenly the adds don’t seem to take and later a bunch of my Environment
variables go missing.

The “local_copy” hash does seem to hold but it isn’t what I need.

  environment.split("\n").each() do |pair|
         splitpos = pair.index('=')

         if ! splitpos.nil?
            key = pair.slice(0, splitpos)
            splitpos += 1
            value = pair.slice(splitpos, pair.length() - splitpos)
         end

         if ( ! key.nil? && ! value.nil?)
           key.strip!
           value.strip!
           verbose( ENV.size().to_s() + " -> ENV[#{key}] = " +

value, 1)
ENV[key] = value.dup;
local_copy[key] = value.dup;
else
verbose(“Nil value found. Input String: #{pair}”, 5)
end
end

output:

322 -> ENV[MAS_REV] = 2
323 -> ENV[MAS_VER] = 1.03c
324 -> ENV[MeetingCenterApp] = C:\Program Files\Meeting Center
324 -> ENV[MINIBOOST_INC] =
F:\source\iie\trunk\external_libs\windows_32\3rdparty\spirit-1.8.4\miniboost
325 -> ENV[MYSQL_DEB_LIB_LOC] =
F:\source\iie\trunk\external_libs\windows_32\3rdparty\mysql\4.1.16\rev1\shared\debug\win32_mtdll
326 -> ENV[MYSQL_DEB_PRODUCT_NAME] = libmysqld

363 -> ENV[US_COM_DRS_INC] =
F:\source\iie\trunk\external_libs\windows_32\USCommercialDRS\DRS\10.01.03.M\Non-Dongled
364 -> ENV[US_COM_DRS_LIB_LOC] =
F:\source\iie\trunk\external_libs\windows_32\USCommercialDRS\DRS\10.01.03.M\Non-Dongled
31 -> ENV[US_COM_DRS_PRODUCT_NAME] = POSTAL32

Anyone every ran into this before?

Herman S. wrote:

I am running in rake ( I have reproduced the problem with a straight
ruby script ) and I read in a batch file that has a few hundred
environment variables in it. At some magic point when 323 entries are
made to the ENV object, suddenly the ENV object gets corrupted.
Suddenly the adds don’t seem to take and later a bunch of my Environment
variables go missing.

This appears to be related to spaces in the value strings. As a Hack I
removed any Env value that had a space, which happens to work for me
now, but I still can’t wrap my head around why size plays a factor.

2009/8/11 Herman S. [email protected]:

now, but I still can’t wrap my head around why size plays a factor.
I cannot either but this is due to the fact that I am missing
information in your original posting. For example, what is the format
of the “batch file” are you reading? What does variable “environment”
contain?

robert

Robert K. wrote:

2009/8/11 Herman S. [email protected]:

now, but I still can’t wrap my head around why size plays a factor.
I cannot either but this is due to the fact that I am missing
information in your original posting. For example, what is the format
of the “batch file” are you reading? What does variable “environment”
contain?

robert

What I do is write the output from ‘set’ on windows to a ruby string
like this:

environment = call setEnvironment.bat;set

setEnvironment.bat is just a bunch of environment sets

i.e.: SET LINK_PLATFORM=windows_32

The environment variables that were giving me trouble come from the
system
Ones like:
ALLUSERSPROFILE=C:\Documents and Settings\All Users

So I get the sense that spaces are the issue, I believe that quoting
variables with spaces would probably solve the issue but I haven’t tried
it yet.

On 12.08.2009 18:17, Robert K. wrote:

And what is your aim, i.e. what do you want to achieve? If you want
to set environment variables for your Ruby script, you could easily do
this instead:

File.foreach “setEnvironment.bat” do |line|
if /^\s*([^\s=]+)\s*=\s*(.*)$/ =~ line
ENV[$1] = $2
end
end

Pardon, should have been

File.foreach “setEnvironment.bat” do |line|
if /^\sSET\s([^\s=]+)\s*=\s*(.*)$/i =~ line
ENV[$1] = $2
end
end

Cheers

robert

Robert K. wrote:

2009/8/12 Herman S. [email protected]:

So I get the sense that spaces are the issue, I believe that quoting
variables with spaces would probably solve the issue but I haven’t tried
it yet.

And what is your aim, i.e. what do you want to achieve? If you want
to set environment variables for your Ruby script, you could easily do
this instead:

File.foreach “setEnvironment.bat” do |line|
if /^\s*([^\s=]+)\s*=\s*(.*)$/ =~ line
ENV[$1] = $2
end
end

and be done. Your approach looks suspiciously complicated to me. Of
course I may be missing something…

Kind regards

robert

Thanks, Robert. I can’t argue your approach isn’t simpler. In fact, I
can’t remember why we ended up with this. All we really want is the same
environment that the build system uses available for test and publishing
systems. Your suggestion is noted.

However, the problem with ENV still exists. The problem with spaces and
large numbers of environment variables. It’s just not in my way
anymore. When I get a chance I will use your approach and see if I can
re-create the problem from just parsing the setEnvironment.bat.

Thanks, again.

2009/8/12 Herman S. [email protected]:

So I get the sense that spaces are the issue, I believe that quoting
variables with spaces would probably solve the issue but I haven’t tried
it yet.

And what is your aim, i.e. what do you want to achieve? If you want
to set environment variables for your Ruby script, you could easily do
this instead:

File.foreach “setEnvironment.bat” do |line|
if /^\s*([^\s=]+)\s*=\s*(.*)$/ =~ line
ENV[$1] = $2
end
end

and be done. Your approach looks suspiciously complicated to me. Of
course I may be missing something…

Kind regards

robert

2009/8/12 Herman S. [email protected]:

this instead:
Thanks, Robert. Â I can’t argue your approach isn’t simpler. Â In fact, I
can’t remember why we ended up with this. All we really want is the same
environment that the build system uses available for test and publishing
systems. Â Your suggestion is noted.

However, the problem with ENV still exists. Â The problem with spaces and
large numbers of environment variables. Â It’s just not in my way
anymore. Â When I get a chance I will use your approach and see if I can
re-create the problem from just parsing the setEnvironment.bat.

I was curious and created the test attached but could not provoke any
issues with spaces. I am pretty sure that the size of the environment
is limited somehow but I did not hit a limit or any issues with my
test (at 36,000 and still running).

What’s going on here?

robert

Robert K. wrote:

2009/8/12 Herman S. [email protected]:

this instead:
Thanks, Robert. Â I can’t argue your approach isn’t simpler. Â In fact, I
can’t remember why we ended up with this. All we really want is the same
environment that the build system uses available for test and publishing
systems. Â Your suggestion is noted.

However, the problem with ENV still exists. Â The problem with spaces and
large numbers of environment variables. Â It’s just not in my way
anymore. Â When I get a chance I will use your approach and see if I can
re-create the problem from just parsing the setEnvironment.bat.

I was curious and created the test attached but could not provoke any
issues with spaces. I am pretty sure that the size of the environment
is limited somehow but I did not hit a limit or any issues with my
test (at 36,000 and still running).

What’s going on here?

robert

I had chance to get and try your routine. I think the author of this
code was trying to get around a recursive problem namely that
environment variables are comprised of one or more environment
variables.

Once I added a routine to resolve this issue I have run without
incident.

def resolve_variables( field )

value = field

value.strip!
replace = ""
verbose( "In Value = " + value , 5)
if value =~ /%(\w+)%/
   value.gsub!(/%(\w+)%/) do
      found = $1
      replace = found.gsub("%","")
      replace = ENV[replace]

      if replace.nil?
         abort("??Error: Use of undefined Environment Variable 

#{found} in #{field}")
end
verbose("Rep = " + replace, 5)
verbose( "Val = " + value , 5)
replace
end
verbose( "Val = " + value , 4)
end
verbose( "Return -> " + value , 4)
return value
end

  File.foreach env_batch_file do |line|
     if /^\s*SET\s*([^\s=]+)\s*=\s*(.*)$/i =~ line
        key = $1
        value = resolve_variables($2)
        verbose("ENV[" + key + "] = " + value, 1)
        ENV[key] = value
     end
  end