Skip to content

Commit

Permalink
✨ [RUM-175] sanitize RegExp and Event (#3188)
Browse files Browse the repository at this point in the history
* ✨ sanitize RegExp and Event
* 👌 review comments
  • Loading branch information
thomas-lebeau authored Dec 23, 2024
1 parent bb800ae commit 4d8d86d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 14 deletions.
33 changes: 27 additions & 6 deletions packages/core/src/tools/serialisation/sanitize.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { display } from '../display'
import { createNewEvent } from '../../../test'
import { registerCleanupTask } from '../../../test'
import { sanitize } from './sanitize'

describe('sanitize', () => {
Expand Down Expand Up @@ -66,18 +66,34 @@ describe('sanitize', () => {
expect(sanitize(node)).toBe('[HTMLDivElement]')
})

it('should serialize events', () => {
const event = createNewEvent('click')
it('should serialize events', (done) => {
const button = document.createElement('button')
document.body.appendChild(button)

expect(sanitize(event)).toEqual({
isTrusted: false,
registerCleanupTask(() => {
document.body.removeChild(button)
})

document.addEventListener(
'click',
(event) => {
expect(sanitize(event)).toEqual({
type: 'click',
isTrusted: false,
target: '[HTMLButtonElement]',
currentTarget: '[HTMLDocument]',
})
done()
},
{ once: true }
)

button.click()
})

it('should serialize errors as JSON.stringify does', () => {
// Explicitely keep the previous behavior to avoid breaking changes in 4.x
// Browsers have different behaviors:
// IE11 adds a description field
// Safari IOS12 adds parts of the stack
const error = new Error('My Error')
expect(sanitize(error)).toEqual({ ...error })
Expand Down Expand Up @@ -114,6 +130,11 @@ describe('sanitize', () => {
const obj = { a: null, b: undefined }
expect(sanitize(obj)).toEqual({ a: null, b: undefined })
})

it('should handle regular expression', () => {
expect(sanitize(/[a-zA-Z0-9]+/g)).toEqual('[RegExp] /[a-zA-Z0-9]+/g')
expect(sanitize(new RegExp('[a-zA-Z0-9]+', 'g'))).toEqual('[RegExp] /[a-zA-Z0-9]+/g')
})
})

describe('arrays handling', () => {
Expand Down
30 changes: 22 additions & 8 deletions packages/core/src/tools/serialisation/sanitize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ type ContainerElementToProcess = {
path: string
}

type sanitizedEvent = {
type: string
isTrusted: boolean
currentTarget: string | null | undefined
target: string | null | undefined
}

// The maximum size of a single event is 256KiB. By default, we ensure that user-provided data
// going through sanitize fits inside our events, while leaving room for other contexts, metadata, ...
const SANITIZE_DEFAULT_MAX_CHARACTER_COUNT = 220 * ONE_KIBI_BYTE
Expand Down Expand Up @@ -203,17 +210,15 @@ function sanitizePrimitivesAndFunctions(value: PrimitivesAndFunctions) {
* LIMITATIONS
* - If a class defines a toStringTag Symbol, it will fall in the catch-all method and prevent enumeration of properties.
* To avoid this, a toJSON method can be defined.
* - IE11 does not return a distinct type for objects such as Map, WeakMap, ... These objects will pass through and their
* properties enumerated if any.
*
*/
function sanitizeObjects(value: object) {
function sanitizeObjects(value: object): string | sanitizedEvent {
try {
// Handle events - Keep a simple implementation to avoid breaking changes
if (value instanceof Event) {
return {
isTrusted: value.isTrusted,
}
return sanitizeEvent(value)
}

if (value instanceof RegExp) {
return `[RegExp] ${value.toString()}`
}

// Handle all remaining object types in a generic way
Expand All @@ -229,6 +234,15 @@ function sanitizeObjects(value: object) {
return '[Unserializable]'
}

function sanitizeEvent(event: Event): sanitizedEvent {
return {
type: event.type,
isTrusted: event.isTrusted,
currentTarget: event.currentTarget ? (sanitizeObjects(event.currentTarget) as string) : null,
target: event.target ? (sanitizeObjects(event.target) as string) : null,
}
}

/**
* Checks if a toJSON function exists and tries to execute it
*
Expand Down

0 comments on commit 4d8d86d

Please sign in to comment.