Merge pull request #7531 from owncloud/dont_create_shared_folder
don't allow to create a file or folder named 'Shared' in the root folder
This commit is contained in:
commit
9111af0478
|
@ -18,7 +18,7 @@ if(\OC\Files\Filesystem::file_exists($target . '/' . $file)) {
|
|||
exit;
|
||||
}
|
||||
|
||||
if ($dir != '' || $file != 'Shared') {
|
||||
if ($target != '' || strtolower($file) != 'shared') {
|
||||
$targetFile = \OC\Files\Filesystem::normalizePath($target . '/' . $file);
|
||||
$sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file);
|
||||
if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) {
|
||||
|
|
|
@ -82,7 +82,7 @@ OC.Upload = {
|
|||
*/
|
||||
isProcessing:function() {
|
||||
var count = 0;
|
||||
|
||||
|
||||
jQuery.each(this._uploads,function(i, data) {
|
||||
if (data.state() === 'pending') {
|
||||
count++;
|
||||
|
@ -208,13 +208,13 @@ $(document).ready(function() {
|
|||
add: function(e, data) {
|
||||
OC.Upload.log('add', e, data);
|
||||
var that = $(this);
|
||||
|
||||
|
||||
// we need to collect all data upload objects before starting the upload so we can check their existence
|
||||
// and set individual conflict actions. unfortunately there is only one variable that we can use to identify
|
||||
// the selection a data upload is part of, so we have to collect them in data.originalFiles
|
||||
// turning singleFileUploads off is not an option because we want to gracefully handle server errors like
|
||||
// already exists
|
||||
|
||||
|
||||
// create a container where we can store the data objects
|
||||
if ( ! data.originalFiles.selection ) {
|
||||
// initialize selection and remember number of files to upload
|
||||
|
@ -225,34 +225,34 @@ $(document).ready(function() {
|
|||
};
|
||||
}
|
||||
var selection = data.originalFiles.selection;
|
||||
|
||||
|
||||
// add uploads
|
||||
if ( selection.uploads.length < selection.filesToUpload ) {
|
||||
// remember upload
|
||||
selection.uploads.push(data);
|
||||
}
|
||||
|
||||
|
||||
//examine file
|
||||
var file = data.files[0];
|
||||
try {
|
||||
// FIXME: not so elegant... need to refactor that method to return a value
|
||||
Files.isFileNameValid(file.name);
|
||||
Files.isFileNameValid(file.name, FileList.getCurrentDirectory());
|
||||
}
|
||||
catch (errorMessage) {
|
||||
data.textStatus = 'invalidcharacters';
|
||||
data.errorThrown = errorMessage;
|
||||
}
|
||||
|
||||
|
||||
if (file.type === '' && file.size === 4096) {
|
||||
data.textStatus = 'dirorzero';
|
||||
data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes',
|
||||
{filename: file.name}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// add size
|
||||
selection.totalBytes += file.size;
|
||||
|
||||
|
||||
// check PHP upload limit
|
||||
if (selection.totalBytes > $('#upload_limit').val()) {
|
||||
data.textStatus = 'sizeexceedlimit';
|
||||
|
@ -270,7 +270,7 @@ $(document).ready(function() {
|
|||
'size2': humanFileSize($('#free_space').val())
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// end upload for whole selection on error
|
||||
if (data.errorThrown) {
|
||||
// trigger fileupload fail
|
||||
|
@ -281,12 +281,12 @@ $(document).ready(function() {
|
|||
|
||||
// check existing files when all is collected
|
||||
if ( selection.uploads.length >= selection.filesToUpload ) {
|
||||
|
||||
|
||||
//remove our selection hack:
|
||||
delete data.originalFiles.selection;
|
||||
|
||||
var callbacks = {
|
||||
|
||||
|
||||
onNoConflicts: function (selection) {
|
||||
$.each(selection.uploads, function(i, upload) {
|
||||
upload.submit();
|
||||
|
@ -309,7 +309,7 @@ $(document).ready(function() {
|
|||
};
|
||||
|
||||
OC.Upload.checkExistingFiles(selection, callbacks);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return true; // continue adding files
|
||||
|
@ -439,7 +439,7 @@ $(document).ready(function() {
|
|||
});
|
||||
fileupload.on('fileuploadstop', function(e, data) {
|
||||
OC.Upload.log('progress handle fileuploadstop', e, data);
|
||||
|
||||
|
||||
$('#uploadprogresswrapper input.stop').fadeOut();
|
||||
$('#uploadprogressbar').fadeOut();
|
||||
Files.updateStorageStatistics();
|
||||
|
@ -531,7 +531,7 @@ $(document).ready(function() {
|
|||
if ($(this).children('p').length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$('#new .error').tipsy('hide');
|
||||
|
||||
$('#new li').each(function(i,element) {
|
||||
|
@ -545,7 +545,7 @@ $(document).ready(function() {
|
|||
var text=$(this).children('p').text();
|
||||
$(this).data('text',text);
|
||||
$(this).children('p').remove();
|
||||
|
||||
|
||||
// add input field
|
||||
var form = $('<form></form>');
|
||||
var input = $('<input type="text">');
|
||||
|
@ -562,7 +562,7 @@ $(document).ready(function() {
|
|||
throw t('files', 'URL cannot be empty');
|
||||
} else if (type !== 'web' && !Files.isFileNameValid(filename)) {
|
||||
// Files.isFileNameValid(filename) throws an exception itself
|
||||
} else if ($('#dir').val() === '/' && filename === 'Shared') {
|
||||
} else if (FileList.getCurrentDirectory() === '/' && filename.toLowerCase() === 'shared') {
|
||||
throw t('files', 'In the home folder \'Shared\' is a reserved filename');
|
||||
} else if (FileList.inList(filename)) {
|
||||
throw t('files', '{new_name} already exists', {new_name: filename});
|
||||
|
|
|
@ -419,15 +419,12 @@ window.FileList={
|
|||
len = input.val().length;
|
||||
}
|
||||
input.selectRange(0, len);
|
||||
|
||||
var checkInput = function () {
|
||||
var filename = input.val();
|
||||
if (filename !== oldname) {
|
||||
if (!Files.isFileNameValid(filename)) {
|
||||
// Files.isFileNameValid(filename) throws an exception itself
|
||||
} else if($('#dir').val() === '/' && filename === 'Shared') {
|
||||
throw t('files','In the home folder \'Shared\' is a reserved filename');
|
||||
} else if (FileList.inList(filename)) {
|
||||
// Files.isFileNameValid(filename) throws an exception itself
|
||||
Files.isFileNameValid(filename, FileList.getCurrentDirectory());
|
||||
if (FileList.inList(filename)) {
|
||||
throw t('files', '{new_name} already exists', {new_name: filename});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,9 +87,12 @@ var Files = {
|
|||
* Throws a string exception with an error message if
|
||||
* the file name is not valid
|
||||
*/
|
||||
isFileNameValid: function (name) {
|
||||
isFileNameValid: function (name, root) {
|
||||
var trimmedName = name.trim();
|
||||
if (trimmedName === '.' || trimmedName === '..') {
|
||||
if (trimmedName === '.'
|
||||
|| trimmedName === '..'
|
||||
|| (root === '/' && trimmedName.toLowerCase() === 'shared'))
|
||||
{
|
||||
throw t('files', '"{name}" is an invalid file name.', {name: name});
|
||||
} else if (trimmedName.length === 0) {
|
||||
throw t('files', 'File name cannot be empty.');
|
||||
|
|
|
@ -48,6 +48,41 @@ describe('Files tests', function() {
|
|||
expect(error).toEqual(false);
|
||||
}
|
||||
});
|
||||
it('Validates correct file names do not create Shared folder in root', function() {
|
||||
// create shared file in subfolder
|
||||
var error = false;
|
||||
try {
|
||||
expect(Files.isFileNameValid('shared', '/foo')).toEqual(true);
|
||||
expect(Files.isFileNameValid('Shared', '/foo')).toEqual(true);
|
||||
}
|
||||
catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toEqual(false);
|
||||
|
||||
// create shared file in root
|
||||
var threwException = false;
|
||||
try {
|
||||
Files.isFileNameValid('Shared', '/');
|
||||
console.error('Invalid file name not detected');
|
||||
}
|
||||
catch (e) {
|
||||
threwException = true;
|
||||
}
|
||||
expect(threwException).toEqual(true);
|
||||
|
||||
// create shared file in root
|
||||
var threwException = false;
|
||||
try {
|
||||
Files.isFileNameValid('shared', '/');
|
||||
console.error('Invalid file name not detected');
|
||||
}
|
||||
catch (e) {
|
||||
threwException = true;
|
||||
}
|
||||
expect(threwException).toEqual(true);
|
||||
|
||||
});
|
||||
it('Detects invalid file names', function() {
|
||||
var fileNames = [
|
||||
'',
|
||||
|
|
|
@ -50,7 +50,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
|
|||
*/
|
||||
public function createFile($name, $data = null) {
|
||||
|
||||
if ($name === 'Shared' && empty($this->path)) {
|
||||
if (strtolower($name) === 'shared' && empty($this->path)) {
|
||||
throw new \Sabre_DAV_Exception_Forbidden();
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
|
|||
*/
|
||||
public function createDirectory($name) {
|
||||
|
||||
if ($name === 'Shared' && empty($this->path)) {
|
||||
if (strtolower($name) === 'shared' && empty($this->path)) {
|
||||
throw new \Sabre_DAV_Exception_Forbidden();
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,9 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
|
|||
}
|
||||
if ($sourceDir !== $destinationDir) {
|
||||
// for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir
|
||||
if (ltrim($destinationDir, '/') === '' && strtolower($sourceNode->getName()) === 'shared') {
|
||||
throw new \Sabre_DAV_Exception_Forbidden();
|
||||
}
|
||||
if (!$fs->isUpdatable($sourceDir)) {
|
||||
throw new \Sabre_DAV_Exception_Forbidden();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue