improve and fix bugs and add Form Flow Sources test files

This commit is contained in:
amammad
2023-10-06 21:01:42 +02:00
parent eef8137166
commit e45268cd4d
8 changed files with 395 additions and 7 deletions

View File

@@ -20,7 +20,7 @@ module BusBoy {
// Files
busboyOnEvent.getParameter(0).asSink().mayHaveStringValue("file") and
// second param of 'file' event is a Readable stream
this = readableStreamDataNode(busboyOnEvent.getParameter(1).getParameter(1)).asSource()
this = readableStreamDataNode(busboyOnEvent.getParameter(1).getParameter(1))
or
// Fields
busboyOnEvent.getParameter(0).asSink().mayHaveStringValue(["file", "field"]) and
@@ -53,6 +53,15 @@ module BusBoy {
}
}
predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(API::Node busboyOnEvent |
busboyOnEvent = API::moduleImport("busboy").getReturn().getMember("on")
|
busboyOnEvent.getParameter(0).asSink().mayHaveStringValue("file") and
customStreamPipeAdditionalTaintStep(busboyOnEvent.getParameter(1).getParameter(1), pred, succ)
)
}
/**
* A module for modeling [formidable](https://www.npmjs.com/package/formidable) package
*/
@@ -112,7 +121,7 @@ module Multiparty {
this = on.getParameter(1).getParameter([0, 1]).asSource()
or
on.getParameter(0).asSink().mayHaveStringValue("part") and
this = readableStreamDataNode(on.getParameter(1).getParameter(0)).asSource()
this = readableStreamDataNode(on.getParameter(1).getParameter(0))
)
)
)
@@ -150,7 +159,7 @@ module Dicer {
exists(API::Node dicer | dicer = API::moduleImport("dicer").getInstance() |
exists(API::Node on | on = dicer.getMember("on") |
on.getParameter(0).asSink().mayHaveStringValue("part") and
this = readableStreamDataNode(on.getParameter(1).getParameter(0)).asSource()
this = readableStreamDataNode(on.getParameter(1).getParameter(0))
or
exists(API::Node onPart | onPart = on.getParameter(1).getParameter(0).getMember("on") |
onPart.getParameter(0).asSink().mayHaveStringValue("header") and
@@ -177,3 +186,14 @@ module Dicer {
}
}
}
/**
* An Additional taint step like `for (succ in pred)`
*/
private class AdditionalTaintStepForIn extends TaintTracking::SharedTaintStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(ForInStmt fis, Variable v | v = fis.getAnIterationVariable() |
succ.asExpr() = v.getAnAccess() and pred.asExpr() = fis.getIterationDomain()
)
}
}

View File

