Skip to content
Open
Show file tree
Hide file tree
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
39 changes: 39 additions & 0 deletions calculator-app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<title>Calculator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>

<div class="calculator">
<input type="text" id="display" disabled />
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Prefer readonly over disabled for the display field.

disabled prevents focus/selection and is less accessible for a calculator display.

✅ Suggested HTML tweak
-  <input type="text" id="display" disabled />
+  <input type="text" id="display" readonly aria-label="Calculator display" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<input type="text" id="display" disabled />
<input type="text" id="display" readonly aria-label="Calculator display" />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@calculator-app/index.html` at line 10, Replace the input attribute disabled
with readonly on the element with id "display" so the field remains
focusable/selectable; update any related styling or JS that checks disabled
(e.g., code referencing document.getElementById("display").disabled) to instead
handle readonly if present and ensure ARIA/labeling still applies for
accessibility.


<div class="buttons">
<button onclick="clearAll()">AC</button>
<button onclick="clearLast()">C</button>
<button onclick="press('/')">/</button>

<button onclick="press('7')">7</button>
<button onclick="press('8')">8</button>
<button onclick="press('9')">9</button>
<button onclick="press('*')">*</button>

<button onclick="press('4')">4</button>
<button onclick="press('5')">5</button>
<button onclick="press('6')">6</button>
<button onclick="press('-')">-</button>

<button onclick="press('1')">1</button>
<button onclick="press('2')">2</button>
<button onclick="press('3')">3</button>
<button onclick="press('+')">+</button>

<button onclick="press('0')">0</button>
<button onclick="calculate()">=</button>
</div>
</div>

<script src="script.js"></script>
</body>
</html>
21 changes: 21 additions & 0 deletions calculator-app/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
let display = document.getElementById("display");

function press(val) {
display.value += val;
}

function calculate() {
try {
display.value = eval(display.value); // (ok for practice)
} catch {
Comment on lines +3 to +10
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify there is no remaining use of eval in JS files.
rg -nP --type=js '\beval\s*\('

Repository: florinpop17/app-ideas

Length of output: 153


Remove eval from expression execution.

eval on calculator input is a security blocker. Replace it with a parser/evaluator limited to digits/operators.

🔒 Safer approach (no dynamic code execution)
+function evaluateExpression(expression) {
+  const sanitized = expression.replace(/\s+/g, "");
+  const tokens = sanitized.match(/\d+(\.\d+)?|[()+\-*/]/g);
+  if (!tokens || tokens.join("") !== sanitized) throw new Error("Invalid expression");
+
+  const prec = { "+": 1, "-": 1, "*": 2, "/": 2 };
+  const output = [];
+  const ops = [];
+
+  for (const t of tokens) {
+    if (/^\d/.test(t)) output.push(Number(t));
+    else if (t in prec) {
+      while (ops.length && ops[ops.length - 1] in prec && prec[ops[ops.length - 1]] >= prec[t]) {
+        output.push(ops.pop());
+      }
+      ops.push(t);
+    } else if (t === "(") ops.push(t);
+    else if (t === ")") {
+      while (ops.length && ops[ops.length - 1] !== "(") output.push(ops.pop());
+      if (ops.pop() !== "(") throw new Error("Mismatched parentheses");
+    }
+  }
+  while (ops.length) {
+    const op = ops.pop();
+    if (op === "(") throw new Error("Mismatched parentheses");
+    output.push(op);
+  }
+
+  const stack = [];
+  for (const t of output) {
+    if (typeof t === "number") stack.push(t);
+    else {
+      const b = stack.pop();
+      const a = stack.pop();
+      if (a === undefined || b === undefined) throw new Error("Invalid expression");
+      stack.push(t === "+" ? a + b : t === "-" ? a - b : t === "*" ? a * b : a / b);
+    }
+  }
+  if (stack.length !== 1) throw new Error("Invalid expression");
+  return stack[0];
+}
+
 function calculate() {
   try {
-    display.value = eval(display.value); // (ok for practice)
+    display.value = String(evaluateExpression(display.value));
   } catch {
     display.value = "ERR";
   }
 }
🧰 Tools
🪛 Biome (2.4.10)

[error] 9-9: eval() exposes to security risks and performance issues.

(lint/security/noGlobalEval)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@calculator-app/script.js` around lines 3 - 10, The calculate() function
currently uses eval(display.value) which is unsafe; replace it with a safe
expression evaluator that only accepts digits, whitespace, parentheses and the
four basic operators (+, -, *, /) and rejects any other characters, then parse
and compute the result (e.g., implement a tokenizer + shunting-yard or simple
recursive descent evaluator) and assign the numeric result back to
display.value; also ensure press() only allows adding valid tokens or update
calculate() to re-validate/sanitize display.value before parsing and handle
parse errors in the existing try/catch.

display.value = "ERR";
}
}

function clearAll() {
display.value = "";
}

function clearLast() {
display.value = display.value.slice(0, -1);
}
15 changes: 15 additions & 0 deletions calculator-app/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
body {
font-family: Arial;
text-align: center;
}

.calculator {
width: 200px;
margin: auto;
}

button {
width: 40px;
height: 40px;
margin: 2px;
}