镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content
16 changes: 13 additions & 3 deletions src/Xamarin.Android.Build.Tasks/Tasks/Aapt2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ namespace Xamarin.Android.Tasks {
public abstract class Aapt2 : AsyncTask {

private const int MAX_PATH = 260;
private const int ASCII_MAX_CHAR = 127;
private static readonly int DefaultMaxAapt2Daemons = 6;
protected Dictionary<string, string> _resource_name_case_map;

Expand Down Expand Up @@ -52,6 +51,17 @@ public abstract class Aapt2 : AsyncTask {
public static bool IsInvalidFilename (string path) =>
Path.GetFileName (path).StartsWith (".", StringComparison.Ordinal);

/// <summary>
/// Returns <see langword="true"/> if <paramref name="c"/> is an ASCII
/// character ([ U+0000..U+007F ]).
/// </summary>
/// <remarks>
/// Per http://www.unicode.org/glossary/#ASCII, ASCII is only U+0000..U+007F.
/// We cannot use Char.IsAscii cos we are .netstandard2.0
/// Source https://github.com/dotnet/runtime/blob/1d1bf92fcf43aa6981804dc53c5174445069c9e4/src/libraries/System.Private.CoreLib/src/System/Char.cs#L91
/// </remarks>
public static bool IsAscii(char c) => (uint)c <= '\x007f';

protected string ResourceDirectoryFullPath (string resourceDirectory)
{
return (Path.IsPathRooted (resourceDirectory) ? resourceDirectory : Path.Combine (WorkingDirectory, resourceDirectory)).TrimEnd ('\\');
Expand Down Expand Up @@ -226,13 +236,13 @@ static bool IsFilePathToLong (string filePath)
return false;
}

static bool IsPathOnlyASCII (string filePath)
static protected bool IsPathOnlyASCII (string filePath)
{
if (!OS.IsWindows)
return true;

foreach (var c in filePath)
if (c > ASCII_MAX_CHAR) // cannot use Char.IsAscii cos we are .netstandard2.0
if (!IsAscii (c))
return false;
return true;
}
Expand Down
16 changes: 15 additions & 1 deletion src/Xamarin.Android.Build.Tasks/Tasks/Aapt2Link.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,16 @@ string [] GenerateCommandLineCommands (string ManifestFile, string currentAbi, s
}
}

var hasAssetsErrors = false;
// When adding Assets the first item found takes precedence.
// So we need to add the applicaiton Assets first.
// So we need to add the application Assets first.
if (!string.IsNullOrEmpty (AssetsDirectory)) {
var assetDir = GetFullPath (AssetsDirectory.TrimEnd ('\\'));
if (Directory.Exists (assetDir)) {
if (OS.IsWindows && !IsPathOnlyASCII (assetDir)) {
hasAssetsErrors = true;
LogCodedError ("APT2265", Properties.Resources.APT2265, assetDir);
}
cmd.Add ("-A");
cmd.Add (assetDir);
} else {
Expand All @@ -289,6 +294,11 @@ string [] GenerateCommandLineCommands (string ManifestFile, string currentAbi, s
var assetDir = GetFullPath (AdditionalAndroidAssetPaths [i].ItemSpec.TrimEnd ('\\'));
if (!string.IsNullOrWhiteSpace (assetDir)) {
if (Directory.Exists (assetDir)) {
if (OS.IsWindows && !IsPathOnlyASCII (assetDir)) {
hasAssetsErrors = true;
LogCodedError ("APT2265", Properties.Resources.APT2265, assetDir);
continue;
}
cmd.Add ("-A");
cmd.Add (GetFullPath (assetDir));
} else {
Expand All @@ -298,6 +308,10 @@ string [] GenerateCommandLineCommands (string ManifestFile, string currentAbi, s
}
}

if (hasAssetsErrors) {
return Array.Empty<string> ();
}

if (!string.IsNullOrEmpty (ProguardRuleOutput)) {
cmd.Add ("--proguard");
cmd.Add (GetFullPath (GetManifestRulesFile (manifestDir)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ protected string[] GenerateCommandLineCommands (ITaskItem manifest, ITaskItem ou
cmd.Add ("--custom-package");
cmd.Add (PackageName);
foreach (var assetDirectory in AssetDirectories) {
var fullPath = GetFullPath (assetDirectory.ItemSpec);
if (OS.IsWindows && !IsPathOnlyASCII (fullPath)) {
LogCodedError ("APT2265", Properties.Resources.APT2265, fullPath);
continue;
}
cmd.Add ("-A");
cmd.Add (GetFullPath (assetDirectory.ItemSpec));
cmd.Add (fullPath);
}
cmd.Add ($"-o");
cmd.Add (GetFullPath (output.ItemSpec));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,26 @@ public void CheckAssetsAreIncludedInAPK ()
}
}

[Test]
public void InvalidAssetDirectoryWithNonASCIIChars ()
{
var proj = new XamarinAndroidApplicationProject () {
ProjectName = "App1",
IsRelease = true,
OtherBuildItems = {
new AndroidItem.AndroidAsset ("Assets\\asset1.txt") {
TextContent = () => "Asset1",
Encoding = Encoding.ASCII,
},
},
};
using (var b = CreateApkBuilder (Path.Combine ("temp", "InvalidAssetDirectoryWithNonASCIIChars_Ümläüt", proj.ProjectName))) {
b.ThrowOnBuildFailure = false;
Assert.AreEqual (!IsWindows, b.Build (proj), $"{proj.ProjectName} should {(IsWindows ? "not " : "")}have built successfully.");
Assert.AreEqual (IsWindows, b.LastBuildOutput.ContainsText ("APT2265"), $"APT2265 should {(IsWindows ? "" : "not ")}have been raised.");
}
}

[Test]
public void FullPath ()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ public void BuildApplicationWithSpacesInPath ([Values (true, false)] bool enable
IsRelease = true,
AotAssemblies = true,
LinkTool = linkTool,
References = { new BuildItem ("ProjectReference", $"..\\{folderName}Library1\\Library1.csproj") }
References = { new BuildItem ("ProjectReference", $"..\\{folderName}Library1\\Library1.csproj") },
};
proj.OtherBuildItems.Add (new BuildItem ("AndroidJavaLibrary", "Hello (World).jar") { BinaryContent = () => Convert.FromBase64String (@"
UEsDBBQACAgIAMl8lUsAAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAAMAUEsHCAAAAAACAAAAA
Expand Down