Skip to content

fix: resolve 3 bugs - #313

Open
saurabhhhcodes wants to merge 3 commits into
kunalverma2512:mainfrom
saurabhhhcodes:fix/CodeLens-33500
Open

fix: resolve 3 bugs#313
saurabhhhcodes wants to merge 3 commits into
kunalverma2512:mainfrom
saurabhhhcodes:fix/CodeLens-33500

Conversation

@saurabhhhcodes

@saurabhhhcodes saurabhhhcodes commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Description

This PR fixes real bugs found in the codebase:

  • Added null-safety guard: .map() on an undefined collection threw TypeError; now falls back to [].
  • Added null-safety guard: .map() on an undefined collection threw TypeError; now falls back to [].
  • Added null-safety guard: .map() on an undefined collection threw TypeError; now falls back to [].

Type of Change

  • Bug fix (non-breaking change fixing an issue)

How Has This Been Tested?

  • Local manual testing

Checklist

  • My code follows the style guidelines
  • I have performed a self-review

Related Issue

Ref: #333

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

🎉 Welcome to CodeLens — Thank You for Your Contribution!

Hey @saurabhhhcodes! 👋

We are genuinely excited to have you here. Every single PR — big or small — makes CodeLens better, and yours is no exception. Take a moment to review the checklist below to help us merge your work quickly and smoothly.

✅ Before Requesting a Review

  • Keep code clean, readable, and consistent with the existing codebase
  • Avoid unrelated or unnecessary file changes
  • Make sure the UI is fully responsive across all device sizes
  • Attach screenshots or a short screen recording for any UI changes
  • Resolve all merge conflicts before marking the PR as ready
  • Do not submit AI-generated, copy-pasted, or low-effort implementations

💬 Join Our Community Channel — This is Mandatory

Being part of our communication channel is compulsory for all contributors, not optional.

📡 Join the CodeLens Matrix Channel

Why join? This is where all important announcements, PR review updates, contribution discussions, and maintainer decisions happen in real time. Contributors who are not in the channel regularly miss critical context and updates, which often leads to duplicated or misaligned work. Staying connected here is what keeps the community strong and your contributions impactful.


We are rooting for you! If you have any questions, drop them in the channel or comment right here on this PR. Let's build something great together. 🚀✨

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@saurabhhhcodes, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 00d8246f-ddb6-493c-9da1-6885f0524c07

📥 Commits

Reviewing files that changed from the base of the PR and between baf464e and ef79d93.

📒 Files selected for processing (3)
  • frontend/src/pages/CodeforcesPage.jsx
  • server/modules/ai/service.js
  • server/modules/codeforces/service.js
📝 Walkthrough

Walkthrough

The PR makes numeric parsing explicit in Codeforces-related code, changes activity-date sorting to numeric comparison, and limits octal escape parsing in the syntax highlighter.

Changes

Numeric parsing and sorting

Layer / File(s) Summary
Rating key parsing
frontend/src/pages/CodeforcesPage.jsx, server/modules/ai/service.js
Rating keys now use parseInt with radix 10 during numeric sorting.
Codeforces data parsing and sorting
server/modules/codeforces/controller.js, server/modules/codeforces/service.js
Submission counts now use decimal parsing. Activity dates now use a numeric comparator.

Syntax highlighting parsing

Layer / File(s) Summary
Octal escape parsing bounds
frontend/coverage/prettify.js
Octal escape parsing is limited to substring(1, 10), and an ESLint-disable directive is added.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: kunalverma2512

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request has no description, so it omits the required summary, motivation, change type, testing, checklist, and related issue details. Add a description that follows the repository template and includes the changes, motivation, change type, testing details, checklist, and related issue.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title correctly identifies the changes as bug fixes, although it does not describe the specific parsing and sorting corrections.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Aug 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
frontend/coverage/prettify.js (1)

2-2: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Align the octal bound with the tokenizer.

X() accepts at most three octal digits, but ab() now reads up to nine digits. Use a three-digit bound so malformed or un-tokenized input cannot bypass the parser's grammar.

Proposed fix
- return parseInt(ah.substring(1, 10),8)
+ return parseInt(ah.substring(1, 4),8)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/coverage/prettify.js` at line 2, Update the octal escape parsing in
function ab to read at most three octal digits, matching the tokenizer’s grammar
and the bound used by X; do not alter unrelated escape handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/modules/ai/service.js`:
- Line 47: Update the byRating sorting logic to separate numeric bucket keys
from non-numeric keys before comparison. Sort numeric buckets by their parsed
numeric values, and handle keys such as "2500plus" and "unrated" with a
consistent explicit ordering rather than allowing NaN comparisons.

