]> source.dussan.org Git - nextcloud-server.git/commitdiff
Fixed various file name escaping issues in core apps
authorVincent Petry <pvince81@owncloud.com>
Fri, 10 Jan 2014 14:02:26 +0000 (15:02 +0100)
committerVincent Petry <pvince81@owncloud.com>
Sun, 12 Jan 2014 14:42:10 +0000 (15:42 +0100)
- Refactored file tr lookup into FileList.findFileEl that uses
  filterAttr to avoid escaping issues in jQuery selectors
- Fixed versions and sharing app to properly escape file names in
  attributes
- Prevent uploading file name with invalid characters

Backport to stable5 of 1042733

apps/files/js/file-upload.js
apps/files/js/fileactions.js
apps/files/js/filelist.js
apps/files/js/files.js
apps/files_sharing/js/public.js
apps/files_sharing/js/share.js
apps/files_trashbin/js/trash.js
apps/files_versions/js/versions.js

index 42f081126191f17f8199cd9730131160f47b07f9..5abe38a33143d2c57b61f827dd66e6bd64920112 100644 (file)
@@ -4,6 +4,12 @@ $(document).ready(function() {
        dropZone: $('#content'), // restrict dropZone to content div
        //singleFileUploads is on by default, so the data.files array will always have length 1
        add: function(e, data) {
+         if (!Files.isFileNameValid(data.files[0].name)) {
+           data.textStatus = 'invalidcharacters';
+           var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
+           fu._trigger('fail', e, data);
+           return true; //don't upload this file but go on with next in queue
+         }
 
          if(data.files[0].type === '' && data.files[0].size == 4096)
          {
@@ -254,7 +260,7 @@ $(document).ready(function() {
                        if (result.status == 'success') {
                          var date=new Date();
                          FileList.addFile(name,0,date,false,hidden);
-                         var tr=$('tr').filterAttr('data-file',name);
+                         var tr=FileList.findFileEl(name);
                          tr.attr('data-mime',result.data.mime);
                          tr.attr('data-id', result.data.id);
                          getMimeIcon(result.data.mime,function(path){
@@ -275,7 +281,7 @@ $(document).ready(function() {
                        if (result.status == 'success') {
                          var date=new Date();
                          FileList.addDir(name,0,date,hidden);
-                         var tr=$('tr').filterAttr('data-file',name);
+                         var tr=FileList.findFileEl(name);
                          tr.attr('data-id', result.data.id);
                        } else {
                          OC.dialogs.alert(result.data.message, t('core', 'Error'));
@@ -319,7 +325,7 @@ $(document).ready(function() {
                  $('#uploadprogressbar').fadeOut();
                  var date=new Date();
                  FileList.addFile(localName,size,date,false,hidden);
-                 var tr=$('tr').filterAttr('data-file',localName);
+                 var tr = FileList.findFileEl(localName);
                  tr.data('mime',mime).data('id',id);
                  tr.attr('data-id', id);
                  getMimeIcon(mime,function(path){
index dbbc57c3b6abc45e1752d69c10895e80021a1f6d..0c0f5be0ace8d974523e244ddbe13c431250607c 100644 (file)
@@ -71,7 +71,7 @@ var FileActions = {
                FileActions.currentFile = parent;
                var actions = FileActions.get(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions());
                var file = FileActions.getCurrentFile();
-               if ($('tr[data-file="'+file+'"]').data('renaming')) {
+               if (FileList.findFileEl(file).data('renaming')) {
                        return;
                }
 
@@ -195,7 +195,7 @@ FileActions.register('all', 'Delete', OC.PERMISSION_DELETE, function () {
                        filename = [filename];
                }
                $.each(filename, function (index, file) {
-                       var filename = $('tr').filterAttr('data-file', file);
+                       var filename = FileList.findFileEl(file);
                        filename.hide();
                        filename.find('input[type="checkbox"]').removeAttr('checked');
                        filename.removeClass('selected');
index 7863903fa1907685c63e6296807a0860260c853b..8c63910e20abec90f7cfb35dc90eeb00f93234c4 100644 (file)
@@ -1,5 +1,12 @@
 var FileList={
        useUndo:true,
+       /**
+        * Returns the tr element for a given file name
+        */
+       findFileEl: function(fileName){
+               // use filterAttr to avoid escaping issues
+               return $('#fileList tr').filterAttr('data-file', fileName);
+       },
        update:function(fileListHtml) {
                $('#fileList').empty().html(fileListHtml);
        },
@@ -142,8 +149,9 @@ var FileList={
                resetFileActionPanel();
        },
        remove:function(name){
-               $('tr').filterAttr('data-file',name).find('td.filename').draggable('destroy');
-               $('tr').filterAttr('data-file',name).remove();
+               var fileEl = FileList.findFileEl(name);
+               fileEl.find('td.filename').draggable('destroy');
+               fileEl.remove();
                if($('tr[data-file]').length==0){
                        $('#emptyfolder').show();
                }
@@ -176,7 +184,7 @@ var FileList={
                $('#emptyfolder').hide();
        },
        loadingDone:function(name, id){
-               var mime, tr=$('tr').filterAttr('data-file',name);
+               var mime, tr = FileList.findFileEl(name);
                tr.data('loading',false);
                mime=tr.data('mime');
                tr.attr('data-mime',mime);
@@ -189,11 +197,11 @@ var FileList={
                tr.find('td.filename').draggable(dragOptions);
        },
        isLoading:function(name){
-               return $('tr').filterAttr('data-file',name).data('loading');
+               return FileList.findFileEl(name).data('loading');
        },
        rename:function(name){
                var tr, td, input, form;
-               tr=$('tr').filterAttr('data-file',name);
+               tr = FileList.findFileEl(name);
                tr.data('renaming',true);
                td=tr.children('td.filename');
                input=$('<input class="filename"/>').val(name);
@@ -265,7 +273,7 @@ var FileList={
                });
        },
        checkName:function(oldName, newName, isNewFile) {
-               if (isNewFile || $('tr').filterAttr('data-file', newName).length > 0) {
+               if (isNewFile || FileList.findFileEl(newName).length > 0) {
                        var html;
                        if(isNewFile){
                                html = t('files', '{new_name} already exists', {new_name: escapeHTML(newName)})+'<span class="replace">'+t('files', 'replace')+'</span><span class="suggest">'+t('files', 'suggest name')+'</span>&nbsp;<span class="cancel">'+t('files', 'cancel')+'</span>';
@@ -284,9 +292,11 @@ var FileList={
        },
        replace:function(oldName, newName, isNewFile) {
                // Finish any existing actions
-               $('tr').filterAttr('data-file', oldName).hide();
-               $('tr').filterAttr('data-file', newName).hide();
-               var tr = $('tr').filterAttr('data-file', oldName).clone();
+               var oldFileEl = FileList.findFileEl(oldName);
+               var newFileEl = FileList.findFileEl(newName);
+               oldFileEl.hide();
+               newFileEl.hide();
+               var tr = oldFileEl.clone();
                tr.attr('data-replace', 'true');
                tr.attr('data-file', newName);
                var td = tr.children('td.filename');
@@ -338,7 +348,7 @@ var FileList={
                        files=[files];
                }
                for (var i=0; i<files.length; i++) {
-                       var deleteAction = $('tr').filterAttr('data-file',files[i]).children("td.date").children(".action.delete");
+                       var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete");
                        var oldHTML = deleteAction[0].outerHTML;
                        var newHTML = '<img class="move2trash" data-action="Delete" title="'+t('files', 'perform delete operation')+'" src="'+ OC.imagePath('core', 'loading.gif') +'"></a>';
                        deleteAction[0].outerHTML = newHTML;
@@ -354,7 +364,7 @@ var FileList={
                                function(result){
                                        if (result.status == 'success') {
                                                $.each(files,function(index,file){
-                                                       var files = $('tr').filterAttr('data-file',file);
+                                                       var files = FileList.findFileEl(file);
                                                        files.remove();
                                                        files.find('input[type="checkbox"]').removeAttr('checked');
                                                        files.removeClass('selected');
@@ -362,7 +372,7 @@ var FileList={
                                                procesSelection();
                                        } else {
                                                $.each(files,function(index,file) {
-                                                       var deleteAction = $('tr').filterAttr('data-file',file).children("td.date").children(".move2trash");
+                                                       var deleteAction = FileList.findFileEl(file).children("td.date").children('.move2trash');
                                                        deleteAction[0].outerHTML = oldHTML;
                                                });
                                        }
@@ -370,7 +380,7 @@ var FileList={
        },
        scrollTo:function(file) {
                //scroll to and highlight preselected file
-               var $scrolltorow = $('tr[data-file="'+file+'"]');
+               var $scrolltorow = FileList.findFileEl(file);
                if ($scrolltorow.exists()) {
                        $scrolltorow.addClass('searchresult');
                        $(window).scrollTop($scrolltorow.position().top);
@@ -443,7 +453,7 @@ $(document).ready(function(){
                                var dirName = dropTarget.data('file');
 
                                // set dir context
-                               data.context = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName);
+                               data.context = FileList.findFileEl(dirName).filterAttr('data-type', 'dir');
 
                                // update upload counter ui
                                var uploadtext = data.context.find('.uploadtext');
@@ -538,7 +548,7 @@ $(document).ready(function(){
                // cleanup files, error notification has been shown by fileupload code
                var tr = data.context;
                if (typeof tr === 'undefined') {
-                       tr = $('tr').filterAttr('data-file', data.files[0].name);
+                       tr = FileList.findFileEl(data.files[0].name);
                }
                if (tr.attr('data-type') === 'dir') {
                        //cleanup uploading to a dir
@@ -558,7 +568,7 @@ $(document).ready(function(){
        $('#notification').on('click', '.undo', function(){
                if (FileList.deleteFiles) {
                        $.each(FileList.deleteFiles,function(index,file){
-                               $('tr').filterAttr('data-file',file).show();
+                               FileList.findFileEl(file).show();
                        });
                        FileList.deleteCanceled=true;
                        FileList.deleteFiles=null;
@@ -568,10 +578,10 @@ $(document).ready(function(){
                                FileList.deleteCanceled = false;
                                FileList.deleteFiles = [FileList.replaceOldName];
                        } else {
-                               $('tr').filterAttr('data-file', FileList.replaceOldName).show();
+                               FileList.findFileEl(FileList.replaceOldName).show();
                        }
                        $('tr').filterAttr('data-replace', 'true').remove();
-                       $('tr').filterAttr('data-file', FileList.replaceNewName).show();
+                       FileList.findFileEl(FileList.replaceNewName).show();
                        FileList.replaceCanceled = true;
                        FileList.replaceOldName = null;
                        FileList.replaceNewName = null;
@@ -586,7 +596,8 @@ $(document).ready(function(){
         });
        });
        $('#notification:first-child').on('click', '.suggest', function() {
-               $('tr').filterAttr('data-file', $('#notification > span').attr('data-oldName')).show();
+               var file = $('#notification > span').attr('data-oldName');
+               FileList.findFileEl(file).show();
         OC.Notification.hide();
        });
        $('#notification:first-child').on('click', '.cancel', function() {
index a603d123ab90291b929fa1cd8d7c077dbcde801a..87486c82bc7ca442d387001a9d053fd0b6fb1ac0 100644 (file)
@@ -12,7 +12,7 @@ Files={
                $.each(uploadingFiles,function(index,file) {
                        if(typeof file['abort'] === 'function') {
                                file.abort();
-                               var filename = $('tr').filterAttr('data-file',index);
+                               var filename = FileList.findFileEl(index);
                                filename.hide();
                                filename.find('input[type="checkbox"]').removeAttr('checked');
                                filename.removeClass('selected');
@@ -164,7 +164,7 @@ $(document).ready(function() {
                        procesSelection();
                } else {
                        var filename=$(this).parent().parent().attr('data-file');
-                       var tr=$('tr').filterAttr('data-file',filename);
+                       var tr = FileList.findFileEl(filename);
                        var renaming=tr.data('renaming');
                        if(!renaming && !FileList.isLoading(filename)){
                                FileActions.currentFile = $(this).parent();
@@ -363,7 +363,7 @@ $(document).ready(function() {
                                                        if (result.status == 'success') {
                                                                var date=new Date();
                                                                FileList.addFile(name,0,date,false,hidden);
-                                                               var tr=$('tr').filterAttr('data-file',name);
+                                                               var tr=FileList.findFileEl(name);
                                                                tr.attr('data-mime','text/plain');
                                                                tr.attr('data-id', result.data.id);
                                                                getMimeIcon('text/plain',function(path){
@@ -383,7 +383,7 @@ $(document).ready(function() {
                                                        if (result.status == 'success') {
                                                                var date=new Date();
                                                                FileList.addDir(name,0,date,hidden);
-                                                               var tr=$('tr').filterAttr('data-file',name);
+                                                               var tr=FileList.findFileEl(name);
                                                                tr.attr('data-id', result.data.id);
                                                        } else {
                                                                OC.dialogs.alert(result.data.message, 'Error');
@@ -427,7 +427,7 @@ $(document).ready(function() {
                                                $('#uploadprogressbar').fadeOut();
                                                var date=new Date();
                                                FileList.addFile(localName,size,date,false,hidden);
-                                               var tr=$('tr').filterAttr('data-file',localName);
+                                               var tr=FileList.findFileEl(localName);
                                                tr.data('mime',mime).data('id',id);
                                                tr.attr('data-id', id);
                                                getMimeIcon(mime,function(path){
@@ -682,10 +682,12 @@ var folderDropOptions={
                                if (result) {
                                        if (result.status === 'success') {
                                                //recalculate folder size
-                                               var oldSize = $('#fileList tr').filterAttr('data-file',target).data('size');
-                                               var newSize = oldSize + $('#fileList tr').filterAttr('data-file',file).data('size');
-                                               $('#fileList tr').filterAttr('data-file',target).data('size', newSize);
-                                               $('#fileList tr').filterAttr('data-file',target).find('td.filesize').text(humanFileSize(newSize));
+                                               var oldFile = FileList.findFileEl(target);
+                                               var newFile = FileList.findFileEl(file);
+                                               var oldSize = oldFile.data('size');
+                                               var newSize = oldSize + newFile.data('size');
+                                               oldFile.data('size', newSize);
+                                               oldFile.find('td.filesize').text(humanFileSize(newSize));
 
                                                FileList.remove(file);
                                                procesSelection();
@@ -830,7 +832,7 @@ function getMimeIcon(mime, ready){
 getMimeIcon.cache={};
 
 function getUniqueName(name){
-       if($('tr').filterAttr('data-file',name).length>0){
+       if (FileList.findFileEl(name).exists()) {
                var parts=name.split('.');
                var extension = "";
                if (parts.length > 1) {
index 294223aa094844640debf983731e83820dfae26f..9fe54ae7f6dce6849ea4a01cc0257b09f318fb66 100644 (file)
@@ -31,19 +31,19 @@ $(document).ready(function() {
                        }
                }
                FileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function(filename) {
-                       var tr = $('tr').filterAttr('data-file', filename)
+                       var tr = FileList.findFileEl(filename);
                        if (tr.length > 0) {
                                window.location = $(tr).find('a.name').attr('href');
                        }
                });
                FileActions.register('file', 'Download', OC.PERMISSION_READ, '', function(filename) {
-                       var tr = $('tr').filterAttr('data-file', filename)
+                       var tr = FileList.findFileEl(filename);
                        if (tr.length > 0) {
                                window.location = $(tr).find('a.name').attr('href');
                        }
                });
                FileActions.register('dir', 'Download', OC.PERMISSION_READ, '', function(filename) {
-                       var tr = $('tr').filterAttr('data-file', filename)
+                       var tr = FileList.findFileEl(filename);
                        if (tr.length > 0) {
                                window.location = $(tr).find('a.name').attr('href')+'&download';
                        }
index 68f6f3ba76f6e9d1eba761b534ea9d91be85227d..ade055eb2a6e11a58a80d6def17d615d86b994c7 100644 (file)
@@ -22,7 +22,7 @@ $(document).ready(function() {
                        } else {
                                var item = $('#dir').val() + '/' + filename;
                        }
-                       var tr = $('tr').filterAttr('data-file', filename);
+                       var tr = FileList.findFileEl(filename);
                        if ($(tr).data('type') == 'dir') {
                                var itemType = 'folder';
                        } else {
index 21a6da388cf35ea3ab038603ecd81c591ddd95fa..fd395fda7b00a6eca49bfbb66a7dcc6914131838 100644 (file)
@@ -3,9 +3,9 @@ $(document).ready(function() {
 
        if (typeof FileActions !== 'undefined') {
                FileActions.register('all', 'Restore', OC.PERMISSION_READ,  OC.imagePath('core', 'actions/undelete.png'), function(filename) {
-                       var tr=$('tr').filterAttr('data-file', filename);
+                       var tr = FileList.findFileEl(filename);
                        var spinner = '<img class="move2trash" title="'+t('files_trashbin', 'perform restore operation')+'" src="'+ OC.imagePath('core', 'loader.gif') +'"></a>';
-                       var undeleteAction = $('tr').filterAttr('data-file',filename).children("td.date");
+                       var undeleteAction = tr.children("td.date");
                        var files = tr.attr('data-file');
                        undeleteAction[0].innerHTML = undeleteAction[0].innerHTML+spinner;
                        $.post(OC.filePath('files_trashbin','ajax','undelete.php'),
@@ -28,8 +28,8 @@ $(document).ready(function() {
                }, function (filename) {
                        $('.tipsy').remove();
 
-                       var tr=$('tr').filterAttr('data-file', filename);
-                       var deleteAction = $('tr').filterAttr('data-file',filename).children("td.date").children(".action.delete");
+                       var tr = FileList.findFileEl(filename);
+                       var deleteAction = tr.children("td.date").children(".action.delete");
                        var oldHTML = deleteAction[0].outerHTML;
                        var newHTML = '<img class="move2trash" data-action="Delete" title="'+t('files', 'delete file permanently')+'" src="'+ OC.imagePath('core', 'loading.gif') +'"></a>';
                        var files = tr.attr('data-file');
@@ -100,7 +100,7 @@ $(document).ready(function() {
                        var dirlisting=getSelectedFiles('dirlisting')[0];
 
                        for (var i=0; i<files.length; i++) {
-                               var undeleteAction = $('tr').filterAttr('data-file',files[i]).children("td.date");
+                               var undeleteAction = $FileList.findFileEl(files[i]).children("td.date");
                                undeleteAction[0].innerHTML = undeleteAction[0].innerHTML+spinner;
                        }
 
@@ -126,7 +126,7 @@ $(document).ready(function() {
                        var dirlisting=getSelectedFiles('dirlisting')[0];
 
                        for (var i=0; i<files.length; i++) {
-                               var deleteAction = $('tr').filterAttr('data-file',files[i]).children("td.date");
+                               var deleteAction = FileList.findFileEl(files[i]).children("td.date");
                                deleteAction[0].innerHTML = deleteAction[0].innerHTML+spinner;
                        }
 
@@ -149,7 +149,7 @@ $(document).ready(function() {
                        event.preventDefault();
                }
                var filename = $(this).parent().parent().attr('data-file');
-               var tr = $('tr').filterAttr('data-file',filename);
+               var tr = FileList.findFileEl(filename);
                var renaming = tr.data('renaming');
                if(!renaming && !FileList.isLoading(filename)){
                        if(mime.substr(0, 5) === 'text/'){ //no texteditor for now
index c0a2f7df59b73d36a34667ecb8243daaa54eb590..532329e7bc8dcb1740030b42b7b8f8d3bff0de4b 100644 (file)
@@ -54,11 +54,11 @@ function createVersionsDropdown(filename, files) {
                data: { source: files },
                async: false,
                success: function( versions ) {
-
+                       var htmlEl, fileEl;
                        // first decide which kind of dialog we need
                        if (versions) {
 
-                               var html = '<div id="dropdown" class="drop drop-versions" data-file="'+escapeHTML(files)+'">';
+                               var html = '<div id="dropdown" class="drop drop-versions">';
                                html += '<div id="private">';
                                html += '<select data-placeholder="Saved versions" id="found_versions" class="chzen-select" style="width:16em;">';
                                html += '<option value=""></option>';
@@ -68,16 +68,19 @@ function createVersionsDropdown(filename, files) {
                                html += '<input id="link" style="display:none; width:90%;" />';
 
                        } else {
-                               var html = '<div id="dropdown" class="drop drop-versions" data-file="'+escapeHTML(files)+'">';
+                               var html = '<div id="dropdown" class="drop drop-versions">';
                                html += '<div style="text-align:center;">No other versions available</div></div>';
                        }
 
                        if (filename) {
-                               $('tr').filterAttr('data-file',filename).addClass('mouseOver');
-                               $(html).appendTo($('tr').filterAttr('data-file',filename).find('td.filename'));
+                               fileEl = FileList.findFileEl(filename);
+                               fileEl.addClass('mouseOver');
+                               htmlEl = $(html);
+                               htmlEl.appendTo(fileEl.find('td.filename'));
                        } else {
-                               $(html).appendTo($('thead .share'));
+                               htmlEl.appendTo($('thead .share'));
                        }
+                       htmlEl.attr('data-file', files);
 
                        $("#makelink").click(function() {
                                goToVersionPage(historyUrl);
@@ -140,10 +143,7 @@ function createVersionsDropdown(filename, files) {
                version.appendTo('#found_versions');
        }
 
-       $('tr').filterAttr('data-file',filename).addClass('mouseOver');
        $('#dropdown').show('blind');
-
-
 }
 
 $(this).click(