@@ -43,20 +43,19 @@ class ClientRequest extends DataFlow::InvokeNode {
4343 * wrapped in a promise object.
4444 *
4545 * The `responseType` describes how the response is represented as a JavaScript value
46- * (after resolving promises).
47- *
48- * The response type may be any of the values supported by
49- * [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType),
50- * namely `arraybuffer`, `blob`, `document`, `json`, or `text`.
51- *
52- * Additionally, the `responseType` may have one of the following values:
53- * - `fetch.response`: The result is a `Response` object as defined by the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Response).
54- * - `stream`: The result is a Node.js stream
55- * - `error`: The result is an error in an unspecified format, possibly containing information from the response
56- *
57- *
58- * Custom implementations of `ClientRequest` may use other formats.
59- * If the responseType is not known the convention is to use an empty string.
46+ * (after resolving promises), and may assume the following values:
47+ * - Any response type defined by [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType):
48+ * - `text`: The result is a string
49+ * - `json`: The result is a deserialized JSON object
50+ * - `arraybuffer`: The result is an `ArrayBuffer` object
51+ * - `blob`: The result is a `Blob` object
52+ * - `document`: The result is a deserialized HTML or XML document
53+ * - Any of the following additional response types defined by this library:
54+ * - `fetch.response`: The result is a `Response` object from [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Response).
55+ * - `stream`: The result is a Node.js stream and `http.IncomingMessage` object
56+ * - `error`: The result is an error in an unspecified format, possibly containing information from the response
57+ * - An empty string, indicating an unknown response type.
58+ * - Any value provided by custom implementations of `ClientRequest::Range`.
6059 */
6160 DataFlow:: Node getAResponseDataNode ( string responseType , boolean promise ) {
6261 result = self .getAResponseDataNode ( responseType , promise )
@@ -99,7 +98,7 @@ module ClientRequest {
9998 * Gets a data flow node that refers to some representation of the response, possibly
10099 * wrapped in a promise object.
101100 *
102- * See the decription of `responseType` in the corresponding predicate in `ClientRequest`.
101+ * See the decription of `responseType` in `ClientRequest::getAResponseDataNode `.
103102 */
104103 DataFlow:: Node getAResponseDataNode ( string responseType , boolean promise ) { none ( ) }
105104 }
@@ -192,9 +191,19 @@ module ClientRequest {
192191 )
193192 }
194193
194+ private int getOptionsArgIndex ( ) {
195+ method = "request" and
196+ result = 0
197+ or
198+ ( method = "get" or method = "delete" or method = "head" ) and
199+ result = 1
200+ or
201+ ( method = "post" or method = "put" or method = "patch" ) and
202+ result = 2
203+ }
204+
195205 private DataFlow:: Node getOptionArgument ( string name ) {
196- // depends on the method name and the call arity, over-approximating slightly in the name of simplicity
197- result = getOptionArgument ( [ 0 .. 2 ] , name )
206+ result = getOptionArgument ( getOptionsArgIndex ( ) , name )
198207 }
199208
200209 override DataFlow:: Node getUrl ( ) {
@@ -218,15 +227,18 @@ module ClientRequest {
218227
219228 /** Gets the response type from the options passed in. */
220229 string getResponseType ( ) {
221- exists ( DataFlow:: Node option | option = getOptionArgument ( [ 0 .. 2 ] , "responseType" ) |
222- result = option .getStringValue ( )
230+ exists ( DataFlow:: Node option | option = getOptionArgument ( "responseType" ) |
231+ option .mayHaveStringValue ( result )
223232 or
224- not exists ( option .getStringValue ( ) ) and
233+ option .analyze ( ) . getAValue ( ) . isIndefinite ( _ ) and
225234 result = ""
226235 )
227236 or
228- not exists ( getOptionArgument ( [ 0 .. 2 ] , "responseType" ) ) and
237+ not exists ( getOptionArgument ( "responseType" ) ) and
229238 result = "json"
239+ or
240+ getArgument ( getOptionsArgIndex ( ) ) .analyze ( ) .getAValue ( ) .isIndefinite ( _) and
241+ result = ""
230242 }
231243
232244 override DataFlow:: Node getAResponseDataNode ( string responseType , boolean promise ) {
0 commit comments