[Pkg-owncloud-commits] [owncloud] 04/66: Fixed various file name escaping issues in core apps

David Prévot taffit at moszumanska.debian.org
Fri Apr 18 22:49:41 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to annotated tag v5.0.15
in repository owncloud.

commit 3f7550cdcf7e7e1f1bb6a529255a09a47e8c7cc5
Author: Vincent Petry <pvince81 at owncloud.com>
Date:   Fri Jan 10 15:02:26 2014 +0100

    Fixed various file name escaping issues in core apps
    
    - 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       | 12 +++++++---
 apps/files/js/fileactions.js       |  4 ++--
 apps/files/js/filelist.js          | 49 +++++++++++++++++++++++---------------
 apps/files/js/files.js             | 22 +++++++++--------
 apps/files_sharing/js/public.js    |  6 ++---
 apps/files_sharing/js/share.js     |  2 +-
 apps/files_trashbin/js/trash.js    | 14 +++++------
 apps/files_versions/js/versions.js | 18 +++++++-------
 8 files changed, 73 insertions(+), 54 deletions(-)

diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index 42f0811..5abe38a 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -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){
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index dbbc57c..0c0f5be 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -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');
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 7863903..8c63910 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -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> <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() {
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index a603d12..87486c8 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -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) {
diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js
index 294223a..9fe54ae 100644
--- a/apps/files_sharing/js/public.js
+++ b/apps/files_sharing/js/public.js
@@ -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';
 			}
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index 68f6f3b..ade055e 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -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 {
diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js
index 21a6da3..fd395fd 100644
--- a/apps/files_trashbin/js/trash.js
+++ b/apps/files_trashbin/js/trash.js
@@ -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
diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js
index c0a2f7d..532329e 100644
--- a/apps/files_versions/js/versions.js
+++ b/apps/files_versions/js/versions.js
@@ -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(

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list