1616from monty .bot import Monty
1717from monty .log import get_logger
1818from monty .utils import scheduling
19- from monty .utils .helpers import EXPAND_BUTTON_PREFIX , decode_github_link
19+ from monty .utils .helpers import EXPAND_BUTTON_PREFIX , block_url_traversal , decode_github_link
2020from monty .utils .markdown import remove_codeblocks
2121from monty .utils .messages import DeleteButton , suppress_embeds
2222
3030
3131# start_char, line_delimiter, and end_char are currently unused.
3232GITHUB_RE = re .compile (
33- r"https?:\/\/github\.(?:com|dev)\/(?P<user>[a-zA-Z0-9-]+)\/(?P<repo>[a-zA-Z0-9-]+)\/(?:blob|tree)\/(?P<path>[^#>]+)(\?[^#>]+)?"
33+ r"https?:\/\/github\.(?:com|dev)\/(?P<user>[a-zA-Z0-9-]+)\/(?P<repo>[a-zA-Z0-9-]+)\/(?:blob|tree)\/"
34+ r"(?P<path>[^#>]+/[^#>]+)(\?[^#>]+)?"
3435 r"(?:(#L(?P<L>L)?(?P<start_line>\d+)(?(L)C(?P<start_char>\d+))(?:(?P<line_delimiter>[-~\:]"
3536 r"|(\.\.))L(?P<end_line>\d+)(?(L)C(?P<end_char>\d+)))?))"
3637)
@@ -119,17 +120,22 @@ async def _fetch_github_snippet(
119120 repo : str ,
120121 path : str ,
121122 start_line : str ,
122- end_line : str ,
123+ end_line : str | None ,
123124 ** kwargs : "NoReturn" ,
124125 ) -> str :
125126 """Fetches a snippet from a GitHub repo."""
127+ user , repo , start_line = block_url_traversal (user , repo , start_line )
128+ if end_line :
129+ end_line = block_url_traversal (end_line )
130+
126131 # Search the GitHub API for the specified branch
127132 r = await self .bot .github .rest .repos .async_list_branches (user , repo , per_page = 100 )
128133 branches = r .json ()
129134 r = await self .bot .github .rest .repos .async_list_tags (user , repo , per_page = 100 )
130135 tags = r .json ()
131136 refs = branches + tags
132137 ref , encoded_file_path = self ._find_ref (path , refs )
138+ ref , encoded_file_path = block_url_traversal (ref , encoded_file_path )
133139
134140 r = await self .bot .github .rest .repos .async_get_content (
135141 user ,
@@ -156,6 +162,9 @@ async def _fetch_github_gist_snippet(
156162 ** kwargs : "NoReturn" ,
157163 ) -> str :
158164 """Fetches a snippet from a GitHub gist."""
165+ gist_id , revision , file_path , start_line , end_line = block_url_traversal (
166+ gist_id , revision , file_path , start_line , end_line
167+ )
159168 if revision :
160169 endpoint = self .bot .github .rest .gists .async_get_revision (gist_id , revision )
161170 else :
@@ -186,20 +195,17 @@ async def _fetch_gitlab_snippet(
186195 ** kwargs : "NoReturn" ,
187196 ) -> str :
188197 """Fetches a snippet from a GitLab repo."""
189- enc_repo = quote_plus (repo )
190-
198+ repo , start_line , end_line = block_url_traversal (repo , start_line , end_line )
191199 # Searches the GitLab API for the specified branch
192- branches = await self ._fetch_response (
193- f"https://gitlab.com/api/v4/projects/{ enc_repo } /repository/branches" , "json"
194- )
195- tags = await self ._fetch_response (f"https://gitlab.com/api/v4/projects/{ enc_repo } /repository/tags" , "json" )
200+ branches = await self ._fetch_response (f"https://gitlab.com/api/v4/projects/{ repo } /repository/branches" , "json" )
201+ tags = await self ._fetch_response (f"https://gitlab.com/api/v4/projects/{ repo } /repository/tags" , "json" )
196202 refs = branches + tags
197203 ref , file_path = self ._find_ref (path , refs )
198- enc_ref = quote_plus (ref )
199- enc_file_path = quote_plus (file_path )
204+ ref = quote_plus (ref )
205+ path = quote_plus (file_path )
200206
201207 file_contents = await self ._fetch_response (
202- f"https://gitlab.com/api/v4/projects/{ enc_repo } /repository/files/{ enc_file_path } /raw?ref={ enc_ref } " ,
208+ f"https://gitlab.com/api/v4/projects/{ repo } /repository/files/{ path } /raw?ref={ ref } " ,
203209 "text" ,
204210 )
205211 return self ._snippet_to_codeblock (file_contents , file_path , start_line , end_line )
0 commit comments