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

Some tweaks to is_in_or_equal #9020

Merged
merged 28 commits into from
Aug 6, 2024
Merged

Some tweaks to is_in_or_equal #9020

merged 28 commits into from
Aug 6, 2024

Conversation

freddyaboulton
Copy link
Collaborator

@freddyaboulton freddyaboulton commented Aug 5, 2024

Description

  • Consolidates usages of "safe_join" across the code base to use a common util function
  • Introduces DeveloperPath and UserProvidedPath type aliases to make it clearer what each argument of safe join should be
  • Adds a test fuzzer for "safe_join"

🎯 PRs Should Target Issues

Before your create a PR, please check to see if there is an existing issue for this change. If not, please create an issue before you create this PR, unless the fix is very small.

Not adhering to this guideline will result in the PR being closed.

Tests

  1. PRs will only be merged if tests pass on CI. To run the tests locally, please set up your Gradio environment locally and run the tests: bash scripts/run_all_tests.sh

  2. You may need to run the linters: bash scripts/format_backend.sh and bash scripts/format_frontend.sh

@gradio-pr-bot
Copy link
Collaborator

gradio-pr-bot commented Aug 5, 2024

🪼 branch checks and previews

Name Status URL
Spaces ready! Spaces preview
Website ready! Website preview
Storybook ready! Storybook preview
🦄 Changes detected! Details

Install Gradio from this PR

pip install https://gradio-pypi-previews.s3.amazonaws.com/8bc4c39139dd33fac41dce5e469886345407e165/gradio-4.40.0-py3-none-any.whl

Install Gradio Python Client from this PR

pip install "gradio-client @ git+https://github.com/gradio-app/gradio@8bc4c39139dd33fac41dce5e469886345407e165#subdirectory=client/python"

Install Gradio JS Client from this PR

npm install https://gradio-npm-previews.s3.amazonaws.com/8bc4c39139dd33fac41dce5e469886345407e165/gradio-client-1.4.0.tgz

@@ -1466,3 +1459,23 @@ def __len__(self):

def as_list(self):
return [v for _, v in self.data]


def safe_join(directory: DeveloperPath, path: UserProvidedPath) -> str:
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using these custom types so that in the future user provided paths are not accidentally sanitized before being joined

freddyaboulton and others added 20 commits August 5, 2024 19:52
* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd
* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* :[
* add max/min-imize and zoom in and out to image preview

* add full screen icon to gallery

* add stories

* add changeset

* use native full screen api

* remove zoom in/out

* add changeset

* tweaks

* remove zoom prop

* fix ui test

* add annotated image btns

* add changeset

* format

* ruff format

* fix test

* remove

* tweak

* fix test

* format

* amend bool check

---------

Co-authored-by: gradio-pr-bot <[email protected]>
Co-authored-by: pngwn <[email protected]>
* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* asd

* :[

* asd
* asd

* asd

* asd

* asd

* adsa

* asd
* asd

* asd

* asd

* asd

* adsa

* asd

* asd
* better header for mobile

* add changeset

* nicer border

* style header

* better search overlay

* responsive changes

* more mobile responsiveness

* docs and guides mobile responsive

* formatting

* fix get started button

* fix header

* test without lite

* formatting

* secondary menu docs

* fix type overflow in paramtable

* playground header

* playground on mobile

* small changes

* formatting

* formatting

---------

Co-authored-by: gradio-pr-bot <[email protected]>
* asd

* asd

* asd

* asd

* adsa

* asd

* asd

* asd
* asd

* asd

* asd

* asd

* adsa

* asd

* asd

* asd

* fix
@gradio-pr-bot
Copy link
Collaborator

gradio-pr-bot commented Aug 6, 2024

🦄 change detected

This Pull Request includes changes to the following packages.

Package Version
gradio patch
  • Maintainers can select this checkbox to manually select packages to update.

With the following changelog entry.

Some tweaks to is_in_or_equal

Maintainers or the PR author can modify the PR title to modify this entry.

Something isn't right?

  • Maintainers can change the version label to modify the version bump.
  • If the bot has failed to detect any changes, or if this pull request needs to update multiple packages to different versions or requires a more comprehensive changelog entry, maintainers can update the changelog file directly.

@freddyaboulton freddyaboulton added the v: patch A change that requires a patch release label Aug 6, 2024
@freddyaboulton freddyaboulton marked this pull request as ready for review August 6, 2024 16:49
path_2=create_path_string(),
)
def test_is_in_or_equal_fuzzer(path_1, path_2):
print(path_1, path_2)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
print(path_1, path_2)

gradio/routes.py Outdated
]