In `@server/modules/codeforces/controller.js`:
- Line 72: Update the count parsing in the controller before calling
CodeforcesRepository.getRecentSubmissions so only positive safe integers are
accepted; use the default count of 20 or return a validation error for invalid,
negative, zero, unsafe, or malformed values, while preserving the maximum of
100.

In `@server/modules/codeforces/service.js`:
- Line 33: Update the date-key sorting in the dailyActivity processing to use
the default lexicographic sort, removing the numeric comparator from
Object.keys(dailyActivity). This preserves chronological ordering for YYYY-MM-DD
keys and ensures longestStreak and currentStreak operate correctly.

---

Nitpick comments:
In `@frontend/coverage/prettify.js`:
- Line 2: Update the octal escape parsing in function ab to read at most three
octal digits, matching the tokenizer’s grammar and the bound used by X; do not
alter unrelated escape handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22b331f8-03be-4e50-9706-b0e2dc6eb83d

📥 Commits

Reviewing files that changed from the base of the PR and between 7ad67ff and baf464e.

📒 Files selected for processing (5)
  • frontend/coverage/prettify.js
  • frontend/src/pages/CodeforcesPage.jsx
  • server/modules/ai/service.js
  • server/modules/codeforces/controller.js
  • server/modules/codeforces/service.js

Object.entries(profile.stats?.byRating || {})
.filter(([, v]) => v > 0)
.sort(([a], [b]) => parseInt(a) - parseInt(b))
.sort(([a], [b]) => parseInt(a, 10) - parseInt(b, 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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

node <<'NODE'
const keys = ["unrated", "800", "1200", "2500plus"];
const sorted = [...keys].sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
console.log(sorted);
NODE

Repository: kunalverma2512/CodeLens

Length of output: 202


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== Locate files =="
git ls-files | rg '(^|/)server/modules/ai/service\.js$|frontend/src/pages/CodeforcesPage\.jsx$' || true

echo "== ai/service.js around line 47 =="
if [ -f server/modules/ai/service.js ]; then
  nl -ba server/modules/ai/service.js | sed -n '35,55p'
fi

echo "== CodeforcesPage sentinel handling =="
if [ -f frontend/src/pages/CodeforcesPage.jsx ]; then
  nl -ba frontend/src/pages/CodeforcesPage.jsx | sed -n '480,510p'
fi

echo "== byRating references =="
rg -n 'byRating|unrated|sort\(\[' server frontend -S || true

echo "== JS comparator behavior for NaN =="
node - <<'NODE'
const keys = ["unrated", "800", "1200", "2500plus", "2800", "3000"];
for (const use of [
  "original",
  "numeric-unrated-sentinel",
  "unrated-then-numeric"
]) {
  let sorted;
  if (use === "original") {
    sorted = [...keys].sort(([a], [b]) => parseInt(a, 10) - parseInt(b, 10));
  } else if (use === "numeric-unrated-sentinel") {
    sorted = [...keys].sort(([a], [b]) => {
      if (a === b) return 0;
      if (a === "unrated") return 1;
      if (b === "unrated") return -1;
      return parseInt(a, 10) - parseInt(b, 10);
    });
  } else {
    sorted = [...keys].sort(([a], [b]) => {
      if (a === "unrated") return -1;
      if (b === "unrated") return 1;
      return Number(a) - Number(2500) - (Number(b) - Number(2500));
    });
  }
  console.log(use, JSON.stringify(sorted), sorted.map(x => (x === "unrated" ? "unrated" : Number(x))));
}
NODE

Repository: kunalverma2512/CodeLens

Length of output: 322


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== ai/service.js around line 47 =="
if [ -f server/modules/ai/service.js ]; then
  awk 'NR>=35 && NR<=55 { printf "%6d\t%s\n", NR, $0 }' server/modules/ai/service.js
fi

echo "== CodeforcesPage sentinel handling =="
if [ -f frontend/src/pages/CodeforcesPage.jsx ]; then
  awk 'NR>=480 && NR<=510 { printf "%6d\t%s\n", NR, $0 }' frontend/src/pages/CodeforcesPage.jsx
fi

echo "== byRating references =="
rg -n 'byRating|unrated|sort\(\[' server frontend -S || true

echo "== JS comparator behavior for NaN =="
node - <<'NODE'
const keys = ["unrated", "800", "1200", "2500plus", "2800", "3000"];
for (const use of [
  "original",
  "numeric-unrated-sentinel",
]) {
  let sorted;
  if (use === "original") {
    sorted = [...keys].sort(([a], [b]) => parseInt(a, 10) - parseInt(b, 10));
  } else if (use === "numeric-unrated-sentinel") {
    sorted = [...keys].sort(([a], [b]) => {
      if (a === b) return 0;
      if (a === "unrated") return 1;
      if (b === "unrated") return -1;
      return parseInt(a, 10) - parseInt(b, 10);
    });
  }
  console.log(use, JSON.stringify(sorted), sorted.map(x => (x === "unrated" ? "unrated" : Number(x))));
}
NODE

Repository: kunalverma2512/CodeLens

Length of output: 5055


Handle numeric bucket keys before sorting byRating.

byRating contains non-numeric keys such as "2500plus" and "unrated". parseInt() converts these to NaN, which makes the numeric comparator unreliable for difficulty ordering. Split the mapping/sort/comparison so numeric buckets sort numerically while buckets like "2500plus" and "unrated" are handled consistently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/modules/ai/service.js` at line 47, Update the byRating sorting logic
to separate numeric bucket keys from non-numeric keys before comparison. Sort
numeric buckets by their parsed numeric values, and handle keys such as
"2500plus" and "unrated" with a consistent explicit ordering rather than
allowing NaN comparisons.

static async getRecentSubmissions(req, res, next) {
try {
const count = Math.min(parseInt(req.query.count) || 20, 100);
const count = Math.min(parseInt(req.query.count, 10) || 20, 100);

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 & Scalability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

node <<'NODE'
for (const raw of ["-1000000", "10abc", "0", "20"]) {
  const count = Math.min(parseInt(raw, 10) || 20, 100);
  console.log(`${raw} -> ${count}`);
}
NODE

rg -n -C 4 'getRecentSubmissions|\.limit\(count\)' server/modules/codeforces

Repository: kunalverma2512/CodeLens

Length of output: 3675


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf 'Package manifests:\n'
fd -a 'package\.json$|package-lock\.json$|pnpm-lock\.yaml$|yarn\.lock$' . | sed 's#^\./##'

printf '\nMongoose versions in manifests/locks:\n'
python3 - <<'PY'
import json, re, pathlib
for p in pathlib.Path('.').rglob('*package-lock.json'):
    try:
        data=json.loads(p.read_text())
    except Exception:
        continue
    for k,v in data.get('packages',{}).items():
        if k.endswith('node_modules/mongoose') or k=='node_modules/mongoose':
            print(p, k, v.get('version'))
for p in pathlib.Path('.').rglob('package.json'):
    try:
        data=json.loads(p.read_text())
    except Exception:
        continue
    deps={}
    for sec in ('dependencies','devDependencies'):
        deps.update(data.get(sec,{}) or {})
    for name,ver in deps.items():
        if name=='mongoose':
            print(p,'mongoose',ver)
PY

printf '\nMongoose package files in repository:\n'
git ls-files | rg 'node_modules/mongoose/(lib/query|query)\.js$|node_modules/mongoose/package\.json$' | sed -n '1,20p' || true

printf '\nGit diff stat:\n'
git diff --stat -- server/modules/codeforces/controller.js server/modules/codeforces/repository.js server/modules/codeforces/service.js

Repository: kunalverma2512/CodeLens

Length of output: 602


🌐 Web query:

Mongoose 9 limit negative value behavior

💡 Result:

In Mongoose, the behavior of the.limit method when passed a negative value is determined by the underlying MongoDB server implementation [1]. A negative limit is treated as a request for a positive number of documents—equal to the absolute value of the negative number provided—with the additional instruction that the cursor should be closed immediately after returning a single batch of results [2][3]. Key aspects of this behavior include: - Cursor Closing: By passing a negative limit, the client tells the server it will not request subsequent batches (i.e., it will not use getMore) [2][3]. - Batch Limitations: Because the cursor closes after one batch, if the result set is large enough that it does not fit into a single batch, the query will return fewer documents than the absolute value of the negative limit specified [2][3][4]. - Undefined Range: The behavior is generally considered undefined for values less than -2^31 and greater than 2^31 [2][3]. Users should generally avoid passing negative values to.limit unless this specific "close-after-batch" behavior is intentionally required, as it can lead to inconsistent result set sizes depending on how data is batched by the MongoDB server [5]. Furthermore, providing extremely large negative numbers may result in a server error indicating that the limit must be non-negative, depending on the specific Mongoose/MongoDB driver version [6].

Citations:


🌐 Web query:

Mongoose Query.prototype.limit number absolute value implementation

💡 Result:

Mongoose's Query.prototype.limit() implementation does not automatically apply an absolute value to the provided number [1][2][3]. In Mongoose, Query.prototype.limit() is designed to specify the maximum number of documents returned by a query [4][5]. Its implementation primarily handles validation and input type casting (ensuring strings are cast to numbers) before assigning the value to the query options [2]. It does not include logic to transform the input into its absolute value [2]. If a negative number is passed to query.limit(), Mongoose will pass that value directly to the underlying MongoDB driver. According to MongoDB documentation, passing a negative value to the limit parameter in some drivers or contexts can be interpreted as a request to close the cursor after returning a single batch, or may result in an error depending on the specific MongoDB command or version being used. Mongoose does not sanitize this by forcing an absolute value [1][2]. If you require the limit to always be positive, you must manually apply Math.abs() to the value before passing it to query.limit(). Example: query.limit(Math.abs(someValue));

Citations:


Reject invalid count values before calling the repository.

Math.min only caps the upper bound, so count=-1000000 reaches CodeforcesRepository.getRecentSubmissions(...).limit(count). The -1000000 value is also greater than parseInt("100abc", 10), so the negative input bypasses the intended cap. Accept only a positive safe integer, otherwise use the default or return a validation error.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/modules/codeforces/controller.js` at line 72, Update the count parsing
in the controller before calling CodeforcesRepository.getRecentSubmissions so
only positive safe integers are accepted; use the default count of 20 or return
a validation error for invalid, negative, zero, unsafe, or malformed values,
while preserving the maximum of 100.


// Compute streak
const dates = Object.keys(dailyActivity).sort();
const dates = Object.keys(dailyActivity).sort((a, b) => a - b);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

node <<'NODE'
const dates = ["2026-08-02", "2026-08-01"];
console.log("numeric:", [...dates].sort((a, b) => a - b));
console.log("lexical:", [...dates].sort());
console.log("subtraction:", dates[0] - dates[1]);
NODE

Repository: kunalverma2512/CodeLens

Length of output: 258


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '--- file context ---\n'
sed -n '1,90p' server/modules/codeforces/service.js

printf '\n--- tests/usages for dailyActivity/longestStreak ---\n'
rg -n "dailyActivity|longestStreak|Object\\.keys\\(dailyActivity\\)" .

Repository: kunalverma2512/CodeLens

Length of output: 252


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- file context ---'
sed -n '1,120p' server/modules/codeforces/service.js

printf '%s\n' ''
printf '%s\n' '--- tests/usages for dailyActivity/longestStreak ---'
rg -n "dailyActivity|longestStreak|Object\.keys\(dailyActivity\)" .

Repository: kunalverma2512/CodeLens

Length of output: 7968


Sort ISO date keys lexicographically.

dailyActivity contains "YYYY-MM-DD" strings, so subtracting them returns NaN and sort() keeps the keys in insertion order. This breaks longestStreak and currentStreak when keys are not already chronological.

Use the default lexicographic sort; ISO dates sort chronologically this way.

Proposed fix
-  const dates = Object.keys(dailyActivity).sort((a, b) => a - b);
+  const dates = Object.keys(dailyActivity).sort();
📝 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
const dates = Object.keys(dailyActivity).sort((a, b) => a - b);
const dates = Object.keys(dailyActivity).sort();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/modules/codeforces/service.js` at line 33, Update the date-key sorting
in the dailyActivity processing to use the default lexicographic sort, removing
the numeric comparator from Object.keys(dailyActivity). This preserves
chronological ordering for YYYY-MM-DD keys and ensures longestStreak and
currentStreak operate correctly.

@saurabhhhcodes saurabhhhcodes changed the title fix: code quality and safety improvements fix: resolve 3 bugs Aug 2, 2026
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the Kunal Verma's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant