Skip to content

Reject null characters in process environment variable names - #132214

Draft
adamsitnik with Copilot wants to merge 4 commits into
mainfrom
copilot/fix-null-characters-environment
Draft

Reject null characters in process environment variable names#132214
adamsitnik with Copilot wants to merge 4 commits into
mainfrom
copilot/fix-null-characters-environment

Conversation

Copilot AI commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Embedded nulls in environment variable names can corrupt Windows environment blocks. This change rejects them during collection mutation.

  • Validation
    • Throw ArgumentException from both indexers and all Add overloads.
    • Preserve existing null-key behavior.
  • Coverage
    • Exercise generic and non-generic mutation paths.

Copilot AI and others added 2 commits August 12, 2026 15:47
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 12, 2026 15:55
@azure-pipelines

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

@adamsitnik adamsitnik left a comment

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.

@copilot address my feedback and extend the tests to cover env var values as well.

Comment thread src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx Outdated

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

This PR hardens ProcessStartInfo.Environment mutation behavior by rejecting environment variable names that contain embedded null ('\0') characters, preventing malformed environment blocks (notably on Windows).

Changes:

  • Add key validation in the environment dictionary wrapper to throw ArgumentException for names containing '\0' during mutation.
  • Introduce a localized resource string for the new validation error message.
  • Add a regression test covering generic and non-generic mutation APIs (indexers and Add overloads).

Reviewed changes

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

File Description
src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs Adds a test ensuring null-containing environment variable names are rejected across mutation entry points.
src/libraries/System.Diagnostics.Process/src/System/Collections/Specialized/DictionaryWrapper.cs Centralizes mutation-time key validation (including '\0' checks) via the string indexer setter used by all Add/indexer mutation paths.
src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx Adds the new localized error message resource used by the thrown ArgumentException.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-diagnostics-process
See info in area-owners.md if you want to be subscribed.

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 12, 2026 16:25

Copilot AI commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address my feedback and extend the tests to cover env var values as well.

Addressed in 327a2ca. Validation and mutation-path coverage now reject embedded null characters in both keys and values.

Note

This response was generated by GitHub Copilot.

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

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

Suppressed comments (2)

src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx:323

  • The new exception message is ambiguous about whether it applies to the environment variable name, value, or both. Since the wrapper now validates both keys and values, consider updating the resource text to reflect that to make the error actionable.
  <data name="Argument_NullCharInEnvVar" xml:space="preserve">
    <value>Environment variable cannot contain a null character.</value>
  </data>

src/libraries/System.Diagnostics.Process/src/System/Collections/Specialized/DictionaryWrapper.cs:96

  • ValidateKey takes a non-nullable string but then checks key is not null, which is redundant under nullable analysis and can trigger “always true” warnings. If the intent is to preserve the existing null-key behavior (letting the underlying Dictionary throw), make the helper accept a nullable string and use a null-safe check.
        private static void ValidateKey(string key)
        {
            if (key is not null && key.Contains('\0'))
            {
                throw new ArgumentException(SR.Argument_NullCharInEnvVar, nameof(key));

@adamsitnik adamsitnik left a comment

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.

@copilot address my feedback and reduce the code duplication

Comment on lines +90 to +104
private static void ValidateKey(string key)
{
if (key is not null && key.Contains('\0'))
{
throw new ArgumentException(SR.Argument_NullCharInEnvVar, nameof(key));
}
}

private static void ValidateValue(string? value)
{
if (value is not null && value.Contains('\0'))
{
throw new ArgumentException(SR.Argument_NullCharInEnvVar, nameof(value));
}
}

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.

Suggested change
private static void ValidateKey(string key)
{
if (key is not null && key.Contains('\0'))
{
throw new ArgumentException(SR.Argument_NullCharInEnvVar, nameof(key));
}
}
private static void ValidateValue(string? value)
{
if (value is not null && value.Contains('\0'))
{
throw new ArgumentException(SR.Argument_NullCharInEnvVar, nameof(value));
}
}
private static void Validate(string name, string? value)
{
if (value is not null && value.Contains('\0'))
{
throw new ArgumentException(SR.Argument_NullCharInEnvVar, name);
}
}

Comment on lines +22 to +23
ValidateKey(key);
ValidateValue(value);

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.

Let's reduce the code duplication

Suggested change
ValidateKey(key);
ValidateValue(value);
Validate(nameof(key), key);
Validate(nameof(value), value);

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 12, 2026 17:36

Copilot AI commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address my feedback and reduce the code duplication

Addressed in dedf422c by consolidating duplicated key/value null-character checks into a single Validate(name, value) helper while keeping the existing key/value test coverage intact.

Note

This reply was generated by GitHub Copilot.

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

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

Suppressed comments (2)

src/libraries/System.Diagnostics.Process/src/System/Collections/Specialized/DictionaryWrapper.cs:25

  • The new null-character validation can change the exception thrown when both arguments are invalid (e.g., key is null and value contains '\0'): the setter currently validates the value before the underlying Dictionary throws ArgumentNullException for the null key. To preserve the usual validation order (ArgumentNullException before ArgumentException) and keep null-key behavior consistent, explicitly throw for a null key before validating the value.
            set
            {
                Validate(nameof(key), key);
                Validate(nameof(value), value);
                _contents[key] = value;
            }

src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs:233

  • The new test exercises generic IDictionary and non-generic IDictionary/ICollection mutation paths, but it doesn't cover the public EnvironmentVariables (StringDictionary) wrapper, which has its own indexer/Add implementations. Adding a couple of assertions for EnvironmentVariables helps ensure the same null-character contract is enforced across both public entry points.
            ProcessStartInfo psi = new ProcessStartInfo();
            IDictionary environment = (IDictionary)psi.Environment;
            ICollection<KeyValuePair<string, string>> environmentCollection = psi.Environment;

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.

3 participants