Conversation
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…nvoicePlane into fix/niels-1-sales-by-year
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull Request Overview
This PR fixes SQL injection vulnerabilities in the sales_by_year report function by properly escaping user input parameters and simplifying quantity validation logic.
- Replaces conditional quantity validation with direct integer casting
- Adds proper database escaping for minQuantity and maxQuantity parameters in SQL queries
- Removes unnecessary empty line spacing
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| $minQuantity = (int) $minQuantity; | ||
| $maxQuantity = (int) $maxQuantity; |
There was a problem hiding this comment.
Casting $maxQuantity (default null) to 0 when it is not provided changes behavior from (previously invalid SQL that should have been omitted) to a restrictive filter (0 >= SUM(...)) that will likely exclude all valid rows. Instead, only apply the max quantity predicate when a max value is explicitly supplied (e.g., not null / not empty), leaving the upper bound unbounded otherwise.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughUpdates Mdl_reports.php to cast quantity filters to integers, escape values in SQL WHERE clauses, and standardize from_date/to_date handling via direct ternary date_to_mysql conversions. Control flow remains the same for taxChecked branches; only type handling and SQL fragment construction are adjusted. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
application/modules/reports/models/Mdl_reports.php (1)
326-326: Handle null quantity values in WHERE clause.After fixing the casting issue at lines 214-215, these lines need null checks to avoid injecting
nullinto the SQL (which would cause syntax errors).Apply this diff to conditionally include the quantity filters:
- AND ' . $minQuantity . ' <= + AND ' . ($minQuantity !== null ? $minQuantity : 0) . ' <= ( SELECT SUM(amounts2.invoice_item_subtotal) FROM ip_invoice_amounts amounts2 WHERE amounts2.invoice_id IN ( SELECT inv2.invoice_id FROM ip_invoices inv2 WHERE inv2.client_id=ip_clients.client_id AND ' . $this->db->escape($from_date) . ' <= inv2.invoice_date_created AND ' . $this->db->escape($to_date) . ' >= inv2.invoice_date_created ) - ) AND ' . $maxQuantity . ' >= + )' . ($maxQuantity !== null ? ' AND ' . $maxQuantity . ' >=' : ' AND 1=1 OR 0 >=') . 'Better yet, refactor to only add these clauses when values are provided (see the conditional logic at line 228 for
if ($maxQuantity)).Also applies to: 336-336
♻️ Duplicate comments (4)
application/modules/reports/models/Mdl_reports.php (4)
449-449: Handle null minQuantity value in WHERE clause.Same issue as lines 326, 336: after fixing the casting at line 214, this needs a null check.
Apply this diff:
- AND ' . $minQuantity . ' <= + AND ' . ($minQuantity !== null ? $minQuantity : 0) . ' <=
214-215: Critical: Casting null to 0 breaks max quantity logic.Casting
$maxQuantity(defaultnull) to0transforms an intended unbounded filter into a highly restrictive one (0 >= SUM(...)) that excludes all positive totals. When no max is provided, the upper-bound check should be omitted entirely.Apply this diff to only cast when values are actually provided:
- $minQuantity = (int) $minQuantity; - $maxQuantity = (int) $maxQuantity; + $minQuantity = $minQuantity !== null && $minQuantity !== '' ? (int) $minQuantity : null; + $maxQuantity = $maxQuantity !== null && $maxQuantity !== '' ? (int) $maxQuantity : null;Then check for null before using these values in WHERE clauses (see subsequent comments).
564-564: Inconsistent quantity handling: mixing inline cast with escape.Line 564 uses
(int)$minQuantitywhile line 574 uses$this->db->escape($maxQuantity). Since both are already cast to integers at lines 214-215, this inconsistency is confusing.Choose one approach and apply consistently:
Option 1: Direct integer concatenation (preferred after fixing null handling):
- AND ' . (int)$minQuantity . ' <= + AND ' . ($minQuantity !== null ? $minQuantity : 0) . ' <= ( SELECT SUM(amounts2.invoice_total) FROM ip_invoice_amounts amounts2 WHERE amounts2.invoice_id IN ( SELECT inv2.invoice_id FROM ip_invoices inv2 WHERE inv2.client_id=ip_clients.client_id AND ' . $this->db->escape($from_date) . ' <= inv2.invoice_date_created AND ' . $this->db->escape($to_date) . ' >= inv2.invoice_date_created ) - ) AND ' . $this->db->escape($maxQuantity) . ' >= + )' . ($maxQuantity !== null ? ' AND ' . $maxQuantity . ' >=' : ' AND 1=1 OR 0 >=') . 'Option 2: Use escape consistently (if you prefer belt-and-suspenders):
- AND ' . (int)$minQuantity . ' <= + AND ' . $this->db->escape($minQuantity !== null ? $minQuantity : 0) . ' <=Also applies to: 574-574
687-687: Inconsistent with line 564 and needs null handling.Line 564 uses
(int)$minQuantitywhile this line uses$this->db->escape($minQuantity). Pick one approach and apply it consistently across all WHERE clauses.After fixing the casting at line 214 to allow null values, update this line:
- AND ' . $this->db->escape($minQuantity) . ' <= + AND ' . ($minQuantity !== null ? $minQuantity : 0) . ' <=Or use escape consistently:
- AND ' . $this->db->escape($minQuantity) . ' <= + AND ' . $this->db->escape($minQuantity !== null ? $minQuantity : 0) . ' <=
🧹 Nitpick comments (1)
application/modules/reports/models/Mdl_reports.php (1)
217-218: Validate date conversion results.
date_to_mysql()returns an empty string if the date format is invalid. Using that empty string directly in SQL comparisons could produce unexpected results.Consider validating the conversion result:
- $from_date = $from_date == '' ? date('Y-m-d') : date_to_mysql($from_date); - $to_date = $to_date == '' ? date('Y-m-d') : date_to_mysql($to_date); + $from_date = $from_date == '' ? date('Y-m-d') : date_to_mysql($from_date); + $to_date = $to_date == '' ? date('Y-m-d') : date_to_mysql($to_date); + + // Fallback to today if conversion fails + $from_date = $from_date ?: date('Y-m-d'); + $to_date = $to_date ?: date('Y-m-d');
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
application/modules/reports/models/Mdl_reports.php(4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
application/modules/reports/models/Mdl_reports.php (1)
application/helpers/date_helper.php (1)
date_to_mysql(120-126)
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
application/modules/reports/models/Mdl_reports.php (2)
326-336: Standardize quantity interpolation across all branches.The code uses three different patterns for inserting integer quantities into SQL:
- Lines 326, 336, 449: direct concatenation (no cast, no escape)
- Line 564: inline
(int)cast- Lines 574, 687:
escape()callsSince quantities are already cast to
intat line 214-215, choose one consistent approach—either direct concatenation or inline casting—and apply it uniformly.- AND ' . $minQuantity . ' <= + AND ' . (int)$minQuantity . ' <= (...) - ) AND ' . $maxQuantity . ' >= + ) AND ' . (int)$maxQuantity . ' >=Then update lines 449, 564, 574, 687 similarly for uniformity.
Based on past review comments.
214-215: Critical: Casting null$maxQuantityto 0 breaks unbounded filtering.Casting
$maxQuantity(defaultnull) to(int)yields0, which changes the filter from "no upper limit" to "exclude rows whereSUM(...) > 0"—effectively blocking all valid results when the user does not specify a max.Solution: Only apply the max-quantity predicate when a non-null, non-zero value is explicitly provided.
Apply this diff to conditionally apply the max filter:
- $minQuantity = (int) $minQuantity; - $maxQuantity = (int) $maxQuantity; + $minQuantity = $minQuantity !== null && $minQuantity !== '' ? (int) $minQuantity : 0; + $maxQuantity = $maxQuantity !== null && $maxQuantity !== '' ? (int) $maxQuantity : null;Then, in the WHERE clauses (lines 326-348, 449-461, 555-586, 678-699), wrap the max-quantity comparison in a conditional check:
AND ' . $minQuantity . ' <= (...) -) AND ' . $maxQuantity . ' >= +)' . ($maxQuantity !== null ? ' AND ' . $maxQuantity . ' >=' : '') . ' (...)Based on learnings and past review comments.
🧹 Nitpick comments (1)
application/modules/reports/models/Mdl_reports.php (1)
217-218: Consider null-safe date handling.The empty-string check (
== '') may not catch all cases where dates are unset. For more robust validation, check fornullorempty().- $from_date = $from_date == '' ? date('Y-m-d') : date_to_mysql($from_date); - $to_date = $to_date == '' ? date('Y-m-d') : date_to_mysql($to_date); + $from_date = empty($from_date) ? date('Y-m-d') : date_to_mysql($from_date); + $to_date = empty($to_date) ? date('Y-m-d') : date_to_mysql($to_date);
|
closing this one, this one was merged when i merged #1354 |
Fix niels: sales by year
Summary by CodeRabbit