Skip to content

fix: parse integers with the reader culture instead of the current culture - #49

Merged
VisualBean merged 1 commit into
ByteBardOrg:vnextfrom
bielu:fix/reader-culture-invariant-integers
Oct 17, 2026
Merged

VisualBean merged 1 commit into
ByteBardOrg:vnextfrom
bielu:fix/reader-culture-invariant-integers

Conversation

@bielu

@bielu bielu commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Problem

ValueNode.GetIntegerValue, GetLongValue and their OrDefault variants call int.TryParse(s, out ...) / long.TryParse(s, out ...) with no culture, so they parse with CultureInfo.CurrentCulture. GetScalarValue formats the value with Settings.CultureInfo, which is invariant by default. The two don't match.

On a machine whose current culture uses a non-ASCII negative sign, every negative integer fails to parse. That covers 57 of the 890 cultures in .NET 10, including all ar-*, he-IL, fa-IR and ckb. Arabic, for example, uses U+061C U+002D. The result:

  • ROS2 deadline: -1, the spec's value for "infinite", is silently read as null, because it goes through GetIntegerValueOrDefault.
  • IBM MQ expiry: -5 gives Value could not parse to long.

The same document reads fine on an en-US machine, which makes this hard to diagnose.

Separately, Avro decimal precision and scale used int.Parse(...). A non-integer value threw FormatException, which escaped ReadFragment/Read instead of becoming a diagnostic.

Change

  • ValueNode integer and long parsing now uses NumberStyles.Integer with Settings.CultureInfo, the same culture GetScalarValue formats with. The JSON Schema and Avro deserializers already parse numbers this way (double.Parse(..., n.Context.Settings.CultureInfo)).
  • Avro precision and scale use n.GetIntegerValue(), so invalid values are reported in diagnostic.Errors.

Tests

Added IntegerParsing_Should (7 cases):

  • Negative int values under ar-SA, he-IL and fa-IR (ROS2 QoS durations) and negative long values under ar-SA and he-IL (IBM MQ expiry).
  • Avro precision and scale set to "abc" report an error instead of throwing.

The test class is [NonParallelizable] and restores CurrentCulture in TearDown. All 7 fail on vnext and pass with this change; the full suite passes on net8.0/net9.0/net10.0.

🤖 Generated with Claude Code

…lture

ValueNode.GetIntegerValue/GetLongValue (and their OrDefault variants)
called int/long.TryParse without a culture, so they used
CultureInfo.CurrentCulture, while GetScalarValue formats the value with
Settings.CultureInfo (invariant by default). On machines whose current
culture has a non-ASCII negative sign (ar-*, he-IL, fa-IR, ... - 57 of
890 .NET cultures), every negative integer failed to parse: e.g. ROS2
`deadline: -1` was silently dropped and IBM MQ `expiry: -5` produced
"Value could not parse to long."

Both now parse with Settings.CultureInfo, matching how the JSON Schema
and Avro deserializers already parse numbers.

Also switch Avro decimal `precision`/`scale` from int.Parse to
GetIntegerValue: int.Parse threw FormatException for a non-integer value,
which escaped the reader instead of becoming a diagnostic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 48 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0d76adf9-ae29-4eb5-8452-8216c68fd4e8
📥 Commits

Reviewing files that changed from the base of the PR and between a13c612 and f325f90.

📒 Files selected for processing: 3
  • src/ByteBard.AsyncAPI.Readers/ParseNodes/ValueNode.cs
  • src/ByteBard.AsyncAPI.Readers/Schemas/AsyncApiAvroSchemaDeserializer.cs
  • test/ByteBard.AsyncAPI.Tests/IntegerParsing_Should.cs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@bielu
bielu marked this pull request as ready for review October 17, 2026 17:44
@bielu
bielu requested a review from VisualBean as a code owner October 17, 2026 17:44

@VisualBean VisualBean left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All of the binding infra is from before I added culture to the options.
Very good change

@VisualBean
VisualBean merged commit c57a8d6 into ByteBardOrg:vnext Oct 17, 2026
9 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.

2 participants