Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions gittensor/utils/github_api_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,15 @@ def check_github_issue_closed(repo: str, issue_number: int, token: str) -> Optio
return None


def _escape_graphql_string(value: str) -> str:
"""Escape special characters for safe interpolation into a GraphQL string literal.

Backslashes and double quotes in file paths would break the GraphQL query
syntax when interpolated into ``expression: "..."`` fields.
"""
return value.replace('\\', '\\\\').replace('"', '\\"')


def _fetch_file_contents_batch(
repo_owner: str,
repo_name: str,
Expand All @@ -1261,7 +1270,7 @@ def _fetch_file_contents_batch(
"""
file_fields = []
for i, path in enumerate(batch_paths):
expression = f'{head_sha}:{path}'
expression = _escape_graphql_string(f'{head_sha}:{path}')
file_fields.append(
f'file{i}: object(expression: "{expression}") {{ ... on Blob {{ text byteSize isBinary }} }}'
)
Expand Down Expand Up @@ -1371,14 +1380,14 @@ def _fetch_file_contents_with_base_batch(

# New files have no base version to fetch
if fc.status != 'added':
base_expr = f'{base_sha}:{base_path}'
base_expr = _escape_graphql_string(f'{base_sha}:{base_path}')
file_fields.append(
f'base{i}: object(expression: "{base_expr}") {{ ... on Blob {{ text byteSize isBinary }} }}'
)

# Deleted files have no head version to fetch
if fc.status != 'removed':
head_expr = f'{head_sha}:{head_path}'
head_expr = _escape_graphql_string(f'{head_sha}:{head_path}')
file_fields.append(
f'head{i}: object(expression: "{head_expr}") {{ ... on Blob {{ text byteSize isBinary }} }}'
)
Expand Down