@@ -117,18 +117,20 @@ API::Node nodeJsStream() {
* Gets a Readable Stream method(not a return value of the method)
* and returns all nodes responsible for a data read access
*/
API::Node readableStreamDataNode(API::Node stream) {
DataFlow::Node readableStreamDataNode(API::Node stream) {
result = stream.asSource()
or
// 'data' event
exists(API::CallNode onEvent | onEvent = stream.getMember("on").getACall() |
result = onEvent.getParameter(1).getParameter(0) and
result = onEvent.getParameter(1).getParameter(0).asSource() and
onEvent.getParameter(0).asSink().mayHaveStringValue("data")
)
or
// 'Readable' event
exists(API::CallNode onEvent | onEvent = stream.getMember("on").getACall() |
(
result = onEvent.getParameter(1).getReceiver().getMember("read").getReturn() or
result = stream.getMember("read").getReturn()
result = onEvent.getParameter(1).getReceiver().getMember("read").getReturn().asSource() or
result = stream.getMember("read").getReturn().asSource()
) and
onEvent.getParameter(0).asSink().mayHaveStringValue("readable")
)

View File

@@ -0,0 +1,234 @@
nodes
| busybus.js:9:30:9:33 | file |
| busybus.js:9:30:9:33 | file |
| busybus.js:9:36:9:39 | info |
| busybus.js:9:36:9:39 | info |
| busybus.js:10:19:10:50 | { filen ... eType } |
| busybus.js:10:19:10:57 | encoding |
| busybus.js:10:19:10:57 | filename |
| busybus.js:10:19:10:57 | mimeType |
| busybus.js:10:21:10:28 | filename |
| busybus.js:10:31:10:38 | encoding |
| busybus.js:10:41:10:48 | mimeType |
| busybus.js:10:54:10:57 | info |
| busybus.js:12:18:12:25 | filename |
| busybus.js:12:18:12:25 | filename |
| busybus.js:12:28:12:35 | encoding |
| busybus.js:12:28:12:35 | encoding |
| busybus.js:12:38:12:45 | mimeType |
| busybus.js:12:38:12:45 | mimeType |
| busybus.js:13:23:13:23 | z |
| busybus.js:13:31:13:36 | sink() |
| busybus.js:13:31:13:36 | sink() |
| busybus.js:15:30:15:33 | data |
| busybus.js:15:30:15:33 | data |
| busybus.js:16:22:16:25 | data |
| busybus.js:16:22:16:25 | data |
| busybus.js:22:25:22:42 | data |
| busybus.js:22:32:22:42 | this.read() |
| busybus.js:22:32:22:42 | this.read() |
| busybus.js:23:26:23:29 | data |
| busybus.js:23:26:23:29 | data |
| busybus.js:27:25:27:28 | name |
| busybus.js:27:25:27:28 | name |
| busybus.js:27:31:27:33 | val |
| busybus.js:27:31:27:33 | val |
| busybus.js:27:36:27:39 | info |
| busybus.js:27:36:27:39 | info |
| busybus.js:28:18:28:21 | name |
| busybus.js:28:18:28:21 | name |
| busybus.js:28:24:28:26 | val |
| busybus.js:28:24:28:26 | val |
| busybus.js:28:29:28:32 | info |
| busybus.js:28:29:28:32 | info |
| dicer.js:12:23:12:26 | part |
| dicer.js:12:23:12:26 | part |
| dicer.js:13:19:13:24 | sink() |
| dicer.js:13:19:13:24 | sink() |
| dicer.js:14:28:14:33 | header |
| dicer.js:14:28:14:33 | header |
| dicer.js:15:23:15:28 | header |
| dicer.js:16:22:16:22 | h |
| dicer.js:16:22:16:22 | h |
| dicer.js:19:26:19:29 | data |
| dicer.js:19:26:19:29 | data |
| dicer.js:20:18:20:21 | data |
| dicer.js:20:18:20:21 | data |
| formidable.js:7:11:7:25 | [fields, files] |
| formidable.js:7:11:7:49 | fields |
| formidable.js:7:11:7:49 | files |
| formidable.js:7:12:7:17 | fields |
| formidable.js:7:20:7:24 | files |
| formidable.js:7:29:7:49 | await f ... se(req) |
| formidable.js:7:35:7:49 | form.parse(req) |
| formidable.js:7:35:7:49 | form.parse(req) |
| formidable.js:8:10:8:15 | fields |
| formidable.js:8:10:8:15 | fields |
| formidable.js:8:18:8:22 | files |
| formidable.js:8:18:8:22 | files |
| formidable.js:9:27:9:34 | formname |
| formidable.js:9:27:9:34 | formname |
| formidable.js:9:37:9:40 | file |
| formidable.js:9:37:9:40 | file |
| formidable.js:10:14:10:21 | formname |
| formidable.js:10:14:10:21 | formname |
| formidable.js:10:24:10:27 | file |
| formidable.js:10:24:10:27 | file |
| formidable.js:12:22:12:29 | formname |
| formidable.js:12:22:12:29 | formname |
| formidable.js:12:32:12:35 | file |
| formidable.js:12:32:12:35 | file |
| formidable.js:13:14:13:21 | formname |
| formidable.js:13:14:13:21 | formname |
| formidable.js:13:24:13:27 | file |
| formidable.js:13:24:13:27 | file |
| formidable.js:15:23:15:31 | fieldName |
| formidable.js:15:23:15:31 | fieldName |
| formidable.js:15:34:15:43 | fieldValue |
| formidable.js:15:34:15:43 | fieldValue |
| formidable.js:16:14:16:22 | fieldName |
| formidable.js:16:14:16:22 | fieldName |
| formidable.js:16:25:16:34 | fieldValue |
| formidable.js:16:25:16:34 | fieldValue |
| multiparty.js:8:22:8:25 | part |
| multiparty.js:8:22:8:25 | part |
| multiparty.js:9:14:9:17 | part |
| multiparty.js:9:14:9:17 | part |
| multiparty.js:10:19:10:24 | sink() |
| multiparty.js:10:19:10:24 | sink() |
| multiparty.js:14:37:14:42 | fields |
| multiparty.js:14:37:14:42 | fields |
| multiparty.js:14:45:14:49 | files |
| multiparty.js:14:45:14:49 | files |
| multiparty.js:15:14:15:19 | fields |
| multiparty.js:15:14:15:19 | fields |
| multiparty.js:15:22:15:26 | files |
| multiparty.js:15:22:15:26 | files |
edges
| busybus.js:9:30:9:33 | file | busybus.js:13:23:13:23 | z |
| busybus.js:9:30:9:33 | file | busybus.js:13:23:13:23 | z |
| busybus.js:9:36:9:39 | info | busybus.js:10:54:10:57 | info |
| busybus.js:9:36:9:39 | info | busybus.js:10:54:10:57 | info |
| busybus.js:10:19:10:50 | { filen ... eType } | busybus.js:10:21:10:28 | filename |
| busybus.js:10:19:10:50 | { filen ... eType } | busybus.js:10:31:10:38 | encoding |
| busybus.js:10:19:10:50 | { filen ... eType } | busybus.js:10:41:10:48 | mimeType |
| busybus.js:10:19:10:57 | encoding | busybus.js:12:28:12:35 | encoding |
| busybus.js:10:19:10:57 | encoding | busybus.js:12:28:12:35 | encoding |
| busybus.js:10:19:10:57 | filename | busybus.js:12:18:12:25 | filename |
| busybus.js:10:19:10:57 | filename | busybus.js:12:18:12:25 | filename |
| busybus.js:10:19:10:57 | mimeType | busybus.js:12:38:12:45 | mimeType |
| busybus.js:10:19:10:57 | mimeType | busybus.js:12:38:12:45 | mimeType |
| busybus.js:10:21:10:28 | filename | busybus.js:10:19:10:57 | filename |
| busybus.js:10:31:10:38 | encoding | busybus.js:10:19:10:57 | encoding |
| busybus.js:10:41:10:48 | mimeType | busybus.js:10:19:10:57 | mimeType |
| busybus.js:10:54:10:57 | info | busybus.js:10:19:10:50 | { filen ... eType } |
| busybus.js:13:23:13:23 | z | busybus.js:13:31:13:36 | sink() |
| busybus.js:13:23:13:23 | z | busybus.js:13:31:13:36 | sink() |
| busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data |
| busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data |
| busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data |
| busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data |
| busybus.js:22:25:22:42 | data | busybus.js:23:26:23:29 | data |
| busybus.js:22:25:22:42 | data | busybus.js:23:26:23:29 | data |
| busybus.js:22:32:22:42 | this.read() | busybus.js:22:25:22:42 | data |
| busybus.js:22:32:22:42 | this.read() | busybus.js:22:25:22:42 | data |
| busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name |
| busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name |
| busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name |
| busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name |
| busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val |
| busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val |
| busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val |
| busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val |
| busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info |
| busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info |
| busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info |
| busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info |
| dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() |
| dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() |
| dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() |
| dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() |
| dicer.js:14:28:14:33 | header | dicer.js:15:23:15:28 | header |
| dicer.js:14:28:14:33 | header | dicer.js:15:23:15:28 | header |
| dicer.js:15:23:15:28 | header | dicer.js:16:22:16:22 | h |
| dicer.js:15:23:15:28 | header | dicer.js:16:22:16:22 | h |
| dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data |
| dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data |
| dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data |
| dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data |
| formidable.js:7:11:7:25 | [fields, files] | formidable.js:7:12:7:17 | fields |
| formidable.js:7:11:7:25 | [fields, files] | formidable.js:7:20:7:24 | files |
| formidable.js:7:11:7:49 | fields | formidable.js:8:10:8:15 | fields |
| formidable.js:7:11:7:49 | fields | formidable.js:8:10:8:15 | fields |
| formidable.js:7:11:7:49 | files | formidable.js:8:18:8:22 | files |
| formidable.js:7:11:7:49 | files | formidable.js:8:18:8:22 | files |
| formidable.js:7:12:7:17 | fields | formidable.js:7:11:7:49 | fields |
| formidable.js:7:20:7:24 | files | formidable.js:7:11:7:49 | files |
| formidable.js:7:29:7:49 | await f ... se(req) | formidable.js:7:11:7:25 | [fields, files] |
| formidable.js:7:35:7:49 | form.parse(req) | formidable.js:7:29:7:49 | await f ... se(req) |
| formidable.js:7:35:7:49 | form.parse(req) | formidable.js:7:29:7:49 | await f ... se(req) |
| formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname |
| formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname |
| formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname |
| formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname |
| formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file |
| formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file |
| formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file |
| formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file |
| formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname |
| formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname |
| formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname |
| formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname |
| formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file |
| formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file |
| formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file |
| formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file |
| formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName |
| formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName |
| formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName |
| formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName |
| formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue |
| formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue |
| formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue |
| formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue |
| multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part |
| multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part |
| multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part |
| multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part |
| multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() |
| multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() |
| multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() |
| multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() |
| multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields |
| multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields |
| multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields |
| multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields |
| multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files |
| multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files |
| multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files |
| multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files |
#select
| busybus.js:12:18:12:25 | filename | busybus.js:9:36:9:39 | info | busybus.js:12:18:12:25 | filename | This entity depends on a $@. | busybus.js:9:36:9:39 | info | user-provided value |
| busybus.js:12:28:12:35 | encoding | busybus.js:9:36:9:39 | info | busybus.js:12:28:12:35 | encoding | This entity depends on a $@. | busybus.js:9:36:9:39 | info | user-provided value |
| busybus.js:12:38:12:45 | mimeType | busybus.js:9:36:9:39 | info | busybus.js:12:38:12:45 | mimeType | This entity depends on a $@. | busybus.js:9:36:9:39 | info | user-provided value |
| busybus.js:13:31:13:36 | sink() | busybus.js:9:30:9:33 | file | busybus.js:13:31:13:36 | sink() | This entity depends on a $@. | busybus.js:9:30:9:33 | file | user-provided value |
| busybus.js:16:22:16:25 | data | busybus.js:15:30:15:33 | data | busybus.js:16:22:16:25 | data | This entity depends on a $@. | busybus.js:15:30:15:33 | data | user-provided value |
| busybus.js:23:26:23:29 | data | busybus.js:22:32:22:42 | this.read() | busybus.js:23:26:23:29 | data | This entity depends on a $@. | busybus.js:22:32:22:42 | this.read() | user-provided value |
| busybus.js:28:18:28:21 | name | busybus.js:27:25:27:28 | name | busybus.js:28:18:28:21 | name | This entity depends on a $@. | busybus.js:27:25:27:28 | name | user-provided value |
| busybus.js:28:24:28:26 | val | busybus.js:27:31:27:33 | val | busybus.js:28:24:28:26 | val | This entity depends on a $@. | busybus.js:27:31:27:33 | val | user-provided value |
| busybus.js:28:29:28:32 | info | busybus.js:27:36:27:39 | info | busybus.js:28:29:28:32 | info | This entity depends on a $@. | busybus.js:27:36:27:39 | info | user-provided value |
| dicer.js:13:19:13:24 | sink() | dicer.js:12:23:12:26 | part | dicer.js:13:19:13:24 | sink() | This entity depends on a $@. | dicer.js:12:23:12:26 | part | user-provided value |
| dicer.js:16:22:16:22 | h | dicer.js:14:28:14:33 | header | dicer.js:16:22:16:22 | h | This entity depends on a $@. | dicer.js:14:28:14:33 | header | user-provided value |
| dicer.js:20:18:20:21 | data | dicer.js:19:26:19:29 | data | dicer.js:20:18:20:21 | data | This entity depends on a $@. | dicer.js:19:26:19:29 | data | user-provided value |
| formidable.js:8:10:8:15 | fields | formidable.js:7:35:7:49 | form.parse(req) | formidable.js:8:10:8:15 | fields | This entity depends on a $@. | formidable.js:7:35:7:49 | form.parse(req) | user-provided value |
| formidable.js:8:18:8:22 | files | formidable.js:7:35:7:49 | form.parse(req) | formidable.js:8:18:8:22 | files | This entity depends on a $@. | formidable.js:7:35:7:49 | form.parse(req) | user-provided value |
| formidable.js:10:14:10:21 | formname | formidable.js:9:27:9:34 | formname | formidable.js:10:14:10:21 | formname | This entity depends on a $@. | formidable.js:9:27:9:34 | formname | user-provided value |
| formidable.js:10:24:10:27 | file | formidable.js:9:37:9:40 | file | formidable.js:10:24:10:27 | file | This entity depends on a $@. | formidable.js:9:37:9:40 | file | user-provided value |
| formidable.js:13:14:13:21 | formname | formidable.js:12:22:12:29 | formname | formidable.js:13:14:13:21 | formname | This entity depends on a $@. | formidable.js:12:22:12:29 | formname | user-provided value |
| formidable.js:13:24:13:27 | file | formidable.js:12:32:12:35 | file | formidable.js:13:24:13:27 | file | This entity depends on a $@. | formidable.js:12:32:12:35 | file | user-provided value |
| formidable.js:16:14:16:22 | fieldName | formidable.js:15:23:15:31 | fieldName | formidable.js:16:14:16:22 | fieldName | This entity depends on a $@. | formidable.js:15:23:15:31 | fieldName | user-provided value |
| formidable.js:16:25:16:34 | fieldValue | formidable.js:15:34:15:43 | fieldValue | formidable.js:16:25:16:34 | fieldValue | This entity depends on a $@. | formidable.js:15:34:15:43 | fieldValue | user-provided value |
| multiparty.js:9:14:9:17 | part | multiparty.js:8:22:8:25 | part | multiparty.js:9:14:9:17 | part | This entity depends on a $@. | multiparty.js:8:22:8:25 | part | user-provided value |
| multiparty.js:10:19:10:24 | sink() | multiparty.js:8:22:8:25 | part | multiparty.js:10:19:10:24 | sink() | This entity depends on a $@. | multiparty.js:8:22:8:25 | part | user-provided value |
| multiparty.js:15:14:15:19 | fields | multiparty.js:14:37:14:42 | fields | multiparty.js:15:14:15:19 | fields | This entity depends on a $@. | multiparty.js:14:37:14:42 | fields | user-provided value |
| multiparty.js:15:22:15:26 | files | multiparty.js:14:45:14:49 | files | multiparty.js:15:22:15:26 | files | This entity depends on a $@. | multiparty.js:14:45:14:49 | files | user-provided value |

View File

@@ -0,0 +1,33 @@
/**
* @name Remote Form Flow Sources
* @description Using remote user controlled sources from Forms
* @kind path-problem
* @problem.severity error
* @security-severity 5
* @precision high
* @id js/remote-flow-source
* @tags correctness
* security
*/
import javascript
import DataFlow::PathGraph
/**
* A taint-tracking configuration for test
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "RemoteFlowSourcesOUserForm" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
sink = API::moduleImport("sink").getAParameter().asSink() or
sink = API::moduleImport("sink").getReturn().asSource()
}
}
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "This entity depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -0,0 +1,33 @@
const http = require('http');
const zlib = require('node:zlib');
const busboy = require('busboy');
const sink = require('sink');
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({ headers: req.headers });
bb.on('file', (name, file, info) => {
const { filename, encoding, mimeType } = info;
const z = zlib.createGzip();
sink(filename, encoding, mimeType) // sink
file.pipe(z).pipe(sink())
file.on('data', (data) => {
sink(data)
})
file.on('readable', function () {
// There is some data to read now.
let data;
while ((data = this.read()) !== null) {
sink(data)
}
});
});
bb.on('field', (name, val, info) => {
sink(name, val, info)
});
}
}).listen(8000, () => {
console.log('Listening for requests');
});

View File

@@ -0,0 +1,25 @@
const { inspect } = require('util');
const http = require('http');
const Dicer = require('dicer');
const sink = require('sink');
const PORT = 8080;
http.createServer((req, res) => {
let m;
const dicer = new Dicer({ boundary: m[1] || m[2] });
dicer.on('part', (part) => {
part.pipe(sink())
part.on('header', (header) => {
for (h in header) {
sink(h)
}
});
part.on('data', (data) => {
sink(data)
});
});
}).listen(PORT, () => {
console.log(`Listening for requests on port ${PORT}`);
});

View File

@@ -0,0 +1,22 @@
import http from 'node:http';
import formidable from 'formidable';
const sink = require('sink');
const server = http.createServer(async (req, res) => {
const form = formidable({});
const [fields, files] = await form.parse(req);
sink(fields, files)
form.on('fileBegin', (formname, file) => {
sink(formname, file)
});
form.on('file', (formname, file) => {
sink(formname, file)
});
form.on('field', (fieldName, fieldValue) => {
sink(fieldName, fieldValue)
});
});
server.listen(8080, () => {
console.log('Server listening on http://localhost:8080/ ...');
});

View File

@@ -0,0 +1,19 @@
var multiparty = require('multiparty');
var http = require('http');
var util = require('util');
const sink = require('sink');
http.createServer(function (req, res) {
var form = new multiparty.Form();
form.on('part', (part) => {
sink(part)
part.pipe(sink())
});
var form2 = new multiparty.Form();
form2.parse(req, function (err, fields, files) {
sink(fields, files)
});
form2.parse(req);
}).listen(8080);