Project

General

Profile

Actions

Bug #15244

closed

Method #extname return empty string if filename is dot ('.')

Added by TiSer (Sergey Ti) over 5 years ago. Updated about 4 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:89529]
Tags:

Description

Example 1:

Current behaviour:

File.extname('..jpg')
=> ""

Expected behaviour:

File.extname('..jpg')
=> ".jpg"

Example 2:

Current behaviour:

File.extname('....jpg')
=> ""

Expected behaviour:

=> ".jpg"

Files

dot-names.diff (891 Bytes) dot-names.diff rushsteve1 (Steven vanZyl), 08/02/2019 03:15 PM
multiple-leading-dot-basename-extname-15244.patch (1.94 KB) multiple-leading-dot-basename-extname-15244.patch jeremyevans0 (Jeremy Evans), 08/14/2019 01:08 AM

Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #15267: File.basename + File.extname does not restore the original nameClosedActions
Actions #1

Updated by TiSer (Sergey Ti) over 5 years ago

  • Description updated (diff)

add one more example

Updated by shevegen (Robert A. Heiler) over 5 years ago

Is this a real problem?

How many people have had entries with more leading '.'?

File.extname('foobar......jpg') # => ".jpg"
File.extname('......jpg') # => ""

It's not that I am not inclined to agree about it; I just think
it's a bit strange to want to change that behaviour. Do people
use lots of '.' for names to files or directories or symlinks?

Updated by ahorek (Pavel Rosický) over 5 years ago

IMO

File.extname('..jpg')

should be

=> ".jpg"

proposed

=> "."

or the current behaviour

=> ""

makes no sense

Actions #4

Updated by TiSer (Sergey Ti) over 5 years ago

  • Description updated (diff)

Updated by TiSer (Sergey Ti) over 5 years ago

ahorek (Pavel Rosický) wrote:

IMO

File.extname('..jpg')

should be

=> ".jpg"

proposed

=> "."

or the current behaviour

=> ""

makes no sense

Yes, sure. I'm sorry, I oversleep correct cases.
Updated.

Updated by nobu (Nobuyoshi Nakada) over 5 years ago

If File.extname("..jpg") returns ".jpg", File.basename("..jpg", ".*") should return "." without that part, to restore the original name from from these results.
It is different from basename(1).

$ basename ..jpg '.*'
..jpg

Updated by TiSer (Sergey Ti) over 5 years ago

This is still present.

Updated by TiSer (Sergey Ti) over 5 years ago

Still present.

Updated by TiSer (Sergey Ti) about 5 years ago

Still present.

Updated by rushsteve1 (Steven vanZyl) over 4 years ago

  • File dot-names.diff added

The issue seemed to be in how .dotfiles were handled, where all leading periods were trimmed when only the first should have been.

I've created a patch that seems to fix the issue and added a spect test for it. It's only a 2 line change.

This is my first patch submission so any and all feedback would be greatly appreciated.

Actions #11

Updated by rushsteve1 (Steven vanZyl) over 4 years ago

  • ruby -v changed from 2.5.0p0 to 2.7.0dev

Updated by rushsteve1 (Steven vanZyl) over 4 years ago

Updated the diff to also account for the if (*p) case so that it will stop if p == 0.

Actions #13

Updated by rushsteve1 (Steven vanZyl) over 4 years ago

  • File deleted (dot-names.diff)
Actions #14

Updated by jeremyevans0 (Jeremy Evans) over 4 years ago

  • Related to Bug #15267: File.basename + File.extname does not restore the original name added

Updated by jeremyevans0 (Jeremy Evans) over 4 years ago

I agree that this is a bug. The comparison that nobu made with basename(1) is relevant, but unlike File.basename, basename(1) does not handle .* specially. You can see that basename(1) does actually strip the extension even for multiple leading periods:

basename '..*' '.*'
.

Attached is a patch that fixes the issue, both for File.basename and File.extname. With the patch:

File.basename('..jpg', '.*')
# => "."
File.extname('..jpg')
# => ".jpg"

Updated by matz (Yukihiro Matsumoto) over 4 years ago

  • Status changed from Open to Feedback

.git is not an extension but a filename. .a.jpg has .jpg extension. I wonder how we can parse ..jpg. It's undefined behavior for me.
Any reasoning?

Matz.

Updated by znz (Kazuhiro NISHIYAMA) over 4 years ago

In some other languages:

% python
Python 2.7.16 (default, Mar  4 2019, 09:01:38)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.path.splitext('..jpg')
('..jpg', '')
% python3
Python 3.7.4 (default, Jul  9 2019, 18:13:23)
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.path.splitext('..jpg')
('..jpg', '')
% php --version
PHP 7.1.23 (cli) (built: Feb 22 2019 22:19:32) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
% php -r 'var_export(pathinfo("..jpg", PATHINFO_EXTENSION));'
'jpg'

ref https://hydrocul.github.io/wiki/programming_languages_diff/io/extname.html

Updated by nobu (Nobuyoshi Nakada) over 4 years ago

znz (Kazuhiro NISHIYAMA) wrote:

% php --version
PHP 7.1.23 (cli) (built: Feb 22 2019 22:19:32) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
% php -r 'var_export(pathinfo("..jpg", PATHINFO_EXTENSION));'
'jpg'

Seems not for us:

var_export(pathinfo(".profile", PATHINFO_EXTENSION)); //=> 'profile'

Updated by TiSer (Sergey Ti) over 4 years ago

Example from .NET:
(https://docs.microsoft.com/en-us/dotnet/api/system.io.path.getextension)

class Program
{
  static void Main(string[] args)
  {
    string ext = Path.GetExtension("..jpg");
    Console.WriteLine(ext);
    Console.ReadLine();
  }
}

=> '.jpg'
Actions #20

Updated by jeremyevans0 (Jeremy Evans) about 4 years ago

  • Status changed from Feedback to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0