Skip to content

Fix BPM validation checks to prevent invalid value access#15793

Open
shbhmexe wants to merge 4 commits into
mixxxdj:mainfrom
shbhmexe:fix-bpm-validation-checks
Open

Fix BPM validation checks to prevent invalid value access#15793
shbhmexe wants to merge 4 commits into
mixxxdj:mainfrom
shbhmexe:fix-bpm-validation-checks

Conversation

@shbhmexe
Copy link
Copy Markdown

Fixes 3 critical issues where mixxx::Bpm::value() was accessed without isValid() checks, risking debug assertions and undefined behavior.

Changes

  • beatutils.cpp: Added validation in roundBpmWithinRange to return early if inputs are invalid.
  • beatutils.cpp: Added check in adjustPhase to prevent division by zero/invalid BPM.
  • bpmcontrol.cpp: Added validation in adjustBeatsBpm before value access.

Verification

  • Static Check: Verified all new value() calls are guarded by isValid().
  • Logic: Confirmed invalid inputs trigger safe fallbacks/returns.
  • Build: Compiles successfully; no logic breaking changes.

Add missing BPM validity checks before calling value() method to prevent
debug assertions and potential undefined behavior when BPM is invalid.

Signed-off-by: shbhmexe <shubhushukla586@gmail.com>
@daschuer
Copy link
Copy Markdown
Member

daschuer commented Jan 6, 2026

Thank you for this fix.

As a first-time contributor we need you to sign the Mixxx Contributor Agreement and comment here when you have done so. It gives us permission to distribute your contribution under the GPL v2 or later license and the Apple Mac App Store. It is also helpful for us to have contact information for contributors in case we may need it in the future.

I think all branches are affected. Can you rebase it to 2.5

git rebase --onto=upstream/2.5 HEAD~1
git push -f

This way it will become outo merged to all branches.

@daschuer
Copy link
Copy Markdown
Member

daschuer commented Jan 6, 2026

The Fixme comments have been introduced here:
#4165

Copy link
Copy Markdown
Member

@daschuer daschuer left a comment

Choose a reason for hiding this comment

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

The code looks good, I have added comments for improvement.

Comment thread src/engine/controls/bpmcontrol.cpp Outdated
Comment thread src/track/beatutils.cpp Outdated
Comment on lines +339 to +342
// First validate all BPM values
if (!minBpm.isValid() || !centerBpm.isValid() || !maxBpm.isValid()) {
// If any BPM is invalid, return the centerBpm as-is
return centerBpm;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These comments are redundant, because they are explaining C++ not the intention. How about this:

Suggested change
// First validate all BPM values
if (!minBpm.isValid() || !centerBpm.isValid() || !maxBpm.isValid()) {
// If any BPM is invalid, return the centerBpm as-is
return centerBpm;
// If any BPM is invalid, return the centerBpm as-is to avoid
// unexpected results in the following calculations
if (!minBpm.isValid() || !centerBpm.isValid() || !maxBpm.isValid()) {
return centerBpm;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you add this check as well to avoid division by zero?

Comment thread src/track/beatutils.cpp Outdated
Comment on lines +413 to +415
// Validate BPM before using it
if (!bpm.isValid()) {
// If BPM is invalid, return firstBeat without adjustment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

adjustPhase() is called here with a isValid() check before. Now we have it inside which allows us to move it before the call here:
https://github.com/daschuer/mixxx/blob/8720b7595fbbecd62d20c89bf66ff500adce5408/src/track/beatfactory.cpp#L83

The comment has also no value:

Suggested change
// Validate BPM before using it
if (!bpm.isValid()) {
// If BPM is invalid, return firstBeat without adjustment
if (!bpm.isValid()) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The change at the cited code position has not been fixed. Can you have a look?

shbhmexe and others added 3 commits January 11, 2026 14:44
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
@shbhmexe
Copy link
Copy Markdown
Author

All changes as requested have been completed. Please let me know if there are any other requests in this PR.

@acolombier acolombier changed the base branch from main to 2.5 January 25, 2026 22:33
@acolombier acolombier changed the base branch from 2.5 to main January 25, 2026 22:34
@acolombier
Copy link
Copy Markdown
Member

@daschuer have all your change requests been addresed? Is the rebase the only thing missing?

@daschuer
Copy link
Copy Markdown
Member

I can confirm that @shbhmexe has signed the contributor agreement. Thank you.

@github-actions
Copy link
Copy Markdown

This PR is marked as stale because it has been open 90 days with no activity.

@github-actions github-actions Bot added the stale Stale issues that haven't been updated for a long time. label Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

engine stale Stale issues that haven't been updated for a long time.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants