Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicitly close div element #31820

Merged
merged 1 commit into from
Apr 5, 2022
Merged

Explicitly close div element #31820

merged 1 commit into from
Apr 5, 2022

Conversation

artonge
Copy link
Contributor

@artonge artonge commented Apr 4, 2022

Fix: #30002

This is actually a global issue from upgrading to jQuery v3.3.5

The HTML prefilter has changed, and self-closing tags are not supported anymore.

A solution to prevent hidden issue would be to set jQuery.migrateEnablePatches( "self-closed-tags" );

@skjnldsv an opinion? No idea if self-closing tags are widespread in our code base.

https://jquery.com/upgrade-guide/3.5/#jquery-htmlprefilter-changes

@artonge artonge added 3. to review Waiting for reviews regression labels Apr 4, 2022
@artonge artonge added this to the Nextcloud 24 milestone Apr 4, 2022
@artonge artonge requested a review from a team April 4, 2022 10:54
@artonge artonge self-assigned this Apr 4, 2022
@artonge artonge requested review from PVince81, skjnldsv and vanpertsch and removed request for a team April 4, 2022 10:55
@artonge artonge requested a review from szaimen April 4, 2022 11:00
@szaimen

This comment was marked as resolved.

@artonge
Copy link
Contributor Author

artonge commented Apr 4, 2022

Already done :)

The scope is larger than this fix, I updated the description.

@szaimen

This comment was marked as resolved.

@szaimen
Copy link
Contributor

szaimen commented Apr 4, 2022

Here are all if my search was good enough:
(I searched for <[^h].*/> in all js files)

click to expand
73 Ergebnisse - 29-Dateien

apps\dav\src\service\CalendarService.js:
  55  			  <x0:prop>
  56: 				<x1:calendar-availability xmlns:x1="urn:ietf:params:xml:ns:caldav"/>
  57  			  </x0:prop>

