GUACAMOLE-926: Add REGEX backup for type sniffing in batch import.

This commit is contained in:
James Muehlner
2023-05-08 22:52:16 +00:00
parent 55d874bcaa
commit 8efb93c3b7

View File

@@ -26,6 +26,15 @@
*/ */
const CSV_MIME_TYPE = 'text/csv'; const CSV_MIME_TYPE = 'text/csv';
/**
* A fallback regular expression for CSV filenames, if no MIME type is provided
* by the browser. Any file that matches this regex will be considered to be a
* CSV file.
*
* @type RegExp
*/
const CSV_FILENAME_REGEX = /\.csv$/i;
/** /**
* The allowed MIME type for JSON files. * The allowed MIME type for JSON files.
* *
@@ -33,6 +42,15 @@ const CSV_MIME_TYPE = 'text/csv';
*/ */
const JSON_MIME_TYPE = 'application/json'; const JSON_MIME_TYPE = 'application/json';
/**
* A fallback regular expression for JSON filenames, if no MIME type is provided
* by the browser. Any file that matches this regex will be considered to be a
* JSON file.
*
* @type RegExp
*/
const JSON_FILENAME_REGEX = /\.json$/i;
/** /**
* The allowed MIME types for YAML files. * The allowed MIME types for YAML files.
* NOTE: There is no registered MIME type for YAML files. This may result in a * NOTE: There is no registered MIME type for YAML files. This may result in a
@@ -50,6 +68,15 @@ const YAML_MIME_TYPES = [
'application/yml' 'application/yml'
]; ];
/**
* A fallback regular expression for YAML filenames, if no MIME type is provided
* by the browser. Any file that matches this regex will be considered to be a
* YAML file.
*
* @type RegExp
*/
const YAML_FILENAME_REGEX = /\.ya?ml$/i;
/** /**
* Possible signatures for zip files (which include most modern Microsoft office * Possible signatures for zip files (which include most modern Microsoft office
* documents - most notable excel). If any file, regardless of extension, has * documents - most notable excel). If any file, regardless of extension, has
@@ -564,12 +591,46 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
// There should only ever be a single file in the array // There should only ever be a single file in the array
const file = files[0]; const file = files[0];
// The MIME type of the provided file // The name and MIME type of the file as provided by the browser
const mimeType = file.type; let fileName = file.name;
let mimeType = file.type;
// If no MIME type was provided by the browser at all, use REGEXes as a
// fallback to try to determine the file type. NOTE: Windows 10/11 are
// known to do this with YAML files.
if (!_.trim(mimeType).length) {
// If the file name matches what we'd expect for a CSV file, set the
// CSV MIME type and move on
if (CSV_FILENAME_REGEX.test(fileName))
mimeType = CSV_MIME_TYPE;
// If the file name matches what we'd expect for a JSON file, set
// the JSON MIME type and move on
else if (JSON_FILENAME_REGEX.test(fileName))
mimeType = JSON_MIME_TYPE;
// If the file name matches what we'd expect for a JSON file, set
// one of the allowed YAML MIME types and move on
else if (YAML_FILENAME_REGEX.test(fileName))
mimeType = YAML_MIME_TYPES[0];
else {
// If none of the REGEXes pass, there's nothing more to be tried
handleError(new ParseError({
message: "Unknown type for file: " + fileName,
key: 'IMPORT.ERROR_DETECTED_INVALID_TYPE'
}));
return;
}
}
// Check if the mimetype is one of the supported types, // Check if the mimetype is one of the supported types,
// e.g. "application/json" or "text/csv" // e.g. "application/json" or "text/csv"
if (LEGAL_MIME_TYPES.indexOf(mimeType) < 0) { else if (LEGAL_MIME_TYPES.indexOf(mimeType) < 0) {
// If the provided file is not one of the supported types, // If the provided file is not one of the supported types,
// display an error and abort processing // display an error and abort processing
@@ -582,7 +643,9 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
} }
$scope.fileName = file.name; // Save the name and type to the scope
$scope.fileName = fileName;
$scope.mimeType = mimeType;
// Initialize upload state // Initialize upload state
$scope.aborted = false; $scope.aborted = false;
@@ -590,9 +653,6 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
$scope.processing = false; $scope.processing = false;
$scope.uploadStarted = true; $scope.uploadStarted = true;
// Save the MIME type to the scope
$scope.mimeType = file.type;
// Save the file to the scope when ready // Save the file to the scope when ready
$scope.fileReader = new FileReader(); $scope.fileReader = new FileReader();
$scope.fileReader.onloadend = (e => { $scope.fileReader.onloadend = (e => {