Skip to content

Commit

Permalink
🚸 Filename validator for new projects (#298)
Browse files Browse the repository at this point in the history
* use regex

* better path checker

* check for emojis in path

* change err message

* fix validation fail oops
  • Loading branch information
12944qwerty authored Feb 18, 2024
1 parent 08c0874 commit a335b80
Showing 1 changed file with 51 additions and 5 deletions.
56 changes: 51 additions & 5 deletions pros/conductor/conductor.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import errno
import os.path
import shutil
from enum import Enum
from pathlib import Path
import sys
from typing import *
import re

import click
from semantic_version import Spec, Version
Expand All @@ -27,6 +30,50 @@ class ReleaseChannel(Enum):
Beta = 'beta'
"""

def is_pathname_valid(pathname: str) -> bool:
'''
A more detailed check for path validity than regex.
https://stackoverflow.com/a/34102855/11177720
'''
try:
if not isinstance(pathname, str) or not pathname:
return False

_, pathname = os.path.splitdrive(pathname)

root_dirname = os.environ.get('HOMEDRIVE', 'C:') \
if sys.platform == 'win32' else os.path.sep
assert os.path.isdir(root_dirname)

root_dirname = root_dirname.rstrip(os.path.sep) + os.path.sep
for pathname_part in pathname.split(os.path.sep):
try:
os.lstat(root_dirname + pathname_part)
except OSError as exc:
if hasattr(exc, 'winerror'):
if exc.winerror == 123: # ERROR_INVALID_NAME, python doesn't have this constant
return False
elif exc.errno in {errno.ENAMETOOLONG, errno.ERANGE}:
return False

# Check for emojis
# https://stackoverflow.com/a/62898106/11177720
ranges = [
(ord(u'\U0001F300'), ord(u"\U0001FAF6")), # 127744, 129782
(126980, 127569),
(169, 174),
(8205, 12953)
]
for a_char in pathname:
char_code = ord(a_char)
for range_min, range_max in ranges:
if range_min <= char_code <= range_max:
return False
except TypeError as exc:
return False
else:
return True

class Conductor(Config):
"""
Provides entrances for all conductor-related tasks (fetching, applying, creating new projects)
Expand Down Expand Up @@ -314,13 +361,12 @@ def new_project(self, path: str, no_default_libs: bool = False, **kwargs) -> Pro
elif self.use_early_access:
ui.echo(f'Early access is enabled.')

if not is_pathname_valid(str(Path(path).absolute())):
raise dont_send(ValueError('Project path contains invalid characters.'))

if Path(path).exists() and Path(path).samefile(os.path.expanduser('~')):
raise dont_send(ValueError('Will not create a project in user home directory'))
for char in str(Path(path)):
if char in ['?', '<', '>', '*', '|', '^', '#', '%', '&', '$', '+', '!', '`', '\'', '=',
'@', '\'', '{', '}', '[', ']', '(', ')', '~'] or ord(char) > 127:
raise dont_send(ValueError(f'Invalid character found in directory name: \'{char}\''))


proj = Project(path=path, create=True)
if 'target' in kwargs:
proj.target = kwargs['target']
Expand Down

0 comments on commit a335b80

Please sign in to comment.