💻 Coding
JavaScript Bug Hunter
Identifies logic errors and syntax issues in JavaScript code snippets.
0Reviews
Prompt
Act as a senior JavaScript developer. Review the following code for bugs, performance bottlenecks, or security vulnerabilities: [Insert Code]. Explain why each issue is a problem and provide a corrected version of the code.
Instructions
Paste your code block where indicated. You can also specify the environment (e.g., Node.js, React).
Examples
Example Input
Act as a senior JavaScript developer. Review the following code for bugs, performance bottlenecks, or security vulnerabilities: [const mysql = require('mysql');
const connection = mysql.createConnection({ /* config */ });
function getUserData(userId, callback) {
// Issue 1 & 2 here
const query = "SELECT * FROM users WHERE id = " + userId;
connection.query(query, (err, results) => {
if (err) throw err;
// Issue 3 here
for (var i = 0; i < results.length; i++) {
setTimeout(function() {
console.log("User ID: " + results[i].id);
}, 1000);
}
callback(results);
});
}]. Explain why each issue is a problem and provide a corrected version of the code. Example Output
This code contains several critical flaws that would fail any professional code review. The primary concerns involve security, stability, and fundamental JavaScript scope logic.
Identified Issues
SQL Injection Vulnerability
Concatenating userId directly into the query string allows an attacker to manipulate the SQL command. If userId contains a string like 1 OR 1=1, they could bypass authentication or dump your entire user database.
Uncaught Exceptions (Process Crashing)
Using throw err inside an asynchronous callback is dangerous. Since the event loop executes the callback later, the original calling context is gone. This exception will become an "uncaught exception," which typically crashes the entire Node.js process.
The var Loop & Closure Bug
The setTimeout uses var i. Because var is function-scoped rather than block-scoped, the loop finishes before the first timer fires. By the time the console.log executes, i equals results.length, and results[i] will be undefined.
Corrected Code
The following version uses parameterized queries for security, modern syntax (let/const) for scope safety, and proper error handling passed through the callback.
JavaScript
const mysql = require('mysql');
const connection = mysql.createConnection({ /* config */ });
function getUserData(userId, callback) {
// Use '?' as a placeholder to prevent SQL injection
const query = "SELECT * FROM users WHERE id = ?";
connection.query(query, [userId], (err, results) => {
if (err) {
// Pass the error to the callback instead of throwing
return callback(err);
}
// Use 'let' for block-scoping so each timeout captures the correct index
for (let i = 0; i < results.length; i++) {
setTimeout(function() {
if (results[i]) {
console.log("User ID: " + results[i].id);
}
}, 1000);
}
callback(null, results);
});
}