Skip to main content

Bug Tracker

Side navigation

#14692 closed feature (migrated)

Opened January 14, 2014 01:52PM UTC

Closed October 21, 2014 12:30AM UTC

Please provide a function for escaping special characters in selectors

Reported by: fejesjoco Owned by: gibson042
Priority: low Milestone: 1.12/2.2
Component: selector Version: 1.10.2
Keywords: Cc:
Blocked by: Blocking:
Description

I read this article: http://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/ .

It says plain and simple that a colon and a period must be escaped. And then the example code also escapes square brackets, so there's a problem already. In the future, you may add a new special character for a cool new selector feature, and that will be a breaking change.

I can see already how many bugs have been filed about special characters in selectors and then closed as being documented. I understand it completely. This is not a bug report, this is a feature request.

Please provide a function for escaping special characters in selectors. Benefits:

  • it's a very easy utility function to implement and useful in many cases
  • all those people who never cared about such issues, will realize they should use this escaping mechanism
  • all those people who used to run into problems with special characters before, used to file all those unnecessary bugs, now they will have an out-of-the-box solution instead
  • if a spec changes or jQuery API changes, it won't be a breaking change because the updated escape function would handle the new cases too
  • the quoted documentation suggests to copy-paste some code into my own JS, but jQuery is about helping eliminate those kinds of code pieces, it would be great to have it embedded

I also realized there are much more characters which could need escaping if we're not just talking about the restricted ID's: http://api.jquery.com/category/selectors/ . This proposed escape function could handle that as well. I hope it's not a problem if it unnecessarily escapes characters in a selector in cases when it's not needed.

Attachments (0)
Change History (12)

Changed January 14, 2014 02:02PM UTC by scottgonzalez comment:1

This issue came up on the WHATWG mailing list a few months ago: http://lists.w3.org/Archives/Public/public-whatwg-archive/2013Oct/0075.html and was added to CSSOM: http://dev.w3.org/csswg/cssom/#the-css.escape()-method

Changed January 14, 2014 02:10PM UTC by fejesjoco comment:2

I'm glad it's being worked on. Do you think it would be reasonable to provide that function in jQuery, and that would call CSS.escape() if it's available, or use a fixed regexp if it's not? I look at jQuery as a layer that, among others, hides those kinds of browser differences. Also, CSS.escape() is only a valid alternative as long as jQuery's syntax is in accordance with CSS, but jQuery can actually extend that syntax. jQuery has lots and lots of functions that depend on selectors, so I believe there would be a real place for this utility method.

Changed January 14, 2014 02:43PM UTC by scottgonzalez comment:3

jQuery allows for additional selectors, but not for additional syntax. I believe there should never be a case where a proper CSS escaping method would fail on a custom jQuery selector.

Changed January 15, 2014 11:19PM UTC by timmywil comment:4

There are certainly helpful use cases. The most common case I foresee is concatenating an attribute value in an attribute selector. Certain special characters have meaning in selectors unless they are escaped, so it is impossible to predict the user's intentions 100% of the time, which means inevitable non-bug reports as well.

I'm inclined to vote against the feature not because of a lack of utility externally, but because we have no need of it internally, which is usually the formula for a great plugin.

Changed January 20, 2014 11:32PM UTC by dmethvin comment:5

component: unfiledselector
milestone: None1.12/2.2
priority: undecidedlow
status: newopen

Since it's being addressed by standards, I don't know that we want to get out ahead of that. We could possibly offer a wrapper, but it seems like someone who wanted this functionality could just as easily create a polyfill. So I'm not a big fan either.

I don't know how it complicates things but $( str ) could also be HTML or a script, not just a selector. Not sure whether a script injection attempt via a CSS fragment could be made to succeed.

Marking this open for discussion at the meeting next month.

Changed January 21, 2014 11:22AM UTC by fejesjoco comment:6

$(str) is not a use case I was thinking about. The use case is when I want to add some variable string into a selector, without breaking the selector. For example, this is broken for parameters like "a.b":

function getElementById2(id) {
  return $("#" + id);
}

I should write this instead:

function getElementById2(id) {
  return $("#" + $.selectorescape(id));
}

There could be many such vulnerabilities out there like that already. For example, this was just fixed in ASP.NET MVC here: https://aspnetwebstack.codeplex.com/SourceControl/changeset/e663ab603486b94162a233ea43d675e1e3452d06 . They added their own escape mechanism for 4 metacharacters .:[], I don't know if its enough or not, and who knows what some other people might think what should be escaped.

It makes sense to me that the question "hey, mr. interpreter, which characters should I escape for you?" can be best answered by the interpreter itself. A good example of that is the regex escaping in .NET: http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.escape%28v=vs.110%29.aspx . It knows what the special characters are and how they should be escaped, so you can put user-supplied strings into a regexp without worrying about anything.

Changed February 25, 2014 02:08PM UTC by dmethvin comment:7

See also #11773. Parts of a built-up str may need to be selector-escaped or html-escaped before being passed to $(str) depending on its purpose and origin.

Changed February 25, 2014 02:29PM UTC by fejesjoco comment:8

Yes, it's a similar problem. Every time when an engine supports certain magic characters, the user may accidentally submit a string which does something else than intended. Also the engine has no way to know what's intentional and what's not. The best solution is if the engine itself provides a proper escaping function. The engine knows what to escape, the user only has to know to call it for string parts where no special interpretation is intended. These functions are way too simple to put into plugins, and they should be the integral parts of the interpreting engines because the rules may change over time. I should be able to do $(whatever).html("<p>" + htmlescape(whatever) + "</p>") or $("#" + cssescape(whatever.id)), etc.

Changed February 26, 2014 01:22PM UTC by fejesjoco comment:9

Found a similar thing: $.ui.autocomplete.escapeRegex. It could also be added to be available globally. It's not strictly jQuery related, but it's already there in jQuery UI (in a very wrong place) and it has a use-case. Since core JavaScript provides RegExp, of course it should also provide its own escaping function, but it doesn't.

Here's a very good example. I may want to find whole words that the user specifies like this: new RegExp('(^|[^\\w])' + user_supplied_value + '($|[^\\w])'). The user supplied value should be properly escaped so that it doesn't contain any characters which are handled specially in a regexp.

Changed May 05, 2014 04:48PM UTC by gibson042 comment:10

owner: → gibson042
status: openassigned

Changed May 05, 2014 04:52PM UTC by gibson042 comment:11

Changed October 21, 2014 12:30AM UTC by m_gol comment:12

resolution: → migrated
status: assignedclosed