') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Tar: Use indexer setter instead of Add on ExtendedAttributes dictionary by jozkee · Pull Request #76404 · dotnet/runtime · GitHub
Skip to content

Tar: Use indexer setter instead of Add on ExtendedAttributes dictionary - #76404

Merged
jozkee merged 3 commits into
dotnet:mainfrom
jozkee:tar_75215
Oct 3, 2022
Merged

Tar: Use indexer setter instead of Add on ExtendedAttributes dictionary#76404
jozkee merged 3 commits into
dotnet:mainfrom
jozkee:tar_75215

Conversation

@jozkee

@jozkeejozkee commented Sep 29, 2022

Copy link
Copy Markdown
Member

Fixes#75215

Minimal fix for the reported scenario.

Note: There's another issue with how we deal with ExtendedAttributes and public properties. There's no syncronization between both, which may lead to unexpected results when writing a PaxTarEntry, see #76405.

@jozkeejozkee added this to the 8.0.0 milestone Sep 29, 2022
@jozkeejozkee self-assigned this Sep 29, 2022
@ghost

Copy link
Copy Markdown

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

Issue Details

Fixes #75215

Minimal fix for the reported scenario.

Note: There's another issue with how we deal with ExtendedAttributes and public properties. There's no syncronization between both, which may lead to unexpected results when writing a PaxTarEntry but I think we can defer that issue and maybe even just fix it for 8.0.

e.g:

[Fact]publicvoidQuickTest(){Dictionary<string,string>ea=new();ea["path"]="foo";PaxTarEntrypaxEntry=newPaxTarEntry(TarEntryType.RegularFile,"bar",ea);Console.WriteLine(paxEntry.Name);// prints barConsole.WriteLine(paxEntry.ExtendedAttributes["path"]);// prints foo}
Author:Jozkee
Assignees:Jozkee
Labels:

area-System.IO

Milestone:8.0.0

@jozkeejozkee changed the title Use indexer setter instead of Add on ExtendedAttributes dictionaryTar: Use indexer setter instead of Add on ExtendedAttributes dictionarySep 29, 2022
Comment on lines 725 to 728
if (!ExtendedAttributes.ContainsKey(PaxEaMTime))
{
ExtendedAttributes.Add(PaxEaMTime, TarHelpers.GetTimestampStringFromDateTimeOffset(_mTime));
}

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Just pointing out some other issues in this code:

  1. someone uses the copy ctor. passing the extended attributes from the other entry.
  2. on the new entry, you set ModificationTime.
  3. pass the new entry to TarWriter.WriteEntry.

The modification time will be neglected due to this check. @carlossanlop please advice if this is something we should address in this PR.

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.

please advice if this is something we should address in this PR.

Yes. We must always update the dictionary value for mtime using the value from the ModificationTime property. So the if condition should be removed.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Do you recall why was added in the first place?

{
ExtendedAttributes.Add(PaxEaSize, _size.ToString());
ExtendedAttributes[PaxEaSize] = _size.ToString();
}

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.

We could add an else here, in case the data stream gets reduced below the max allowed size, in which case, we can remove the PaxEaSize value from the dictionary entry.

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.

In my other PR which was replaced by this one, I had a fake stream implementation that simulated having 99_999_999 length. You can reuse that to test this.


if (!string.IsNullOrEmpty(_linkName))
{
Debug.Assert(_typeFlag is TarEntryType.SymbolicLink or TarEntryType.HardLink);

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.

Nice.

@carlossanlopcarlossanlop 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.

LGTM. Thanks for adding the tests and addressing the mtime suggestion.

CI failure unrelated: iOSSimulator timeout cancellation during build (longer than 60 min).

##[error]The operation was canceled.

@jozkee
jozkee merged commit 221717b into dotnet:mainOct 3, 2022
@jozkee
jozkee deleted the tar_75215 branch October 3, 2022 20:45
@jozkee

Copy link
Copy Markdown
MemberAuthor

/backport to release/7.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/7.0: https://github.com/dotnet/runtime/actions/runs/3177692797

@github-actions

Copy link
Copy Markdown
Contributor

@jozkee backporting to release/7.0 failed, the patch most likely resulted in conflicts:

$ git am --3way --ignore-whitespace --keep-non-patch changes.patch
Applying: Use indexer setter instead of Add on ExtendedAttributes dictionary
Using index info to reconstruct a base tree...
M	src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs
M	src/libraries/System.Formats.Tar/tests/TarTestsBase.cs
M	src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.Tests.cs
M	src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.Tests.cs
Falling back to patching base and 3-way merge...
Auto-merging src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.Tests.cs
CONFLICT (content): Merge conflict in src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.Tests.cs
Auto-merging src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.Tests.cs
CONFLICT (content): Merge conflict in src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.Tests.cs
Auto-merging src/libraries/System.Formats.Tar/tests/TarTestsBase.cs
CONFLICT (content): Merge conflict in src/libraries/System.Formats.Tar/tests/TarTestsBase.cs
Auto-merging src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Use indexer setter instead of Add on ExtendedAttributes dictionary
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

jozkee added a commit that referenced this pull request Oct 3, 2022
…ry (#76404)
* Use indexer setter instead of Add on ExtendedAttributes dictionary
* Add roundtrip tests
* Fix TryAddStringField and always set mtime
@carlossanlopcarlossanlop added Servicing-consider Issue for next servicing release review and removed Servicing-consider Issue for next servicing release review labels Oct 3, 2022
carlossanlop pushed a commit that referenced this pull request Oct 4, 2022
* Use UTF8 encoding on Tar string fields
* Slice destination on Checksum
* Use Encoding.GetByteCount as fast path
* Use escape sequences on hardcoded UTF8 characters
* Fix ustar prefix logic and throw if name would be truncated
* Address feedback
* Fix truncation and prefix logic
* Fix nits
* Add async tests
* Add tests for unseekable streams
* Address feedback
* Tar: Use indexer setter instead of Add on ExtendedAttributes dictionary (#76404)
* Use indexer setter instead of Add on ExtendedAttributes dictionary
* Add roundtrip tests
* Fix TryAddStringField and always set mtime
Co-authored-by: David Cantu <dacantu@microsoft.com>
@ghostghost locked as resolved and limited conversation to collaborators Nov 3, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tar: Not able to write a PaxTarEntry from a TarReader.

3 participants

@jozkee@carlossanlop@jeffhandley