From 1ee0ba430e1d4b6b391782a937e51d220bcf8da8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 20 Sep 2025 11:03:05 +0000 Subject: [PATCH 1/3] Initial plan From f86a8c26c99cf21d8c2a21c7acf7276f088c7bdf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 20 Sep 2025 11:05:30 +0000 Subject: [PATCH 2/3] Initial plan for VGDE codebase improvements Co-authored-by: veddevv <101126539+veddevv@users.noreply.github.com> --- __pycache__/vgde.cpython-312.pyc | Bin 0 -> 22111 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 __pycache__/vgde.cpython-312.pyc diff --git a/__pycache__/vgde.cpython-312.pyc b/__pycache__/vgde.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6045c69c640a91d70df7be40014737b72107d5c1 GIT binary patch literal 22111 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 Date: Sat, 20 Sep 2025 11:07:48 +0000 Subject: [PATCH 3/3] Implement core improvements: regex pre-compilation, robust DEVELOPER_MODE parsing, and constant cleanup Co-authored-by: veddevv <101126539+veddevv@users.noreply.github.com> --- .gitignore | 37 ++++++++++++++++++++++ __pycache__/vgde.cpython-312.pyc | Bin 22111 -> 0 bytes vgde.py | 52 +++++++++++++++++++------------ 3 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 .gitignore delete mode 100644 __pycache__/vgde.cpython-312.pyc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..efaef3e --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Python cache files +__pycache__/ +*.py[cod] +*$py.class + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual environments +venv/ +env/ +ENV/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/__pycache__/vgde.cpython-312.pyc b/__pycache__/vgde.cpython-312.pyc deleted file mode 100644 index 6045c69c640a91d70df7be40014737b72107d5c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22111 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 bool: + """Parse environment variable as boolean with various truthy/falsey values.""" + if not value: + return default + value = value.lower().strip() + return value in ('true', '1', 't', 'yes', 'y', 'on', 'enable', 'enabled') + +DEVELOPER_MODE = _parse_boolean_env(os.getenv('DEVELOPER_MODE', 'false')) # Enhanced timeout validation with bounds checking try: @@ -136,9 +141,13 @@ def strip_html_tags(html_text: str) -> str: result = html.unescape(s.get_data()).strip() # Additional length check after processing return result[:config.MAX_DESCRIPTION_SIZE] if len(result) > config.MAX_DESCRIPTION_SIZE else result - except Exception as e: + except (html.parser.HTMLParseError, UnicodeDecodeError, UnicodeError) as e: logger.warning(f"HTML parsing failed: {e}") return html_text # Return original text if parsing fails + except Exception as e: + # Log unexpected errors but still handle gracefully + logger.warning(f"Unexpected error during HTML parsing: {e}") + return html_text def validate_game_name(game_name: str) -> str: """ @@ -172,7 +181,7 @@ def validate_game_name(game_name: str) -> str: # Replace smart quotes and other special characters with standard ones game_name = _normalize_special_characters(game_name) - if not re.match(config.GAME_NAME_PATTERN, game_name): + if not GAME_NAME_REGEX.match(game_name): raise InvalidInputError( "Game name contains invalid characters. Only letters, numbers, spaces, " "and the following special characters are allowed: - . ' , : ! &" @@ -247,13 +256,18 @@ def _check_content_size(response: requests.Response) -> None: Raises: ValueError: If content is too large """ + # Primary guard: Check content-length header first to avoid reading large content content_length = response.headers.get('content-length') if content_length and int(content_length) > config.MAX_RESPONSE_SIZE: raise ValueError("Response too large") - content = response.content - if len(content) > config.MAX_RESPONSE_SIZE: - raise ValueError("Response content too large") + # If no content-length header, we need to check actual content size + # but only read it once when necessary + if not content_length and not hasattr(response, '_content_checked'): + content = response.content # This will cache the content + if len(content) > config.MAX_RESPONSE_SIZE: + raise ValueError("Response content too large") + response._content_checked = True def fetch_game_data(game_name: str) -> Optional[Dict[str, Any]]: @@ -269,7 +283,7 @@ def fetch_game_data(game_name: str) -> Optional[Dict[str, Any]]: Raises: RateLimitError: If the API rate limit is exceeded. """ - url = f"{BASE_URL}{GAMES_ENDPOINT}" + url = f"{config.BASE_URL}{config.GAMES_ENDPOINT}" params = {'key': API_KEY, 'search': game_name} try: @@ -310,14 +324,12 @@ def fetch_game_data(game_name: str) -> Optional[Dict[str, Any]]: logger.error("Unexpected API response format") return None - if 'results' in data and isinstance(data['results'], list): - if len(data['results']) > 0: - return data['results'][0] - else: - logger.warning(f"No results found for game '{game_name}'.") - return None + # Since _validate_api_response already confirmed structure, we can safely access results + results = data['results'] + if len(results) > 0: + return results[0] else: - logger.error("Unexpected API response structure") + logger.warning(f"No results found for game '{game_name}'.") return None except requests.exceptions.Timeout: