diff --git a/.gitignore b/.gitignore index 533e4f04..49144af2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ /dexlib2/accessorTestGenerator/build /smali/build /util/build +*.iml +*.ipr +*.iws diff --git a/NOTICE b/NOTICE index a3f1ba06..e29e98b8 100644 --- a/NOTICE +++ b/NOTICE @@ -85,56 +85,6 @@ limitations under the License. ******************************************************************************* -The smali mojo plugin is (very loosely) based on an unknown mojo plugin with -the following license: - -******************************************************************************* -Copyright 2001-2005 The Apache Software Foundation. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -******************************************************************************* - - -The RadixTree implementation in the "util" project is taken from -http://code.google.com/p/radixtree/ (version .3), and is used with minor -modifications in accordance with the following license: - -******************************************************************************* -The MIT License - -Copyright (c) 2008 Tahseen Ur Rehman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -******************************************************************************* - - - Some parts of the smalidea plugin are based on code from the IDEA project, per the following license diff --git a/baksmali/build.gradle b/baksmali/build.gradle index 150eb6fd..4780cd76 100644 --- a/baksmali/build.gradle +++ b/baksmali/build.gradle @@ -29,8 +29,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -configurations { - proguard +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath depends.proguard_gradle + } } dependencies { @@ -41,8 +46,6 @@ dependencies { testCompile depends.junit testCompile project(':smali') - - proguard depends.proguard } processResources.inputs.property('version', version) @@ -59,11 +62,11 @@ task fatJar(type: Jar) { from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } manifest { - attributes("Main-Class": "org.jf.baksmali.main") + attributes('Main-Class': 'org.jf.baksmali.main') } doLast { - if (!System.getProperty("os.name").toLowerCase().contains("windows")) { + if (!System.getProperty('os.name').toLowerCase().contains('windows')) { ant.symlink(link: file("${destinationDir}/baksmali.jar"), resource: archivePath, overwrite: true) } } @@ -81,22 +84,22 @@ uploadArchives { } } -task proguard(type: JavaExec, dependsOn: fatJar) { +task proguard(type: proguard.gradle.ProGuardTask, dependsOn: fatJar) { def outFile = fatJar.destinationDir.getPath() + '/' + fatJar.baseName + '-' + fatJar.version + '-small' + '.' + fatJar.extension - inputs.file fatJar.archivePath - outputs.file outFile - classpath = configurations.proguard - main = 'proguard.ProGuard' - args '-injars ' + fatJar.archivePath - args '-outjars ' + outFile - args '-libraryjars ' + System.properties['java.home'] + '/lib/rt.jar' - args '-dontobfuscate' - args '-dontoptimize' - args '-keep public class org.jf.baksmali.main { public static void main(java.lang.String[]); }' - args '-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }' - args '-dontwarn com.google.common.**' - args '-dontnote com.google.common.**' + injars fatJar.archivePath + outjars outFile + + libraryjars "${System.properties['java.home']}/lib/rt.jar" + + dontobfuscate + dontoptimize + + keep 'public class org.jf.baksmali.main { public static void main(java.lang.String[]); }' + keepclassmembers 'enum * { public static **[] values(); public static ** valueOf(java.lang.String); }' + + dontwarn 'com.google.common.**' + dontnote 'com.google.common.**' } tasks.getByPath(':release').dependsOn(proguard) diff --git a/build.gradle b/build.gradle index a9ee7e0e..32977047 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ if (!('release' in gradle.startParameter.taskNames)) { def versionSuffix try { def git = org.eclipse.jgit.api.Git.open(file('.')) - def head = git.getRepository().getRef("HEAD") + def head = git.getRepository().getRef('HEAD') versionSuffix = head.getObjectId().abbreviate(8).name() if (!git.status().call().clean) { @@ -90,7 +90,8 @@ subprojects { stringtemplate: 'org.antlr:stringtemplate:3.2.1', commons_cli: 'commons-cli:commons-cli:1.2', jflex: 'de.jflex:jflex:1.4.3', - proguard: 'net.sf.proguard:proguard-base:4.8' + jflex_plugin: 'co.tomlee.gradle.plugins:gradle-jflex-plugin:0.0.1', + proguard_gradle: 'net.sf.proguard:proguard-gradle:5.1' ] } @@ -124,7 +125,7 @@ subprojects { } signing { - required { gradle.taskGraph.hasTask("uploadArchives") } + required { gradle.taskGraph.hasTask('uploadArchives') } sign configurations.archives } @@ -135,7 +136,7 @@ subprojects { beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } if (rootProject.hasProperty('sonatypeUsername') && rootProject.hasProperty('sonatypePassword')) { - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2/') { authentication(userName: sonatypeUsername, password: sonatypePassword) } } @@ -182,5 +183,5 @@ buildscript { } task wrapper(type: Wrapper) { - gradleVersion = '1.10' + gradleVersion = '2.3' } \ No newline at end of file diff --git a/deodexerant/Android.mk b/deodexerant/Android.mk index c1921f9b..46a9dba8 100644 --- a/deodexerant/Android.mk +++ b/deodexerant/Android.mk @@ -39,4 +39,6 @@ LOCAL_SHARED_LIBRARIES := libdl LOCAL_MODULE_TAGS := optional -include $(BUILD_EXECUTABLE) \ No newline at end of file +LOCAL_LDFLAGS := -Wl,--hash-style=sysv + +include $(BUILD_EXECUTABLE) diff --git a/dexlib2/build.gradle b/dexlib2/build.gradle index d39c5db9..9027132e 100644 --- a/dexlib2/build.gradle +++ b/dexlib2/build.gradle @@ -46,37 +46,6 @@ dependencies { ext.testAccessorOutputDir = file("${buildDir}/generated-accessor-test-sources") ext.testAccessorOutputFile = file("${buildDir}/generated-accessor-test-sources/org/jf/dexlib2/AccessorTypes.java") -sourceSets { - // The sources for building the test dex file for the accessor test - accessorTestDex { - java { - srcDir testAccessorOutputDir - } - } - - // The sources for the accessor test itself - accessorTest { - java { - compileClasspath += main.output - runtimeClasspath += main.output - } - } -} - -configurations { - accessorTestDexCompile.extendsFrom compile - accessorTestDexRuntime.extendsFrom runtime - - accessorTestCompile.extendsFrom testCompile - accessorTestRuntime.extendsFrom testRuntime -} - -idea { - module { - testSourceDirs += sourceSets.accessorTest.java.srcDirs - } -} - // You must manually execute this task to regenerate SyntheticAccessorFSM.java, after modifying the ragel file // e.g. ./gradlew ragel task ragel(type:Exec) { @@ -87,36 +56,47 @@ task ragel(type:Exec) { } task generateAccessorTestSource(type: JavaExec) { - outputs.dir file(testAccessorOutputDir) + doFirst { + file(testAccessorOutputFile.parent).mkdirs() + } - mkdir(file(testAccessorOutputFile).parent) + outputs.dir file(testAccessorOutputDir) + sourceSets['test'].java.srcDir file(testAccessorOutputDir) classpath = configurations.accessorTestGenerator main = 'org.jf.dexlib2.AccessorTestGenerator' args testAccessorOutputFile } -compileAccessorTestDexJava.dependsOn(generateAccessorTestSource) +compileTestJava.dependsOn generateAccessorTestSource -task generateAccessorTestDex(type: Exec, dependsOn: compileAccessorTestDexJava) { - def outputDex = file("${sourceSets.accessorTest.output.resourcesDir}/accessorTest.dex") - mkdir(outputDex.parent) +task generateAccessorTestDex(type: Exec, dependsOn: compileTestJava) { + def outputDex = file(new File(sourceSets.test.output.resourcesDir, 'accessorTest.dex')) - inputs.dir project.sourceSets.accessorTestDex.output.classesDir + doFirst { + file(outputDex.parent).mkdirs() + } + + inputs.dir(project.sourceSets.test.output.classesDir) outputs.file outputDex - sourceSets.accessorTest.resources - - workingDir project.sourceSets.accessorTestDex.output.classesDir + workingDir project.sourceSets.test.output.classesDir executable 'dx' args '--dex' + args '--no-strict' args "--output=${outputDex}" - args '.' -} -task accessorTest(type: Test, dependsOn: generateAccessorTestDex) { - testClassesDir = project.sourceSets.accessorTest.output.classesDir - classpath = project.sourceSets.accessorTest.runtimeClasspath + doFirst { + // this has to be done in doFirst, so that the generated classes will be available. + // otherwise, it the tree will be populated while the build is being configured, + // which is before the compileTestJava has run + fileTree(project.sourceSets.test.output.classesDir) { + include 'org/jf/dexlib2/AccessorTypes*.class' + }.each { File file -> + args file + } + } } +test.dependsOn generateAccessorTestDex uploadArchives { repositories.mavenDeployer { diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java index 87a2ae6b..268df9b1 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java @@ -576,6 +576,9 @@ public abstract class DexWriter< private void writeAnnotationSets(@Nonnull DexDataWriter writer) throws IOException { writer.align(); annotationSetSectionOffset = writer.getPosition(); + if (shouldCreateEmptyAnnotationSet()) { + writer.writeInt(0); + } for (Map.Entry entry: annotationSetSection.getItems()) { Collection annotations = Ordering.from(BaseAnnotation.BY_TYPE) .immutableSortedCopy(annotationSetSection.getAnnotations(entry.getKey())); @@ -613,6 +616,8 @@ public abstract class DexWriter< for (AnnotationSetKey annotationSetKey: parameterAnnotations) { if (annotationSetSection.getAnnotations(annotationSetKey).size() > 0) { writer.writeInt(annotationSetSection.getItemOffset(annotationSetKey)); + } else if (shouldCreateEmptyAnnotationSet()) { + writer.writeInt(annotationSetSectionOffset); } else { writer.writeInt(NO_OFFSET); } @@ -1115,7 +1120,7 @@ public abstract class DexWriter< if (annotationSection.getItems().size() > 0) { numItems++; } - if (annotationSetSection.getItems().size() > 0) { + if (annotationSetSection.getItems().size() > 0 || shouldCreateEmptyAnnotationSet()) { numItems++; } if (numAnnotationSetRefItems > 0) { @@ -1163,8 +1168,8 @@ public abstract class DexWriter< writeMapItem(writer, ItemType.TYPE_LIST, typeListSection.getItems().size(), typeListSectionOffset); writeMapItem(writer, ItemType.ENCODED_ARRAY_ITEM, numEncodedArrayItems, encodedArraySectionOffset); writeMapItem(writer, ItemType.ANNOTATION_ITEM, annotationSection.getItems().size(), annotationSectionOffset); - writeMapItem(writer, ItemType.ANNOTATION_SET_ITEM, annotationSetSection.getItems().size(), - annotationSetSectionOffset); + writeMapItem(writer, ItemType.ANNOTATION_SET_ITEM, + annotationSetSection.getItems().size() + (shouldCreateEmptyAnnotationSet() ? 1 : 0), annotationSetSectionOffset); writeMapItem(writer, ItemType.ANNOTATION_SET_REF_LIST, numAnnotationSetRefItems, annotationSetRefSectionOffset); writeMapItem(writer, ItemType.ANNOTATION_DIRECTORY_ITEM, numAnnotationDirectoryItems, annotationDirectorySectionOffset); @@ -1226,4 +1231,11 @@ public abstract class DexWriter< writer.writeInt(0); } } + + private boolean shouldCreateEmptyAnnotationSet() { + // Workaround for a crash in Dalvik VM before Jelly Bean MR1 (4.2) + // which is triggered by NO_OFFSET in parameter annotation list. + // (https://code.google.com/p/android/issues/detail?id=35304) + return (api < 17); + } } diff --git a/dexlib2/src/accessorTest/java/org/jf/dexlib2/AccessorTest.java b/dexlib2/src/test/java/org/jf/dexlib2/AccessorTest.java similarity index 100% rename from dexlib2/src/accessorTest/java/org/jf/dexlib2/AccessorTest.java rename to dexlib2/src/test/java/org/jf/dexlib2/AccessorTest.java diff --git a/gradle.properties b/gradle.properties index 335740c6..567bbb91 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,2 @@ -org.gradle.daemon=true \ No newline at end of file +org.gradle.daemon=true +org.gradle.parallel=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 58385981..085a1cdc 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3f70b064..7e793277 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Feb 02 12:47:14 PST 2014 +#Sun Mar 01 19:20:47 PST 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-all.zip diff --git a/smali/build.gradle b/smali/build.gradle index 0f43d756..0e5cbf2d 100644 --- a/smali/build.gradle +++ b/smali/build.gradle @@ -29,25 +29,28 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -configurations { - antlr3 - jflex - proguard +apply plugin: 'antlr' +apply plugin: 'jflex' + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath depends.jflex_plugin + classpath depends.proguard_gradle + } } -ext.antlrSource = 'src/main/antlr3' -ext.antlrOutput = file("${buildDir}/generated-sources/antlr3") +configurations { + // Remove the full antlr library that's added by the antlr plugin. We manually + // add the smaller antlr_runtime library instead + compile.exclude group: 'org.antlr', module: 'antlr' -ext.jflexSource = "src/main/jflex" -ext.jflexOutput = file("${buildDir}/generated-sources/jflex") - -ext.testAntlrSource = 'src/test/antlr3' -ext.testAntlrOutput = file("${buildDir}/generated-test-sources/antlr3") - -sourceSets.main.java.srcDir antlrOutput -sourceSets.main.java.srcDir jflexOutput - -sourceSets.test.java.srcDir testAntlrOutput + // The jflex lexer doesn't have any runtime dependencies, so remove the dependency + // that gets added by the jflex plugin + compile.exclude group: 'de.jflex', module: 'jflex' +} idea { module { @@ -73,68 +76,10 @@ dependencies { testCompile depends.junit - antlr3 depends.antlr + antlr depends.antlr jflex depends.jflex - proguard depends.proguard } -task generateParserAntlrSource(type: JavaExec) { - inputs.dir file(antlrSource) - outputs.dir file(antlrOutput) - - mkdir(antlrOutput) - def grammars = fileTree(antlrSource).include('**/smaliParser.g') - - classpath = configurations.antlr3 - main = 'org.antlr.Tool' - args '-fo', relativePath("${antlrOutput}/org/jf/smali") - args grammars.files -} - -task generateTreeWalkerAntlrSource(type: JavaExec) { - inputs.dir file(antlrSource) - outputs.dir file(antlrOutput) - - mkdir(antlrOutput) - def grammars = fileTree(antlrSource).include('**/smaliTreeWalker.g') - - classpath = configurations.antlr3 - main = 'org.antlr.Tool' - args '-fo', relativePath("${antlrOutput}/org/jf/smali") - args grammars.files -} - -task generateTestAntlrSource(type: JavaExec) { - inputs.dir file(testAntlrSource) - outputs.dir file(testAntlrOutput) - - mkdir(testAntlrOutput) - def grammars = fileTree(testAntlrSource).include('**/*.g') - - classpath = configurations.antlr3 - main = 'org.antlr.Tool' - args '-fo', relativePath("${testAntlrOutput}/org/jf/smali") - args grammars.files.join(' ') -} - -task generateJflexSource(type: JavaExec) { - inputs.dir file(jflexSource) - outputs.dir file(jflexOutput) - - mkdir(jflexOutput) - def grammars = fileTree(jflexSource).include('**/*.flex') - - classpath = configurations.jflex - main = 'JFlex.Main' - args '-q' - args '-d', relativePath("${jflexOutput}/org/jf/smali") - args grammars.files.join(' ') - environment LC_ALL: "en_US" -} - -compileJava.dependsOn generateParserAntlrSource, generateTreeWalkerAntlrSource, generateJflexSource -compileTestJava.dependsOn generateTestAntlrSource - processResources.inputs.property('version', version) processResources.expand('version': version) @@ -149,17 +94,29 @@ task fatJar(type: Jar, dependsOn: jar) { from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } manifest { - attributes("Main-Class": "org.jf.smali.main") + attributes('Main-Class': 'org.jf.smali.main') } doLast { - if (!System.getProperty("os.name").toLowerCase().contains("windows")) { + if (!System.getProperty('os.name').toLowerCase().contains('windows')) { ant.symlink(link: file("${destinationDir}/smali.jar"), resource: archivePath, overwrite: true) } } } tasks.getByPath('build').dependsOn(fatJar) +generateTestGrammarSource { + outputDirectory = new File(outputDirectory, 'org/jf/smali') +} + +generateGrammarSource { + outputDirectory = new File(outputDirectory, 'org/jf/smali') +} + +generateJFlexSource { + outputDirectory = new File(outputDirectory, 'org/jf/smali') +} + uploadArchives { repositories.mavenDeployer { pom.project { @@ -171,22 +128,23 @@ uploadArchives { } } -task proguard(type: JavaExec, dependsOn: fatJar) { - def outFile = fatJar.destinationDir.getPath() + '/' + fatJar.baseName + '-' + fatJar.version + '-small' + '.' + fatJar.extension - inputs.file fatJar.archivePath - outputs.file outFile +task proguard(type: proguard.gradle.ProGuardTask, dependsOn: fatJar) { + def outFile = fatJar.destinationDir.getPath() + '/' + fatJar.baseName + '-' + + fatJar.version + '-small' + '.' + fatJar.extension - classpath = configurations.proguard - main = 'proguard.ProGuard' - args "-injars ${fatJar.archivePath}(!**/TestStringTemplate*.class)" - args "-outjars ${outFile}" - args "-libraryjars ${System.properties['java.home']}/lib/rt.jar" - args '-dontobfuscate' - args '-dontoptimize' - args '-keep public class org.jf.smali.main { public static void main(java.lang.String[]); }' - args '-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }' - args '-dontwarn com.google.common.**' - args '-dontnote com.google.common.**' + injars fatJar.archivePath + outjars outFile + + libraryjars "${System.properties['java.home']}/lib/rt.jar" + + dontobfuscate + dontoptimize + + keep 'public class org.jf.smali.main { public static void main(java.lang.String[]); }' + keepclassmembers 'enum * { public static **[] values(); public static ** valueOf(java.lang.String); }' + + dontwarn 'com.google.common.**' + dontnote 'com.google.common.**' } tasks.getByPath(':release').dependsOn(proguard) diff --git a/smali/src/main/antlr3/smaliParser.g b/smali/src/main/antlr/smaliParser.g similarity index 100% rename from smali/src/main/antlr3/smaliParser.g rename to smali/src/main/antlr/smaliParser.g diff --git a/smali/src/main/antlr3/smaliTreeWalker.g b/smali/src/main/antlr/smaliTreeWalker.g similarity index 100% rename from smali/src/main/antlr3/smaliTreeWalker.g rename to smali/src/main/antlr/smaliTreeWalker.g diff --git a/smali/src/main/jflex/smaliLexer.flex b/smali/src/main/jflex/smaliLexer.jflex similarity index 99% rename from smali/src/main/jflex/smaliLexer.flex rename to smali/src/main/jflex/smaliLexer.jflex index 9c4a3c3a..7a1134b2 100644 --- a/smali/src/main/jflex/smaliLexer.flex +++ b/smali/src/main/jflex/smaliLexer.jflex @@ -667,5 +667,5 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayPrefix} ({ClassDescriptor} | "." { return invalidToken("Invalid directive"); } "." [a-zA-z\-_] { return invalidToken("Invalid directive"); } "." [a-zA-z\-_] [a-zA-z0-9\-_]* { return invalidToken("Invalid directive"); } - . { return invalidToken("Invalid text"); } + [^] { return invalidToken("Invalid text"); } } diff --git a/smali/src/test/antlr3/org/jf/smali/expectedTokensTestGrammar.g b/smali/src/test/antlr/org/jf/smali/expectedTokensTestGrammar.g similarity index 100% rename from smali/src/test/antlr3/org/jf/smali/expectedTokensTestGrammar.g rename to smali/src/test/antlr/org/jf/smali/expectedTokensTestGrammar.g diff --git a/smali/src/test/java/LexerTest.java b/smali/src/test/java/LexerTest.java index c1b70435..d156015a 100644 --- a/smali/src/test/java/LexerTest.java +++ b/smali/src/test/java/LexerTest.java @@ -40,6 +40,7 @@ import org.junit.Test; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.util.HashMap; import java.util.List; @@ -158,7 +159,7 @@ public class LexerTest { if (smaliStream == null) { Assert.fail("Could not load " + smaliFile); } - smaliFlexLexer lexer = new smaliFlexLexer(smaliStream); + smaliFlexLexer lexer = new smaliFlexLexer(new InputStreamReader(smaliStream)); lexer.setSourceFile(new File(test + ".smali")); lexer.setSuppressErrors(true); diff --git a/util/src/main/java/org/jf/util/ClassFileNameHandler.java b/util/src/main/java/org/jf/util/ClassFileNameHandler.java index 67037817..a223d30e 100644 --- a/util/src/main/java/org/jf/util/ClassFileNameHandler.java +++ b/util/src/main/java/org/jf/util/ClassFileNameHandler.java @@ -68,7 +68,7 @@ public class ClassFileNameHandler { public ClassFileNameHandler(File path, String fileExtension) { this.top = new DirectoryEntry(path); this.fileExtension = fileExtension; - this.modifyWindowsReservedFilenames = testForWindowsReservedFileNames(path); + this.modifyWindowsReservedFilenames = isWindows(); } // for testing @@ -229,27 +229,8 @@ public class ClassFileNameHandler { return sb.toString(); } - private static boolean testForWindowsReservedFileNames(File path) { - String[] reservedNames = new String[]{"aux", "con", "com1", "com9", "lpt1", "com9"}; - - for (String reservedName: reservedNames) { - File f = new File(path, reservedName + ".smali"); - if (f.exists()) { - continue; - } - - try { - FileWriter writer = new FileWriter(f); - writer.write("test"); - writer.flush(); - writer.close(); - f.delete(); //doesn't throw IOException - } catch (IOException ex) { - //if an exception occurred, it's likely that we're on a windows system. - return true; - } - } - return false; + private static boolean isWindows() { + return System.getProperty("os.name").startsWith("Windows"); } private static Pattern reservedFileNameRegex = Pattern.compile("^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\\..*)?$",