1
0
mirror of https://github.com/termux/termux-app synced 2024-06-14 13:26:39 +00:00

Fixed: Fix termux.properties reload not working if the properties file didn't exist at app startup

Closes #2836
This commit is contained in:
agnostic-apollo 2022-06-15 18:30:21 +05:00
parent e92a6db06b
commit 82b1580312
4 changed files with 59 additions and 64 deletions

View File

@ -9,6 +9,8 @@ import androidx.annotation.Nullable;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableBiMap;
import com.google.common.primitives.Primitives; import com.google.common.primitives.Primitives;
import com.termux.shared.file.FileUtils;
import com.termux.shared.file.filesystem.FileType;
import com.termux.shared.logger.Logger; import com.termux.shared.logger.Logger;
import java.io.File; import java.io.File;
@ -16,6 +18,7 @@ import java.io.FileInputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
@ -253,6 +256,38 @@ public class SharedProperties {
return properties; return properties;
} }
/** Returns the first {@link File} found in
* {@code propertiesFilePaths} from which app properties can be loaded. If the {@link File} found
* is not a regular file or is not readable, then {@code null} is returned. Symlinks **will not**
* be followed for potential security reasons.
*
* @param propertiesFilePaths The {@link List<String>} containing properties file paths.
* @param logTag If log tag to use for logging errors.
* @return Returns the {@link File} object for Termux:Float app properties.
*/
public static File getPropertiesFileFromList(List<String> propertiesFilePaths, @NonNull String logTag) {
if (propertiesFilePaths == null || propertiesFilePaths.size() == 0)
return null;
for(String propertiesFilePath : propertiesFilePaths) {
File propertiesFile = new File(propertiesFilePath);
// Symlinks **will not** be followed.
FileType fileType = FileUtils.getFileType(propertiesFilePath, false);
if (fileType == FileType.REGULAR) {
if (propertiesFile.canRead())
return propertiesFile;
else
Logger.logWarn(logTag, "Ignoring properties file at \"" + propertiesFilePath + "\" since it is not readable");
} else if (fileType != FileType.NO_EXIST) {
Logger.logWarn(logTag, "Ignoring properties file at \"" + propertiesFilePath + "\" of type: \"" + fileType.getName() + "\"");
}
}
Logger.logDebug(logTag, "No readable properties file found at: " + propertiesFilePaths);
return null;
}
public static String getProperty(Context context, File propertiesFile, String key, String def) { public static String getProperty(Context context, File propertiesFile, String key, String def) {

View File

@ -13,7 +13,7 @@ public class TermuxAppSharedProperties extends TermuxSharedProperties {
private TermuxAppSharedProperties(@NonNull Context context) { private TermuxAppSharedProperties(@NonNull Context context) {
super(context, TermuxConstants.TERMUX_APP_NAME, super(context, TermuxConstants.TERMUX_APP_NAME,
TermuxPropertyConstants.getTermuxPropertiesFile(), TermuxPropertyConstants.TERMUX_APP_PROPERTIES_LIST, TermuxConstants.TERMUX_PROPERTIES_FILE_PATHS_LIST, TermuxPropertyConstants.TERMUX_APP_PROPERTIES_LIST,
new TermuxSharedProperties.SharedPropertiesParserClient()); new TermuxSharedProperties.SharedPropertiesParserClient());
} }

View File

@ -478,58 +478,4 @@ public final class TermuxPropertyConstants {
public static final Set<String> TERMUX_DEFAULT_INVERETED_TRUE_BOOLEAN_BEHAVIOUR_PROPERTIES_LIST = new HashSet<>(Arrays.asList( public static final Set<String> TERMUX_DEFAULT_INVERETED_TRUE_BOOLEAN_BEHAVIOUR_PROPERTIES_LIST = new HashSet<>(Arrays.asList(
)); ));
/** Returns the first {@link File} found in
* {@link TermuxConstants#TERMUX_PROPERTIES_FILE_PATHS_LIST} via a call to
* {@link #getPropertiesFile(List)}.
*
* @return Returns the {@link File} object for Termux app properties.
*/
public static File getTermuxPropertiesFile() {
return getPropertiesFile(TermuxConstants.TERMUX_PROPERTIES_FILE_PATHS_LIST);
}
/** Returns the first {@link File} found in
* {@link TermuxConstants#TERMUX_FLOAT_PROPERTIES_FILE_PATHS_LIST} via a call to
* {@link #getPropertiesFile(List)}.
*
* @return Returns the {@link File} object for Termux:Float app properties.
*/
public static File getTermuxFloatPropertiesFile() {
return getPropertiesFile(TermuxConstants.TERMUX_FLOAT_PROPERTIES_FILE_PATHS_LIST);
}
/** Returns the first {@link File} found in
* {@code propertiesFilePaths} from which app properties can be loaded. If the {@link File} found
* is not a regular file or is not readable, then {@code null} is returned. Symlinks **will not**
* be followed for potential security reasons.
*
* @return Returns the {@link File} object for Termux:Float app properties.
*/
public static File getPropertiesFile(List<String> propertiesFilePaths) {
if (propertiesFilePaths == null || propertiesFilePaths.size() == 0)
return null;
for(String propertiesFilePath : propertiesFilePaths) {
File propertiesFile = new File(propertiesFilePath);
// Symlinks **will not** be followed.
FileType fileType = FileUtils.getFileType(propertiesFilePath, false);
if (fileType == FileType.REGULAR) {
if (propertiesFile.canRead())
return propertiesFile;
else
Logger.logWarn(LOG_TAG, "Ignoring properties file at \"" + propertiesFilePath + "\" since it is not readable");
} else if (fileType != FileType.NO_EXIST) {
Logger.logWarn(LOG_TAG, "Ignoring properties file at \"" + propertiesFilePath + "\" of type: \"" + fileType.getName() + "\"");
}
}
Logger.logDebug(LOG_TAG, "No readable properties file found at: " + propertiesFilePaths);
return null;
}
} }

View File

@ -12,6 +12,7 @@ import com.termux.shared.termux.TermuxConstants;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
@ -20,24 +21,35 @@ public abstract class TermuxSharedProperties {
protected final Context mContext; protected final Context mContext;
protected final String mLabel; protected final String mLabel;
protected final File mPropertiesFile; protected final List<String> mPropertiesFilePaths;
protected final SharedProperties mSharedProperties; protected final Set<String> mPropertiesList;
protected final SharedPropertiesParser mSharedPropertiesParser;
protected File mPropertiesFile;
protected SharedProperties mSharedProperties;
public static final String LOG_TAG = "TermuxSharedProperties"; public static final String LOG_TAG = "TermuxSharedProperties";
public TermuxSharedProperties(@NonNull Context context, @NonNull String label, File propertiesFile, public TermuxSharedProperties(@NonNull Context context, @NonNull String label, List<String> propertiesFilePaths,
@NonNull Set<String> propertiesList, @NonNull SharedPropertiesParser sharedPropertiesParser) { @NonNull Set<String> propertiesList, @NonNull SharedPropertiesParser sharedPropertiesParser) {
mContext = context.getApplicationContext(); mContext = context.getApplicationContext();
mLabel = label; mLabel = label;
mPropertiesFile = propertiesFile; mPropertiesFilePaths = propertiesFilePaths;
mSharedProperties = new SharedProperties(context, mPropertiesFile, propertiesList, sharedPropertiesParser); mPropertiesList = propertiesList;
mSharedPropertiesParser = sharedPropertiesParser;
loadTermuxPropertiesFromDisk(); loadTermuxPropertiesFromDisk();
} }
/** /**
* Reload the termux properties from disk into an in-memory cache. * Reload the termux properties from disk into an in-memory cache.
*/ */
public void loadTermuxPropertiesFromDisk() { public synchronized void loadTermuxPropertiesFromDisk() {
// Properties files must be searched everytime since no file may exist when constructor is
// called or a higher priority file may have been created afterward. Otherwise, if no file
// was found, then default props would keep loading, since mSharedProperties would be null. #2836
mPropertiesFile = SharedProperties.getPropertiesFileFromList(mPropertiesFilePaths, LOG_TAG);
mSharedProperties = null;
mSharedProperties = new SharedProperties(mContext, mPropertiesFile, mPropertiesList, mSharedPropertiesParser);
mSharedProperties.loadPropertiesFromDisk(); mSharedProperties.loadPropertiesFromDisk();
dumpPropertiesToLog(); dumpPropertiesToLog();
dumpInternalPropertiesToLog(); dumpInternalPropertiesToLog();
@ -167,8 +179,8 @@ public abstract class TermuxSharedProperties {
/** /**
* Get the internal {@link Object} value for the key passed from the file returned by * Get the internal {@link Object} value for the key passed from the first file found in
* {@link TermuxPropertyConstants#getTermuxPropertiesFile()}. The {@link Properties} object is * {@link TermuxConstants#TERMUX_PROPERTIES_FILE_PATHS_LIST}. The {@link Properties} object is
* read directly from the file and internal value is returned for the property value against the key. * read directly from the file and internal value is returned for the property value against the key.
* *
* @param context The context for operations. * @param context The context for operations.
@ -177,7 +189,9 @@ public abstract class TermuxSharedProperties {
* the object stored against the key is {@code null}. * the object stored against the key is {@code null}.
*/ */
public static Object getTermuxInternalPropertyValue(Context context, String key) { public static Object getTermuxInternalPropertyValue(Context context, String key) {
return SharedProperties.getInternalProperty(context, TermuxPropertyConstants.getTermuxPropertiesFile(), key, new SharedPropertiesParserClient()); return SharedProperties.getInternalProperty(context,
SharedProperties.getPropertiesFileFromList(TermuxConstants.TERMUX_PROPERTIES_FILE_PATHS_LIST, LOG_TAG),
key, new SharedPropertiesParserClient());
} }
/** /**