Bug #7374

File.expand_path resolving to first file/dir instead of absolute path

Added by Martin Dubé over 2 years ago. Updated over 2 years ago.

[ruby-core:49451]
Status:Closed
Priority:High
Assignee:Luis Lavena
ruby -v:ruby 1.9.3p327 (2012-11-10) [i386-mingw32] Backport:

Description

=begin
(({File.expand_path("./*", "c:)"}))
will give "c:/$recycle.bin" as result instead of "c:/*"

(({File.expand_path("./*", "c:/temp)"}))
will give "c:/temp/." as result instead of "c:/temp/*"

It looks like the first directory entry is returned instead of the absolute path.

=end


Related issues

Related to Backport193 - Backport #7381: File.expand_path resolving to first file/dir instead of a... Closed 11/18/2012

Associated revisions

Revision 37692
Added by Luis Lavena over 2 years ago

skip long name conversion if last character is a wildcard one

  • win32/file.c (replace_to_long_name): skip automatic path expansion
    when wildcard character is used. [Bug #7374]

  • test/ruby/test_file_exhaustive.rb: add a test for above.

Revision 37692
Added by Luis Lavena over 2 years ago

skip long name conversion if last character is a wildcard one

  • win32/file.c (replace_to_long_name): skip automatic path expansion
    when wildcard character is used. [Bug #7374]

  • test/ruby/test_file_exhaustive.rb: add a test for above.

Revision 37700
Added by Luis Lavena over 2 years ago

Skip path expansion for all wildcard characters

  • win32/file.c (replace_to_long_name): skip expansion for all wildcard
    characters.
    [Bug #7374]

  • test/ruby/test_file_exhaustive.rb: add more assertions to test.

Revision 37700
Added by Luis Lavena over 2 years ago

Skip path expansion for all wildcard characters

  • win32/file.c (replace_to_long_name): skip expansion for all wildcard
    characters.
    [Bug #7374]

  • test/ruby/test_file_exhaustive.rb: add more assertions to test.

Revision 37706
Added by Luis Lavena over 2 years ago

Swap logic around wildcard character detection

  • win32/file.c (replace_to_long_name): correct logic around wildcard characters detection and ensure wide-chars are used as pattern. [Bug #7374]

Revision 37706
Added by Luis Lavena over 2 years ago

Swap logic around wildcard character detection

  • win32/file.c (replace_to_long_name): correct logic around wildcard characters detection and ensure wide-chars are used as pattern. [Bug #7374]

History

#1 Updated by Martin Dubé over 2 years ago

ruby 1.9.3p194 (2012-04-20) [i386-mingw32] is working fine:

irb(main):002:0> File.expand_path("./*", "c:/temp")
=> "c:/temp/*"

#2 Updated by Luis Lavena over 2 years ago

  • Category set to core
  • Status changed from Open to Assigned
  • Assignee set to Hiroshi Shirosaki

Martin,

Can you confirm if this happen with Ruby 2.0? (trunk, you can get automated builds from RubyInstaller CI)

Shirosaki-san,

Seems that globing has been enabled?

#3 Updated by Luis Lavena over 2 years ago

  • Assignee changed from Hiroshi Shirosaki to Luis Lavena
  • Priority changed from Normal to High
  • Target version set to 2.0.0

=begin
I can confirm this happens on both 1.9.3-p327 and trunk.

Problem seems to be related to replace_to_long_name which attempts to expand the last part of the path using FindFirstFileW (globing), but is ignoring that it includes "*" in the filename.

I'm checking this and adding a test for this scenario.

Thank you for your report.
=end

#4 Updated by Martin Dubé over 2 years ago

luislavena (Luis Lavena) wrote:

Martin,

Can you confirm if this happen with Ruby 2.0? (trunk, you can get automated builds from RubyInstaller CI)

Shirosaki-san,

Seems that globing has been enabled?

Yes, same problem with r37691:

C:\ruby-2.0.0-r37691-i386-mingw32\bin>irb.bat
irb(main):001:0> File.expand_path("./*", "c:/")
=> "c:/$RECYCLE.BIN"
irb(main):002:0>

#5 Updated by Luis Lavena over 2 years ago

Martin,

I'm adding tests for this, do you have any other scenario that is failing and you want to report?

It will be great if we can cover all those by a single commit.

Thank you.

#6 Updated by Martin Dubé over 2 years ago

=begin
No other scenario. Caught that bug trying to install a plugin to redmine 2.1.2 with ruby 1.9.3p327

Redmine then attempt to add plugins routes with the following code:

(({Dir.glob File.expand_path("plugins/*", Rails.root) do |plugin_dir|}))

Which end up enumerating only the "." directory instead of all subdirectories in ./plugins
=end

#7 Updated by Luis Lavena over 2 years ago

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

This issue was solved with changeset r37692.
Martin, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


skip long name conversion if last character is a wildcard one

  • win32/file.c (replace_to_long_name): skip automatic path expansion
    when wildcard character is used. [Bug #7374]

  • test/ruby/test_file_exhaustive.rb: add a test for above.

#8 Updated by Luis Lavena over 2 years ago

Martin,

I've committed some tests and a fix for this.

Automated builds will kick in soon, please check RubyInstaller CI to download binary packages.

I'll request a backport once I get confirmation this works on your end.

#9 Updated by Hiroshi Shirosaki over 2 years ago

  • Status changed from Closed to Assigned

It seems if the last part of the path contains * or ?, FindFirstFileW should not be used since FindFirstFileW expands wildcard.

Examples:
File.expand_path("foo/ab*c")
File.expand_path("foo/ab?c")

Code in file.c uses strpbrk(s, "*?") for that.
https://github.com/ruby/ruby/blob/trunk/file.c#L3141

#10 Updated by Luis Lavena over 2 years ago

  • % Done changed from 100 to 50

h.shirosaki (Hiroshi Shirosaki) wrote:

It seems if the last part of the path contains * or ?, FindFirstFileW should not be used since FindFirstFileW expands wildcard.

Thank you Shirosaki, I did a naive fix and completely missed "?" character.

Will modify replace_to_long_name to check for this.

#11 Updated by Luis Lavena over 2 years ago

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

This issue was solved with changeset r37700.
Martin, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


Skip path expansion for all wildcard characters

  • win32/file.c (replace_to_long_name): skip expansion for all wildcard
    characters.
    [Bug #7374]

  • test/ruby/test_file_exhaustive.rb: add more assertions to test.

#12 Updated by Luis Lavena over 2 years ago

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

=begin
Sorry for the noise, but seems I've a Webrick failure caused by this that didn't catch when sent r37700 in.

test_short_filename(WEBrick::TestFileHandler) [C:/Users/Worker/Jenkins/workspace/ruby-trunk-x86-build/test/webrick/test_filehandler.rb:240]:
webrick log start:
[2012-11-17 12:49:00] INFO WEBrick 1.3.1
[2012-11-17 12:49:00] INFO ruby 2.0.0 (2012-11-17) [i386-mingw32]
[2012-11-17 12:49:00] INFO WEBrick::HTTPServer#start: pid=14444 port=62527

[2012-11-17 12:49:00] WARN the request refers nondisclosure name .htaccess'.
[2012-11-17 12:49:00] ERROR
/.htaccess' not found.

webrick log end.
<"404"> expected but was
<"200">.

Looking into this right now.
=end

#13 Updated by Luis Lavena over 2 years ago

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

This issue was solved with changeset r37706.
Martin, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


Swap logic around wildcard character detection

  • win32/file.c (replace_to_long_name): correct logic around wildcard characters detection and ensure wide-chars are used as pattern. [Bug #7374]

#14 Updated by Luis Lavena over 2 years ago

Martin, Hiroshi,

This should be finally fixed by r37706, sorry for all the inconveniences!

(note to myself: don't commit to Ruby on during night, even less on friday).

Also available in: Atom PDF