Skip to content
Open
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
36 changes: 36 additions & 0 deletions examples/review-demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Demo file for exercising PRowl end-to-end on a real PR.
// It contains three deliberate issues (one per detectable type) plus one
// intentionally clean function that must NOT be flagged.

const db = require("./db");

// (1) SECURITY — SQL injection: user input concatenated straight into a query.
function getOrder(req, res) {
const orderId = req.query.id;
const sql = "SELECT * FROM orders WHERE id = " + orderId;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SECURITY] The code is vulnerable to SQL injection because it directly concatenates user input (orderId) into the SQL query string.

Suggested change
const sql = "SELECT * FROM orders WHERE id = " + orderId;
const sql = "SELECT * FROM orders WHERE id = ?";

return db.query(sql);
}

// (2) BUG — unguarded access: cart.items may be undefined/empty, [0].price throws.
function firstItemPrice(cart) {
return cart.items[0].price;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[BUG] The code assumes that 'cart.items' is not empty, which can lead to an error if 'cart.items' is an empty array. Accessing the first element without checking can cause an 'undefined' error.

Suggested change
return cart.items[0].price;
if (cart.items.length > 0) {
return cart.items[0].price;
} else {
return 0; // or handle the empty case appropriately
}

}

// (3) PERFORMANCE — O(n^2) duplicate scan with a doubly-nested loop.
function hasDuplicate(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[PERFORMANCE] The nested loop results in an O(n^2) time complexity, which is inefficient for checking duplicates. Using a Set to track seen elements reduces the complexity to O(n).

Suggested change
for (let j = 0; j < arr.length; j++) {
function hasDuplicate(arr) {
const seen = new Set();
for (let i = 0; i < arr.length; i++) {
if (seen.has(arr[i])) {
return true;
}
seen.add(arr[i]);
}
return false;
}

if (i !== j && arr[i] === arr[j]) {
return true;
}
}
}
return false;
}

// (4) CLEAN — straightforward, no issues. Should produce NO comment.
function add(a, b) {
return a + b;
}

module.exports = { getOrder, firstItemPrice, hasDuplicate, add };
Loading