From c241278aee53b3db7eaecb87b1e0012b88b88f09 Mon Sep 17 00:00:00 2001 From: Alexandru-Constantin Bledea Date: Wed, 25 Oct 2017 19:42:06 +0300 Subject: [PATCH] [PATCH] [Fernflower] prevent null to be cast as short/byte --- .../modules/decompiler/ExprProcessor.java | 2 +- .../modules/decompiler/exps/ConstExprent.java | 4 ++ .../java/decompiler/SingleClassesTest.java | 1 + .../classes/pkg/TestPrimitiveNarrowing.class | Bin 0 -> 805 bytes testData/results/TestPrimitiveNarrowing.dec | 64 ++++++++++++++++++ testData/src/pkg/TestPrimitiveNarrowing.java | 24 +++++++ 6 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 testData/classes/pkg/TestPrimitiveNarrowing.class create mode 100644 testData/results/TestPrimitiveNarrowing.dec create mode 100644 testData/src/pkg/TestPrimitiveNarrowing.java diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index 48e7d3f..6a03bf4 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -877,7 +877,7 @@ public class ExprProcessor implements CodeConstants { boolean quote = cast && exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST); // cast instead to 'byte' / 'short' when int constant is used as a value for 'Byte' / 'Short' - if (castNarrowing && exprent.type == Exprent.EXPRENT_CONST) { + if (castNarrowing && exprent.type == Exprent.EXPRENT_CONST && !((ConstExprent) exprent).isNull()) { if (leftType.equals(VarType.VARTYPE_BYTE_OBJ)) { leftType = VarType.VARTYPE_BYTE; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java index e77b680..cfd300d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -247,6 +247,10 @@ public class ConstExprent extends Exprent { throw new RuntimeException("invalid constant type: " + constType); } + public boolean isNull() { + return CodeConstants.TYPE_NULL == constType.type; + } + private static String convertStringToJava(String value, boolean ascii) { char[] arr = value.toCharArray(); StringBuilder buffer = new StringBuilder(arr.length); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 2e6c819..11d393e 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -32,6 +32,7 @@ public class SingleClassesTest { fixture = null; } + @Test public void testPrimitiveNarrowing() { doTest("pkg/TestPrimitiveNarrowing"); } @Test public void testClassFields() { doTest("pkg/TestClassFields"); } @Test public void testInterfaceFields() { doTest("pkg/TestInterfaceFields"); } @Test public void testClassLambda() { doTest("pkg/TestClassLambda"); } diff --git a/testData/classes/pkg/TestPrimitiveNarrowing.class b/testData/classes/pkg/TestPrimitiveNarrowing.class new file mode 100644 index 0000000000000000000000000000000000000000..dc7c0c533580ea09f0e605b8ade813c72a9fb526 GIT binary patch literal 805 zcmaixT~AX%5Qg9FcTW#eT0APE^5F$wLc=x4g(fB@4Vpk|yxf+xT{xU$4%-rc7FQ5R z`~m(b!#m3{G^pWXXJ=;jeRg){*YB&J0JiWtKou_nl<`u`D=|w|EX%%9#i~MO$0pY8 zD$K8SkMu-$Vx0^-`=c~-+v`1r();w#D9mPMzaI}f2jic2cZe0l$HbYT$rPe#N}lzg_LTBZUZE~x-x7sj zKOJWS^TA3Fp8xxco6^V-HMBxJ!P5{6sE24{USZ+?jS)dzp?NojPyHh^a9HB7svIY{ zLoR`3(0j|hAlZ!zsB=06G-!j{Buc0tWE|!33?4BO$Sj(a)-Z=wj@m`hpGE2t1+F4j z=^Ev)>H?K7!e$F;BVR(D?11_P`5_)-hCY9nv)=gIRNR$R;Su<#loNViQ5G?(NrN5| Yw(kj_c_EwnkTAL@Y*NUn(H5|H1BW4z1ONa4 literal 0 HcmV?d00001 diff --git a/testData/results/TestPrimitiveNarrowing.dec b/testData/results/TestPrimitiveNarrowing.dec new file mode 100644 index 0000000..1e5d30c --- /dev/null +++ b/testData/results/TestPrimitiveNarrowing.dec @@ -0,0 +1,64 @@ +package pkg; + +class TestPrimitiveNarrowing { + TestPrimitiveNarrowing(Short value) { + }// 6 + + static void invocations() { + withInteger((Integer)null);// 9 + withShort((Short)null);// 10 + withByte((Byte)null);// 11 + new TestPrimitiveNarrowing((Short)null);// 12 + }// 13 + + static void withByte(Byte defaultValue) { + }// 16 + + static void withInteger(Integer defaultValue) { + }// 19 + + static void withShort(Short defaultValue) { + }// 22 +} + +class 'pkg/TestPrimitiveNarrowing' { + method ' (Ljava/lang/Short;)V' { + 4 4 + } + + method 'invocations ()V' { + 0 7 + 1 7 + 4 8 + 5 8 + 8 9 + 9 9 + 10 10 + 15 11 + } + + method 'withByte (Ljava/lang/Byte;)V' { + 0 14 + } + + method 'withInteger (Ljava/lang/Integer;)V' { + 0 17 + } + + method 'withShort (Ljava/lang/Short;)V' { + 0 20 + } +} + +Lines mapping: +6 <-> 5 +9 <-> 8 +10 <-> 9 +11 <-> 10 +12 <-> 11 +13 <-> 12 +16 <-> 15 +19 <-> 18 +22 <-> 21 +Not mapped: +5 diff --git a/testData/src/pkg/TestPrimitiveNarrowing.java b/testData/src/pkg/TestPrimitiveNarrowing.java new file mode 100644 index 0000000..672ceb8 --- /dev/null +++ b/testData/src/pkg/TestPrimitiveNarrowing.java @@ -0,0 +1,24 @@ +package pkg; + +class TestPrimitiveNarrowing { + + TestPrimitiveNarrowing(Short value) { + } + + static void invocations() { + withInteger(null); + withShort(null); + withByte(null); + new TestPrimitiveNarrowing(null); + } + + static void withByte(Byte defaultValue) { + } + + static void withInteger(Integer defaultValue) { + } + + static void withShort(Short defaultValue) { + } + +}