Fix LocaleNumberSystem + ConfigFlag reading (#3205)

* fix: prevent over-reading config flags

* fix: properly read localeNumberingSystem

* test: adjust test for bcp47 aapt2 test

* fix: properly add 8 to 'read' on parser

* test: add test for aapt2 bcp47 tag

* test: add additional bcp47 test

* fix: handle numbering system parsing

* fix: add comment about localeNumber usage
This commit is contained in:
Connor Tumbleson 2023-07-23 17:25:25 -04:00 committed by GitHub
parent 54836509ed
commit d1a0c941ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 15 deletions

View File

@ -51,6 +51,8 @@ public class ResConfigFlags {
private final byte screenLayout2;
private final byte colorMode;
private final char[] localeNumberingSystem;
public final boolean isInvalid;
private final String mQualifiers;
@ -80,6 +82,7 @@ public class ResConfigFlags {
localeVariant = null;
screenLayout2 = 0;
colorMode = COLOR_WIDE_UNDEFINED;
localeNumberingSystem = null;
isInvalid = false;
mQualifiers = "";
size = 0;
@ -92,7 +95,8 @@ public class ResConfigFlags {
short sdkVersion, byte screenLayout, byte uiMode,
short smallestScreenWidthDp, short screenWidthDp,
short screenHeightDp, char[] localeScript, char[] localeVariant,
byte screenLayout2, byte colorMode, boolean isInvalid, int size) {
byte screenLayout2, byte colorMode, char[] localeNumberingSystem,
boolean isInvalid, int size) {
if (orientation < 0 || orientation > 3) {
LOGGER.warning("Invalid orientation value: " + orientation);
orientation = 0;
@ -157,6 +161,7 @@ public class ResConfigFlags {
this.localeVariant = localeVariant;
this.screenLayout2 = screenLayout2;
this.colorMode = colorMode;
this.localeNumberingSystem = localeNumberingSystem;
this.isInvalid = isInvalid;
this.size = size;
mQualifiers = generateQualifiers();
@ -466,6 +471,12 @@ public class ResConfigFlags {
if (localeVariant != null && localeVariant.length >= 5) {
sb.append("+").append(toUpper(localeVariant));
}
// If we have a numbering system - it isn't used in qualifiers for build tools, but AOSP understands it
// So chances are - this may be valid, but aapt 1/2 will not like it.
if (localeNumberingSystem != null && localeNumberingSystem.length > 0) {
sb.append("+u+nu+").append(localeNumberingSystem);
}
}
return sb.toString();
}

View File

@ -497,8 +497,8 @@ public class ARSCDecoder {
char[] localeScript = null;
char[] localeVariant = null;
if (size >= 48) {
localeScript = readScriptOrVariantChar(4).toCharArray();
localeVariant = readScriptOrVariantChar(8).toCharArray();
localeScript = readVariantLengthString(4).toCharArray();
localeVariant = readVariantLengthString(8).toCharArray();
read = 48;
}
@ -511,16 +511,16 @@ public class ARSCDecoder {
read = 52;
}
if (size > 52) {
int length = size - read;
mIn.skipBytes(length); // localeNumberingSystem
read += length;
char[] localeNumberingSystem = null;
if (size >= 60) {
localeNumberingSystem = readVariantLengthString(8).toCharArray();
read = 60;
}
int exceedingSize = size - KNOWN_CONFIG_BYTES;
if (exceedingSize > 0) {
byte[] buf = new byte[exceedingSize];
read += exceedingSize;
int exceedingKnownSize = size - KNOWN_CONFIG_BYTES;
if (exceedingKnownSize > 0) {
byte[] buf = new byte[exceedingKnownSize];
read += exceedingKnownSize;
mIn.readFully(buf);
BigInteger exceedingBI = new BigInteger(1, buf);
@ -545,7 +545,7 @@ public class ARSCDecoder {
inputFlags, screenWidth, screenHeight, sdkVersion,
screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp,
screenHeightDp, localeScript, localeVariant, screenLayout2,
colorMode, isInvalid, size);
colorMode, localeNumberingSystem, isInvalid, size);
}
private char[] unpackLanguageOrRegion(byte in0, byte in1, char base) {
@ -562,17 +562,17 @@ public class ARSCDecoder {
return new char[] { (char) in0, (char) in1 };
}
private String readScriptOrVariantChar(int length) throws IOException {
private String readVariantLengthString(int maxLength) throws IOException {
StringBuilder string = new StringBuilder(16);
while (length-- != 0) {
while (maxLength-- != 0) {
short ch = mIn.readByte();
if (ch == 0) {
break;
}
string.append((char) ch);
}
mIn.skipBytes(length);
mIn.skipBytes(maxLength);
return string.toString();
}

View File

@ -76,6 +76,17 @@ public class BuildAndDecodeTest extends BaseTest {
compareValuesFiles("values-es/strings.xml");
}
@Test
public void valuesBcp47LanguageVariantTest() throws BrutException {
compareValuesFiles("values-b+iw+660/strings.xml");
}
@Test
public void valuesBcp47LanguageScriptRegionVariantTest() throws BrutException {
compareValuesFiles("values-b+ast+Latn+IT+AREVELA/strings.xml");
compareValuesFiles("values-b+ast+Hant+IT+ARABEXT/strings.xml");
}
@Test
public void confirmZeroByteFileExtensionIsNotStored() throws BrutException {
ApkInfo apkInfo = ApkInfo.load(sTestNewDir);

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">testapp</string>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">testapp</string>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">testapp</string>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">testapp</string>
</resources>