Skip to content

fix(core-amqp): ignore ASCII case in the entity path match - #7343

Draft
Johnathan W (j7nw4r) wants to merge 3 commits into
Azure:mainfrom
j7nw4r:fix/7261-case-insensitive-entity-path
Draft

fix(core-amqp): ignore ASCII case in the entity path match#7343
Johnathan W (j7nw4r) wants to merge 3 commits into
Azure:mainfrom
j7nw4r:fix/7261-case-insensitive-entity-path

Conversation

@j7nw4r

Copy link
Copy Markdown
Member

Summary

ServiceBusSasConnectionStringCredential compared the entity path argument against the connection string EntityPath element byte for byte. A caller who passed MyHub against a connection string that carries EntityPath=myhub got std::invalid_argument before any network call. The comparison now ignores ASCII letter case.

Motivation

The Microsoft resource naming rules say to always do a case-insensitive comparison of names, and the namespaces/eventhubs row lists no case exception. .NET compares the same two names with StringComparison.InvariantCultureIgnoreCase in EventHubsConnectionStringProperties.Validate. The byte comparison in C++ rejected a pair of names that the service accepts, so ProducerClient and ConsumerClient threw on a valid input. This change aligns with .NET. A legal Event Hubs entity name contains ASCII alphanumerics plus period, hyphen, and underscore. An ASCII fold and the .NET culture-aware fold thus agree on every name that the service accepts.

Changes

  • ServiceBusSasConnectionStringCredential matches the two names through the existing Azure::Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual helper.
  • A name that differs by more than ASCII letter case still throws std::invalid_argument with the same message.
  • Deletes the dead private member m_entityPath, which the constructor wrote and no code read.
  • Records the two deviations from .NET in the azure-core-amqp and azure-messaging-eventhubs changelogs: the fold covers ASCII A-Z only, and GetEntityPath() returns the connection string spelling.
  • Updates the ProducerClient and ConsumerClient constructor documentation and the Event Hubs README.
  • Adds no public API, no new comparison helper, no CMake change, and no ApiView change. The deleted member is private, and ApiViewSettings.json sets includePrivate to false.

Test plan

  • Three new tests fail against the unchanged source and pass now: ConnectionStringTest.ServiceBusSasEntityPathCaseInsensitive, ConnectionStringClientTest.ProducerAcceptsCaseInsensitiveEntityPath, and ConnectionStringClientTest.ConsumerAcceptsCaseInsensitiveEntityPath.
  • Four more tests guard the behavior that must not change: an empty entity path argument, a connection string with no EntityPath, a non-ASCII byte pair that must still throw, and a mixed-case caller name against a connection string with no EntityPath.
  • The AMQP connection string filter runs 9 of 9. The Event Hubs connection string filter runs 15 of 15.

Fixes #7261

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
7 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI 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.

Pull request overview

Fixes case-sensitive Event Hub entity-path validation by using the existing ASCII case-insensitive comparison.

Changes:

  • Accepts entity paths differing only by ASCII letter case.
  • Removes an unused private member.
  • Adds tests and updates API documentation, README, and changelogs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
sdk/core/azure-core-amqp/inc/azure/core/amqp/internal/connection_string_credential.hpp Implements case-insensitive validation.
sdk/core/azure-core-amqp/test/ut/connection_string_tests.cpp Tests matching and edge cases.
sdk/core/azure-core-amqp/CHANGELOG.md Records core behavior change.
sdk/eventhubs/azure-messaging-eventhubs/test/ut/connection_string_test.cpp Tests producer and consumer behavior.
sdk/eventhubs/azure-messaging-eventhubs/inc/azure/messaging/eventhubs/producer_client.hpp Documents producer validation.
sdk/eventhubs/azure-messaging-eventhubs/inc/azure/messaging/eventhubs/consumer_client.hpp Documents consumer validation.
sdk/eventhubs/azure-messaging-eventhubs/README.md Explains connection-string matching.
sdk/eventhubs/azure-messaging-eventhubs/CHANGELOG.md Records client behavior change.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

The ServiceBusSasConnectionStringCredential constructor compares the
entity path argument with the connection string EntityPath element byte
for byte. A caller that gives a different case gets an exception. These
tests pin the case-insensitive comparison that issue 7261 asks for.

Three tests fail against the unchanged source:
ServiceBusSasEntityPathCaseInsensitive,
ProducerAcceptsCaseInsensitiveEntityPath, and
ConsumerAcceptsCaseInsensitiveEntityPath.

Four more items pass today, and they guard the behavior that must not
change: an empty entity path argument, a connection string without an
EntityPath element, a non-ASCII byte pair that stays a mismatch, and an
explicit event hub name that keeps its case.
The ServiceBusSasConnectionStringCredential constructor compared the
connection string EntityPath element and the entityPath argument byte
for byte. A caller that spelled the name with different ASCII letter
case got a std::invalid_argument. Issue 7261 asks for a match that
ignores that case.

The constructor now calls
StringExtensions::LocaleInvariantCaseInsensitiveEqual. That helper
folds ASCII A-Z only. It is not the culture-aware comparison that .NET
uses. An argument that differs by more than ASCII letter case still
throws std::invalid_argument with the same message. An empty argument
still keeps the connection string value.

GetEntityPath() returns the connection string spelling. ProducerClient
and ConsumerClient read that value through
EventHubsUtilities::CreateConnectionStringDetails, so
GetEventHubName() returns the connection string spelling too. .NET
returns the explicit argument instead, so this behavior deviates from
.NET.

The change also deletes the dead private member m_entityPath from
ServiceBusSasConnectionStringCredential. Only the deleted branch wrote
to that member, and no code read it. The identically named member of
ConnectionStringParser stays.

The header comments, the Event Hubs README, and both changelogs record
the new rule.
The branch diff carried 16 comment lines against 78 added lines, which
is 20.5 percent. The budget is 10 percent.

Delete the comment above ServiceBusSasEntityPathAbsentFromConnectionString,
because the test name states it. Cut the two comments above
ServiceBusSasEntityPathArgumentEmpty and
ServiceBusSasEntityPathNonAsciiMismatch to one line each, and keep the
reason a reader cannot get from the code.

No test name, no test body, and no assertion changes.
@j7nw4r
Johnathan W (j7nw4r) force-pushed the fix/7261-case-insensitive-entity-path branch from 9baad0b to dab0599 Compare August 18, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Event Hubs] Case-sensitive entity path comparison rejects a valid Event Hub name

2 participants