diff --git a/backend/app/services/code_assistant.py b/backend/app/services/code_assistant.py index 951853c..c83c5b6 100644 --- a/backend/app/services/code_assistant.py +++ b/backend/app/services/code_assistant.py @@ -495,8 +495,8 @@ class BugPattern: # ── Java ── BugPattern( "Null Pointer Risk", - r"\w+\s*\.\s*\w+\s*\(", - "Method called on object that may be null — NullPointerException risk.", + r"=\s*null\b.{0,200}\.(\w+)\s*\(|\breturn\s+null\b", + "Variable assigned null then used, or method returns null directly — NullPointerException risk.", "Add null check: `if (obj != null) { ... }` or use `Optional`.", "warning", ["Java"], @@ -533,6 +533,78 @@ class BugPattern: "error", ["Java"], ), + BugPattern( + "Empty Catch Block", + r"catch\s*\([^)]+\)\s*\{\s*\}", + "Empty catch block silently swallows exceptions — bugs become invisible.", + "At minimum log the exception: `e.printStackTrace()` or use a logger.", + "warning", + ["Java"], + ), + BugPattern( + "printStackTrace Usage", + r"\.printStackTrace\s*\(\s*\)", + "`printStackTrace()` writes to stderr and is not suitable for production logging.", + "Use a proper logger: `logger.error(\"msg\", e)`.", + "warning", + ["Java"], + ), + BugPattern( + "Mutable Static Field", + r"\bstatic\b(?!.*\bfinal\b).*\b(List|Map|Set|ArrayList|HashMap|HashSet)\b", + "Mutable static field shared across all instances — thread-safety and state leak risk.", + "Make it `static final` and use an immutable collection, or use instance fields.", + "warning", + ["Java"], + ), + BugPattern( + "String Concatenation in Loop", + r"(for|while)[^{]*\{[^}]*\+=[^}]*\"", + "String concatenation with `+=` inside a loop creates many temporary objects — O(n²).", + "Use `StringBuilder` and call `.append()` inside the loop, then `.toString()` after.", + "warning", + ["Java"], + ), + BugPattern( + "Catching Throwable", + r"catch\s*\(\s*Throwable\s+\w+\s*\)", + "Catching `Throwable` includes `Error` subclasses like `OutOfMemoryError` — almost never correct.", + "Catch `Exception` or a specific checked exception instead.", + "error", + ["Java"], + ), + BugPattern( + "Hardcoded IP Address", + r"\"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\"", + "Hardcoded IP address found — breaks portability across environments.", + "Move the IP to a configuration file or environment variable.", + "warning", + ["Java"], + ), + BugPattern( + "Thread.sleep in Production", + r"Thread\.sleep\s*\(", + "`Thread.sleep()` blocks the thread and is a sign of polling anti-pattern.", + "Use `ScheduledExecutorService`, `CompletableFuture`, or event-driven design instead.", + "warning", + ["Java"], + ), + BugPattern( + "Ignoring Return Value", + r"^\s*\w+\.\w+\([^)]*\)\s*;\s*$", + "Return value of method call is ignored — may silently discard errors or results.", + "Assign the return value or verify the method has no meaningful return.", + "info", + ["Java"], + ), + BugPattern( + "Finalize Method", + r"protected\s+void\s+finalize\s*\(", + "`finalize()` is deprecated in Java 9+ and unreliable for resource cleanup.", + "Use `try-with-resources` or implement `AutoCloseable` instead.", + "warning", + ["Java"], + ), # ── C++ ── BugPattern( "Memory Leak", @@ -710,6 +782,78 @@ class BugPattern: "error", ["C++", "Java", "JavaScript", "TypeScript"], ), + BugPattern( + "strcpy/strcat Usage", + r"\b(strcpy|strcat)\s*\(", + "`strcpy`/`strcat` do not check buffer size — classic buffer overflow vulnerability.", + "Use `strncpy`/`strncat` with explicit size, or prefer `std::string`.", + "error", + ["C++"], + ), + BugPattern( + "Missing Virtual Destructor", + r"class\s+\w+[^{]*\{[^}]*virtual[^}]*(?", + "Explicit null pointer dereference detected — immediate crash at runtime.", + "Always check pointer validity before dereferencing.", + "error", + ["C++"], + ), + BugPattern( + "sprintf Usage", + r"\bsprintf\s*\(", + "`sprintf` does not check buffer bounds — use `snprintf` with explicit size.", + "Replace with `snprintf(buf, sizeof(buf), ...)` to prevent buffer overflow.", + "error", + ["C++"], + ), + BugPattern( + "Catching All Exceptions", + r"catch\s*\(\.\.\.\)", + "`catch(...)` silently swallows all exceptions including system signals.", + "Catch specific exception types and log or rethrow appropriately.", + "warning", + ["C++"], + ), + BugPattern( + "Integer Overflow Risk", + r"\b(int|short)\s+\w+\s*\*\s*\w+", + "Multiplication of `int`/`short` values may silently overflow.", + "Cast to `long long` before multiplying: `(long long)a * b`.", + "warning", + ["C++"], + ), + BugPattern( + "Hardcoded File Path", + r'"(/home/|/tmp/|C:\\\\|/var/)', + "Hardcoded absolute file path — breaks portability across systems.", + "Use relative paths or read the path from a config/environment variable.", + "warning", + ["C++", "Java"], + ), # ── PHP ── BugPattern( "PHP MySQL Deprecated", diff --git a/backend/tests/test_share.py b/backend/tests/test_share.py index c7edef5..eeea1b3 100644 --- a/backend/tests/test_share.py +++ b/backend/tests/test_share.py @@ -1,6 +1,8 @@ from __future__ import annotations -from datetime import UTC, datetime, timedelta +from datetime import datetime, timedelta, timezone + +UTC = timezone.utc from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker diff --git a/frontend/index.html b/frontend/index.html index 71b8e3a..da19307 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -661,7 +661,44 @@ border-right: 1px solid var(--border); } + .editor-inner { + position: relative; + flex: 1; + overflow: hidden; + } + + #lintOverlay { + position: absolute; + top: 0; left: 0; + width: 100%; + pointer-events: none; + padding: 16px; + font-family: var(--font-mono); + font-size: 13px; + line-height: 1.7; + white-space: pre-wrap; + word-break: break-all; + overflow: hidden; + box-sizing: border-box; + color: transparent; + z-index: 2; + } + + .lint-error-line { + display: block; + border-bottom: 2px solid var(--red); + background: rgba(242, 87, 87, 0.08); + } + + .lint-warning-line { + display: block; + border-bottom: 2px solid var(--yellow); + background: rgba(245, 200, 66, 0.07); + } + #codeEditor { + position: relative; + z-index: 3; width: 100%; min-height: 300px; max-height: 500px; @@ -2188,7 +2225,10 @@

File Upload

1
- +
+ + +