@datadog/native-iast-rewriter
Advanced tools
Comparing version 2.0.2 to 2.1.0
'use strict' | ||
const path = require('path') | ||
const fs = require('fs') | ||
const LRU = require('lru-cache') | ||
const { SourceMap } = require('./node_source_map') | ||
const SOURCE_MAP_LINE_START = '//# sourceMappingURL=' | ||
const SOURCE_MAP_INLINE_LINE_START = '//# sourceMappingURL=data:application/json;base64,' | ||
const rewrittenSourceMapsCache = new Map() | ||
const originalSourceMapsCache = new LRU({ max: 1000 }) | ||
@@ -19,3 +23,3 @@ function generateSourceMapFromFileContent (fileContent, filePath) { | ||
if (sourceMappingURL) { | ||
sourceMappingURL = path.join(filePath, sourceMappingURL) | ||
sourceMappingURL = path.isAbsolute(sourceMappingURL) ? sourceMappingURL : path.join(filePath, sourceMappingURL) | ||
rawSourceMap = fs.readFileSync(sourceMappingURL).toString() | ||
@@ -40,5 +44,4 @@ } | ||
function getSourcePathAndLineFromSourceMaps (filename, line, column = 0) { | ||
function getPathAndLine (sourceMap, filename, line, column) { | ||
try { | ||
const sourceMap = rewrittenSourceMapsCache.get(filename) | ||
if (sourceMap) { | ||
@@ -59,6 +62,32 @@ const filePath = getFilePathFromName(filename) | ||
function getSourcePathAndLineFromSourceMaps (filename, line, column = 0) { | ||
const sourceMap = rewrittenSourceMapsCache.get(filename) | ||
return getPathAndLine(sourceMap, filename, line, column) | ||
} | ||
function getOriginalPathAndLineFromSourceMap (filename, line, column = 0) { | ||
if (filename && line) { | ||
let sourceMap | ||
try { | ||
sourceMap = originalSourceMapsCache.get(filename) | ||
if (sourceMap === undefined) { | ||
const filePath = getFilePathFromName(filename) | ||
sourceMap = generateSourceMapFromFileContent(fs.readFileSync(filename).toString(), filePath) | ||
originalSourceMapsCache.set(filename, sourceMap || null) | ||
} | ||
return getPathAndLine(sourceMap, filename, line, column) | ||
} catch (e) { | ||
if (sourceMap === undefined) { | ||
originalSourceMapsCache.set(filename, null) | ||
} | ||
} | ||
} | ||
return { path: filename, line, column } | ||
} | ||
module.exports = { | ||
getSourcePathAndLineFromSourceMaps, | ||
getOriginalPathAndLineFromSourceMap, | ||
cacheRewrittenSourceMap, | ||
generateSourceMapFromFileContent | ||
} |
@@ -7,3 +7,3 @@ /** | ||
const { getPrepareStackTrace } = require('./js/stack-trace/') | ||
const { cacheRewrittenSourceMap } = require('./js/source-map') | ||
const { cacheRewrittenSourceMap, getOriginalPathAndLineFromSourceMap } = require('./js/source-map') | ||
@@ -73,3 +73,4 @@ class DummyRewriter { | ||
DummyRewriter, | ||
getPrepareStackTrace | ||
getPrepareStackTrace, | ||
getOriginalPathAndLineFromSourceMap | ||
} |
{ | ||
"name": "@datadog/native-iast-rewriter", | ||
"homepage": "https://github.com/DataDog/dd-native-iast-rewriter-js/blob/main/README.md", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "Datadog IAST instrumentation addon for NodeJS", | ||
@@ -32,2 +32,3 @@ "main": "main.js", | ||
"dependencies": { | ||
"lru-cache": "^7.14.0", | ||
"node-gyp-build": "^4.5.0" | ||
@@ -34,0 +35,0 @@ }, |
105
README.md
# dd-native-iast-rewriter-js | ||
Nodejs native AST rewriter | ||
Nodejs native AST rewriter heavily based on [Speedy Web Compiler o SWC compiler](https://github.com/swc-project/swc) used to instrument Javascript source files. | ||
## Workflow | ||
1. Parse Javascript code to obtain the AST | ||
2. Replace certain AST expressions -> Currently it is focused in certain operators like `+` and `+=`, template literals and some String methods | ||
3. Generate the new Javascript code as from the modified AST -> In addition to the Javascript code, the corresponding source map is returned chaining it with the original source map if necessary. | ||
## Usage | ||
```javascript | ||
const Rewriter = require('@datadog/native-iast-rewriter') | ||
const rewriter = new Rewriter(rewriterConfig) | ||
const rewrittenCode = rewriter.rewrite(code, filename) | ||
``` | ||
## Configuration options | ||
```javascript | ||
RewriterConfig { | ||
// enable/disable sourceMap chaining - false by default | ||
chainSourceMap?: boolean | ||
// enable/disable comments printing - false by default | ||
comments?: boolean | ||
// establishes the prefix for the injected local variables - 6 random characters by default | ||
localVarPrefix?: string | ||
// sets the list of methods or operators to be rewritten | ||
csiMethods?: Array<CsiMethod> | ||
} | ||
CsiMethod { | ||
// name of the String method to rewrite | ||
src: string | ||
// optional name of the replacement method. If not specified a convention shall be used | ||
dst?: string | ||
// indicates if it is an operator like + | ||
operator?: boolean | ||
} | ||
``` | ||
## Example | ||
```javascript | ||
const Rewriter = require('@datadog/native-iast-rewriter') | ||
const rewriterConfig = { | ||
csiMethods: [ | ||
{ src: 'substring' } | ||
], | ||
localVarPrefix: 'test' | ||
} | ||
const rewriter = new Rewriter(rewriterConfig) | ||
const code = `function sub(a) { | ||
return a.substring(1) | ||
}` | ||
const rewrittenCode = rewriter.rewrite(code, filename) | ||
console.log(rewrittenCode) | ||
/* | ||
function sub(a) { | ||
let __datadog_test_0, __datadog_test_1; | ||
return (__datadog_test_0 = a, __datadog_test_1 = __datadog_test_0.substring, _ddiast.stringSubstring(__datadog_test_1.call(__datadog_test_0, 1), __datadog_test_1, __datadog_test_0, 1)); | ||
} | ||
*/ | ||
``` | ||
## Local setup | ||
To set up the project locally, you should install `cargo` and `wasm-pack`: | ||
``` | ||
$ curl https://sh.rustup.rs -sSf | sh | ||
$ cargo install wasm-pack | ||
``` | ||
and project dependencies: | ||
``` | ||
$ npm install | ||
``` | ||
### Build | ||
Build the project with | ||
``` | ||
$ npm run build | ||
``` | ||
It will compile WASM binaries by default | ||
and then it will be possible to run the tests with | ||
``` | ||
$ npm t | ||
``` |
let imports = {}; | ||
imports['__wbindgen_placeholder__'] = module.exports; | ||
let wasm; | ||
const { log, setLogger } = require(String.raw`./snippets/native-iast-rewriter-acbd5d0040d81049/tracer_logger.js`); | ||
const { log, setLogger } = require(String.raw`./snippets/native-iast-rewriter-3c02817c02df886a/tracer_logger.js`); | ||
const { readFileSync } = require(`fs`); | ||
const { dirname } = require(`path`); | ||
const { TextEncoder, TextDecoder } = require(`util`); | ||
const { TextDecoder, TextEncoder } = require(`util`); | ||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); | ||
cachedTextDecoder.decode(); | ||
let cachedUint8Memory0 = null; | ||
function getUint8Memory0() { | ||
if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { | ||
cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); | ||
} | ||
return cachedUint8Memory0; | ||
} | ||
function getStringFromWasm0(ptr, len) { | ||
ptr = ptr >>> 0; | ||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); | ||
} | ||
const heap = new Array(128).fill(undefined); | ||
@@ -13,6 +31,15 @@ | ||
let heap_next = heap.length; | ||
function addHeapObject(obj) { | ||
if (heap_next === heap.length) heap.push(heap.length + 1); | ||
const idx = heap_next; | ||
heap_next = heap[idx]; | ||
heap[idx] = obj; | ||
return idx; | ||
} | ||
function getObject(idx) { return heap[idx]; } | ||
let heap_next = heap.length; | ||
function dropObject(idx) { | ||
@@ -32,11 +59,2 @@ if (idx < 132) return; | ||
let cachedUint8Memory0 = null; | ||
function getUint8Memory0() { | ||
if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { | ||
cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); | ||
} | ||
return cachedUint8Memory0; | ||
} | ||
let cachedTextEncoder = new TextEncoder('utf-8'); | ||
@@ -108,20 +126,2 @@ | ||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); | ||
cachedTextDecoder.decode(); | ||
function getStringFromWasm0(ptr, len) { | ||
ptr = ptr >>> 0; | ||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); | ||
} | ||
function addHeapObject(obj) { | ||
if (heap_next === heap.length) heap.push(heap.length + 1); | ||
const idx = heap_next; | ||
heap_next = heap[idx]; | ||
heap[idx] = obj; | ||
return idx; | ||
} | ||
let cachedFloat64Memory0 = null; | ||
@@ -200,2 +200,7 @@ | ||
} | ||
/** | ||
*/ | ||
module.exports.init = function() { | ||
wasm.init(); | ||
}; | ||
@@ -209,7 +214,2 @@ function handleError(f, args) { | ||
} | ||
/** | ||
*/ | ||
module.exports.init = function() { | ||
wasm.init(); | ||
}; | ||
@@ -318,2 +318,7 @@ let stack_pointer = 128; | ||
module.exports.__wbindgen_error_new = function(arg0, arg1) { | ||
const ret = new Error(getStringFromWasm0(arg0, arg1)); | ||
return addHeapObject(ret); | ||
}; | ||
module.exports.__wbindgen_object_drop_ref = function(arg0) { | ||
@@ -354,29 +359,24 @@ takeObject(arg0); | ||
module.exports.__wbindgen_string_new = function(arg0, arg1) { | ||
const ret = getStringFromWasm0(arg0, arg1); | ||
module.exports.__wbg_readFileSync_d1b76c3c81a689f6 = function() { return handleError(function (arg0, arg1) { | ||
const ret = readFileSync(getStringFromWasm0(arg0, arg1)); | ||
return addHeapObject(ret); | ||
}; | ||
module.exports.__wbg_log_1e5b8fc0542531be = function() { return handleError(function (arg0, arg1) { | ||
const ret = log(getObject(arg0), getObject(arg1)); | ||
return addHeapObject(ret); | ||
}, arguments) }; | ||
module.exports.__wbg_readFileSync_aa285b429e2cd22b = function() { return handleError(function (arg0, arg1) { | ||
const ret = readFileSync(getStringFromWasm0(arg0, arg1)); | ||
module.exports.__wbg_dirname_6a29e623f78f12a3 = function() { return handleError(function (arg0, arg1) { | ||
const ret = dirname(getStringFromWasm0(arg0, arg1)); | ||
return addHeapObject(ret); | ||
}, arguments) }; | ||
module.exports.__wbg_dirname_58fb94654ffa26ce = function() { return handleError(function (arg0, arg1) { | ||
const ret = dirname(getStringFromWasm0(arg0, arg1)); | ||
module.exports.__wbg_setLogger_73de3e1aa22b4d27 = function() { return handleError(function (arg0) { | ||
const ret = setLogger(getObject(arg0)); | ||
return addHeapObject(ret); | ||
}, arguments) }; | ||
module.exports.__wbindgen_error_new = function(arg0, arg1) { | ||
const ret = new Error(getStringFromWasm0(arg0, arg1)); | ||
module.exports.__wbindgen_string_new = function(arg0, arg1) { | ||
const ret = getStringFromWasm0(arg0, arg1); | ||
return addHeapObject(ret); | ||
}; | ||
module.exports.__wbg_setLogger_c5129afd2a443f10 = function() { return handleError(function (arg0) { | ||
const ret = setLogger(getObject(arg0)); | ||
module.exports.__wbg_log_95d827da01cfa979 = function() { return handleError(function (arg0, arg1) { | ||
const ret = log(getObject(arg0), getObject(arg1)); | ||
return addHeapObject(ret); | ||
@@ -383,0 +383,0 @@ }, arguments) }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
1192
106
2196430
2
+ Addedlru-cache@^7.14.0
+ Addedlru-cache@7.18.3(transitive)