Skip to content

Commit ff5c51a

Browse files
committed
Core: Warn about attribute selectors that have an unquoted hash
(cherry picked from commit 2ad1982)
1 parent d542e5b commit ff5c51a

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

src/core.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var matched, browser,
33
oldInit = jQuery.fn.init,
44
oldParseJSON = jQuery.parseJSON,
55
rspaceAngle = /^\s*</,
6+
rattrHash = /\[\s*\w+\s*[~|^$*]?=\s*(?![\s'"])[^#\]]*#/,
67
// Note: XSS check is done below after string is trimmed
78
rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;
89

@@ -38,10 +39,17 @@ jQuery.fn.init = function( selector, context, rootjQuery ) {
3839
}
3940
}
4041

41-
// jQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0
4242
if ( selector === "#" ) {
43+
44+
// jQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0
4345
migrateWarn( "jQuery( '#' ) is not a valid selector" );
4446
selector = [];
47+
48+
} else if ( rattrHash.test( selector ) ) {
49+
50+
// The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0
51+
// Note that this doesn't actually fix the selector due to potential false positives
52+
migrateWarn( "Attribute selectors with '#' must be quoted: '" + selector + "'" );
4553
}
4654

4755
ret = oldInit.apply( this, arguments );

test/core.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,48 @@ test( "jQuery( '#' )", function() {
6262
});
6363
});
6464

65+
test( "attribute selectors with naked '#'", function() {
66+
expect( 6 );
67+
68+
// These are wrapped in try/catch because they throw on jQuery 1.12.0+
69+
70+
expectWarning( "attribute equals", function() {
71+
try {
72+
jQuery( "a[href=#]" );
73+
} catch( e ) {}
74+
});
75+
76+
expectWarning( "attribute contains", function() {
77+
try {
78+
jQuery( "link[rel*=#stuff]" );
79+
} catch( e ) {}
80+
});
81+
82+
expectWarning( "attribute starts, with spaces", function() {
83+
try {
84+
jQuery( "a[href ^= #junk]" );
85+
} catch( e ) {}
86+
});
87+
88+
expectWarning( "attribute equals, hash not starting", function() {
89+
try {
90+
jQuery( "a[href=space#junk]" );
91+
} catch( e ) {}
92+
});
93+
94+
expectNoWarning( "attribute equals, with single quotes", function() {
95+
try {
96+
jQuery( "a[href='#junk']" );
97+
} catch( e ) {}
98+
});
99+
100+
expectNoWarning( "attribute equals, with double quotes", function() {
101+
try {
102+
jQuery( "a[href=\"#junk\"]" );
103+
} catch( e ) {}
104+
});
105+
});
106+
65107
test( "selector state", function() {
66108
expect( 18 );
67109

warnings.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ This is _not_ a warning, but a console log message the plugin shows when it firs
3030

3131
**Solution**: Usually this warning is due to an error in the HTML string, where text is present when it should not be there. Remove the leading or trailing text before passing the string to `$.parseHTML()` if it should not be part of the collection. Alternatively you can use `$($.parseHTML(html)).filter("*")` to remove all top-level text nodes from the set and leave only elements.
3232

33+
### JQMIGRATE: Attribute selectors with '#' must be quoted
34+
35+
**Cause:** CSS selectors such as `a[href=#main]` are not valid CSS syntax because the value contains special characters that are not quoted. Until jQuery 1.11.3/2.1.4 this syntax was accepted, but the behavior is non-standard and was never documented. In later versions this selector throws an error. *In some rare cases Migrate may mis-diagnose this problem, so it does not attempt a repair.*
36+
37+
**Solution**: Put quotes around any attribute values that have special characters, e.g. `a[href="#main"]`. The warning message contains the selector that caused the problem, use that to find the selector in the source files.
38+
3339
### JQMIGRATE: Can't change the 'type' of an input or button in IE 6/7/8
3440

3541
**Cause:** IE 6, 7, and 8 throw an error if you attempt to change the type attribute of an input or button element, for example to change a radio button to a checkbox. Prior to 1.9, jQuery threw an error for every browser to create consistent behavior. As of jQuery 1.9 setting the type is allowed, but will still throw an error in oldIE.

0 commit comments

Comments
 (0)