Skip to content

Commit 122f609

Browse files
pabloerhardjuan-fernandez
authored andcommitted
fix: safer wrapFunction for ESM instrumentation (#6761)
* Added prevention into wrapFunction * Modify shimmer tests to comply with new behavior * Added express-mongo-sanitize-test
1 parent 7d1c70e commit 122f609

File tree

8 files changed

+89
-6
lines changed

8 files changed

+89
-6
lines changed

.github/workflows/apm-integrations.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,16 @@ jobs:
384384
- uses: ./.github/actions/install
385385
- run: yarn test:plugins:ci
386386

387+
express-mongo-sanitize:
388+
runs-on: ubuntu-latest
389+
env:
390+
PLUGINS: express-mongo-sanitize
391+
steps:
392+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
393+
- uses: ./.github/actions/plugins/test
394+
with:
395+
dd_api_key: ${{ secrets.DD_API_KEY }}
396+
387397
express-session:
388398
runs-on: ubuntu-latest
389399
env:

packages/datadog-instrumentations/src/cookie-parser.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ addHook({
2525
name: 'cookie-parser',
2626
versions: ['>=1.0.0']
2727
}, cookieParser => {
28-
// This prevents the non default export from entering the wrapping process
29-
if (cookieParser.default) return cookieParser
3028
return shimmer.wrapFunction(cookieParser, cookieParser => function () {
3129
const cookieMiddleware = cookieParser.apply(this, arguments)
3230

packages/datadog-instrumentations/src/express-session.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,5 @@ addHook({
3737
name: 'express-session',
3838
versions: ['>=1.5.0']
3939
}, session => {
40-
if (session.default) return session
4140
return shimmer.wrapFunction(session, wrapSession)
4241
})
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict'
2+
3+
const {
4+
createSandbox, varySandbox,
5+
FakeAgent, spawnPluginIntegrationTestProc
6+
} = require('../../../../integration-tests/helpers')
7+
const { assert } = require('chai')
8+
const { withVersions } = require('../../../dd-trace/test/setup/mocha')
9+
const axios = require('axios')
10+
withVersions('express-mongo-sanitize', 'express-mongo-sanitize', version => {
11+
describe('ESM', () => {
12+
let sandbox, variants, proc, agent
13+
14+
before(async function () {
15+
this.timeout(50000)
16+
sandbox = await createSandbox([`'express-mongo-sanitize@${version}'`, 'express@<=4.0.0'], false,
17+
['./packages/datadog-plugin-express-mongo-sanitize/test/integration-test/*'])
18+
variants = varySandbox(sandbox, 'server.mjs', 'expressMongoSanitize', undefined, 'express-mongo-sanitize')
19+
})
20+
21+
after(async function () {
22+
this.timeout(50000)
23+
await sandbox.remove()
24+
})
25+
26+
beforeEach(async () => {
27+
agent = await new FakeAgent().start()
28+
})
29+
30+
afterEach(async () => {
31+
proc?.kill()
32+
await agent.stop()
33+
})
34+
35+
for (const variant of varySandbox.VARIANTS) {
36+
it(`is instrumented loaded with ${variant}`, async () => {
37+
const proc = await spawnPluginIntegrationTestProc(sandbox.folder, variants[variant], agent.port)
38+
const response = await axios.get(`${proc.url}/?param=paramvalue`)
39+
assert.equal(response.headers['x-counter'], '1')
40+
})
41+
}
42+
})
43+
})
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'dd-trace/init.js'
2+
import express from 'express'
3+
import expressMongoSanitize from 'express-mongo-sanitize'
4+
import dc from 'dc-polyfill'
5+
const app = express()
6+
7+
const sanitizeMiddlewareFinished = dc.channel('datadog:express-mongo-sanitize:filter:finish')
8+
9+
let counter = 0
10+
11+
sanitizeMiddlewareFinished.subscribe(() => {
12+
counter += 1
13+
})
14+
15+
app.use(expressMongoSanitize())
16+
app.all('/', (req, res) => {
17+
res.setHeader('X-Counter', counter)
18+
res.end()
19+
})
20+
21+
const server = app.listen(0, () => {
22+
const port = server.address().port
23+
process.send({ port })
24+
})

packages/datadog-shimmer/src/shimmer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ function copyObjectProperties (original, wrapped, skipKey) {
7373
* @returns {Function} The wrapped function.
7474
*/
7575
function wrapFunction (original, wrapper) {
76+
if (typeof original === 'object' && original !== null) return original
77+
7678
const wrapped = wrapper(original)
7779

7880
if (typeof original === 'function') {

packages/datadog-shimmer/test/shimmer.spec.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,18 @@ describe('shimmer', () => {
372372
expect(() => shimmer.wrap(() => {}, () => {})).to.throw()
373373
})
374374

375-
it('should work without a function', () => {
376-
const a = { b: 1 }
375+
it('should work with null instead of function', () => {
376+
const a = null
377377
const wrapped = shimmer.wrapFunction(a, x => () => x)
378378
expect(wrapped()).to.equal(a)
379379
})
380380

381+
it('should not work with an object', () => {
382+
const a = { b: 1 }
383+
const wrapped = shimmer.wrapFunction(a, x => () => x)
384+
expect(typeof wrapped).to.not.equal('function')
385+
})
386+
381387
it('should wrap the function', () => {
382388
const count = inc => inc
383389

packages/dd-trace/test/plugins/plugin-structure.spec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ const missingPlugins = [
2020
'datadog-plugin-limitd-client', // limitd-client instrumentation handles trace context propagation, no tracing is done
2121
'datadog-plugin-mongoose', // mongoose tracing is done through mongodb-core instrumentation
2222
'datadog-plugin-cookie-parser', // cookie-parser does not produce spans
23-
'datadog-plugin-express-session' // express-session does not produce spans
23+
'datadog-plugin-express-session', // express-session does not produce spans
24+
'datadog-plugin-express-mongo-sanitize' // express-mongo-sanitize does not produce spans
2425
]
2526

2627
// instrumentations that do not have a hook, but are still instrumented

0 commit comments

Comments
 (0)