mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
@@ -4,6 +4,23 @@
|
||||
|
||||
import javascript
|
||||
|
||||
/**
|
||||
* A call that can produce a file name.
|
||||
*/
|
||||
abstract private class FileNameProducer extends DataFlow::Node {
|
||||
/**
|
||||
* Gets a file name produced by this producer.
|
||||
*/
|
||||
abstract DataFlow::Node getAFileName();
|
||||
}
|
||||
|
||||
/**
|
||||
* A node that contains a file name, and is produced by a `ProducesFileNames`.
|
||||
*/
|
||||
private class ProducedFileName extends FileNameSource {
|
||||
ProducedFileName() { this = any(FileNameProducer producer).getAFileName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A file name from the `walk-sync` library.
|
||||
*/
|
||||
@@ -106,3 +123,143 @@ private class FastGlobFileNameSource extends FileNameSource {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Classes and predicates for modelling the `fstream` library (https://www.npmjs.com/package/fstream).
|
||||
*/
|
||||
private module FStream {
|
||||
/**
|
||||
* Gets a reference to a method in the `fstream` library.
|
||||
*/
|
||||
private DataFlow::SourceNode getAnFStreamProperty() {
|
||||
exists(DataFlow::SourceNode mod, string readOrWrite, string subMod |
|
||||
mod = DataFlow::moduleImport("fstream") and
|
||||
(readOrWrite = "Reader" or readOrWrite = "Writer") and
|
||||
(subMod = "File" or subMod = "Dir" or subMod = "Link" or subMod = "Proxy")
|
||||
|
|
||||
result = mod.getAPropertyRead(readOrWrite) or
|
||||
result = mod.getAPropertyRead(readOrWrite).getAPropertyRead(subMod) or
|
||||
result = mod.getAPropertyRead(subMod).getAPropertyRead(readOrWrite)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An invocation of a method defined in the `fstream` library.
|
||||
*/
|
||||
private class FStream extends FileSystemAccess, DataFlow::InvokeNode {
|
||||
FStream() { this = getAnFStreamProperty().getAnInvocation() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = getOptionArgument(0, "path")
|
||||
or
|
||||
not exists(getOptionArgument(0, "path")) and
|
||||
result = getArgument(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the library `write-file-atomic`.
|
||||
*/
|
||||
private class WriteFileAtomic extends FileSystemWriteAccess, DataFlow::CallNode {
|
||||
WriteFileAtomic() {
|
||||
this = DataFlow::moduleImport("write-file-atomic").getACall()
|
||||
or
|
||||
this = DataFlow::moduleMember("write-file-atomic", "sync").getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = getArgument(0) }
|
||||
|
||||
override DataFlow::Node getADataNode() { result = getArgument(1) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the library `recursive-readdir`.
|
||||
*/
|
||||
private class RecursiveReadDir extends FileSystemAccess, FileNameProducer, DataFlow::CallNode {
|
||||
RecursiveReadDir() { this = DataFlow::moduleImport("recursive-readdir").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = getArgument(0) }
|
||||
|
||||
override DataFlow::Node getAFileName() { result = getCallback([1 .. 2]).getParameter(1) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Classes and predicates for modelling the `jsonfile` library (https://www.npmjs.com/package/jsonfile).
|
||||
*/
|
||||
private module JSONFile {
|
||||
/**
|
||||
* A reader for JSON files.
|
||||
*/
|
||||
class JSONFileReader extends FileSystemReadAccess, DataFlow::CallNode {
|
||||
JSONFileReader() {
|
||||
this =
|
||||
DataFlow::moduleMember("jsonfile", any(string s | s = "readFile" or s = "readFileSync"))
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = getArgument(0) }
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
this.getCalleeName() = "readFile" and result = getCallback([1 .. 2]).getParameter(1)
|
||||
or
|
||||
this.getCalleeName() = "readFileSync" and result = this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A writer for JSON files.
|
||||
*/
|
||||
class JSONFileWriter extends FileSystemWriteAccess, DataFlow::CallNode {
|
||||
JSONFileWriter() {
|
||||
this =
|
||||
DataFlow::moduleMember("jsonfile", any(string s | s = "writeFile" or s = "writeFileSync"))
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = getArgument(0) }
|
||||
|
||||
override DataFlow::Node getADataNode() { result = getArgument(1) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A file system access made by a NodeJS library.
|
||||
* This class models multiple NodeJS libraries that access files.
|
||||
*/
|
||||
private class LibraryAccess extends FileSystemAccess, DataFlow::InvokeNode {
|
||||
int pathArgument; // The index of the path argument.
|
||||
|
||||
LibraryAccess() {
|
||||
pathArgument = 0 and
|
||||
(
|
||||
this = DataFlow::moduleImport("path-exists").getACall()
|
||||
or
|
||||
this = DataFlow::moduleImport("rimraf").getACall()
|
||||
or
|
||||
this =
|
||||
DataFlow::moduleMember("node-dir",
|
||||
any(string s |
|
||||
s = "readFiles" or
|
||||
s = "readFilesStream" or
|
||||
s = "files" or
|
||||
s = "promiseFiles" or
|
||||
s = "subdirs" or
|
||||
s = "paths"
|
||||
)).getACall()
|
||||
)
|
||||
or
|
||||
pathArgument = 0 and
|
||||
this =
|
||||
DataFlow::moduleMember("vinyl-fs", any(string s | s = "src" or s = "dest" or s = "symlink"))
|
||||
.getACall()
|
||||
or
|
||||
pathArgument = [0 .. 1] and
|
||||
(
|
||||
this = DataFlow::moduleImport("ncp").getACall() or
|
||||
this = DataFlow::moduleMember("ncp", "ncp").getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = getArgument(pathArgument) }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
getPathArgument
|
||||
| file-access.js:3:1:4:34 | fstream ... file"}) | file-access.js:4:19:4:32 | "path/to/file" |
|
||||
| file-access.js:8:1:9:24 | fstream ... o/dir") | file-access.js:9:11:9:23 | "path/to/dir" |
|
||||
| file-access.js:10:9:10:43 | fstream ... r/dir") | file-access.js:10:24:10:42 | "path/to/other/dir" |
|
||||
| file-access.js:15:1:15:60 | writeFi ... rr) {}) | file-access.js:15:17:15:28 | 'atmoic.txt' |
|
||||
| file-access.js:18:1:18:59 | writeFi ... tions]) | file-access.js:18:21:18:34 | "syncFile.txt" |
|
||||
| file-access.js:22:1:22:48 | recursi ... es) {}) | file-access.js:22:11:22:21 | "some/path" |
|
||||
| file-access.js:25:1:25:59 | jsonfil ... bj) {}) | file-access.js:25:19:25:34 | '/tmp/data.json' |
|
||||
| file-access.js:26:1:26:39 | jsonfil ... .json') | file-access.js:26:23:26:38 | '/tmp/data.json' |
|
||||
| file-access.js:28:1:28:60 | jsonfil ... rr) {}) | file-access.js:28:20:28:35 | '/tmp/data.json' |
|
||||
| file-access.js:29:1:29:45 | jsonfil ... ', obj) | file-access.js:29:24:29:39 | '/tmp/data.json' |
|
||||
| file-access.js:34:4:34:23 | pathExists('foo.js') | file-access.js:34:15:34:22 | 'foo.js' |
|
||||
| file-access.js:39:1:39:28 | rimraf( ... => {}) | file-access.js:39:8:39:10 | "/" |
|
||||
| file-access.js:42:1:42:59 | dir.rea ... on(){}) | file-access.js:42:15:42:31 | "/some/directory" |
|
||||
| file-access.js:46:1:46:25 | vfs.src ... path"]) | file-access.js:46:9:46:24 | ["some", "path"] |
|
||||
| file-access.js:47:1:47:36 | vfs.des ... true }) | file-access.js:47:10:47:13 | './' |
|
||||
| file-access.js:51:1:51:36 | ncp("fr ... rr) {}) | file-access.js:51:5:51:10 | "from" |
|
||||
| file-access.js:51:1:51:36 | ncp("fr ... rr) {}) | file-access.js:51:13:51:16 | "to" |
|
||||
getReadNode
|
||||
| file-access.js:25:1:25:59 | jsonfil ... bj) {}) | file-access.js:25:52:25:54 | obj |
|
||||
| file-access.js:26:1:26:39 | jsonfil ... .json') | file-access.js:26:1:26:39 | jsonfil ... .json') |
|
||||
getWriteNode
|
||||
| file-access.js:15:1:15:60 | writeFi ... rr) {}) | file-access.js:15:31:15:36 | 'Data' |
|
||||
| file-access.js:18:1:18:59 | writeFi ... tions]) | file-access.js:18:37:18:47 | "More data" |
|
||||
| file-access.js:28:1:28:60 | jsonfil ... rr) {}) | file-access.js:28:38:28:40 | obj |
|
||||
| file-access.js:29:1:29:45 | jsonfil ... ', obj) | file-access.js:29:42:29:44 | obj |
|
||||
@@ -0,0 +1,7 @@
|
||||
import javascript
|
||||
|
||||
query DataFlow::Node getPathArgument(FileSystemAccess access) { result = access.getAPathArgument() }
|
||||
|
||||
query DataFlow::Node getReadNode(FileSystemReadAccess access) { result = access.getADataNode() }
|
||||
|
||||
query DataFlow::Node getWriteNode(FileSystemWriteAccess access) { result = access.getADataNode() }
|
||||
@@ -1,3 +1,4 @@
|
||||
| file-access.js:22:39:22:43 | files |
|
||||
| tst-file-names.js:7:1:7:10 | walkSync() |
|
||||
| tst-file-names.js:9:35:9:44 | stats.name |
|
||||
| tst-file-names.js:11:1:11:12 | glob.sync(_) |
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
var fstream = require("fstream");
|
||||
|
||||
fstream
|
||||
.Writer({ path: "path/to/file"})
|
||||
.write("hello\n")
|
||||
.end()
|
||||
|
||||
fstream
|
||||
.Reader("path/to/dir")
|
||||
.pipe(fstream.Writer("path/to/other/dir"))
|
||||
|
||||
|
||||
var writeFileAtomic= require("write-file-atomic");
|
||||
|
||||
writeFileAtomic('atmoic.txt', 'Data', {}, function (err) {});
|
||||
|
||||
var writeFileAtomicSync = require('write-file-atomic').sync
|
||||
writeFileAtomicSync("syncFile.txt", "More data", [options])
|
||||
|
||||
var recursive = require("recursive-readdir");
|
||||
|
||||
recursive("some/path", function (err, files) {});
|
||||
|
||||
const jsonfile = require('jsonfile');
|
||||
jsonfile.readFile('/tmp/data.json', function (err, obj) {});
|
||||
jsonfile.readFileSync('/tmp/data.json');
|
||||
|
||||
jsonfile.writeFile('/tmp/data.json', obj, function (err) {});
|
||||
jsonfile.writeFileSync('/tmp/data.json', obj);
|
||||
|
||||
|
||||
const pathExists = require('path-exists');
|
||||
|
||||
if(pathExists('foo.js')) {
|
||||
// do something.
|
||||
}
|
||||
|
||||
var rimraf = require("rimraf");
|
||||
rimraf("/", {}, (err) => {});
|
||||
|
||||
var dir = require("node-dir");
|
||||
dir.readFiles("/some/directory",function() {},function(){});
|
||||
|
||||
var vfs = require("vinyl-fs");
|
||||
|
||||
vfs.src(["some", "path"]);
|
||||
vfs.dest('./', { sourcemaps: true });
|
||||
|
||||
|
||||
var ncp = require('ncp').ncp;
|
||||
ncp("from", "to", function (err) {});
|
||||
Reference in New Issue
Block a user