From 62431b8ac322e3eadbcaaf7e61e4379686003c17 Mon Sep 17 00:00:00 2001 From: transaero21 Date: Mon, 9 Dec 2024 14:30:17 +0300 Subject: [PATCH] fix: use DirectoryStream to prevent failure on invalid utf-8 filenames You can create invalid file using `touch "$(echo -e '\xEB\xEE\xE2\xE0\xF0\xE8')"` Unfortunately in Lollipop ang higher ART is used, and it can't handle some symbols - https://stackoverflow.com/a/34282026 There is not many options to read directory files, and another option only available on Oreo and higher - use DirectoryStream, which will not throw exception --- .../developer/filepicker/utils/Utility.java | 59 +++++++++++++------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/library/src/main/java/com/developer/filepicker/utils/Utility.java b/library/src/main/java/com/developer/filepicker/utils/Utility.java index cd75cbd..0d25ea3 100644 --- a/library/src/main/java/com/developer/filepicker/utils/Utility.java +++ b/library/src/main/java/com/developer/filepicker/utils/Utility.java @@ -1,7 +1,6 @@ package com.developer.filepicker.utils; import android.Manifest; -import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; @@ -9,9 +8,13 @@ import com.developer.filepicker.model.FileListItem; import java.io.File; +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; -import java.util.Objects; +import java.util.List; /** * @author akshay sunil masram @@ -47,24 +50,44 @@ public static boolean checkMediaAccessPermissions(Context context) { public static ArrayList prepareFileListEntries(ArrayList internalList, File inter, ExtensionFilter filter, boolean show_hidden_files) { - try { - for (File name : Objects.requireNonNull(inter.listFiles(filter))) { - if (name.canRead()) { - if(name.getName().startsWith(".") && !show_hidden_files) continue; - FileListItem item = new FileListItem(); - item.setFilename(name.getName()); - item.setDirectory(name.isDirectory()); - item.setLocation(name.getAbsolutePath()); - item.setTime(name.lastModified()); - internalList.add(item); - } + List fileList = getFiles(inter, filter); + for (File name : fileList) { + if (name.canRead()) { + if(name.getName().startsWith(".") && !show_hidden_files) continue; + FileListItem item = new FileListItem(); + item.setFilename(name.getName()); + item.setDirectory(name.isDirectory()); + item.setLocation(name.getAbsolutePath()); + item.setTime(name.lastModified()); + internalList.add(item); } - Collections.sort(internalList); - } - catch (NullPointerException e) { - e.printStackTrace(); - internalList=new ArrayList<>(); } + Collections.sort(internalList); + return internalList; } + + private static List getFiles(File inter, ExtensionFilter filter) { + List fileList = new ArrayList<>(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + try (DirectoryStream stream = Files.newDirectoryStream( + inter.toPath(), + entry -> filter.accept(entry.toFile()) + )) { + for (Path entry : stream) { + fileList.add(entry.toFile()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } else { + File[] files = inter.listFiles(filter); + if (files != null) { + Collections.addAll(fileList, files); + } + } + + return fileList; + } }