metaeducation / ren-c

Library for embedding a Rebol interpreter into C codebases
GNU Lesser General Public License v3.0
126 stars 27 forks source link

Discrepancy in Directory Handling using File Scheme #1103

Open rgchris opened 3 years ago

rgchris commented 3 years ago

There appears to be a discrepancy when handling directories within the FILE scheme depending on whether a port is initiated with a URL! or FILE! type:

>> read %/
== [...]

>> read file:///
** Error: Is a directory
** Where: fail read console
** Near: [fail make error! [
    type: _
    id: _
    message: "Is a...
** Line: 1

It's not clear why there'd be a difference between the two approaches.

hostilefork commented 3 years ago

Well, R3-Alpha seems to crash:

>> read file:///
== Segmentation fault (core dumped)

Anyway, I looked.

The reason is that when you have a filename, you can take it through the "directory actor" or the "file actor". If you give it to the directory actor, then it will treat the file string as a query...so if you give it a non-directory filename it will just tell you it's there...instead of reading its content.

For when a FILE! is given to make a port, there is a moment of decision in a helper called make-port* where it picks what actor to use...[dir file]...by way of picking which "scheme".

But when a URL! is given to that same helper, it goes through the URL's actor...which does a subdispatch. However, when this subdispatch runs it doesn't have the ability to distinguish between the "file actor" and the "directory actor". Instead the FILE:// handler always uses the file actor

Given the scheme right below the file:// one, it appears this was known to be how it was, and you are supposed to read dir:/// instead if that is what you mean.

There's not an obvious "right" way to change it, as written. Changing the scheme word for the request in the file code won't affect the actor, and changing the actor would "corrupt" it for the next request.

But long story short: The code path which achieves the detection for the dir-looking-FILE! %/ vs. the file-looking-FILE %foo.txt is early in the chain than where the broken-down URL! finds itself. The port is already open at that point and the decision made on what actor to use, as a direct consequence of the scheme word.