apps\files\js\fileactions.js:
  559  			nameLinks.find('.fileactions, .nametext .action').remove();
  560: 			nameLinks.append('<span class="fileactions" />');
  561  			var defaultAction = this.getDefaultFileAction(

apps\files\js\filelist.js:
  2847  			td = tr.children('td.filename');
  2848: 			input = $('<input type="text" class="filename"/>').val(oldName);
  2849  			form = $('<form></form>');

apps\files\js\files.js:
  424  		// TODO: refactor this with the table row creation code
  425: 		var newtr = $('<tr/>')
  426  			.attr('data-dir', dir)

  428  			.attr('data-origin', elem.origin);
  429: 		newtr.append($('<td class="filename" />').text(elem.name).css('background-size', 32));
  430: 		newtr.append($('<td class="size" />').text(OC.Util.humanFileSize(elem.size)));
  431  		tbody.append(newtr);

apps\files\js\sidebarpreviewtext.js:
  27  				$thumbnailContainer.addClass('text');
  28: 				var $textPreview = $('<pre/>').text(content);
  29  				$thumbnailDiv.children('.stretcher').remove();

apps\files\js\templates.js:
  381      + alias4(((helper = (helper = lookupProperty(helpers,"fileName") || (depth0 != null ? lookupProperty(depth0,"fileName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"fileName","hash":{},"data":data,"loc":{"start":{"line":2,"column":59},"end":{"line":2,"column":71}}}) : helper)))
  382:     + "\" autocomplete=\"off\" autocapitalize=\"off\">\n	<input type=\"submit\" value=\" \" class=\"icon-confirm\" />\n</form>\n";
  383  },"useData":true});

apps\files\src\services\FileInfo.js:
  37  			<d:prop>
  38: 				<d:getlastmodified />
  39: 				<d:getetag />
  40: 				<d:getcontenttype />
  41: 				<d:resourcetype />
  42: 				<oc:fileid />
  43: 				<oc:permissions />
  44: 				<oc:size />
  45: 				<d:getcontentlength />
  46: 				<nc:has-preview />
  47: 				<nc:mount-type />
  48: 				<nc:is-encrypted />
  49: 				<ocs:share-permissions />
  50: 				<oc:tags />
  51: 				<oc:favorite />
  52: 				<oc:comments-unread />
  53: 				<oc:owner-id />
  54: 				<oc:owner-display-name />
  55: 				<oc:share-types />
  56  			</d:prop>

apps\files_external\js\settings.js:
   143  		formatResult: function (element) {
   144: 			var $result = $('<span><div class="avatardiv"/><span>'+escapeHTML(element.displayname)+'</span></span>');
   145  			var $div = $result.find('.avatardiv')

   893  
   894: 		var priorityEl = $('<input type="hidden" class="priority" value="' + backend.priority + '" />');
   895  		$tr.append(priorityEl);

  1045  		if (placeholder.type === MountConfigListView.ParameterTypes.PASSWORD) {
  1046: 			newElement = $('<input type="password" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+ trimmedPlaceholder+'" />');
  1047  		} else if (placeholder.type === MountConfigListView.ParameterTypes.BOOLEAN) {
  1048  			var checkboxId = _.uniqueId('checkbox_');
  1049: 			newElement = $('<div><label><input type="checkbox" id="'+checkboxId+'" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" />'+ trimmedPlaceholder+'</label></div>');
  1050  		} else if (placeholder.type === MountConfigListView.ParameterTypes.HIDDEN) {
  1051: 			newElement = $('<input type="hidden" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" />');
  1052  		} else {
  1053: 			newElement = $('<input type="text" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+ trimmedPlaceholder+'" />');
  1054  		}

apps\files_external\js\statusmanager.js:
  378  		'<form>' +
  379: 		'<input type="text" name="username" placeholder="{{placeholder_username}}"/>' +
  380: 		'<input type="password" name="password" placeholder="{{placeholder_password}}"/>' +
  381  		'</form>' +

apps\files_external\js\templates.js:
  26  
  27:   return "<div class=\"popovermenu open\">\n	<ul>\n		<li class=\"optionRow\">\n			<span class=\"menuitem\">\n				<input id=\"mountOptionsEncrypt\" class=\"checkbox\" name=\"encrypt\" type=\"checkbox\" value=\"true\" checked=\"checked\"/>\n				<label for=\"mountOptionsEncrypt\">"
  28      + alias4(((helper = (helper = lookupProperty(helpers,"mountOptionsEncryptLabel") || (depth0 != null ? lookupProperty(depth0,"mountOptionsEncryptLabel") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"mountOptionsEncryptLabel","hash":{},"data":data,"loc":{"start":{"line":6,"column":37},"end":{"line":6,"column":65}}}) : helper)))
  29:     + "</label>\n			</span>\n		</li>\n		<li class=\"optionRow\">\n			<span class=\"menuitem\">\n				<input id=\"mountOptionsPreviews\" class=\"checkbox\" name=\"previews\" type=\"checkbox\" value=\"true\" checked=\"checked\"/>\n				<label for=\"mountOptionsPreviews\">"
  30      + alias4(((helper = (helper = lookupProperty(helpers,"mountOptionsPreviewsLabel") || (depth0 != null ? lookupProperty(depth0,"mountOptionsPreviewsLabel") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"mountOptionsPreviewsLabel","hash":{},"data":data,"loc":{"start":{"line":12,"column":38},"end":{"line":12,"column":67}}}) : helper)))
  31:     + "</label>\n			</span>\n		</li>\n		<li class=\"optionRow\">\n			<span class=\"menuitem\">\n				<input id=\"mountOptionsSharing\" class=\"checkbox\" name=\"enable_sharing\" type=\"checkbox\" value=\"true\"/>\n				<label for=\"mountOptionsSharing\">"
  32      + alias4(((helper = (helper = lookupProperty(helpers,"mountOptionsSharingLabel") || (depth0 != null ? lookupProperty(depth0,"mountOptionsSharingLabel") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"mountOptionsSharingLabel","hash":{},"data":data,"loc":{"start":{"line":18,"column":37},"end":{"line":18,"column":65}}}) : helper)))

  38      + alias4(((helper = (helper = lookupProperty(helpers,"mountOptionsFilesystemCheckDA") || (depth0 != null ? lookupProperty(depth0,"mountOptionsFilesystemCheckDA") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"mountOptionsFilesystemCheckDA","hash":{},"data":data,"loc":{"start":{"line":26,"column":43},"end":{"line":26,"column":76}}}) : helper)))
  39:     + "</option>\n				</select>\n			</span>\n		</li>\n		<li class=\"optionRow\">\n			<span class=\"menuitem\">\n				<input id=\"mountOptionsEncoding\" class=\"checkbox\" name=\"encoding_compatibility\" type=\"checkbox\" value=\"true\"/>\n				<label for=\"mountOptionsEncoding\">"
  40      + alias4(((helper = (helper = lookupProperty(helpers,"mountOptionsEncodingLabel") || (depth0 != null ? lookupProperty(depth0,"mountOptionsEncodingLabel") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"mountOptionsEncodingLabel","hash":{},"data":data,"loc":{"start":{"line":33,"column":38},"end":{"line":33,"column":67}}}) : helper)))
  41:     + "</label>\n			</span>\n		</li>\n		<li class=\"optionRow\">\n			<span class=\"menuitem\">\n				<input id=\"mountOptionsReadOnly\" class=\"checkbox\" name=\"readonly\" type=\"checkbox\" value=\"true\"/>\n				<label for=\"mountOptionsReadOnly\">"
  42      + alias4(((helper = (helper = lookupProperty(helpers,"mountOptionsReadOnlyLabel") || (depth0 != null ? lookupProperty(depth0,"mountOptionsReadOnlyLabel") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"mountOptionsReadOnlyLabel","hash":{},"data":data,"loc":{"start":{"line":39,"column":38},"end":{"line":39,"column":67}}}) : helper)))

apps\files_sharing\js\public.js:
  357  	_showTextPreview: function (data, previewHeight) {
  358: 		var textDiv = $('<div/>').addClass('text-preview');
  359  		textDiv.text(data);

  362  		if (data.length > 999) {
  363: 			var ellipsis = $('<div/>').addClass('ellipsis');
  364  			ellipsis.html('(&#133;)');

apps\settings\js\settings\personalInfo.js:
  74  	var $cropper = $('#cropper');
  75: 	var $cropperImage = $('<img/>');
  76  	$cropperImage.css('opacity', 0); // prevent showing the unresized image

apps\settings\src\service\rebuild-navigation.js:
  44  					  </defs>
  45: 					  <image x="0" y="0" width="16" height="16" filter="url(#invertMenuMore-${entry.id})" preserveAspectRatio="xMinYMin meet" xlink:href="${entry.icon}"  class="app-icon" />
  46  					</svg>`

  86  						  <defs>
  87: 						    <filter id="invert"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" /></filter>
  88  						  </defs>
  89: 						  <image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" xlink:href="${entry.icon}"  class="app-icon" />
  90  						</svg>`

  92  						img = `<svg width="20" height="20" viewBox="0 0 20 20" alt="">
  93: 						  <image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" xlink:href="${entry.icon}"  class="app-icon" />
  94  						</svg>`

apps\systemtags\src\systemtagsfilelist.js:
  102  				const self = this
  103: 				this.$filterField = $('<input type="hidden" name="tags"/>')
  104  				$container.append(this.$filterField)

apps\theming\js\settings-admin.js:
  46  		var old = $('link[href*="' + cssFile + '"]');
  47: 		var stylesheet = $("<link/>", {
  48  			rel: "stylesheet",

apps\user_ldap\js\vendor\ui-multiselect\src\jquery.multiselect.js:
  58  
  59: 			buttonlabel = (this.buttonlabel = $('<span />'))
  60  				.html( o.noneSelectedText )

  62  
  63: 			menu = (this.menu = $('<div />'))
  64  				.addClass('ui-multiselect-menu ui-widget ui-widget-content ui-corner-all')

  67  
  68: 			header = (this.header = $('<div />'))
  69  				.addClass('ui-widget-header ui-corner-all ui-multiselect-header ui-helper-clearfix')

  71  
  72: 			headerLinkContainer = (this.headerLinkContainer = $('<ul />'))
  73  				.addClass('ui-helper-reset')

  85  
  86: 			checkboxContainer = (this.checkboxContainer = $('<ul />'))
  87  				.addClass('ui-multiselect-checkboxes ui-helper-reset')

apps\user_ldap\js\wizard\wizardTabLoginFilter.js:
  145  					var filter = $('<p>').text(result.changes.ldap_test_effective_filter).html();
  146: 					message = t('user_ldap', 'User not found. Please check your login attributes and username. Effective filter (to copy-and-paste for command-line validation): <br/>' + filter);
  147  					console.warn(filter);

apps\workflowengine\src\components\Checks\MultiselectTag\api.js:
  100  					  <d:prop>
  101: 						<oc:id />
  102: 						<oc:display-name />
  103: 						<oc:user-visible />
  104: 						<oc:user-assignable />
  105: 						<oc:can-assign />
  106  					  </d:prop>

core\js\setupchecks.js:
  40  						'<d:propfind xmlns:d="DAV:">' +
  41: 						'<d:prop><d:resourcetype/></d:prop>' +
  42  						'</d:propfind>',

core\src\components\MainMenu.js:
   79  			// but we need it over the primary colour
   80: 			$app.prepend($('<div/>').addClass('icon-loading-small'))
   81  		} else {

  105  			$app.find('div').remove() // prevent odd double-clicks
  106: 			$app.prepend($('<div/>').addClass(
  107  				OCA.Theming && OCA.Theming.inverted

core\src\components\UserMenu.js:
  43  				$page.find('div').remove() // prevent odd double-clicks
  44: 				$page.prepend($('<div/>').addClass('icon-loading-small'))
  45  			}

core\src\files\client.js:
  583  				const property = self._client.parseClarkNotation(prop)
  584: 				body += '        <' + self._client.xmlNamespaces[property.namespace] + ':' + property.name + ' />\n'
  585  			})

core\src\jquery\ocdialog.js:
   48  
   49: 		this.$dialog = $('<div class="oc-dialog" />')
   50  			.attr({

  135  			} else {
  136: 				const $buttonrow = $('<div class="oc-dialog-buttonrow" />')
  137  				this.$buttonrow = $buttonrow.appendTo(this.$dialog)

core\src\jquery\octemplate.js:
  54   *        <td class="name">
  55:  *            <input type="checkbox" name="id" value="{id}" /><span class="nametext">{name}</span>
  56   *        </td>

core\src\jquery\showpassword.js:
  50  
  51: 			const $clone = $('<input />')
  52  

core\src\OC\dialogs.js:
  173  			})
  174: 			var input = $('<input/>')
  175  			input.attr('type', password ? 'password' : 'text').attr('id', dialogName + '-input').attr('placeholder', name)
  176: 			var label = $('<label/>').attr('for', dialogName + '-input').text(name + ': ')
  177  			$dlg.append(label)

core\src\OC\eventsource.js:
  67  		OCEventSource.fallBackSources[OCEventSource.iframeCount] = this
  68: 		this.iframe = $('<iframe/>')
  69  		this.iframe.attr('id', iframeId)

core\src\OC\legacy-loader.js:
  74  		} else {
  75: 			style = $('<link rel="stylesheet" type="text/css" href="' + path + '"/>')
  76  			$('head').append(style)

core\src\systemtags\systemtagsinputfield.js:
  51  			template: function(data) {
  52: 				return '<input class="systemTagsInputField" type="hidden" name="tags" value=""/>'
  53  			},

@artonge
Copy link
Contributor Author

artonge commented Apr 4, 2022

After looking into it, it seems like the initial case was the only problematic one.

However, I preemptively changed other cases to ensure that future changes won't lead to new issues.

Copy link
Contributor

@szaimen szaimen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Fix: #30002
Signed-off-by: Louis Chemineau <louis@chmn.me>
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
@artonge artonge merged commit 9c84aa5 into master Apr 5, 2022
@artonge artonge deleted the fix/30002 branch April 5, 2022 09:35
@blizzz blizzz mentioned this pull request Apr 7, 2022
@artonge
Copy link
Contributor Author

artonge commented May 16, 2022

/backport to stable23

1 similar comment
@artonge
Copy link
Contributor Author

artonge commented May 16, 2022

/backport to stable23

@artonge
Copy link
Contributor Author

artonge commented May 16, 2022

^ Backport requests to unlock jQuery version bump in both versions as they contain CVEs (CVE-2020-11022, CVE-2020-11023, CVE-2019-5428, CVE-2019-11358)

@backportbot-nextcloud
Copy link

The backport to stable23 failed. Please do this backport manually.

@backportbot-nextcloud
Copy link

The backport to stable23 failed. Please do this backport manually.

artonge added a commit to nextcloud/richdocuments that referenced this pull request Jun 20, 2022
Since the upgrade to jQuery v3.6, HTML tags need to be explicitely closed.

cf: nextcloud/server#31820
Signed-off-by: Louis Chemineau <louis@chmn.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3. to review Waiting for reviews regression
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invisible user labels in external storage dropdown
4 participants