Opened 7 years ago

Closed 2 years ago

Last modified 2 years ago

#5014 closed bug (fixed)

canonicalizePath throws exception on paths that do not exist

Reported by: hesselink Owned by: ekmett
Priority: low Milestone: 8.0.1
Component: Core Libraries Version: 7.0.2
Keywords: Cc: dterei, the.dead.shall.rise@…, core-libraries-committee@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime crash Test Case:
Blocked By: Blocking:
Related Tickets: #4215 Differential Rev(s):
Wiki Page:

Description

Assume path foo exists, but foo/bar doesn't. On GHC 6.12, canonicalizePath "foo/bar" gave back a result. On GHC 7.02, I get an exception:

*** Exception: foo/bar: canonicalizePath: does not exist (No such file or directory)

The behavior is not defined by the documentation, or at all (see #4215) but it would be nice if it didn't crash.

Change History (22)

comment:2 Changed 7 years ago by batterseapower

Status: newpatch

I have implemented and validated alternative behaviour for canonicalizePath on the patch-5014 branch of the testsuite and directory repos. As a side effect, this change fixes T4113 on OS X.

Does this change require a libraries proposal?

One missing piece is that I understand from #4480 that some versions of Windows may have a bug so that (contrary to its documentation) GetFullPathName may fail on non-existant files.

comment:3 Changed 7 years ago by simonmar

I'm not sure about this. For example, if ./a exists and ./b does not, then canonicalizePath "a/../b" will currently fail, but your patch would make it return <pwd>/a/../b. This is inconsistent with canonicalizePath "a/.." which will return simply <pwd>.

comment:4 Changed 7 years ago by batterseapower

It's possible to construct examples where this revised implementation gives a poor canonicalization. However, I would argue that this is fine because it's only meant to be a best-effort process, anyway. If the file is missing, that best effort is just a bit weaker than usual - a condition I do not think justifies throwing an exception.

comment:5 Changed 7 years ago by simonmar

Ok, fair enough.

comment:6 Changed 7 years ago by igloo

Milestone: 7.2.1
Status: patchnew

Hmm, we can't really make it consistent; I think it would be better to just document it as

The precise behaviour is that of the C realpath function
GetFullPathNameW on Windows). In particular, the behaviour
on paths that do not exist is known to vary from platform
to platform. Some platforms do not alter the input, some
do, and on some an exception will be thrown.

Perhaps making a library proposal would be best?

comment:7 Changed 7 years ago by batterseapower

You are right that this is best resolved by a libraries proposal. I'll try to get around to it.

comment:8 Changed 6 years ago by igloo

See also #4215, #4480.

comment:9 Changed 6 years ago by igloo

Milestone: 7.2.17.4.1

comment:10 Changed 6 years ago by igloo

Milestone: 7.4.17.6.1
Priority: normallow

comment:11 Changed 5 years ago by igloo

Milestone: 7.6.17.6.2

comment:12 Changed 5 years ago by dterei

Cc: dterei added

Argh, this bug just bit me. Max, any chance of making that libraries proposal? Otherwise, Ian what is the correct documentation for this function? On OSX and Linux for me, non-existent paths throw an exception. Is that always the case or it varies from platforms? I think the documentation needs some warning about this.

comment:13 Changed 5 years ago by igloo

difficulty: Unknown

I think that what I put in the grey box above documents the current state.

comment:14 Changed 5 years ago by refold

Cc: the.dead.shall.rise@… added

comment:15 Changed 5 years ago by refold

Can we just ape what Python's os.path.normpath is doing?

comment:16 Changed 3 years ago by Blaisorblade

Documenting the current behavior is better than nothing, but settling on that seems a regression from portable languages to C.

I want to argue that settling on platform-dependent behavior is a worse idea than figuring out a sensible platform-independent behavior, possibly by surveying other languages (Python as proposed above, or maybe Java). Additional system-specific APIs are probably fine for lower-level development, but they seem lower-priority to me.

This bug keeps causing portability problems for Haskell applications. I remember cabal needed fixing for this; right now I ran into this for hp2any-graph, which tries to canonicalize a filename that is going to appear. Therefore, quite a few programs that use canonicalizePath and were developed on Linux only break on other platforms.

comment:17 Changed 3 years ago by thoughtpolice

Milestone: 7.6.27.10.1

Moving to 7.10.1.

comment:18 Changed 3 years ago by thoughtpolice

Component: libraries/directoryCore Libraries
Owner: set to ekmett

Moving over to new owning component 'Core Libraries'.

comment:19 Changed 3 years ago by thoughtpolice

Milestone: 7.10.17.12.1

Moving to 7.12.1 milestone; if you feel this is an error and should be addressed sooner, please move it back to the 7.10.1 milestone.

comment:20 Changed 3 years ago by ekmett

Cc: core-libraries-committee@… added

#4215 seems related

comment:21 Changed 2 years ago by Rufflewind

Resolution: fixed
Status: newclosed

Fixed upstream.

comment:22 Changed 2 years ago by thoughtpolice

Milestone: 7.12.18.0.1

Milestone renamed

Note: See TracTickets for help on using tickets.