Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for https://github.com/fyne-io/fyne/issues/5207 #5215

Open
wants to merge 3 commits into
base: release/v2.5.x
Choose a base branch
from

Conversation

brucealthompson
Copy link

Description:

Fixes #(issue)

Checklist:

  • Tests included.
  • Lint and formatter run with no errors.
  • Tests all pass.

Where applicable:

  • Public APIs match existing style and have Since: line.
  • Any breaking changes have a deprecation path or have been discussed.
  • Check for binary size increases when importing new modules.

Copy link
Member

@andydotxyz andydotxyz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right - the new URI is constructed essentially from a file path, you can see it starts with:

buildDir := filepath.VolumeName(localdir)

but then is created as:

newURL := dir.Scheme() + "://" + filepath.ToSlash(buildDir)

This does not seem right. I cannot tell exactly what is happening here, but simply swapping the correct scheme where "file://" is used will not be the right fix as file uris/paths are being assumed in this whole code chunk.

I think the right fix will be to traverse this properly with the storage API to iterate on the storage.Parent result to walk back up the "tree".

@brucealthompson
Copy link
Author

I was trying to make as minimal a change as possible. The fix certainly works for the "file" repository and my "httpfile" repository that I created.

This does not seem right. I cannot tell exactly what is happening here, but simply swapping the correct scheme where "file://" is used will not be the right fix as file uris/paths are being assumed in this whole code chunk.

I think the right fix will be to traverse this properly with the storage API to iterate on the storage. Parent result to walk back up the "tree".

I did not touch the code that manipulated the path. I believe the data structure represented by a fyne URI is the same as an RFC 3986 URI and the same as is represented by the golang URI https://pkg.go.dev/go.lsp.dev/uri#URI. I believe the path manipulation code you are referring to is correct for manipulating an RFC 3986 compliant path.

The only potential issue with the code you are referring to is that the "file" repository as well as the the "httpfile" repository can include DOS drive letters in the path. IE, a valid "file" repository URL is "file://c:/foo". This is a valid URI according to RFC 8089 https://datatracker.ietf.org/doc/html/rfc8089#page-13. The fyne storage.ParseURI() call does not parse this type of URI correctly and ends up putting the drive letter in the Authority field of the URI. I had to work around this issue in my "httpfile" repository code. So there is a bug in the fyne fyne storage.ParseURI() code. I think the storage.ParseURI() implementation should call the golang uri.ParseURI function instead of having the fyne repository interface provide its own implementation for this.

The only issue I could see with the fix I made is this:
newURL := dir.Scheme() + "://" + filepath.ToSlash(buildDir)

The filepath.ToSlash() call should not be necessary since buildDir should be an RFC 3986 compliant path, I do not remember why I did this. I will try removing it and test to make sure everything works.

@brucealthompson
Copy link
Author

OK. I fixed the path manipulation code. Here are the changes
fyne fix

Notice newURL := dir.Scheme() + "://" + filepath.ToSlash(buildDir) >> newURL := dir.Scheme() + "://" + buildDir

I also found the issue in the fyne storage.ParseURI() code. Here it is:
if strings.EqualFold(scheme, "file") {
// Does this really deserve to be special? In principle, the
// purpose of this check is to pass it to NewFileURI, which
// allows platform path seps in the URI (against the RFC, but
// easier for people building URIs naively on Windows). Maybe
// we should punt this to whoever generated the URI in the
// first place?

This code should be independent of scheme. This is a separate issue.

@brucealthompson
Copy link
Author

I also found the issue in the fyne storage.ParseURI() code. Here it is:
if strings.EqualFold(scheme, "file") {
// Does this really deserve to be special? In principle, the
// purpose of this check is to pass it to NewFileURI, which
// allows platform path seps in the URI (against the RFC, but
// easier for people building URIs naively on Windows). Maybe
// we should punt this to whoever generated the URI in the
// first place?

This code should be independent of scheme. This is a separate issue.

I have fixed this issue for my httpfile repository. The fix is to add a ParseURI method to the repository. Here is what I imples code should be independent of scheme. This is a separate issue.

I have fixed this issue for my httpfile repository. The fix is to add a ParseURI method to the repository. Here is what I implemented for the httpfile repository:

func (r *HttpFileRepository) ParseURI(uristring string) (fyne.URI, error) {
	localurl, err := url.Parse(uristring)
	if err != nil {
		return nil, err
	}
	uri := &uri{
		scheme: localurl.Scheme,
		// url.Parse interprets windows drive letters as a Host. Include this in the path.
		path:      localurl.Host + localurl.Path,
		authority: "",
		fragment:  "",
		query:     "",
	}
	return uri, nil
}

I believe the same fix cam be applied to the "file" repository. Then the repository specific code in fyne storage.ParseURI() that I highlighted above can be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants