Skip to content

Fix OverflowException in SecurityIdentifier hash code - #9765

Merged
Martin-Molinero merged 1 commit into
QuantConnect:masterfrom
Martin-Molinero:fix-security-identifier-hash-overflow
Aug 28, 2026
Merged

Fix OverflowException in SecurityIdentifier hash code#9765
Martin-Molinero merged 1 commit into
QuantConnect:masterfrom
Martin-Molinero:fix-security-identifier-hash-overflow

Conversation

@Martin-Molinero

Copy link
Copy Markdown
Member

Description

SecurityIdentifier.GetHashCode() wraps its hash in Math.Abs:

_hashCode = Math.Abs(unchecked (symbol.GetHashCode() * 397) ^ properties.GetHashCode());

Math.Abs throws OverflowException: Negating the minimum value of a twos complement number is invalid when its argument is int.MinValue, and the XOR feeding it can land there. Any symbol whose hash happens to hit that value fails to construct:

System.OverflowException: Negating the minimum value of a twos complement number is invalid.
   at QuantConnect.SecurityIdentifier..ctor(String symbol, UInt64 properties)
   at QuantConnect.SecurityIdentifier.Generate(...)

Because .NET randomizes string hashing per process, whether a given symbol trips it varies from run to run, so it surfaces as an intermittent failure on an arbitrary symbol.

This removes the Math.Abs from both sites, restoring the previous behaviour.

Related Issue

N/A

Motivation and Context

Bug fix. Hash codes carry no requirement to be non-negative — Dictionary and HashSet mask the sign off internally, and negative values were returned here for years before Math.Abs was introduced in #9088.

Nothing reads the sign of this value: _hashCode is only ever returned from GetHashCode(), and every consumer folds it into its own hash with * 397 ^ or similar. There is no modulo or indexing use of it that lacks a uint cast. Since the value already differs between processes, nothing can depend on its stability either.

Requires Documentation Change

N/A

How Has This Been Tested?

Existing tests.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Refactor (non-breaking change which improves implementation)
  • Performance (non-breaking change which improves performance. Please add associated performance test and results)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Non-functional change (xml comments/documentation/etc)

Math.Abs throws OverflowException when its argument is int.MinValue,
which the XOR feeding it can produce. Hash codes are not required to be
non-negative, and nothing reads the sign of this one, so return the raw
value as it did previously.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FL5xQMtSCw5bcPZ3gvkedp
@Martin-Molinero
Martin-Molinero merged commit b692bf4 into QuantConnect:master Aug 28, 2026
8 checks passed
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