-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Fix resource-collection.js fingerprint for non-fingerprinted assets #64857
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…ted assets - Modified ComputeFingerprintSuffix to include integrity hash for non-fingerprinted assets - Added comprehensive unit tests to verify the fix - Tests verify different scenarios: fingerprinted, non-fingerprinted, mixed, and null properties Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
- Changed ComputeFingerprintSuffix from private to internal for better testability - Added early exit when label is found to avoid unnecessary iterations - Updated tests to use internal method directly instead of reflection Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
| if (resource.Properties != null) | ||
| { | ||
| var hasLabel = false; | ||
| string? integrity = null; | ||
| foreach (var property in resource.Properties) | ||
| { | ||
| if (property.Name.Equals("label", StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| hasLabel = true; | ||
| // No need to continue if we found a label - we won't use integrity | ||
| break; | ||
| } | ||
| else if (property.Name.Equals("integrity", StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| integrity = property.Value; | ||
| // Continue searching in case there's also a label property | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this into a helper method that returns a string and then have the check be against the returned string. If there is more data we need to hash we will return a non-null string. Otherwise, we return null and skip.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extracted GetAdditionalDataForFingerprint helper method that returns string? - returns the integrity value for non-fingerprinted assets or null otherwise. Commit: 9c8b9c1
| public class ResourceCollectionUrlEndpointTest | ||
| { | ||
| [Fact] | ||
| public void ComputeFingerprintSuffix_IncludesIntegrityForNonFingerprintedAssets() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at the microsoftdocs and use modern C# (collection initializers, target type, etc.) where possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to use collection expressions and target-typed new() throughout the tests for modern C# style. Commit: 9c8b9c1
- Extracted GetAdditionalDataForFingerprint helper method that returns string? for cleaner separation - Updated tests to use collection expressions and target-typed new() for modern C# style - All tests passing Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
| var fingerprint = ResourceCollectionUrlEndpoint.ComputeFingerprintSuffix(collection); | ||
| Assert.NotNull(fingerprint); | ||
| Assert.StartsWith(".", fingerprint); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot Add a unit test that simulates the original scenario, which is the integrity of a non-fingerprinted asset changes.
First we compute the fingerprint suffix, then we change the integrity on a non-fingerprinted asset and verify the suffix is different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only test we need for this. All other behavior will be well covered by existing tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added ComputeFingerprintSuffix_ChangesWhenNonFingerprintedAssetIntegrityChanges test that simulates the original scenario - computes fingerprint with initial integrity, changes the integrity on a non-fingerprinted asset (same URL), and verifies the fingerprint is different. Commit: 0a8a76e
… change Added ComputeFingerprintSuffix_ChangesWhenNonFingerprintedAssetIntegrityChanges test that directly simulates the original issue scenario where a file change (e.g., Counter.razor or styles.css) updates integrity but not URL with WasmFingerprintAssets=false Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
Fix resource-collection.js fingerprint for non-fingerprinted assets
Include integrity hash in resource-collection fingerprint for non-fingerprinted assets
Description
When
WasmFingerprintAssets=false, asset URLs lack content hashes. Content changes between builds update integrity values but not the resource-collection URL fingerprint, causing cached files to have stale integrity hashes and fail SRI validation.Root Cause
ComputeFingerprintSuffixonly hashed asset URLs. For non-fingerprinted assets, identical URLs produced identical fingerprints despite content changes.Solution
Modified
ComputeFingerprintSuffixto include theintegrityproperty in the hash for assets without alabelproperty (non-fingerprinted). Fingerprinted assets (withlabel) already encode content in their URLs, so integrity is skipped for them.Extracted a helper method
GetAdditionalDataForFingerprintthat returnsstring?to encapsulate the logic for determining if additional data should be included in the fingerprint calculation. This method returns the integrity value for non-fingerprinted assets ornullotherwise.Changes
ComputeFingerprintSuffixfromprivatetointernalfor testabilityGetAdditionalDataForFingerprinthelper method for cleaner code separationlabelproperty)labelproperty)new()syntaxOriginal prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.