-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
Changes to attribute whitelist logic #10564
Changes from 23 commits
e10694a
711bafe
4c5dfbb
e086ff1
0410651
ab75d9a
6077e0b
6f913ed
aca8d9c
af7d035
9c0751f
f8da44e
b93e093
fbcced1
a270e03
ed92af0
5a339a1
0b2ba65
3f85316
76a6318
b29bb74
0a2aec4
501e86d
8d1f487
72666fa
cb687ed
1d61379
2b0f61a
1590c2a
cb883a6
32f6321
6d9c0e0
10e0c09
ba71ec1
dc760af
10950c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,8 +99,12 @@ var DOMMarkupOperations = { | |
(propertyInfo.hasOverloadedBooleanValue && value === true) | ||
) { | ||
return attributeName + '=""'; | ||
} else if ( | ||
typeof value !== 'boolean' || | ||
DOMProperty.shouldAttributeAcceptBooleanValue(name) | ||
) { | ||
return attributeName + '=' + quoteAttributeValueForBrowser(value); | ||
} | ||
return attributeName + '=' + quoteAttributeValueForBrowser(value); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd love to just lean on |
||
} else if (DOMProperty.shouldSetAttribute(name, value)) { | ||
if (value == null) { | ||
return ''; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,9 @@ var invariant = require('fbjs/lib/invariant'); | |
// These attributes should be all lowercase to allow for | ||
// case insensitive checks | ||
var RESERVED_PROPS = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I realize this isn't part of this change but this seems problematic to me. This is a non-trivial case insensitive look up (as opposed to say a super quick interned string comparison). We should make reserved props case sensitive and pass other ones through but warn just like we do for any other "possible standard name". |
||
aria: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is We might not need to reserve these. A warning is probably enough. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It turned out we actually use |
||
children: true, | ||
data: true, | ||
dangerouslysetinnerhtml: true, | ||
autofocus: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't comment on the unchanged line but |
||
defaultvalue: true, | ||
|
@@ -42,6 +44,7 @@ var DOMPropertyInjection = { | |
HAS_NUMERIC_VALUE: 0x8, | ||
HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8, | ||
HAS_OVERLOADED_BOOLEAN_VALUE: 0x20, | ||
HAS_STRING_BOOLEAN_VALUE: 0x40, | ||
|
||
/** | ||
* Inject some specialized knowledge about the DOM. This takes a config object | ||
|
@@ -103,6 +106,10 @@ var DOMPropertyInjection = { | |
propConfig, | ||
Injection.HAS_OVERLOADED_BOOLEAN_VALUE, | ||
), | ||
hasStringBooleanValue: checkMask( | ||
propConfig, | ||
Injection.HAS_STRING_BOOLEAN_VALUE, | ||
), | ||
}; | ||
invariant( | ||
propertyInfo.hasBooleanValue + | ||
|
@@ -201,26 +208,21 @@ var DOMProperty = { | |
if (DOMProperty.isReservedProp(name)) { | ||
return false; | ||
} | ||
|
||
if ( | ||
(name[0] === 'o' || name[0] === 'O') && | ||
(name[1] === 'n' || name[1] === 'N') | ||
) { | ||
return false; | ||
} | ||
if (value === null) { | ||
return true; | ||
} | ||
|
||
var lowerCased = name.toLowerCase(); | ||
|
||
var propertyInfo = DOMProperty.properties[name]; | ||
|
||
switch (typeof value) { | ||
case 'boolean': | ||
if (propertyInfo) { | ||
return true; | ||
} | ||
var prefix = lowerCased.slice(0, 5); | ||
return prefix === 'data-' || prefix === 'aria-'; | ||
return DOMProperty.shouldAttributeAcceptBooleanValue(name); | ||
case 'undefined': | ||
case 'number': | ||
case 'string': | ||
return true; | ||
case 'object': | ||
return true; | ||
default: | ||
|
@@ -235,6 +237,22 @@ var DOMProperty = { | |
: null; | ||
}, | ||
|
||
shouldAttributeAcceptBooleanValue(name) { | ||
if (DOMProperty.isReservedProp(name)) { | ||
return true; | ||
} | ||
let propertyInfo = DOMProperty.getPropertyInfo(name); | ||
if (propertyInfo) { | ||
return ( | ||
propertyInfo.hasBooleanValue || | ||
propertyInfo.hasStringBooleanValue || | ||
propertyInfo.hasOverloadedBooleanValue | ||
); | ||
} | ||
var prefix = name.toLowerCase().slice(0, 5); | ||
return prefix === 'data-' || prefix === 'aria-'; | ||
}, | ||
|
||
/** | ||
* Checks to see if a property name is within the list of properties | ||
* reserved for internal React operations. These properties should | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,13 +20,17 @@ var HAS_POSITIVE_NUMERIC_VALUE = | |
DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; | ||
var HAS_OVERLOADED_BOOLEAN_VALUE = | ||
DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; | ||
var HAS_STRING_BOOLEAN_VALUE = DOMProperty.injection.HAS_STRING_BOOLEAN_VALUE; | ||
|
||
var HTMLDOMPropertyConfig = { | ||
// When adding attributes to this list, be sure to also add them to | ||
// the `possibleStandardNames` module to ensure casing and incorrect | ||
// name warnings. | ||
Properties: { | ||
allowFullScreen: HAS_BOOLEAN_VALUE, | ||
// IE only true/false iFrame attribute | ||
// https://msdn.microsoft.com/en-us/library/ms533072(v=vs.85).aspx | ||
allowTransparency: HAS_STRING_BOOLEAN_VALUE, | ||
// specifies target context for links with `preload` type | ||
async: HAS_BOOLEAN_VALUE, | ||
// autoFocus is polyfilled/normalized by AutoFocusUtils | ||
|
@@ -35,11 +39,13 @@ var HTMLDOMPropertyConfig = { | |
capture: HAS_BOOLEAN_VALUE, | ||
checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, | ||
cols: HAS_POSITIVE_NUMERIC_VALUE, | ||
contentEditable: HAS_STRING_BOOLEAN_VALUE, | ||
controls: HAS_BOOLEAN_VALUE, | ||
default: HAS_BOOLEAN_VALUE, | ||
defer: HAS_BOOLEAN_VALUE, | ||
disabled: HAS_BOOLEAN_VALUE, | ||
download: HAS_OVERLOADED_BOOLEAN_VALUE, | ||
draggable: HAS_STRING_BOOLEAN_VALUE, | ||
formNoValidate: HAS_BOOLEAN_VALUE, | ||
hidden: HAS_BOOLEAN_VALUE, | ||
loop: HAS_BOOLEAN_VALUE, | ||
|
@@ -62,6 +68,7 @@ var HTMLDOMPropertyConfig = { | |
start: HAS_NUMERIC_VALUE, | ||
// support for projecting regular DOM Elements via V1 named slots ( shadow dom ) | ||
span: HAS_POSITIVE_NUMERIC_VALUE, | ||
spellCheck: HAS_STRING_BOOLEAN_VALUE, | ||
// Style must be explicitly set in the attribute list. React components | ||
// expect a style object | ||
style: 0, | ||
|
@@ -75,22 +82,8 @@ var HTMLDOMPropertyConfig = { | |
htmlFor: 0, | ||
httpEquiv: 0, | ||
// Attributes with mutation methods must be specified in the whitelist | ||
value: 0, | ||
// The following attributes expect boolean values. They must be in | ||
// the whitelist to allow boolean attribute assignment: | ||
autoComplete: 0, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed autoComplete. It is actually |
||
// IE only true/false iFrame attribute | ||
// https://msdn.microsoft.com/en-us/library/ms533072(v=vs.85).aspx | ||
allowTransparency: 0, | ||
contentEditable: 0, | ||
draggable: 0, | ||
spellCheck: 0, | ||
// autoCapitalize and autoCorrect are supported in Mobile Safari for | ||
// keyboard hints. | ||
autoCapitalize: 0, | ||
autoCorrect: 0, | ||
// autoSave allows WebKit/Blink to persist values of input fields on page reloads | ||
autoSave: 0, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same deal with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we special case these so that they work? It's odd when the form There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just for context, This default value appears to be an empty string, at least when I log out Hmm. It is frustrating that In the mean time, should we want to parse @aweary is this in line what what you were thinking for boolean attributes? Random fun aside: This is my first time using a footnote in a reply on Github. What a time to be alive. |
||
// Set the string boolean flag to allow the behavior | ||
value: HAS_STRING_BOOLEAN_VALUE, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This must be in here for backwards compatibility. |
||
}, | ||
DOMAttributeNames: { | ||
acceptCharset: 'accept-charset', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably don't intend to merge this part, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol. I honestly thought that was an edge case test. 😨