diff --git a/app/assets/locales/android_translatable_strings.txt b/app/assets/locales/android_translatable_strings.txt index 37e630bde4..d710245070 100644 --- a/app/assets/locales/android_translatable_strings.txt +++ b/app/assets/locales/android_translatable_strings.txt @@ -286,6 +286,7 @@ mult.install.bad=The selected ZIP file is not valid. Please choose a valid zip f mult.install.progress.baddest=Couldn't write multimedia to the local filesystem at: ${0} mult.install.progress.badentry=There was a bad entry in the zip file: ${0} mult.install.progress.errormoving=There was a problem copying the multimedia from the zip file, please try again. +mult.install.progress.invalid.ccz=The selected CCZ file is invalid, please verify it and try again! mult.install.prompt=From here you can install your app multimedia from a ZIP file on the local filesystem mult.install.button=Install Multimedia diff --git a/app/src/org/commcare/tasks/UnzipTask.java b/app/src/org/commcare/tasks/UnzipTask.java index a28b7563bf..eeb39cf09e 100755 --- a/app/src/org/commcare/tasks/UnzipTask.java +++ b/app/src/org/commcare/tasks/UnzipTask.java @@ -77,38 +77,51 @@ private Integer unZipFromStream(ZipInputStream zis, String destinationPath) { int count = 0; ZipEntry entry = null; try { + String destCanonicalPath = destination.getCanonicalPath(); while ((entry = zis.getNextEntry()) != null) { publishProgress(Localization.get("mult.install.progress", new String[]{String.valueOf(count)})); count++; - Logger.log(TAG, "Unzipped entry " + entry.getName()); + File entryOutput = new File(destination, entry.getName()); + String outputCanonicalPath = entryOutput.getCanonicalPath(); + // Check if the entry path aligns with the destination folder + if (!outputCanonicalPath.startsWith(destCanonicalPath)) { + throw new SecurityException(Localization.get("mult.install.progress.invalid.ccz")); + } + if (entry.isDirectory()) { - FileUtil.createFolder(new File(destination, entry.getName()).toString()); + FileUtil.createFolder(entryOutput.toString()); //If it's a directory we can move on to the next one continue; } - File outputFile = new File(destination, entry.getName()); - if (!outputFile.getParentFile().exists()) { - FileUtil.createFolder(outputFile.getParentFile().toString()); + if (!entryOutput.getParentFile().exists()) { + FileUtil.createFolder(entryOutput.getParentFile().toString()); } - if (outputFile.exists()) { + + if (entryOutput.exists()) { //Try to overwrite if we can - if (!outputFile.delete()) { + if (!entryOutput.delete()) { //If we couldn't, just skip for now continue; } } - if (!copyZipEntryToOutputFile(outputFile, zis)) { + if (!copyZipEntryToOutputFile(entryOutput, zis)) { return -1; } } - } catch (IOException e) { + } + catch (IOException e) { publishProgress(Localization.get("mult.install.progress.badentry", new String[]{entry.getName()})); return -1; - } finally { + } + catch (SecurityException e) { + publishProgress(e.getMessage()); + return -1; + } + finally { StreamsUtil.closeStream(zis); } Logger.log(TAG, "Successfully unzipped files"); diff --git a/app/src/org/commcare/views/widgets/RecordingFragment.java b/app/src/org/commcare/views/widgets/RecordingFragment.java index 017a278f15..95c11af3c2 100644 --- a/app/src/org/commcare/views/widgets/RecordingFragment.java +++ b/app/src/org/commcare/views/widgets/RecordingFragment.java @@ -52,6 +52,9 @@ public class RecordingFragment extends DialogFragment { private static final String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm"; + private static final int HEAAC_SAMPLE_RATE = 44100; + private static final int AMRNB_SAMPLE_RATE = 8000; + private String fileName; private static final String FILE_EXT = ".mp3"; @@ -192,10 +195,13 @@ private void setupRecorder() { recorder = new MediaRecorder(); } + boolean isHeAacSupported = isHeAacEncoderSupported(); + recorder.setAudioSource(MediaRecorder.AudioSource.MIC); + recorder.setAudioSamplingRate(isHeAacSupported ? HEAAC_SAMPLE_RATE : AMRNB_SAMPLE_RATE); recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); recorder.setOutputFile(fileName); - if (isHeAacEncoderSupported()) { + if (isHeAacSupported) { recorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC); } else { recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);