Skip to content

Commit

Permalink
Sanitize dynamic styles (#403)
Browse files Browse the repository at this point in the history
Sanitizes dynamic styles for SSR. Client styles are fine since we use `document.createTextNode` (dev) and the CSSOM Api `sheet.insertRule` (prod).
  • Loading branch information
giuseppeg authored Feb 7, 2018
1 parent d018577 commit c5b3f67
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
13 changes: 13 additions & 0 deletions src/stylesheet-registry.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import hashString from 'string-hash'
import DefaultStyleSheet from './lib/stylesheet'

const sanitize = rule => rule.replace(/\/style/g, '\\/style')
export default class StyleSheetRegistry {
constructor({
styleSheet = null,
Expand All @@ -13,7 +14,13 @@ export default class StyleSheetRegistry {
name: 'styled-jsx',
optimizeForSpeed
})

this._sheet.inject()
if (styleSheet && typeof optimizeForSpeed === 'boolean') {
this._sheet.setOptimizeForSpeed(optimizeForSpeed)
this._optimizeForSpeed = this._sheet.isOptimizeForSpeed()
}

this._isBrowser = isBrowser

this._fromServer = undefined
Expand Down Expand Up @@ -146,6 +153,12 @@ export default class StyleSheetRegistry {
) {
const cache = {}
return function(id, css) {
// Sanitize SSR-ed CSS.
// Client side code doesn't need to be sanitized since we use
// document.createTextNode (dev) and the CSSOM api sheet.insertRule (prod).
if (!this._isBrowser) {
css = sanitize(css)
}
const idcss = id + css
if (!cache[idcss]) {
cache[idcss] = css.replace(selectoPlaceholderRegexp, id)
Expand Down
25 changes: 23 additions & 2 deletions test/stylesheet-registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import test from 'ava'
import StyleSheetRegistry from '../src/stylesheet-registry'
import makeSheet, { invalidRules } from './stylesheet'

function makeRegistry(options) {
function makeRegistry(options = { optimizeForSpeed: true, isBrowser: true }) {
const registry = new StyleSheetRegistry({
styleSheet: makeSheet(options),
...options
Expand Down Expand Up @@ -85,6 +85,25 @@ test('add - filters out invalid rules (index `-1`)', t => {
])
})

test('add - sanitizes dynamic CSS on the server', t => {
const registry = makeRegistry({ optimizeForSpeed: false, isBrowser: false })

registry.add({
styleId: '123',
css: [
'div.__jsx-style-dynamic-selector { color: red</style><script>alert("howdy")</script> }'
],
dynamic: ['red</style><script>alert("howdy")</script>']
})

t.deepEqual(registry.cssRules(), [
[
'jsx-1871671996',
'div.jsx-1871671996 { color: red<\\/style><script>alert("howdy")</script> }'
]
])
})

// registry.remove

test('remove', t => {
Expand Down Expand Up @@ -196,7 +215,9 @@ test('createComputeId', t => {
// createComputeSelector

test('createComputeSelector', t => {
const computeSelector = utilRegistry.createComputeSelector()
const computeSelector = utilRegistry
.createComputeSelector()
.bind(utilRegistry)

t.is(
computeSelector(
Expand Down

0 comments on commit c5b3f67

Please sign in to comment.