def routes_safe_join(directory: DeveloperPath, path: UserProvidedPath) -> str:
"""Safely join the user path to the directory while performing some additional http-related checks."""
Copy link
Member

Choose a reason for hiding this comment

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

Nice this makes sense. Perhaps worth mentioning the checks explicitly here:

Suggested change
"""Safely join the user path to the directory while performing some additional http-related checks."""
"""Safely join the user path to the directory while performing some additional http-related checks, e.g. ensuring that the full path exists on the local file system and is not a directory."""

@@ -543,7 +559,7 @@ async def file(path_or_url: str, request: fastapi.Request):

is_dir = abs_path.is_dir()

if in_blocklist or is_dir:
if is_dir or in_blocklist:
Copy link
Member

Choose a reason for hiding this comment

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

curious why :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Typo hehe. Originally moved is_blocklist to be a separate check but realized we don't have to do that

gradio/routes.py Outdated
temp_file.file.close()
# we need to move the temp file to the cache directory
# but that's possibly blocking and we're in an async function
# but that's possibl y blocking and we're in an async function
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# but that's possibl y blocking and we're in an async function
# but that's possibly blocking and we're in an async function

Comment on lines 1344 to 1345
import tempfile
from pathlib import Path
Copy link
Member

Choose a reason for hiding this comment

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

nit: might as well put these imports at the top of the file?

gradio/utils.py Outdated
@@ -1090,7 +1083,7 @@ def is_in_or_equal(path_1: str | Path, path_2: str | Path):
return ".." not in str(relative_path)
except ValueError:
return False
return True
return False
Copy link
Member

@abidlabs abidlabs Aug 6, 2024

Choose a reason for hiding this comment

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

When is this ever used? It seems like the function should terminate by lines 1083 or 1085 at the latest

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes this is right - I think we can remove but just kept because I figured it was there for a reason lol


if path.is_absolute():
return path
return Path(os.path.abspath(str(path)))
Copy link
Member

Choose a reason for hiding this comment

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

Ok so the reason we used the convoluted symlink logic is because of this issue: #3024

Basically, we don't want to resolve symlinks but we do want to make them absolute. This fix might work, let me check

Copy link
Member

Choose a reason for hiding this comment

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

Ok so this should work, nice! I would just add a test case in test_utils.py to confirm that symlinks are made absolute but not resolved.

def _safe_join(self, folders: list[str]):
if not folders or len(folders) == 0:
return self.root_dir
head, tail = folders[0], folders[1:]
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's the purpose of splitting head and tail? Why can't we do combined_path = UserProvidedPath(os.path.join(*folders)) directly

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It was originally like that but then I ran into errors in the functional tests. I thought it was because os.path.join couldn't handle a single argument but it's actually because the list was empty.

So long story short, I think we can use the line you're suggesting since I added the empty list check right above.

@@ -85,7 +86,7 @@ def __init__(
)
root_dir = root
self._constructor_args[0]["root_dir"] = root
self.root_dir = os.path.abspath(root_dir)
self.root_dir = cast(DeveloperPath, os.path.abspath(root_dir))
Copy link
Collaborator

Choose a reason for hiding this comment

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

could we do DeveloperPath(os.path.abspath(root_dir)) instead of using casting?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also applies to casting in routes.py, can we replace all casting with just directly creating the DeveloperPath with a string?

Copy link
Member

@abidlabs abidlabs left a comment

Choose a reason for hiding this comment

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

Awesome PR @freddyaboulton! I went through and reviewed it as thoroughly as I good and everything lgtm. Just a few nits above

Copy link
Collaborator

@aliabid94 aliabid94 left a comment

Choose a reason for hiding this comment

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

LGTM, some small comments but great work freddy

@freddyaboulton
Copy link
Collaborator Author

Thanks for the reviews! I've addressed all of the comments

@freddyaboulton freddyaboulton merged commit 08b5159 into main Aug 6, 2024
18 checks passed
@freddyaboulton freddyaboulton deleted the is-in-or-equal-tweaks branch August 6, 2024 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v: patch A change that requires a patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants