Skip to content

Commit 2365df5

Browse files
authored
fix(browser): skip deep copy for snapshot events to prevent stack overflow (#3298)
* fix(browser): skip deep copy for snapshot events to prevent stack overflow $snapshot and $exception events set _noTruncate which means no string truncation is needed. Move the guard to the call site so we skip _copyAndTruncateStrings entirely, and tighten the parameter type from number | null to number. This avoids stack overflows on deeply nested rrweb DOM snapshots from complex pages. * chore: add changeset
1 parent 517d49b commit 2365df5

File tree

4 files changed

+11
-8
lines changed

4 files changed

+11
-8
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"posthog-js": patch
3+
---
4+
5+
fix: skip deep copy for snapshot/exception events to prevent stack overflow on deeply nested DOM trees

packages/browser/src/__tests__/utils.test.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ describe('utils', () => {
5454
expect(copy).not.toEqual(target)
5555
})
5656

57-
it('does not truncate when passed null', () => {
58-
expect(_copyAndTruncateStrings(target, null)).toEqual(target)
59-
})
60-
6157
it('handles recursive objects', () => {
6258
const recursiveObject: Record<string, any> = { key: 'vaaaaalue', values: ['fooobar'] }
6359
recursiveObject.values.push(recursiveObject)

packages/browser/src/posthog-core.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,9 @@ export class PostHog implements PostHogInterface {
12691269
data.$set_once = setOnceProperties
12701270
}
12711271

1272-
data = _copyAndTruncateStrings(data, options?._noTruncate ? null : this.config.properties_string_max_length)
1272+
if (!options?._noTruncate) {
1273+
data = _copyAndTruncateStrings(data, this.config.properties_string_max_length)
1274+
}
12731275
data.timestamp = timestamp
12741276
if (!isUndefined(options?.timestamp)) {
12751277
data.properties['$event_time_override_provided'] = true

packages/browser/src/utils/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PostHogConfig, Properties } from '../types'
22
import { logger } from './logger'
3-
import { isFormData, isNull, isNullish, isNumber, isString, hasOwnProperty, isArray } from '@posthog/core'
3+
import { isFormData, isNullish, isNumber, isString, hasOwnProperty, isArray } from '@posthog/core'
44

55
export function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined {
66
for (let i = 0; i < value.length; i++) {
@@ -144,10 +144,10 @@ function deepCircularCopy<T extends Record<string, any> = Record<string, any>>(
144144

145145
export function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(
146146
object: T,
147-
maxStringLength: number | null
147+
maxStringLength: number
148148
): T {
149149
return deepCircularCopy(object, (value: any) => {
150-
if (isString(value) && !isNull(maxStringLength)) {
150+
if (isString(value)) {
151151
return (value as string).slice(0, maxStringLength)
152152
}
153153
return value

0 commit comments

Comments
 (0)