Add import with file signature check

This commit is contained in:
Vitaliy 2020-10-07 03:17:16 +03:00
parent 4774382258
commit 27b235cb39
10 changed files with 156 additions and 19 deletions

View file

@ -14,7 +14,8 @@ public class IndexConstants {
public static final String TEMP_SOURCE_TO_LOAD = "temp"; public static final String TEMP_SOURCE_TO_LOAD = "temp";
public static final String POI_INDEX_EXT = ".poi.odb"; //$NON-NLS-1$ public static final String POI_INDEX_EXT = ".poi.odb"; //$NON-NLS-1$
public static final String ZIP_EXT = ".zip"; //$NON-NLS-1$
public static final String BINARY_MAP_INDEX_EXT = ".obf"; //$NON-NLS-1$ public static final String BINARY_MAP_INDEX_EXT = ".obf"; //$NON-NLS-1$
public static final String BINARY_MAP_INDEX_EXT_ZIP = ".obf.zip"; //$NON-NLS-1$ public static final String BINARY_MAP_INDEX_EXT_ZIP = ".obf.zip"; //$NON-NLS-1$
@ -71,7 +72,7 @@ public class IndexConstants {
public static final String FONT_INDEX_DIR = "fonts/"; //$NON-NLS-1$ public static final String FONT_INDEX_DIR = "fonts/"; //$NON-NLS-1$
public static final String VOICE_INDEX_DIR = "voice/"; //$NON-NLS-1$ public static final String VOICE_INDEX_DIR = "voice/"; //$NON-NLS-1$
public static final String RENDERERS_DIR = "rendering/"; //$NON-NLS-1$ public static final String RENDERERS_DIR = "rendering/"; //$NON-NLS-1$
public static final String ROUTING_XML_FILE= "routing.xml"; public static final String ROUTING_XML_FILE = "routing.xml";
public static final String SETTINGS_DIR = "settings/"; //$NON-NLS-1$ public static final String SETTINGS_DIR = "settings/"; //$NON-NLS-1$
public static final String TEMP_DIR = "temp/"; public static final String TEMP_DIR = "temp/";
public static final String ROUTING_PROFILES_DIR = "routing/"; public static final String ROUTING_PROFILES_DIR = "routing/";

View file

@ -49,6 +49,11 @@ public class Algorithms {
private static char[] CHARS_TO_NORMALIZE_KEY = new char['']; private static char[] CHARS_TO_NORMALIZE_KEY = new char[''];
private static char[] CHARS_TO_NORMALIZE_VALUE = new char['\'']; private static char[] CHARS_TO_NORMALIZE_VALUE = new char['\''];
public static final int ZIP_FILE_SIGNATURE = 0x504b0304;
public static final int XML_FILE_SIGNATURE = 0x3c3f786d;
public static final int OBF_FILE_SIGNATURE = 0x08029001;
public static final int SQLITE_FILE_SIGNATURE = 0x53514C69;
public static String normalizeSearchText(String s) { public static String normalizeSearchText(String s) {
boolean norm = false; boolean norm = false;
for (int i = 0; i < s.length() && !norm; i++) { for (int i = 0; i < s.length() && !norm; i++) {
@ -293,7 +298,7 @@ public class Algorithms {
FileInputStream in = new FileInputStream(file); FileInputStream in = new FileInputStream(file);
int test = readInt(in); int test = readInt(in);
in.close(); in.close();
return test == 0x504b0304; return test == ZIP_FILE_SIGNATURE;
} }
/** /**
@ -322,7 +327,7 @@ public class Algorithms {
return false; return false;
} }
private static int readInt(InputStream in) throws IOException { public static int readInt(InputStream in) throws IOException {
int ch1 = in.read(); int ch1 = in.read();
int ch2 = in.read(); int ch2 = in.read();
int ch3 = in.read(); int ch3 = in.read();

View file

@ -5,7 +5,6 @@ import android.content.Intent;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint;
import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper;
@ -45,7 +44,7 @@ class FavoritesImportTask extends BaseImportAsyncTask<Void, Void, GPXFile> {
} }
@Override @Override
protected void onPostExecute(GPXUtilities.GPXFile result) { protected void onPostExecute(GPXFile result) {
hideProgress(); hideProgress();
FragmentActivity activity = activityRef.get(); FragmentActivity activity = activityRef.get();
if (activity != null) { if (activity != null) {

View file

@ -52,7 +52,7 @@ class GpxImportTask extends BaseImportAsyncTask<Void, Void, GPXFile> {
} }
@Override @Override
protected void onPostExecute(GPXUtilities.GPXFile result) { protected void onPostExecute(GPXFile result) {
hideProgress(); hideProgress();
importHelper.handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity); importHelper.handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity);
} }

View file

@ -76,7 +76,7 @@ class GpxOrFavouritesImportTask extends BaseImportAsyncTask<Void, Void, GPXFile>
} }
@Override @Override
protected void onPostExecute(final GPXUtilities.GPXFile result) { protected void onPostExecute(GPXFile result) {
hideProgress(); hideProgress();
importHelper.importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx); importHelper.importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx);
} }

View file

@ -20,7 +20,6 @@ import net.osmand.CallbackWithObject;
import net.osmand.GPXUtilities; import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint;
import net.osmand.data.FavouritePoint.BackgroundType; import net.osmand.data.FavouritePoint.BackgroundType;
@ -55,6 +54,7 @@ import java.util.Locale;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT; import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT;
import static net.osmand.IndexConstants.GPX_FILE_EXT; import static net.osmand.IndexConstants.GPX_FILE_EXT;
import static net.osmand.IndexConstants.GPX_IMPORT_DIR;
import static net.osmand.IndexConstants.GPX_INDEX_DIR; import static net.osmand.IndexConstants.GPX_INDEX_DIR;
import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT;
import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; import static net.osmand.IndexConstants.RENDERER_INDEX_EXT;
@ -176,7 +176,7 @@ public class ImportHelper {
boolean saveFile = !isFileIntent || !isOsmandSubdir; boolean saveFile = !isFileIntent || !isOsmandSubdir;
if (fileName == null) { if (fileName == null) {
handleGpxOrFavouritesImport(intentUri, fileName, saveFile, useImportDir, false, false); handleUriImport(intentUri, saveFile, useImportDir);
} else if (fileName.endsWith(KML_SUFFIX)) { } else if (fileName.endsWith(KML_SUFFIX)) {
handleKmlImport(intentUri, fileName, saveFile, useImportDir); handleKmlImport(intentUri, fileName, saveFile, useImportDir);
} else if (fileName.endsWith(KMZ_SUFFIX)) { } else if (fileName.endsWith(KMZ_SUFFIX)) {
@ -243,11 +243,11 @@ public class ImportHelper {
executeImportTask(new KmlImportTask(this, activity, kmlFile, name, save, useImportDir)); executeImportTask(new KmlImportTask(this, activity, kmlFile, name, save, useImportDir));
} }
private void handleObfImport(Uri obfFile, String name) { protected void handleObfImport(Uri obfFile, String name) {
executeImportTask(new ObfImportTask(activity, obfFile, name)); executeImportTask(new ObfImportTask(activity, obfFile, name));
} }
private void handleSqliteTileImport(Uri uri, String name) { protected void handleSqliteTileImport(Uri uri, String name) {
executeImportTask(new SqliteTileImportTask(activity, uri, name)); executeImportTask(new SqliteTileImportTask(activity, uri, name));
} }
@ -266,10 +266,14 @@ public class ImportHelper {
executeImportTask(new SettingsImportTask(activity, uri, name, latestChanges, version, callback)); executeImportTask(new SettingsImportTask(activity, uri, name, latestChanges, version, callback));
} }
private void handleXmlFileImport(Uri intentUri, String fileName, CallbackWithObject routingCallback) { protected void handleXmlFileImport(Uri intentUri, String fileName, CallbackWithObject routingCallback) {
executeImportTask(new XmlImportTask(activity, intentUri, fileName, routingCallback)); executeImportTask(new XmlImportTask(activity, intentUri, fileName, routingCallback));
} }
private void handleUriImport(Uri uri, boolean save, boolean useImportDir) {
executeImportTask(new UriImportTask(this, activity, uri, save, useImportDir));
}
@Nullable @Nullable
public static String copyFile(OsmandApplication app, @NonNull File dest, @NonNull Uri uri, boolean overwrite) { public static String copyFile(OsmandApplication app, @NonNull File dest, @NonNull Uri uri, boolean overwrite) {
if (dest.exists() && !overwrite) { if (dest.exists() && !overwrite) {
@ -442,7 +446,7 @@ public class ImportHelper {
} else { } else {
final File importDir; final File importDir;
if (useImportDir) { if (useImportDir) {
importDir = app.getAppPath(IndexConstants.GPX_IMPORT_DIR); importDir = app.getAppPath(GPX_IMPORT_DIR);
} else { } else {
importDir = app.getAppPath(GPX_INDEX_DIR); importDir = app.getAppPath(GPX_INDEX_DIR);
} }

View file

@ -15,7 +15,7 @@ import java.io.FileNotFoundException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
class KmlImportTask extends BaseImportAsyncTask<Void, Void, GPXUtilities.GPXFile> { class KmlImportTask extends BaseImportAsyncTask<Void, Void, GPXFile> {
private ImportHelper importHelper; private ImportHelper importHelper;
private Uri uri; private Uri uri;

View file

@ -5,7 +5,6 @@ import android.net.Uri;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -16,7 +15,7 @@ import java.util.zip.ZipInputStream;
import static net.osmand.plus.importfiles.ImportHelper.KML_SUFFIX; import static net.osmand.plus.importfiles.ImportHelper.KML_SUFFIX;
import static net.osmand.plus.importfiles.KmlImportTask.loadGpxFromKml; import static net.osmand.plus.importfiles.KmlImportTask.loadGpxFromKml;
class KmzImportTask extends BaseImportAsyncTask<Void, Void, GPXUtilities.GPXFile> { class KmzImportTask extends BaseImportAsyncTask<Void, Void, GPXFile> {
private ImportHelper importHelper; private ImportHelper importHelper;
private Uri uri; private Uri uri;
@ -60,7 +59,7 @@ class KmzImportTask extends BaseImportAsyncTask<Void, Void, GPXUtilities.GPXFile
} }
@Override @Override
protected void onPostExecute(GPXUtilities.GPXFile result) { protected void onPostExecute(GPXFile result) {
hideProgress(); hideProgress();
importHelper.handleResult(result, name, save, useImportDir, false); importHelper.handleResult(result, name, save, useImportDir, false);
} }

View file

@ -17,7 +17,7 @@ class ObfImportTask extends BaseImportAsyncTask<Void, Void, String> {
private Uri uri; private Uri uri;
private String name; private String name;
public ObfImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, String name) { public ObfImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, @NonNull String name) {
super(activity); super(activity);
this.uri = uri; this.uri = uri;
this.name = name; this.name = name;

View file

@ -0,0 +1,129 @@
package net.osmand.plus.importfiles;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import net.osmand.util.Algorithms;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static net.osmand.FileUtils.createUniqueFileName;
import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT;
import static net.osmand.IndexConstants.MAPS_PATH;
import static net.osmand.IndexConstants.ROUTING_FILE_EXT;
import static net.osmand.IndexConstants.SQLITE_EXT;
import static net.osmand.IndexConstants.TEMP_DIR;
import static net.osmand.IndexConstants.TILES_INDEX_DIR;
import static net.osmand.IndexConstants.ZIP_EXT;
import static net.osmand.util.Algorithms.OBF_FILE_SIGNATURE;
import static net.osmand.util.Algorithms.SQLITE_FILE_SIGNATURE;
import static net.osmand.util.Algorithms.XML_FILE_SIGNATURE;
import static net.osmand.util.Algorithms.ZIP_FILE_SIGNATURE;
class UriImportTask extends BaseImportAsyncTask<Void, Void, String> {
private ImportHelper importHelper;
private Uri uri;
private String tempFileName;
private int fileSignature;
private boolean save;
private boolean useImportDir;
public UriImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity,
@NonNull Uri uri, boolean save, boolean useImportDir) {
super(activity);
this.importHelper = importHelper;
this.uri = uri;
this.save = save;
this.useImportDir = useImportDir;
}
@Override
protected String doInBackground(Void... nothing) {
String error = null;
InputStream is = null;
OutputStream out = null;
try {
is = app.getContentResolver().openInputStream(uri);
if (is != null) {
fileSignature = Algorithms.readInt(is);
if (isSupportedFileSignature()) {
File tempDir = app.getAppPath(TEMP_DIR);
if (!tempDir.exists()) {
tempDir.mkdirs();
}
tempFileName = getTempFileName();
File dest = new File(tempDir, tempFileName);
out = new FileOutputStream(dest);
Algorithms.writeInt(out, Integer.reverseBytes(fileSignature));
Algorithms.streamCopy(is, out);
}
}
} catch (FileNotFoundException e) {
ImportHelper.log.error(e);
error = e.getMessage();
} catch (SecurityException e) {
ImportHelper.log.error(e);
error = e.getMessage();
} catch (IOException e) {
ImportHelper.log.error(e);
error = e.getMessage();
} finally {
Algorithms.closeStream(is);
Algorithms.closeStream(out);
}
return error;
}
private boolean isSupportedFileSignature() {
return fileSignature == XML_FILE_SIGNATURE || fileSignature == OBF_FILE_SIGNATURE
|| fileSignature == ZIP_FILE_SIGNATURE || fileSignature == SQLITE_FILE_SIGNATURE;
}
@Override
protected void onPostExecute(String error) {
hideProgress();
File file = app.getAppPath(TEMP_DIR + tempFileName);
if (error == null && file.exists()) {
Uri tempUri = AndroidUtils.getUriForFile(app, file);
if (XML_FILE_SIGNATURE == fileSignature) {
importHelper.handleXmlFileImport(tempUri, null, null);
} else if (OBF_FILE_SIGNATURE == fileSignature) {
String name = createUniqueFileName(app, "map", MAPS_PATH, BINARY_MAP_INDEX_EXT);
importHelper.handleObfImport(tempUri, name);
} else if (ZIP_FILE_SIGNATURE == fileSignature) {
// importHelper.handleKmzImport(tempUri, null, save, useImportDir);
} else if (SQLITE_FILE_SIGNATURE == fileSignature) {
String name = createUniqueFileName(app, "online_map", TILES_INDEX_DIR, SQLITE_EXT);
importHelper.handleSqliteTileImport(tempUri, name);
}
} else {
app.showShortToastMessage(app.getString(R.string.file_import_error, tempFileName, error));
}
}
private String getTempFileName() {
if (XML_FILE_SIGNATURE == fileSignature) {
return createUniqueFileName(app, "xml_file", TEMP_DIR, ROUTING_FILE_EXT);
} else if (OBF_FILE_SIGNATURE == fileSignature) {
return createUniqueFileName(app, "map", TEMP_DIR, BINARY_MAP_INDEX_EXT);
} else if (ZIP_FILE_SIGNATURE == fileSignature) {
return createUniqueFileName(app, "zip_file", TEMP_DIR, ZIP_EXT);
} else if (SQLITE_FILE_SIGNATURE == fileSignature) {
return createUniqueFileName(app, "online_map", TEMP_DIR, SQLITE_EXT);
}
return "";
}
}