UNPKG

dd-trace

Version:

Datadog APM tracing client for JavaScript

117 lines (96 loc) 3.4 kB
'use strict' const path = require('path') const process = require('process') const { fileURLToPath } = require('url') const { ddBasePath } = require('../../util') const { getOriginalPathAndLineFromSourceMap } = require('./taint-tracking/rewriter') const pathLine = { getNodeModulesPaths, getRelativePath, getCallSiteFramesForLocation, ddBasePath, // Exported only for test purposes } const EXCLUDED_PATHS = [ path.join(path.sep, 'node_modules', 'dc-polyfill'), ] /** * Processes and filters call site frames to find the best location for a vulnerability. * Returns client frames if available, otherwise falls back to all processed frames. * Excludes dd-trace frames and all Node.js built-in/internal modules (node:*). * @param {CallSiteFrame[]} callSiteFrames * @param {string[]} externallyExcludedPaths * @returns {CallSiteFrame[]} Client frames if available, otherwise all processed frames * * @typedef {object} CallSiteFrame * @property {number} id * @property {string} file - Original file path * @property {number} line * @property {number} column * @property {string} function * @property {string} class_name * @property {boolean} isNative * @property {string} [path] - Relative path, added during processing * @property {boolean} [isInternal] - Whether the frame is internal, added during processing */ function getCallSiteFramesForLocation (callSiteFrames, externallyExcludedPaths) { if (!callSiteFrames) { return [] } const allFrames = [] const clientFrames = [] for (const callsite of callSiteFrames) { let filepath = callsite.file?.startsWith('file://') ? fileURLToPath(callsite.file) : callsite.file if (globalThis.__DD_ESBUILD_IAST_WITH_SM) { const callsiteLocation = { path: filepath, line: callsite.line, column: callsite.column, } const { path: originalPath, line, column } = getOriginalPathAndLineFromSourceMap(callsiteLocation) callsite.path = filepath = originalPath callsite.line = line callsite.column = column } if (filepath) { callsite.path = getRelativePath(filepath) callsite.isInternal = !path.isAbsolute(filepath) allFrames.push(callsite) if ( !isExcluded(callsite, externallyExcludedPaths) && (!filepath.includes(pathLine.ddBasePath) || globalThis.__DD_ESBUILD_IAST_WITH_NO_SM) ) { clientFrames.push(callsite) } } } return clientFrames.length > 0 ? clientFrames : allFrames } function getRelativePath (filepath) { return filepath && path.relative(process.cwd(), filepath) } function isExcluded (callsite, externallyExcludedPaths) { if (callsite.isNative) return true const filename = globalThis.__DD_ESBUILD_IAST_WITH_SM ? callsite.path : callsite.file if (!filename || filename.startsWith('node:')) { return true } let excludedPaths = EXCLUDED_PATHS if (externallyExcludedPaths) { excludedPaths = [...excludedPaths, ...externallyExcludedPaths] } for (const excludedPath of excludedPaths) { if (filename.includes(excludedPath)) { return true } } return false } function getNodeModulesPaths (...paths) { const nodeModulesPaths = [] for (const p of paths) { const pathParts = p.split('/') nodeModulesPaths.push(path.join('node_modules', ...pathParts)) } return nodeModulesPaths } module.exports = pathLine