Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

[Bug] [Windows] Xamarin.Build.Download Fix Max Path Length Extraction #1296

Merged
merged 4 commits into from
Dec 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public void TestZipDownload ()

var success = BuildProject (engine, project, "_XamarinBuildDownload", log);


AssertNoMessagesOrWarnings (log, DEFAULT_IGNORE_PATTERNS);
Assert.True (success);

Expand Down Expand Up @@ -332,7 +332,7 @@ public void TestAndroidAarAdded()
var artifactXbdId = "gpsbasement-16.2.0";

var r = AndroidAarAdd(unpackDir, artifactXbdId, "https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/16.2.0/play-services-basement-16.2.0.aar", true);

AssertNoMessagesOrWarnings(r.logs, DEFAULT_IGNORE_PATTERNS);
Assert.True(r.success);

Expand Down Expand Up @@ -361,7 +361,7 @@ public void TestAndroidAarIdeTooOld()
var engine = new ProjectCollection ();
var prel = ProjectRootElement.Create (Path.Combine (TempDir, "project.csproj"), engine);


prel.SetProperty ("XamarinBuildDownloadDir", unpackDir);
prel.SetProperty ("TargetFrameworkIdentifier", "MonoAndroid");
prel.SetProperty ("TargetFrameworkVersion", "v9.0");
Expand Down Expand Up @@ -678,7 +678,7 @@ public void TestGetPartialZipItemsToDownload ()
{ "RangeStart", "199278205" },
{ "RangeEnd", "199589731" },
});

AddCoreTargets (prel);

var project = new ProjectInstance (prel);
Expand All @@ -694,5 +694,37 @@ public void TestGetPartialZipItemsToDownload ()
Assert.Equal (2, itemToDownload.Count);
Assert.True (itemToDownload.First ().GetMetadata ("Url").EvaluatedValue == itemUrl);
}

[Fact]
public void TestPathGreaterThan260Chars ()
{
var engine = new ProjectCollection ();
var prel = ProjectRootElement.Create (Path.Combine (TempDir, "project.csproj"), engine);

var unpackDir = GetTempPath ("unpacked");

for (var i = 1; unpackDir.Length < 260; i++)
unpackDir = Path.Combine (unpackDir, $"segment{i}");

prel.SetProperty ("XamarinBuildDownloadDir", unpackDir);

prel.AddItem (
"XamarinBuildDownload", "GAppM-8.8.0", new Dictionary<string, string> {
{ "Url", "https://dl.google.com/firebase/ios/analytics/86849febfdc4ff13/GoogleAppMeasurement-8.8.0.tar.gz" },
{ "Kind", "Tgz" }
});

AddCoreTargets (prel);

var project = new ProjectInstance (prel);
var log = new MSBuildTestLogger ();

var success = BuildProject (engine, project, "_XamarinBuildDownload", log);

AssertNoMessagesOrWarnings (log, DEFAULT_IGNORE_PATTERNS);
Assert.True (success);

Assert.True (File.Exists (Path.Combine (unpackDir, "GAppM-8.8.0", "GoogleAppMeasurement-8.8.0", "dummy.txt")));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ namespace Xamarin.MacDev
/// </summary>
class ProcessArgumentBuilder
{
static readonly char[] QuoteSpecials = new char[] { ' ', '\\', '\'', '"', ',', ';' };

readonly HashSet<string> hash = new HashSet<string> ();
readonly StringBuilder builder = new StringBuilder ();

Expand Down Expand Up @@ -91,19 +89,9 @@ public void AddQuotedFormat (string argumentFormat, object val0)

static void AppendQuoted (StringBuilder quoted, string text)
{
if (text.IndexOfAny (QuoteSpecials) != -1) {
quoted.Append ("\"");

for (int i = 0; i < text.Length; i++) {
if (text[i] == '\\' || text[i] == '"')
quoted.Append ('\\');
quoted.Append (text[i]);
}

quoted.Append ("\"");
} else {
quoted.Append (text);
}
quoted.Append ("\"");
quoted.Append (text);
quoted.Append ("\"");
}

/// <summary>Adds an argument, quoting and escaping as necessary.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<PackageId>Xamarin.Build.Download</PackageId>
<Title>Xamarin Build-time Download Support</Title>
<PackageVersion>0.10.0</PackageVersion>
<PackageVersion>0.11.0</PackageVersion>
<Authors>Microsoft</Authors>
<Owners>Microsoft</Owners>
<PackageProjectUrl>https://go.microsoft.com/fwlink/?linkid=865061</PackageProjectUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,22 @@ ProcessStartInfo CreateExtractionArgs (string file, string contentDir, ArchiveKi
default:
throw new ArgumentException ("kind");
}
return new ProcessStartInfo (args.ProcessPath, args.ToString ()) {
WorkingDirectory = contentDir,
CreateNoWindow = true
};

ProcessStartInfo psi = null;
if (Platform.IsWindows)
psi = new ProcessStartInfo (args.ProcessPath, args.ToString ())
{
WorkingDirectory = null,
Copy link
Member

Choose a reason for hiding this comment

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

could you provide link to docs for this trick, please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Setting to null will default to System32 as the working directory, see here. This should be fine as no user/pass is specified & all the paths for the process and extraction are absolute. If we set it to contentDir it'll fail for paths over 260 chars.

CreateNoWindow = true
};
else
psi = new ProcessStartInfo (args.ProcessPath, args.ToString ())
{
WorkingDirectory = contentDir,
CreateNoWindow = true
};

return psi;
}

static ProcessArgumentBuilder Build7ZipExtractionArgs (string file, string contentDir, string user7ZipPath, bool ignoreTarSymLinks, string vsInstallRoot)
Expand Down