Bug #1679

rb_w32_getenv() invalidates previous environment pointers

Added by Jarek Jurasz almost 5 years ago. Updated almost 3 years ago.

Assignee:Akio Tajima
Target version:1.9.3
ruby -v:ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32] Backport:


On Windows turning on page heap (gflags -p /enable ruby.exe /full) revealed that environment pointers returned by rbw32getenv() get invalidated on the next call to this function due to the freeing of the environment buffer.
In particular getenv("RUBYLIBPREFIX") in rubylibmangle() frees getenv("RUBYLIB") fetched in rubyinitloadpath(). This bug is also present in ruby 1.9.1-p129.

The workaround - the RTL version of getenv() - worked fine for me so far.

Associated revisions

Revision 32310
Added by Nobuyoshi Nakada almost 3 years ago

  • ruby.c (rubyinitloadpathsafe): ensure RUBYLIBPREFIX stored before RUBYLIB, even if MANGLEDPATH is enabled. fixed #1679. MANGLEDPATH is disabled by the default and will be removed completely in the future.


#1 Updated by Jarek Jurasz over 4 years ago

It does not know about SetEnvironmentVariable() in ruby_setenv() / hash.c.
GetEnvironmentVariable() needs some memory management.
The following leaky version passes the test.

char *
rbw32getenv(const char name)
char env[1024];
unsigned len = GetEnvironmentVariable(name, env, sizeof(env));
if (! len) {
return NULL;
Memory leak */
return strdup(env);

#2 Updated by Usaku NAKAMURA over 4 years ago

  • Category set to core

ISO C and POSIX say that the returned string may be overwritten by a subsequent call of getenv().
So, the behavior of rbw32getenv() is collect and the wrong point is rbinitloadpath().

#3 Updated by Akira Tanaka almost 3 years ago

  • Project changed from Ruby to ruby-trunk
  • Category changed from core to core

#4 Updated by Yui NARUSE almost 3 years ago

  • Status changed from Open to Assigned
  • Assignee set to Akio Tajima

#5 Updated by Hiroshi Nakamura almost 3 years ago

  • Target version set to 1.9.3

#6 Updated by Usaku NAKAMURA almost 3 years ago

In current trunk (at least), this problem is not occurred.
The return value of getenv("RUBYLIB") is rbstr_new()'ed before another getenv() call.

#7 Updated by Usaku NAKAMURA almost 3 years ago

  • Status changed from Assigned to Closed

Also available in: Atom PDF