diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowDispatch.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowDispatch.qll index 48fedd9f466d..f5a0cb85c482 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowDispatch.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowDispatch.qll @@ -79,3 +79,13 @@ class ArgumentPosition extends int { /** Holds if arguments at position `apos` match parameters at position `ppos`. */ pragma[inline] predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } + +/** + * Holds if flow from `call`'s argument `arg` to parameter `p` is permissible. + * + * This is a temporary hook to support technical debt in the Go language; do not use. + */ +pragma[inline] +predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + any() +} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll index e6fce328326c..648d5c2b073a 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll @@ -425,7 +425,8 @@ private module Cached { exists(ParameterPosition ppos | viableParam(call, ppos, p) and argumentPositionMatch(call, arg, ppos) and - compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) + compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and + golangSpecificParamArgFilter(call, p, arg) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll index 7bc51e3e2fcb..707a07deee60 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll @@ -271,3 +271,13 @@ Function viableImplInCallContext(CallInstruction call, CallInstruction ctx) { /** Holds if arguments at position `apos` match parameters at position `ppos`. */ pragma[inline] predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } + +/** + * Holds if flow from `call`'s argument `arg` to parameter `p` is permissible. + * + * This is a temporary hook to support technical debt in the Go language; do not use. + */ +pragma[inline] +predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + any() +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index e6fce328326c..648d5c2b073a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -425,7 +425,8 @@ private module Cached { exists(ParameterPosition ppos | viableParam(call, ppos, p) and argumentPositionMatch(call, arg, ppos) and - compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) + compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and + golangSpecificParamArgFilter(call, p, arg) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll index a6142ce11eea..c9dd4fb9b98b 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll @@ -555,3 +555,13 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { apos.isImplicitCapturedArgumentPosition(v) ) } + +/** + * Holds if flow from `call`'s argument `arg` to parameter `p` is permissible. + * + * This is a temporary hook to support technical debt in the Go language; do not use. + */ +pragma[inline] +predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + any() +} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll index e6fce328326c..648d5c2b073a 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll @@ -425,7 +425,8 @@ private module Cached { exists(ParameterPosition ppos | viableParam(call, ppos, p) and argumentPositionMatch(call, arg, ppos) and - compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) + compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and + golangSpecificParamArgFilter(call, p, arg) ) } diff --git a/go/ql/lib/ext/archive.tar.model.yml b/go/ql/lib/ext/archive.tar.model.yml new file mode 100644 index 000000000000..2ca4d2c93c23 --- /dev/null +++ b/go/ql/lib/ext/archive.tar.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["archive/tar", "", False, "FileInfoHeader", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["archive/tar", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["archive/tar", "Header", True, "FileInfo", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["archive/tar", "Reader", True, "Next", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["archive/tar", "Writer", True, "WriteHeader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/archive.zip.model.yml b/go/ql/lib/ext/archive.zip.model.yml new file mode 100644 index 000000000000..0e9f0b48ffaf --- /dev/null +++ b/go/ql/lib/ext/archive.zip.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["archive/zip", "", False, "FileInfoHeader", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["archive/zip", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["archive/zip", "", False, "OpenReader", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["archive/zip", "File", True, "Open", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["archive/zip", "File", True, "OpenRaw", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["archive/zip", "Writer", True, "Copy", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/archive_tar.model.yml b/go/ql/lib/ext/archive_tar.model.yml deleted file mode 100644 index 9b8fd572bf36..000000000000 --- a/go/ql/lib/ext/archive_tar.model.yml +++ /dev/null @@ -1,6 +0,0 @@ -extensions: - - addsTo: - pack: codeql/go-all - extensible: summaryModel - data: - - ["archive/tar", "", True, "FileInfoHeader", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] \ No newline at end of file diff --git a/go/ql/lib/ext/bufio.model.yml b/go/ql/lib/ext/bufio.model.yml new file mode 100644 index 000000000000..c7d55f149577 --- /dev/null +++ b/go/ql/lib/ext/bufio.model.yml @@ -0,0 +1,22 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["bufio", "", False, "NewReadWriter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bufio", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bufio", "", False, "NewReaderSize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bufio", "", False, "NewScanner", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bufio", "", False, "ScanBytes", "", "", "Argument[0]", "ReturnValue[1]", "taint", "manual"] + - ["bufio", "", False, "ScanLines", "", "", "Argument[0]", "ReturnValue[1]", "taint", "manual"] + - ["bufio", "", False, "ScanRunes", "", "", "Argument[0]", "ReturnValue[1]", "taint", "manual"] + - ["bufio", "", False, "ScanWords", "", "", "Argument[0]", "ReturnValue[1]", "taint", "manual"] + - ["bufio", "Reader", True, "Peek", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["bufio", "Reader", True, "ReadBytes", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["bufio", "Reader", True, "ReadLine", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["bufio", "Reader", True, "ReadSlice", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["bufio", "Reader", True, "ReadString", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["bufio", "Reader", True, "Reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["bufio", "Scanner", True, "Bytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["bufio", "Scanner", True, "Text", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["bufio", "Writer", True, "Reset", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/bytes.model.yml b/go/ql/lib/ext/bytes.model.yml new file mode 100644 index 000000000000..975cc47397be --- /dev/null +++ b/go/ql/lib/ext/bytes.model.yml @@ -0,0 +1,48 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["bytes", "", False, "Clone", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Cut", "", "", "Argument[0]", "ReturnValue[0..1]", "taint", "manual"] + - ["bytes", "", False, "CutPrefix", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["bytes", "", False, "CutSuffix", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["bytes", "", False, "Fields", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "FieldsFunc", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Join", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Map", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "NewBuffer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "NewBufferString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Repeat", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Replace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Replace", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "ReplaceAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "ReplaceAll", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Runes", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Split", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "SplitAfter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "SplitAfterN", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "SplitN", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Title", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "ToLower", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "ToLowerSpecial", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "ToTitle", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "ToTitleSpecial", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "ToUpper", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "ToUpperSpecial", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "ToValidUTF8", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "Trim", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "TrimFunc", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "TrimLeft", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "TrimLeftFunc", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "TrimPrefix", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "TrimRight", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "TrimRightFunc", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "TrimSpace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "", False, "TrimSuffix", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["bytes", "Buffer", True, "Bytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["bytes", "Buffer", True, "Next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["bytes", "Buffer", True, "ReadBytes", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["bytes", "Buffer", True, "ReadString", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["bytes", "Reader", True, "Reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/compress.bzip2.model.yml b/go/ql/lib/ext/compress.bzip2.model.yml new file mode 100644 index 000000000000..38719037de18 --- /dev/null +++ b/go/ql/lib/ext/compress.bzip2.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["compress/bzip2", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/compress.flate.model.yml b/go/ql/lib/ext/compress.flate.model.yml new file mode 100644 index 000000000000..028039c66786 --- /dev/null +++ b/go/ql/lib/ext/compress.flate.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["compress/flate", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["compress/flate", "", False, "NewReaderDict", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["compress/flate", "Resetter", True, "Reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["compress/flate", "Writer", True, "Reset", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/compress.gzip.model.yml b/go/ql/lib/ext/compress.gzip.model.yml new file mode 100644 index 000000000000..bd37d74bbc5b --- /dev/null +++ b/go/ql/lib/ext/compress.gzip.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["compress/gzip", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["compress/gzip", "Reader", True, "Reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["compress/gzip", "Writer", True, "Reset", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/compress.lzw.model.yml b/go/ql/lib/ext/compress.lzw.model.yml new file mode 100644 index 000000000000..5db30e14ec36 --- /dev/null +++ b/go/ql/lib/ext/compress.lzw.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["compress/lzw", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/compress.zlib.model.yml b/go/ql/lib/ext/compress.zlib.model.yml new file mode 100644 index 000000000000..df140e6b862e --- /dev/null +++ b/go/ql/lib/ext/compress.zlib.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["compress/zlib", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["compress/zlib", "", False, "NewReaderDict", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["compress/zlib", "Resetter", True, "Reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["compress/zlib", "Writer", True, "Reset", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/container.heap.model.yml b/go/ql/lib/ext/container.heap.model.yml new file mode 100644 index 000000000000..dc3d5e2c918c --- /dev/null +++ b/go/ql/lib/ext/container.heap.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["container/heap", "", False, "Pop", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["container/heap", "", False, "Push", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["container/heap", "", False, "Remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["container/heap", "Interface", True, "Pop", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["container/heap", "Interface", True, "Push", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/container.list.model.yml b/go/ql/lib/ext/container.list.model.yml new file mode 100644 index 000000000000..f41bddc61d3a --- /dev/null +++ b/go/ql/lib/ext/container.list.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["container/list", "Element", True, "Next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["container/list", "Element", True, "Prev", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["container/list", "List", True, "Back", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["container/list", "List", True, "Front", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["container/list", "List", True, "Init", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["container/list", "List", True, "InsertAfter", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "InsertAfter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["container/list", "List", True, "InsertBefore", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "InsertBefore", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["container/list", "List", True, "MoveAfter", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "MoveBefore", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "MoveToBack", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "MoveToFront", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "PushBack", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "PushBack", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["container/list", "List", True, "PushBackList", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "PushFront", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "PushFront", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["container/list", "List", True, "PushFrontList", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["container/list", "List", True, "Remove", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/container.ring.model.yml b/go/ql/lib/ext/container.ring.model.yml new file mode 100644 index 000000000000..5e815bcd2911 --- /dev/null +++ b/go/ql/lib/ext/container.ring.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["container/ring", "Ring", True, "Link", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["container/ring", "Ring", True, "Move", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["container/ring", "Ring", True, "Next", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["container/ring", "Ring", True, "Prev", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["container/ring", "Ring", True, "Unlink", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/context.model.yml b/go/ql/lib/ext/context.model.yml new file mode 100644 index 000000000000..c134980a1967 --- /dev/null +++ b/go/ql/lib/ext/context.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["context", "", False, "WithCancel", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["context", "", False, "WithDeadline", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["context", "", False, "WithTimeout", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["context", "", False, "WithValue", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["context", "Context", True, "Value", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/crypto.cipher.model.yml b/go/ql/lib/ext/crypto.cipher.model.yml new file mode 100644 index 000000000000..081dd447c027 --- /dev/null +++ b/go/ql/lib/ext/crypto.cipher.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["crypto/cipher", "AEAD", True, "Open", "", "", "Argument[2]", "Argument[0]", "taint", "manual"] + - ["crypto/cipher", "AEAD", True, "Open", "", "", "Argument[2]", "ReturnValue[0]", "taint", "manual"] + - ["crypto/cipher", "Block", True, "Decrypt", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/crypto.model.yml b/go/ql/lib/ext/crypto.model.yml new file mode 100644 index 000000000000..353c965df2f0 --- /dev/null +++ b/go/ql/lib/ext/crypto.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["crypto", "Decrypter", True, "Decrypt", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/crypto.rsa.model.yml b/go/ql/lib/ext/crypto.rsa.model.yml new file mode 100644 index 000000000000..851251973a62 --- /dev/null +++ b/go/ql/lib/ext/crypto.rsa.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["crypto/rsa", "", False, "DecryptOAEP", "", "", "Argument[3]", "ReturnValue[0]", "taint", "manual"] + - ["crypto/rsa", "", False, "DecryptPKCS1v15", "", "", "Argument[2]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/crypto.tls.model.yml b/go/ql/lib/ext/crypto.tls.model.yml new file mode 100644 index 000000000000..ecb4c8859946 --- /dev/null +++ b/go/ql/lib/ext/crypto.tls.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["crypto/tls", "", False, "Client", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["crypto/tls", "", False, "NewListener", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["crypto/tls", "", False, "Server", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/crypto.x509.model.yml b/go/ql/lib/ext/crypto.x509.model.yml new file mode 100644 index 000000000000..dd16777a75b7 --- /dev/null +++ b/go/ql/lib/ext/crypto.x509.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["crypto/x509", "", False, "DecryptPEMBlock", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/database.sql.driver.model.yml b/go/ql/lib/ext/database.sql.driver.model.yml new file mode 100644 index 000000000000..473439fb173a --- /dev/null +++ b/go/ql/lib/ext/database.sql.driver.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["database/sql/driver", "Conn", True, "Prepare", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["database/sql/driver", "ConnPrepareContext", True, "PrepareContext", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] + - ["database/sql/driver", "ValueConverter", True, "ConvertValue", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["database/sql/driver", "Valuer", True, "Value", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/database.sql.model.yml b/go/ql/lib/ext/database.sql.model.yml new file mode 100644 index 000000000000..bb4dc1a612d5 --- /dev/null +++ b/go/ql/lib/ext/database.sql.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["database/sql", "", False, "Named", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["database/sql", "Conn", True, "PrepareContext", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] + - ["database/sql", "DB", True, "Prepare", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["database/sql", "DB", True, "PrepareContext", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] + - ["database/sql", "Scanner", True, "Scan", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["database/sql", "Tx", True, "Prepare", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["database/sql", "Tx", True, "PrepareContext", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.ascii85.model.yml b/go/ql/lib/ext/encoding.ascii85.model.yml new file mode 100644 index 000000000000..51c15078176b --- /dev/null +++ b/go/ql/lib/ext/encoding.ascii85.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/ascii85", "", False, "Decode", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["encoding/ascii85", "", False, "NewDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.asn1.model.yml b/go/ql/lib/ext/encoding.asn1.model.yml new file mode 100644 index 000000000000..e0c08cc216ef --- /dev/null +++ b/go/ql/lib/ext/encoding.asn1.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/asn1", "", False, "Marshal", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/asn1", "", False, "MarshalWithParams", "", "", "Argument[0..1]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/asn1", "", False, "Unmarshal", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["encoding/asn1", "", False, "Unmarshal", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/asn1", "", False, "UnmarshalWithParams", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["encoding/asn1", "", False, "UnmarshalWithParams", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/asn1", "", False, "UnmarshalWithParams", "", "", "Argument[2]", "Argument[1]", "taint", "manual"] + - ["encoding/asn1", "", False, "UnmarshalWithParams", "", "", "Argument[2]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.base32.model.yml b/go/ql/lib/ext/encoding.base32.model.yml new file mode 100644 index 000000000000..5cabdb05a414 --- /dev/null +++ b/go/ql/lib/ext/encoding.base32.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/base32", "", False, "NewDecoder", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["encoding/base32", "Encoding", True, "Decode", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["encoding/base32", "Encoding", True, "DecodeString", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.base64.model.yml b/go/ql/lib/ext/encoding.base64.model.yml new file mode 100644 index 000000000000..1e199c5f4692 --- /dev/null +++ b/go/ql/lib/ext/encoding.base64.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/base64", "", False, "NewDecoder", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["encoding/base64", "Encoding", True, "Decode", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["encoding/base64", "Encoding", True, "DecodeString", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.binary.model.yml b/go/ql/lib/ext/encoding.binary.model.yml new file mode 100644 index 000000000000..34705c1364ed --- /dev/null +++ b/go/ql/lib/ext/encoding.binary.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/binary", "", False, "Read", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["encoding/binary", "", False, "Write", "", "", "Argument[2]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.csv.model.yml b/go/ql/lib/ext/encoding.csv.model.yml new file mode 100644 index 000000000000..2107e3d784dd --- /dev/null +++ b/go/ql/lib/ext/encoding.csv.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/csv", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["encoding/csv", "Reader", True, "Read", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/csv", "Reader", True, "ReadAll", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/csv", "Writer", True, "Write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["encoding/csv", "Writer", True, "WriteAll", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.gob.model.yml b/go/ql/lib/ext/encoding.gob.model.yml new file mode 100644 index 000000000000..b999cf874606 --- /dev/null +++ b/go/ql/lib/ext/encoding.gob.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/gob", "", False, "NewDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["encoding/gob", "Decoder", True, "Decode", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["encoding/gob", "Decoder", True, "DecodeValue", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["encoding/gob", "Encoder", True, "Encode", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["encoding/gob", "Encoder", True, "EncodeValue", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["encoding/gob", "GobDecoder", True, "GobDecode", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["encoding/gob", "GobEncoder", True, "GobEncode", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.hex.model.yml b/go/ql/lib/ext/encoding.hex.model.yml new file mode 100644 index 000000000000..2c9dbdac031c --- /dev/null +++ b/go/ql/lib/ext/encoding.hex.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/hex", "", False, "Decode", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["encoding/hex", "", False, "DecodeString", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/hex", "", False, "NewDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.json.model.yml b/go/ql/lib/ext/encoding.json.model.yml new file mode 100644 index 000000000000..7ae60f829cc8 --- /dev/null +++ b/go/ql/lib/ext/encoding.json.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/json", "", False, "Compact", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["encoding/json", "", False, "HTMLEscape", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["encoding/json", "", False, "Indent", "", "", "Argument[1..3]", "Argument[0]", "taint", "manual"] + - ["encoding/json", "", False, "Marshal", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/json", "", False, "MarshalIndent", "", "", "Argument[0..2]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/json", "", False, "NewDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["encoding/json", "", False, "Unmarshal", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["encoding/json", "Decoder", True, "Buffered", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["encoding/json", "Decoder", True, "Decode", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["encoding/json", "Decoder", True, "Token", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/json", "Encoder", True, "Encode", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["encoding/json", "Encoder", True, "SetIndent", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["encoding/json", "Marshaler", True, "MarshalJSON", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/json", "Unmarshaler", True, "UnmarshalJSON", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.model.yml b/go/ql/lib/ext/encoding.model.yml new file mode 100644 index 000000000000..6fd6bef16ebe --- /dev/null +++ b/go/ql/lib/ext/encoding.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding", "BinaryMarshaler", True, "MarshalBinary", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["encoding", "BinaryUnmarshaler", True, "UnmarshalBinary", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["encoding", "TextMarshaler", True, "MarshalText", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["encoding", "TextUnmarshaler", True, "UnmarshalText", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.pem.model.yml b/go/ql/lib/ext/encoding.pem.model.yml new file mode 100644 index 000000000000..57c0f1fc662d --- /dev/null +++ b/go/ql/lib/ext/encoding.pem.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/pem", "", False, "Decode", "", "", "Argument[0]", "ReturnValue[0..1]", "taint", "manual"] + - ["encoding/pem", "", False, "Encode", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["encoding/pem", "", False, "EncodeToMemory", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/encoding.xml.model.yml b/go/ql/lib/ext/encoding.xml.model.yml new file mode 100644 index 000000000000..c14b95ae37b9 --- /dev/null +++ b/go/ql/lib/ext/encoding.xml.model.yml @@ -0,0 +1,28 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["encoding/xml", "", False, "CopyToken", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["encoding/xml", "", False, "Escape", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["encoding/xml", "", False, "EscapeText", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["encoding/xml", "", False, "Marshal", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/xml", "", False, "MarshalIndent", "", "", "Argument[0..2]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/xml", "", False, "NewDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["encoding/xml", "", False, "NewTokenDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["encoding/xml", "", False, "Unmarshal", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["encoding/xml", "CharData", True, "Copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["encoding/xml", "Comment", True, "Copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["encoding/xml", "Decoder", True, "Decode", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["encoding/xml", "Decoder", True, "DecodeElement", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["encoding/xml", "Decoder", True, "RawToken", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/xml", "Directive", True, "Copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["encoding/xml", "Encoder", True, "Encode", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["encoding/xml", "Encoder", True, "EncodeElement", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["encoding/xml", "Encoder", True, "EncodeToken", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["encoding/xml", "Encoder", True, "Indent", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["encoding/xml", "Marshaler", True, "MarshalXML", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["encoding/xml", "ProcInst", True, "Copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["encoding/xml", "StartElement", True, "Copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["encoding/xml", "TokenReader", True, "Token", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["encoding/xml", "Unmarshaler", True, "UnmarshalXML", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/errors.model.yml b/go/ql/lib/ext/errors.model.yml new file mode 100644 index 000000000000..a94c8e558ff4 --- /dev/null +++ b/go/ql/lib/ext/errors.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["errors", "", False, "As", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["errors", "", False, "New", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["errors", "", False, "Unwrap", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/expvar.model.yml b/go/ql/lib/ext/expvar.model.yml new file mode 100644 index 000000000000..fbb7a099d40c --- /dev/null +++ b/go/ql/lib/ext/expvar.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["expvar", "Func", True, "Value", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["expvar", "Map", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["expvar", "Map", True, "Set", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["expvar", "String", True, "Set", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["expvar", "String", True, "Value", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["expvar", "Var", True, "String", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/fmt.model.yml b/go/ql/lib/ext/fmt.model.yml new file mode 100644 index 000000000000..0f883bf37498 --- /dev/null +++ b/go/ql/lib/ext/fmt.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["fmt", "GoStringer", True, "GoString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["fmt", "ScanState", True, "Read", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["fmt", "ScanState", True, "Token", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["fmt", "State", True, "Write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["fmt", "Stringer", True, "String", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.astaxie.beego.context.model.yml b/go/ql/lib/ext/github.com.astaxie.beego.context.model.yml new file mode 100644 index 000000000000..1c9717af7015 --- /dev/null +++ b/go/ql/lib/ext/github.com.astaxie.beego.context.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/astaxie/beego/context", "", False, "WriteBody", "", "", "Argument[2]", "Argument[1]", "taint", "manual"] + - ["github.com/beego/beego/server/web/context", "", False, "WriteBody", "", "", "Argument[2]", "Argument[1]", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.astaxie.beego.model.yml b/go/ql/lib/ext/github.com.astaxie.beego.model.yml new file mode 100644 index 000000000000..0866d4f55aa2 --- /dev/null +++ b/go/ql/lib/ext/github.com.astaxie.beego.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/astaxie/beego", "", False, "HTML2str", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego", "", False, "Htmlquote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego", "", False, "Htmlunquote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego", "", False, "MapGet", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/astaxie/beego", "", False, "ParseForm", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["github.com/astaxie/beego", "", False, "Str2html", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego", "", False, "Substr", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/server/web", "", False, "HTML2str", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/server/web", "", False, "Htmlquote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/server/web", "", False, "Htmlunquote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/server/web", "", False, "MapGet", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/beego/beego/server/web", "", False, "ParseForm", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["github.com/beego/beego/server/web", "", False, "Str2html", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/server/web", "", False, "Substr", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.astaxie.beego.utils.model.yml b/go/ql/lib/ext/github.com.astaxie.beego.utils.model.yml new file mode 100644 index 000000000000..7c7e8dd74289 --- /dev/null +++ b/go/ql/lib/ext/github.com.astaxie.beego.utils.model.yml @@ -0,0 +1,31 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/astaxie/beego/utils", "", False, "SliceChunk", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "", False, "SliceDiff", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "", False, "SliceFilter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "", False, "SliceIntersect", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "", False, "SliceMerge", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "", False, "SlicePad", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "", False, "SliceRand", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "", False, "SliceReduce", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "", False, "SliceShuffle", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "", False, "SliceUnique", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "BeeMap", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "BeeMap", True, "Items", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/astaxie/beego/utils", "BeeMap", True, "Set", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SliceChunk", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SliceDiff", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SliceFilter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SliceIntersect", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SliceMerge", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SlicePad", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SliceRand", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SliceReduce", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SliceShuffle", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "", False, "SliceUnique", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "BeeMap", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "BeeMap", True, "Items", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/beego/beego/core/utils", "BeeMap", True, "Set", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml b/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml new file mode 100644 index 000000000000..8b73a46afaa8 --- /dev/null +++ b/go/ql/lib/ext/github.com.elazarl.goproxy.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/elazarl/goproxy", "CertStorage", True, "Fetch", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/elazarl/goproxy", "CertStorage", True, "Fetch", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.evanphx.json-patch.model.yml b/go/ql/lib/ext/github.com.evanphx.json-patch.model.yml new file mode 100644 index 000000000000..227e97354936 --- /dev/null +++ b/go/ql/lib/ext/github.com.evanphx.json-patch.model.yml @@ -0,0 +1,17 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/evanphx/json-patch", "", False, "CreateMergePatch", "", "", "Argument[0..1]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "", False, "DecodePatch", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "", False, "MergeMergePatches", "", "", "Argument[0..1]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "", False, "MergePatch", "", "", "Argument[0..1]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "Patch", True, "Apply", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "Patch", True, "Apply", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "Patch", True, "ApplyIndent", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "Patch", True, "ApplyIndent", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "Patch", True, "ApplyIndentWithOptions", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "Patch", True, "ApplyIndentWithOptions", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "Patch", True, "ApplyWithOptions", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/evanphx/json-patch", "Patch", True, "ApplyWithOptions", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.gin-gonic.gin.model.yml b/go/ql/lib/ext/github.com.gin-gonic.gin.model.yml new file mode 100644 index 000000000000..04c9f1e821ed --- /dev/null +++ b/go/ql/lib/ext/github.com.gin-gonic.gin.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/gin-gonic/gin", "Params", True, "ByName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/gin-gonic/gin", "Params", True, "Get", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.go-pg.pg.orm.model.yml b/go/ql/lib/ext/github.com.go-pg.pg.orm.model.yml new file mode 100644 index 000000000000..7b8d32998fdf --- /dev/null +++ b/go/ql/lib/ext/github.com.go-pg.pg.orm.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/go-pg/pg/$ANYVERSION/orm", "Formatter", True, "Append", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["github.com/go-pg/pg/$ANYVERSION/orm", "Formatter", True, "Append", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["github.com/go-pg/pg/$ANYVERSION/orm", "Formatter", True, "AppendBytes", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["github.com/go-pg/pg/$ANYVERSION/orm", "Formatter", True, "AppendBytes", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["github.com/go-pg/pg/$ANYVERSION/orm", "Formatter", True, "FormatQuery", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["github.com/go-pg/pg/$ANYVERSION/orm", "Formatter", True, "FormatQuery", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.json-iterator.go.model.yml b/go/ql/lib/ext/github.com.json-iterator.go.model.yml new file mode 100644 index 000000000000..bf974a171097 --- /dev/null +++ b/go/ql/lib/ext/github.com.json-iterator.go.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/json-iterator/go", "", False, "Unmarshal", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["github.com/json-iterator/go", "", False, "UnmarshalFromString", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["github.com/json-iterator/go", "API", True, "Unmarshal", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["github.com/json-iterator/go", "API", True, "UnmarshalFromString", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.labstack.echo.model.yml b/go/ql/lib/ext/github.com.labstack.echo.model.yml new file mode 100644 index 000000000000..964c55ec2fc0 --- /dev/null +++ b/go/ql/lib/ext/github.com.labstack.echo.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/labstack/echo", "Context", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/labstack/echo", "Context", True, "Set", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.revel.revel.model.yml b/go/ql/lib/ext/github.com.revel.revel.model.yml new file mode 100644 index 000000000000..3bff43153b1e --- /dev/null +++ b/go/ql/lib/ext/github.com.revel.revel.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/revel/revel", "Params", True, "Bind", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["github.com/revel/revel", "Params", True, "BindJSON", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["github.com/revel/revel", "RevelHeader", True, "Add", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["github.com/revel/revel", "RevelHeader", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/revel/revel", "RevelHeader", True, "GetAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/revel/revel", "RevelHeader", True, "Set", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["github.com/revel/revel", "RevelHeader", True, "SetCookie", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["github.com/revel/revel", "ServerCookie", True, "GetValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/revel/revel", "ServerMultipartForm", True, "GetFiles", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/revel/revel", "ServerMultipartForm", True, "GetValues", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/robfig/revel", "Params", True, "Bind", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["github.com/robfig/revel", "Params", True, "BindJSON", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["github.com/robfig/revel", "RevelHeader", True, "Add", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["github.com/robfig/revel", "RevelHeader", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/robfig/revel", "RevelHeader", True, "GetAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/robfig/revel", "RevelHeader", True, "Set", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["github.com/robfig/revel", "RevelHeader", True, "SetCookie", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["github.com/robfig/revel", "ServerCookie", True, "GetValue", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/robfig/revel", "ServerMultipartForm", True, "GetFiles", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/robfig/revel", "ServerMultipartForm", True, "GetValues", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/github.com.sendgrid.sendgrid-go.helpers.mail.model.yml b/go/ql/lib/ext/github.com.sendgrid.sendgrid-go.helpers.mail.model.yml new file mode 100644 index 000000000000..54a70d6371b9 --- /dev/null +++ b/go/ql/lib/ext/github.com.sendgrid.sendgrid-go.helpers.mail.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/sendgrid/sendgrid-go/$ANYVERSION/helpers/mail", "", False, "NewContent", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/go.uber.org.zap.model.yml b/go/ql/lib/ext/go.uber.org.zap.model.yml new file mode 100644 index 000000000000..2ca7f7e8a804 --- /dev/null +++ b/go/ql/lib/ext/go.uber.org.zap.model.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["go.uber.org/zap", "", False, "Any", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "Binary", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "ByteString", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "ByteStrings", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "Error", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "Errors", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "NamedError", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "Reflect", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "String", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "Stringp", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["go.uber.org/zap", "", False, "Strings", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/golang.org.x.net.context.model.yml b/go/ql/lib/ext/golang.org.x.net.context.model.yml new file mode 100644 index 000000000000..d0da8c74903f --- /dev/null +++ b/go/ql/lib/ext/golang.org.x.net.context.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["golang.org/x/net/context", "", False, "WithCancel", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["golang.org/x/net/context", "", False, "WithDeadline", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["golang.org/x/net/context", "", False, "WithTimeout", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["golang.org/x/net/context", "", False, "WithValue", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["golang.org/x/net/context", "Context", True, "Value", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/golang.org.x.net.html.model.yml b/go/ql/lib/ext/golang.org.x.net.html.model.yml new file mode 100644 index 000000000000..a92654d0f633 --- /dev/null +++ b/go/ql/lib/ext/golang.org.x.net.html.model.yml @@ -0,0 +1,21 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["golang.org/x/net/$ANYVERSION/html", "", False, "EscapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "", False, "NewTokenizer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "", False, "NewTokenizerFragment", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "", False, "Parse", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "", False, "ParseFragment", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "", False, "ParseFragmentWithOptions", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "", False, "ParseWithOptions", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "", False, "Render", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "", False, "UnescapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "Node", True, "AppendChild", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "Node", True, "InsertBefore", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "Tokenizer", True, "Buffered", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "Tokenizer", True, "Raw", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "Tokenizer", True, "TagAttr", "", "", "Argument[-1]", "ReturnValue[1]", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "Tokenizer", True, "Text", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["golang.org/x/net/$ANYVERSION/html", "Tokenizer", True, "Token", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/google.golang.org.protobuf.internal.encoding.text.model.yml b/go/ql/lib/ext/google.golang.org.protobuf.internal.encoding.text.model.yml new file mode 100644 index 000000000000..90c36d3d69bb --- /dev/null +++ b/go/ql/lib/ext/google.golang.org.protobuf.internal.encoding.text.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["google.golang.org/protobuf/$ANYVERSION/internal/encoding/text", "Token", True, "String", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/google.golang.org.protobuf.internal.impl.model.yml b/go/ql/lib/ext/google.golang.org.protobuf.internal.impl.model.yml new file mode 100644 index 000000000000..bb60c9861e3d --- /dev/null +++ b/go/ql/lib/ext/google.golang.org.protobuf.internal.impl.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["google.golang.org/protobuf/$ANYVERSION/internal/impl", "aberrantMessage", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["google.golang.org/protobuf/$ANYVERSION/internal/impl", "aberrantMessage", True, "GetUnknown", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/google.golang.org.protobuf.proto.model.yml b/go/ql/lib/ext/google.golang.org.protobuf.proto.model.yml new file mode 100644 index 000000000000..4db37463b097 --- /dev/null +++ b/go/ql/lib/ext/google.golang.org.protobuf.proto.model.yml @@ -0,0 +1,17 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/golang/protobuf/$ANYVERSION/proto", "", False, "Clone", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/golang/protobuf/$ANYVERSION/proto", "", False, "Marshal", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["github.com/golang/protobuf/$ANYVERSION/proto", "", False, "Merge", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["github.com/golang/protobuf/$ANYVERSION/proto", "", False, "Unmarshal", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["google.golang.org/protobuf/$ANYVERSION/proto", "", False, "Clone", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["google.golang.org/protobuf/$ANYVERSION/proto", "", False, "Marshal", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["google.golang.org/protobuf/$ANYVERSION/proto", "", False, "Merge", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["google.golang.org/protobuf/$ANYVERSION/proto", "", False, "Unmarshal", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["google.golang.org/protobuf/$ANYVERSION/proto", "MarshalOptions", True, "Marshal", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["google.golang.org/protobuf/$ANYVERSION/proto", "MarshalOptions", True, "MarshalAppend", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["google.golang.org/protobuf/$ANYVERSION/proto", "MarshalOptions", True, "MarshalAppend", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] + - ["google.golang.org/protobuf/$ANYVERSION/proto", "UnmarshalOptions", True, "Unmarshal", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] diff --git a/go/ql/lib/ext/google.golang.org.protobuf.reflect.protoreflect.model.yml b/go/ql/lib/ext/google.golang.org.protobuf.reflect.protoreflect.model.yml new file mode 100644 index 000000000000..94aca9789f73 --- /dev/null +++ b/go/ql/lib/ext/google.golang.org.protobuf.reflect.protoreflect.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["google.golang.org/protobuf/$ANYVERSION/reflect/protoreflect", "ProtoMessage", True, "ProtoReflect", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/gopkg.in.couchbase.gocb.model.yml b/go/ql/lib/ext/gopkg.in.couchbase.gocb.model.yml new file mode 100644 index 000000000000..2a6355bd6a87 --- /dev/null +++ b/go/ql/lib/ext/gopkg.in.couchbase.gocb.model.yml @@ -0,0 +1,59 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["gopkg.in/couchbase/gocb", "", False, "NewAnalyticsQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "", False, "NewN1qlQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "AnalyticsQuery", True, "ContextId", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "AnalyticsQuery", True, "Deferred", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "AnalyticsQuery", True, "Pretty", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "AnalyticsQuery", True, "Priority", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "AnalyticsQuery", True, "RawParam", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "AnalyticsQuery", True, "ServerSideTimeout", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "AdHoc", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "Consistency", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "ConsistentWith", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "Custom", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "PipelineBatch", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "PipelineCap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "Profile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "ReadOnly", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "ScanCap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/couchbase/gocb", "N1qlQuery", True, "Timeout", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "", False, "NewAnalyticsQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "", False, "NewN1qlQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "AnalyticsQuery", True, "ContextId", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "AnalyticsQuery", True, "Deferred", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "AnalyticsQuery", True, "Pretty", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "AnalyticsQuery", True, "Priority", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "AnalyticsQuery", True, "RawParam", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "AnalyticsQuery", True, "ServerSideTimeout", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "AdHoc", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "Consistency", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "ConsistentWith", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "Custom", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "PipelineBatch", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "PipelineCap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "Profile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "ReadOnly", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "ScanCap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbase/gocb", "N1qlQuery", True, "Timeout", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "", False, "NewAnalyticsQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "", False, "NewN1qlQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "AnalyticsQuery", True, "ContextId", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "AnalyticsQuery", True, "Deferred", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "AnalyticsQuery", True, "Pretty", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "AnalyticsQuery", True, "Priority", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "AnalyticsQuery", True, "RawParam", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "AnalyticsQuery", True, "ServerSideTimeout", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "AdHoc", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "Consistency", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "ConsistentWith", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "Custom", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "PipelineBatch", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "PipelineCap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "Profile", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "ReadOnly", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "ScanCap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["github.com/couchbaselabs/gocb", "N1qlQuery", True, "Timeout", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/gopkg.in.macaron.model.yml b/go/ql/lib/ext/gopkg.in.macaron.model.yml new file mode 100644 index 000000000000..c0c0de872678 --- /dev/null +++ b/go/ql/lib/ext/gopkg.in.macaron.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["gopkg.in/macaron", "RequestBody", True, "String", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/gopkg.in.yaml.model.yml b/go/ql/lib/ext/gopkg.in.yaml.model.yml new file mode 100644 index 000000000000..7718dca0a7df --- /dev/null +++ b/go/ql/lib/ext/gopkg.in.yaml.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["gopkg.in/yaml", "", False, "Marshal", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["gopkg.in/yaml", "", False, "Unmarshal", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["gopkg.in/yaml", "", False, "UnmarshalStrict", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["gopkg.in/yaml", "", False, "NewDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["gopkg.in/yaml", "Decoder", True, "Decode", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["gopkg.in/yaml", "Encoder", True, "Encode", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["gopkg.in/yaml", "Node", True, "Decode", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["gopkg.in/yaml", "Node", True, "Encode", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["gopkg.in/yaml", "Node", True, "SetString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/html.model.yml b/go/ql/lib/ext/html.model.yml new file mode 100644 index 000000000000..24d4e70152c2 --- /dev/null +++ b/go/ql/lib/ext/html.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["html", "", False, "EscapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["html", "", False, "UnescapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/html.template.model.yml b/go/ql/lib/ext/html.template.model.yml new file mode 100644 index 000000000000..0ee840c4eaed --- /dev/null +++ b/go/ql/lib/ext/html.template.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["html/template", "", False, "HTMLEscape", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["html/template", "", False, "HTMLEscapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["html/template", "", False, "JSEscape", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["html/template", "", False, "JSEscapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["html/template", "Template", True, "Execute", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["html/template", "Template", True, "ExecuteTemplate", "", "", "Argument[2]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/io.fs.model.yml b/go/ql/lib/ext/io.fs.model.yml new file mode 100644 index 000000000000..8797d50c5619 --- /dev/null +++ b/go/ql/lib/ext/io.fs.model.yml @@ -0,0 +1,17 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["io/fs", "", False, "FileInfoToDirEntry", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io/fs", "", False, "Glob", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["io/fs", "", False, "ReadDir", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["io/fs", "", False, "ReadFile", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["io/fs", "", False, "Sub", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["io/fs", "DirEntry", True, "Info", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["io/fs", "DirEntry", True, "Name", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io/fs", "FS", True, "Open", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["io/fs", "GlobFS", True, "Glob", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["io/fs", "ReadDirFS", True, "ReadDir", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["io/fs", "ReadFileFS", True, "ReadFile", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["io/fs", "SubFS", True, "Sub", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/io.ioutil.model.yml b/go/ql/lib/ext/io.ioutil.model.yml new file mode 100644 index 000000000000..c3182daf36d0 --- /dev/null +++ b/go/ql/lib/ext/io.ioutil.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["io/ioutil", "", False, "NopCloser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io/ioutil", "", False, "ReadAll", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/io.model.yml b/go/ql/lib/ext/io.model.yml new file mode 100644 index 000000000000..1da83059617d --- /dev/null +++ b/go/ql/lib/ext/io.model.yml @@ -0,0 +1,24 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["io", "", False, "Copy", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io", "", False, "CopyBuffer", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io", "", False, "CopyN", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io", "", False, "LimitReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io", "", False, "NewSectionReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io", "", False, "NopCloser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io", "", False, "ReadAll", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["io", "", False, "ReadAtLeast", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["io", "", False, "ReadFull", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["io", "", False, "TeeReader", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["io", "", False, "TeeReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io", "", False, "WriteString", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io", "Reader", True, "Read", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io", "ReaderAt", True, "ReadAt", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io", "ReaderFrom", True, "ReadFrom", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io", "StringWriter", True, "WriteString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io", "Writer", True, "Write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io", "WriterAt", True, "WriteAt", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io", "WriterTo", True, "WriteTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/k8s.io.api.core.model.yml b/go/ql/lib/ext/k8s.io.api.core.model.yml new file mode 100644 index 000000000000..eda9af13280d --- /dev/null +++ b/go/ql/lib/ext/k8s.io.api.core.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["k8s.io/api/core", "Secret", True, "DeepCopy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/api/core", "Secret", True, "DeepCopyInto", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/api/core", "Secret", True, "DeepCopyObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/api/core", "Secret", True, "Marshal", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/api/core", "Secret", True, "Unmarshal", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/api/core", "SecretList", True, "DeepCopy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/api/core", "SecretList", True, "DeepCopyInto", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/api/core", "SecretList", True, "DeepCopyObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/api/core", "SecretList", True, "Marshal", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/api/core", "SecretList", True, "Unmarshal", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/k8s.io.apimachinery.pkg.runtime.model.yml b/go/ql/lib/ext/k8s.io.apimachinery.pkg.runtime.model.yml new file mode 100644 index 000000000000..6bfbf8ded320 --- /dev/null +++ b/go/ql/lib/ext/k8s.io.apimachinery.pkg.runtime.model.yml @@ -0,0 +1,52 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Convert_Slice_string_To_Pointer_int64", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Convert_Slice_string_To_int", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Convert_Slice_string_To_int64", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Convert_Slice_string_To_string", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Convert_runtime_Object_To_runtime_RawExtension", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Convert_runtime_RawExtension_To_runtime_Object", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Convert_string_To_Pointer_int64", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Convert_string_To_int64", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Decode", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "DecodeInto", "", "", "Argument[1]", "Argument[2]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "DeepCopyJSON", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "DeepCopyJSONValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Encode", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "EncodeOrDie", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "Field", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "FieldPtr", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "NewEncodable", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "NewEncodableList", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "SetField", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "", False, "UseOrCreateObject", "", "", "Argument[3]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "CacheableObject", True, "CacheEncode", "", "", "Argument[-1]", "Argument[2]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "CacheableObject", True, "GetObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Decoder", True, "Decode", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Decoder", True, "Decode", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Encoder", True, "Encode", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Framer", True, "NewFrameReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Framer", True, "NewFrameWriter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Object", True, "DeepCopyObject", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "ObjectConvertor", True, "Convert", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "ObjectVersioner", True, "ConvertToVersion", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "ParameterCodec", True, "DecodeParameters", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "ParameterCodec", True, "EncodeParameters", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "ProtobufMarshaller", True, "MarshalTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "ProtobufReverseMarshaller", True, "MarshalToSizedBuffer", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "RawExtension", True, "DeepCopy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "RawExtension", True, "DeepCopyInto", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "RawExtension", True, "Marshal", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "RawExtension", True, "Unmarshal", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Unknown", True, "DeepCopy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Unknown", True, "DeepCopyInto", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Unknown", True, "Marshal", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Unknown", True, "NestedMarshalTo", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Unknown", True, "Unmarshal", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Unstructured", True, "SetUnstructuredContent", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "Unstructured", True, "UnstructuredContent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "WithoutVersionDecoder", True, "Decode", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["k8s.io/apimachinery/$ANYVERSION/pkg/runtime", "WithoutVersionDecoder", True, "Decode", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/log.model.yml b/go/ql/lib/ext/log.model.yml new file mode 100644 index 000000000000..fe1dd40394de --- /dev/null +++ b/go/ql/lib/ext/log.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["log", "Logger", True, "SetOutput", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["log", "Logger", True, "SetPrefix", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["log", "Logger", True, "Writer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/mime.model.yml b/go/ql/lib/ext/mime.model.yml new file mode 100644 index 000000000000..9027905423f7 --- /dev/null +++ b/go/ql/lib/ext/mime.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["mime", "", False, "FormatMediaType", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["mime", "", False, "ParseMediaType", "", "", "Argument[0]", "ReturnValue[0..1]", "taint", "manual"] + - ["mime", "WordDecoder", True, "Decode", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["mime", "WordDecoder", True, "DecodeHeader", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["mime", "WordEncoder", True, "Encode", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/mime.multipart.model.yml b/go/ql/lib/ext/mime.multipart.model.yml new file mode 100644 index 000000000000..c6eafbb2f547 --- /dev/null +++ b/go/ql/lib/ext/mime.multipart.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["mime/multipart", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["mime/multipart", "FileHeader", True, "Open", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["mime/multipart", "Part", True, "FileName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["mime/multipart", "Part", True, "FormName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["mime/multipart", "Reader", True, "NextPart", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["mime/multipart", "Reader", True, "NextRawPart", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["mime/multipart", "Reader", True, "ReadForm", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["mime/multipart", "Writer", True, "WriteField", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/mime.quotedprintable.model.yml b/go/ql/lib/ext/mime.quotedprintable.model.yml new file mode 100644 index 000000000000..7ac77332727c --- /dev/null +++ b/go/ql/lib/ext/mime.quotedprintable.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["mime/quotedprintable", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/net.http.httputil.model.yml b/go/ql/lib/ext/net.http.httputil.model.yml new file mode 100644 index 000000000000..b8b7095c2a0a --- /dev/null +++ b/go/ql/lib/ext/net.http.httputil.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["net/http/httputil", "", False, "DumpRequest", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/http/httputil", "", False, "DumpRequestOut", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/http/httputil", "", False, "DumpResponse", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/http/httputil", "", False, "NewChunkedReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/http/httputil", "", False, "NewClientConn", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["net/http/httputil", "", False, "NewProxyClientConn", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["net/http/httputil", "BufferPool", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/http/httputil", "BufferPool", True, "Put", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["net/http/httputil", "ClientConn", True, "Hijack", "", "", "Argument[-1]", "ReturnValue[0..1]", "taint", "manual"] + - ["net/http/httputil", "ServerConn", True, "Hijack", "", "", "Argument[-1]", "ReturnValue[0..1]", "taint", "manual"] diff --git a/go/ql/lib/ext/net.http.model.yml b/go/ql/lib/ext/net.http.model.yml new file mode 100644 index 000000000000..8dfd52a0d108 --- /dev/null +++ b/go/ql/lib/ext/net.http.model.yml @@ -0,0 +1,39 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["net/http", "", False, "CanonicalHeaderKey", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/http", "", False, "Error", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["net/http", "", False, "MaxBytesReader", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["net/http", "", False, "NewRequest", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"] + - ["net/http", "", False, "NewRequestWithContext", "", "", "Argument[2]", "ReturnValue[0]", "taint", "manual"] + - ["net/http", "", False, "ReadRequest", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/http", "", False, "ReadResponse", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/http", "", False, "SetCookie", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["net/http", "Header", True, "Add", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["net/http", "Header", True, "Clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/http", "Header", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/http", "Header", True, "Set", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["net/http", "Header", True, "Values", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/http", "Header", True, "Write", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["net/http", "Header", True, "WriteSubset", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["net/http", "Hijacker", True, "Hijack", "", "", "Argument[-1]", "ReturnValue[0..1]", "taint", "manual"] + - ["net/http", "Request", True, "AddCookie", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["net/http", "Request", True, "Clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/http", "Request", True, "Write", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["net/http", "Request", True, "WriteProxy", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["net/http", "Response", True, "Write", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["net/http", "Transport", True, "Clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["net/http", "Request", True, "Cookie", "", "", "ReturnValue[0]", "remote", "manual"] + - ["net/http", "Request", True, "Cookies", "", "", "ReturnValue.ArrayElement", "remote", "manual"] + - ["net/http", "Request", True, "FormFile", "", "", "ReturnValue[0..1]", "remote", "manual"] + - ["net/http", "Request", True, "FormValue", "", "", "ReturnValue", "remote", "manual"] + - ["net/http", "Request", True, "MultipartReader", "", "", "ReturnValue[0]", "remote", "manual"] + - ["net/http", "Request", True, "PostFormValue", "", "", "ReturnValue", "remote", "manual"] + - ["net/http", "Request", True, "Referer", "", "", "ReturnValue", "remote", "manual"] + - ["net/http", "Request", True, "UserAgent", "", "", "ReturnValue", "remote", "manual"] diff --git a/go/ql/lib/ext/net.mail.model.yml b/go/ql/lib/ext/net.mail.model.yml new file mode 100644 index 000000000000..d5db3c97b1be --- /dev/null +++ b/go/ql/lib/ext/net.mail.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["net/mail", "", False, "ParseAddress", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/mail", "", False, "ParseAddressList", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/mail", "", False, "ReadMessage", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/mail", "AddressParser", True, "Parse", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/mail", "AddressParser", True, "ParseList", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/mail", "Header", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/net.model.yml b/go/ql/lib/ext/net.model.yml new file mode 100644 index 000000000000..968b03fd3c2d --- /dev/null +++ b/go/ql/lib/ext/net.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["net", "", False, "FileConn", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net", "", False, "FilePacketConn", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net", "", False, "JoinHostPort", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["net", "", False, "SplitHostPort", "", "", "Argument[0]", "ReturnValue[0..1]", "taint", "manual"] + - ["net", "IPConn", True, "ReadFromIP", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["net", "IPConn", True, "ReadMsgIP", "", "", "Argument[-1]", "Argument[0..1]", "taint", "manual"] + - ["net", "IPConn", True, "WriteMsgIP", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["net", "IPConn", True, "WriteToIP", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["net", "PacketConn", True, "ReadFrom", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["net", "PacketConn", True, "WriteTo", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["net", "TCPListener", True, "File", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net", "UDPConn", True, "ReadFromUDP", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["net", "UDPConn", True, "ReadMsgUDP", "", "", "Argument[-1]", "Argument[0..1]", "taint", "manual"] + - ["net", "UDPConn", True, "WriteMsgUDP", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["net", "UDPConn", True, "WriteToUDP", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["net", "UnixConn", True, "ReadFromUnix", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["net", "UnixConn", True, "ReadMsgUnix", "", "", "Argument[-1]", "Argument[0..1]", "taint", "manual"] + - ["net", "UnixConn", True, "WriteMsgUnix", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["net", "UnixConn", True, "WriteToUnix", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["net", "UnixListener", True, "File", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/net.textproto.model.yml b/go/ql/lib/ext/net.textproto.model.yml new file mode 100644 index 000000000000..0ff47eeebdb1 --- /dev/null +++ b/go/ql/lib/ext/net.textproto.model.yml @@ -0,0 +1,24 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["net/textproto", "", False, "CanonicalMIMEHeaderKey", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/textproto", "", False, "NewConn", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/textproto", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/textproto", "", False, "TrimBytes", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/textproto", "", False, "TrimString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/textproto", "MIMEHeader", True, "Add", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["net/textproto", "MIMEHeader", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/textproto", "MIMEHeader", True, "Set", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["net/textproto", "MIMEHeader", True, "Values", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/textproto", "Reader", True, "DotReader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/textproto", "Reader", True, "ReadCodeLine", "", "", "Argument[-1]", "ReturnValue[1]", "taint", "manual"] + - ["net/textproto", "Reader", True, "ReadContinuedLine", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/textproto", "Reader", True, "ReadContinuedLineBytes", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/textproto", "Reader", True, "ReadDotBytes", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/textproto", "Reader", True, "ReadDotLines", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/textproto", "Reader", True, "ReadLine", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/textproto", "Reader", True, "ReadLineBytes", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/textproto", "Reader", True, "ReadMIMEHeader", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/textproto", "Reader", True, "ReadResponse", "", "", "Argument[-1]", "ReturnValue[1]", "taint", "manual"] diff --git a/go/ql/lib/ext/net.url.model.yml b/go/ql/lib/ext/net.url.model.yml new file mode 100644 index 000000000000..deba3d5b39ef --- /dev/null +++ b/go/ql/lib/ext/net.url.model.yml @@ -0,0 +1,28 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["net/url", "", False, "Parse", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/url", "", False, "ParseQuery", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/url", "", False, "ParseRequestURI", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/url", "", False, "PathEscape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/url", "", False, "PathUnescape", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/url", "", False, "QueryEscape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/url", "", False, "QueryUnescape", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/url", "", False, "User", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/url", "", False, "UserPassword", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["net/url", "URL", True, "EscapedPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/url", "URL", True, "Hostname", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/url", "URL", True, "MarshalBinary", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/url", "URL", True, "Parse", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/url", "URL", True, "Parse", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["net/url", "URL", True, "Port", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/url", "URL", True, "Query", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/url", "URL", True, "RequestURI", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/url", "URL", True, "ResolveReference", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/url", "URL", True, "ResolveReference", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["net/url", "Userinfo", True, "Password", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["net/url", "Userinfo", True, "Username", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/url", "Values", True, "Encode", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["net/url", "Values", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/net_http.model.yml b/go/ql/lib/ext/net_http.model.yml deleted file mode 100644 index 0b686cfb4320..000000000000 --- a/go/ql/lib/ext/net_http.model.yml +++ /dev/null @@ -1,13 +0,0 @@ -extensions: - - addsTo: - pack: codeql/go-all - extensible: sourceModel - data: - - ["net/http", "Request", True, "Cookie", "", "", "ReturnValue[0]", "remote", "manual"] - - ["net/http", "Request", True, "Cookies", "", "", "ReturnValue.ArrayElement", "remote", "manual"] - - ["net/http", "Request", True, "FormFile", "", "", "ReturnValue[0..1]", "remote", "manual"] - - ["net/http", "Request", True, "FormValue", "", "", "ReturnValue", "remote", "manual"] - - ["net/http", "Request", True, "MultipartReader", "", "", "ReturnValue[0]", "remote", "manual"] - - ["net/http", "Request", True, "PostFormValue", "", "", "ReturnValue", "remote", "manual"] - - ["net/http", "Request", True, "Referer", "", "", "ReturnValue", "remote", "manual"] - - ["net/http", "Request", True, "UserAgent", "", "", "ReturnValue", "remote", "manual"] diff --git a/go/ql/lib/ext/os.model.yml b/go/ql/lib/ext/os.model.yml new file mode 100644 index 000000000000..2ca99c370e3a --- /dev/null +++ b/go/ql/lib/ext/os.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["os", "", False, "Expand", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["os", "", False, "ExpandEnv", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["os", "", False, "NewFile", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["os", "File", True, "Fd", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/path.filepath.model.yml b/go/ql/lib/ext/path.filepath.model.yml new file mode 100644 index 000000000000..15bcb7d386d8 --- /dev/null +++ b/go/ql/lib/ext/path.filepath.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["path/filepath", "", False, "Abs", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["path/filepath", "", False, "Base", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path/filepath", "", False, "Clean", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path/filepath", "", False, "Dir", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path/filepath", "", False, "EvalSymlinks", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["path/filepath", "", False, "Ext", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path/filepath", "", False, "FromSlash", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path/filepath", "", False, "Glob", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["path/filepath", "", False, "Rel", "", "", "Argument[0..1]", "ReturnValue[0]", "taint", "manual"] + - ["path/filepath", "", False, "Split", "", "", "Argument[0]", "ReturnValue[0..1]", "taint", "manual"] + - ["path/filepath", "", False, "SplitList", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path/filepath", "", False, "ToSlash", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path/filepath", "", False, "VolumeName", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/path.model.yml b/go/ql/lib/ext/path.model.yml new file mode 100644 index 000000000000..5a494b24d7ca --- /dev/null +++ b/go/ql/lib/ext/path.model.yml @@ -0,0 +1,10 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["path", "", False, "Base", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path", "", False, "Clean", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path", "", False, "Dir", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path", "", False, "Ext", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["path", "", False, "Split", "", "", "Argument[0]", "ReturnValue[0..1]", "taint", "manual"] diff --git a/go/ql/lib/ext/reflect.model.yml b/go/ql/lib/ext/reflect.model.yml new file mode 100644 index 000000000000..1299b3a61f0d --- /dev/null +++ b/go/ql/lib/ext/reflect.model.yml @@ -0,0 +1,42 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["reflect", "", False, "AppendSlice", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["reflect", "", False, "Copy", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["reflect", "", False, "Indirect", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["reflect", "", False, "ValueOf", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["reflect", "MapIter", True, "Key", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "MapIter", True, "Value", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "StructTag", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "StructTag", True, "Lookup", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["reflect", "Value", True, "Addr", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Bytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Convert", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Elem", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Field", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "FieldByIndex", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "FieldByName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "FieldByNameFunc", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Index", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Interface", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "InterfaceData", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "MapIndex", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "MapKeys", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "MapRange", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Method", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "MethodByName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Pointer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Recv", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["reflect", "Value", True, "Send", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["reflect", "Value", True, "Set", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["reflect", "Value", True, "SetBytes", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["reflect", "Value", True, "SetMapIndex", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["reflect", "Value", True, "SetPointer", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["reflect", "Value", True, "SetString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["reflect", "Value", True, "Slice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "Slice3", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["reflect", "Value", True, "TryRecv", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["reflect", "Value", True, "TrySend", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["reflect", "Value", True, "UnsafeAddr", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/regexp.model.yml b/go/ql/lib/ext/regexp.model.yml new file mode 100644 index 000000000000..281bd2e81704 --- /dev/null +++ b/go/ql/lib/ext/regexp.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["regexp", "", False, "QuoteMeta", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "Expand", "", "", "Argument[1..2]", "Argument[0]", "taint", "manual"] + - ["regexp", "Regexp", True, "Expand", "", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "ExpandString", "", "", "Argument[1..2]", "Argument[0]", "taint", "manual"] + - ["regexp", "Regexp", True, "ExpandString", "", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "Find", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "FindAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "FindAllString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "FindAllStringSubmatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "FindAllSubmatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "FindString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "FindStringSubmatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "FindSubmatch", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "ReplaceAll", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "ReplaceAllFunc", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "ReplaceAllLiteral", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "ReplaceAllLiteralString", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "ReplaceAllString", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "ReplaceAllStringFunc", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["regexp", "Regexp", True, "Split", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/sort.model.yml b/go/ql/lib/ext/sort.model.yml new file mode 100644 index 000000000000..36d0070de66d --- /dev/null +++ b/go/ql/lib/ext/sort.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["sort", "", False, "Reverse", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/strconv.model.yml b/go/ql/lib/ext/strconv.model.yml new file mode 100644 index 000000000000..65203b121064 --- /dev/null +++ b/go/ql/lib/ext/strconv.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["strconv", "", False, "AppendQuote", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["strconv", "", False, "AppendQuoteToASCII", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["strconv", "", False, "AppendQuoteToGraphic", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["strconv", "", False, "Quote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strconv", "", False, "QuoteToASCII", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strconv", "", False, "QuoteToGraphic", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strconv", "", False, "QuotedPrefix", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["strconv", "", False, "Unquote", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["strconv", "", False, "UnquoteChar", "", "", "Argument[0]", "ReturnValue[2]", "taint", "manual"] diff --git a/go/ql/lib/ext/strings.model.yml b/go/ql/lib/ext/strings.model.yml new file mode 100644 index 000000000000..2757277a0f08 --- /dev/null +++ b/go/ql/lib/ext/strings.model.yml @@ -0,0 +1,39 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["strings", "", False, "Fields", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "FieldsFunc", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Join", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Map", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "NewReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Repeat", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Replace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Replace", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "ReplaceAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "ReplaceAll", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Split", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "SplitAfter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "SplitAfterN", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "SplitN", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Title", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "ToLower", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "ToLowerSpecial", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "ToTitle", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "ToTitleSpecial", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "ToUpper", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "ToUpperSpecial", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "ToValidUTF8", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "Trim", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "TrimFunc", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "TrimLeft", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "TrimLeftFunc", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "TrimPrefix", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "TrimRight", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "TrimRightFunc", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "TrimSpace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "", False, "TrimSuffix", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "Reader", True, "Reset", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["strings", "Replacer", True, "Replace", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["strings", "Replacer", True, "WriteString", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/sync.atomic.model.yml b/go/ql/lib/ext/sync.atomic.model.yml new file mode 100644 index 000000000000..025097a8e835 --- /dev/null +++ b/go/ql/lib/ext/sync.atomic.model.yml @@ -0,0 +1,29 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["sync/atomic", "", False, "AddUintptr", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["sync/atomic", "", False, "AddUintptr", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "", False, "CompareAndSwapPointer", "", "", "Argument[2]", "Argument[0]", "taint", "manual"] + - ["sync/atomic", "", False, "CompareAndSwapUintptr", "", "", "Argument[2]", "Argument[0]", "taint", "manual"] + - ["sync/atomic", "", False, "LoadPointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "", False, "LoadUintptr", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "", False, "StorePointer", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["sync/atomic", "", False, "StoreUintptr", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["sync/atomic", "", False, "SwapPointer", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["sync/atomic", "", False, "SwapPointer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "", False, "SwapUintptr", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["sync/atomic", "", False, "SwapUintptr", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "Pointer", True, "Load", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "Pointer", True, "Store", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["sync/atomic", "Pointer", True, "Swap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "Pointer", True, "Swap", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["sync/atomic", "Uintptr", True, "Load", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "Uintptr", True, "Store", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["sync/atomic", "Uintptr", True, "Swap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "Uintptr", True, "Swap", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["sync/atomic", "Value", True, "Load", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "Value", True, "Store", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["sync/atomic", "Value", True, "Swap", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["sync/atomic", "Value", True, "Swap", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/sync.model.yml b/go/ql/lib/ext/sync.model.yml new file mode 100644 index 000000000000..d7dd66558be4 --- /dev/null +++ b/go/ql/lib/ext/sync.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["sync", "Map", True, "CompareAndSwap", "", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["sync", "Map", True, "Load", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["sync", "Map", True, "LoadOrStore", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["sync", "Map", True, "LoadOrStore", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["sync", "Map", True, "LoadOrStore", "", "", "Argument[0..1]", "ReturnValue[0]", "taint", "manual"] + - ["sync", "Map", True, "Store", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["sync", "Map", True, "Swap", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["sync", "Map", True, "Swap", "", "", "Argument[0..1]", "Argument[-1]", "taint", "manual"] + - ["sync", "Pool", True, "Get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["sync", "Pool", True, "Put", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/syscall.model.yml b/go/ql/lib/ext/syscall.model.yml new file mode 100644 index 000000000000..5f83e2d38502 --- /dev/null +++ b/go/ql/lib/ext/syscall.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["syscall", "", False, "BytePtrFromString", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["syscall", "", False, "ByteSliceFromString", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["syscall", "", False, "StringBytePtr", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["syscall", "", False, "StringByteSlice", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["syscall", "", False, "StringSlicePtr", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["syscall", "Conn", True, "SyscallConn", "", "", "Argument[-1]", "ReturnValue[0]", "taint", "manual"] + - ["syscall", "RawConn", True, "Read", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["syscall", "RawConn", True, "Write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/go/ql/lib/ext/text.scanner.model.yml b/go/ql/lib/ext/text.scanner.model.yml new file mode 100644 index 000000000000..76ea2c1a73cb --- /dev/null +++ b/go/ql/lib/ext/text.scanner.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["text/scanner", "Scanner", True, "Init", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["text/scanner", "Scanner", True, "Init", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["text/scanner", "Scanner", True, "TokenText", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/text.tabwriter.model.yml b/go/ql/lib/ext/text.tabwriter.model.yml new file mode 100644 index 000000000000..6972e2d93a6b --- /dev/null +++ b/go/ql/lib/ext/text.tabwriter.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["text/tabwriter", "Writer", True, "Init", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/text.template.model.yml b/go/ql/lib/ext/text.template.model.yml new file mode 100644 index 000000000000..669af3a8854f --- /dev/null +++ b/go/ql/lib/ext/text.template.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["text/template", "", False, "HTMLEscape", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["text/template", "", False, "HTMLEscapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["text/template", "", False, "JSEscape", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["text/template", "", False, "JSEscapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["text/template", "Template", True, "Execute", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["text/template", "Template", True, "ExecuteTemplate", "", "", "Argument[2]", "Argument[0]", "taint", "manual"] diff --git a/go/ql/lib/go.qll b/go/ql/lib/go.qll index 01fba3376823..038916ed76ae 100644 --- a/go/ql/lib/go.qll +++ b/go/ql/lib/go.qll @@ -38,7 +38,6 @@ import semmle.go.frameworks.Echo import semmle.go.frameworks.ElazarlGoproxy import semmle.go.frameworks.Email import semmle.go.frameworks.Encoding -import semmle.go.frameworks.EvanphxJsonPatch import semmle.go.frameworks.Gin import semmle.go.frameworks.Glog import semmle.go.frameworks.GoRestfulHttp diff --git a/go/ql/lib/semmle/go/Scopes.qll b/go/ql/lib/semmle/go/Scopes.qll index 28a32fe3de51..074894cbb8c0 100644 --- a/go/ql/lib/semmle/go/Scopes.qll +++ b/go/ql/lib/semmle/go/Scopes.qll @@ -101,6 +101,7 @@ class Entity extends @object { * Note that for methods `pkg` is the package path followed by `.` followed * by the name of the receiver type, for example `io.Writer`. */ + pragma[nomagic] predicate hasQualifiedName(string pkg, string name) { pkg = this.getPackage().getPath() and name = this.getName() @@ -517,6 +518,7 @@ class Method extends Function { * `exists(Type t | t.hasQualifiedName(pkg, tp) and meth = t.getMethod(m))`: the latter * distinguishes between the method sets of `T` and `*T`, while the former does not. */ + pragma[nomagic] predicate hasQualifiedName(string pkg, string tp, string m) { exists(NamedType t | this.isIn(t, m) and @@ -533,9 +535,20 @@ class Method extends Function { * implement themselves. */ predicate implements(Method m) { + if this.isInterfaceMethod() then this = m else this.implementsIncludingInterfaceMethods(m) + } + + /** + * Holds if this method implements the method `m`, that is, if `m` is a method + * on an interface, and this is a method with the same name on a type that + * implements that interface. + * + * Note that all methods implement themselves, and that unlike the predicate `implements` + * this does allow interface methods to implement other interfaces. + */ + predicate implementsIncludingInterfaceMethods(Method m) { this = m or - not this.isInterfaceMethod() and exists(Type t | this = t.getMethod(m.getName()) and t.implements(m.getReceiverType().getUnderlyingType()) diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 7fde586838a3..6036bbf9a86a 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -206,7 +206,7 @@ module ModelValidation { or summaryModel(package, type, _, name, signature, ext, _, _, _, provenance) and pred = "summary" | - not package.regexpMatch("[a-zA-Z0-9_\\./]*") and + not package.replaceAll("$ANYVERSION", "").regexpMatch("[a-zA-Z0-9_\\./-]*") and result = "Dubious package \"" + package + "\" in " + pred + " model." or not type.regexpMatch("[a-zA-Z0-9_\\$<>]*") and @@ -265,6 +265,15 @@ private string paramsStringPart(Function f, int i) { */ string paramsString(Function f) { result = concat(int i | | paramsStringPart(f, i) order by i) } +bindingset[p] +private string interpretPackage(string p) { + exists(string r | r = "([^$]+)([./]\\$ANYVERSION(/|$)(.*))?" | + if exists(p.regexpCapture(r, 4)) + then result = package(p.regexpCapture(r, 1), p.regexpCapture(r, 4)) + else result = package(p, "") + ) +} + /** Gets the source/sink/summary element corresponding to the supplied parameters. */ SourceOrSinkElement interpretElement( string pkg, string type, boolean subtypes, string name, string signature, string ext @@ -273,16 +282,16 @@ SourceOrSinkElement interpretElement( // Go does not need to distinguish functions with signature signature = "" and ( - exists(Field f | f.hasQualifiedName(pkg, type, name) | result.asEntity() = f) + exists(Field f | f.hasQualifiedName(interpretPackage(pkg), type, name) | result.asEntity() = f) or - exists(Method m | m.hasQualifiedName(pkg, type, name) | + exists(Method m | m.hasQualifiedName(interpretPackage(pkg), type, name) | result.asEntity() = m or - subtypes = true and result.asEntity().(Method).implements(m) + subtypes = true and result.asEntity().(Method).implementsIncludingInterfaceMethods(m) ) or type = "" and - exists(Entity e | e.hasQualifiedName(pkg, name) | result.asEntity() = e) + exists(Entity e | e.hasQualifiedName(interpretPackage(pkg), name) | result.asEntity() = e) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll index 2c7e3356f3c2..ea768f547153 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll @@ -51,6 +51,12 @@ private predicate isConcreteInterfaceCall(DataFlow::Node call, DataFlow::Node re isInterfaceCallReceiver(call, recv, _, m) and isConcreteValue(recv) } +private Function getRealOrSummarizedFunction(DataFlowCallable c) { + result = c.asCallable().asFunction() + or + result = c.asSummarizedCallable().asFunction() +} + /** * Gets a function that might be called by `call`, where the receiver of `call` has interface type, * but its concrete types can be determined by local reasoning. @@ -59,7 +65,7 @@ private DataFlowCallable getConcreteTarget(DataFlow::CallNode call) { exists(string m | isConcreteInterfaceCall(call, _, m) | exists(Type concreteReceiverType | concreteReceiverType = getConcreteType(getInterfaceCallReceiverSource(call)) and - result.asFunction() = concreteReceiverType.getMethod(m) + getRealOrSummarizedFunction(result) = concreteReceiverType.getMethod(m) ) ) } @@ -78,7 +84,7 @@ private predicate isInterfaceMethodCall(DataFlow::CallNode call) { private DataFlowCallable getRestrictedInterfaceTarget(DataFlow::CallNode call) { exists(InterfaceType tp, Type recvtp, string m | isInterfaceCallReceiver(call, _, tp, m) and - result.asFunction() = recvtp.getMethod(m) and + getRealOrSummarizedFunction(result) = recvtp.getMethod(m) and recvtp.implements(tp) ) } @@ -93,7 +99,8 @@ DataFlowCallable viableCallable(CallExpr ma) { else if isInterfaceMethodCall(call) then result = getRestrictedInterfaceTarget(call) - else result.asCallable() = call.getACalleeIncludingExternals() + else + [result.asCallable(), result.asSummarizedCallable()] = call.getACalleeIncludingExternals() ) } @@ -126,3 +133,25 @@ class ArgumentPosition extends int { /** Holds if arguments at position `apos` match parameters at position `ppos`. */ pragma[inline] predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } + +private predicate isInterfaceMethod(Method c) { + c.getReceiverBaseType().getUnderlyingType() instanceof InterfaceType +} + +/** + * Holds if `call` is passing `arg` to param `p` in any circumstance except passing + * a receiver parameter to a concrete method. + */ +pragma[inline] +predicate golangSpecificParamArgFilter( + DataFlowCall call, DataFlow::ParameterNode p, DataFlow::ArgumentNode arg +) { + // Interface methods calls may be passed strictly to that exact method's model receiver: + arg.getPosition() != -1 + or + exists(Function callTarget | callTarget = call.getNode().(DataFlow::CallNode).getTarget() | + not isInterfaceMethod(callTarget) + or + callTarget = p.getCallable().asSummarizedCallable().asFunction() + ) +} diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll index e6fce328326c..648d5c2b073a 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll @@ -425,7 +425,8 @@ private module Cached { exists(ParameterPosition ppos | viableParam(call, ppos, p) and argumentPositionMatch(call, arg, ppos) and - compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) + compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and + golangSpecificParamArgFilter(call, p, arg) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 23751641d5df..86c3651b0d36 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -10,14 +10,8 @@ private newtype TNode = MkInstructionNode(IR::Instruction insn) or MkSsaNode(SsaDefinition ssa) or MkGlobalFunctionNode(Function f) or - MkSummarizedParameterNode(DataFlowCallable c, int i) { - not exists(c.getFuncDef()) and - c.asCallable() instanceof SummarizedCallable and - ( - i in [0 .. c.getType().getNumParameter() - 1] - or - c.asFunction() instanceof Method and i = -1 - ) + MkSummarizedParameterNode(SummarizedCallable c, int i) { + FlowSummaryImpl::Private::summaryParameterNodeRange(c, i) } or MkSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { FlowSummaryImpl::Private::summaryNodeRange(c, state) @@ -31,12 +25,18 @@ module Private { DataFlowCallable nodeGetEnclosingCallable(Node n) { result.asCallable() = n.getEnclosingCallable() or - not exists(n.getEnclosingCallable()) and result.asFileScope() = n.getFile() + (n = MkInstructionNode(_) or n = MkSsaNode(_) or n = MkGlobalFunctionNode(_)) and + not exists(n.getEnclosingCallable()) and + result.asFileScope() = n.getFile() + or + n = MkSummarizedParameterNode(result.asSummarizedCallable(), _) + or + n = MkSummaryInternalNode(result.asSummarizedCallable(), _) } /** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */ predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { - p.isParameterOf(c.asCallable(), pos) + p.isParameterOf(c, pos) } /** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */ @@ -115,15 +115,7 @@ module Public { ControlFlow::Root getRoot() { none() } // overridden in subclasses /** INTERNAL: Use `getRoot()` instead. */ - Callable getEnclosingCallable() { - result.getFuncDef() = this.getRoot() - or - exists(DataFlowCallable dfc | result = dfc.asCallable() | - this = MkSummarizedParameterNode(dfc, _) - or - this = MkSummaryInternalNode(dfc.asCallable(), _) - ) - } + Callable getEnclosingCallable() { result.getFuncDef() = this.getRoot() } /** Gets the type of this node. */ Type getType() { none() } // overridden in subclasses @@ -577,7 +569,13 @@ module Public { /** A representation of a parameter initialization. */ abstract class ParameterNode extends DataFlow::Node { /** Holds if this node initializes the `i`th parameter of `c`. */ - abstract predicate isParameterOf(Callable c, int i); + abstract predicate isParameterOf(DataFlowCallable c, int i); + + /** Gets the callable that this parameter belongs to. */ + DataFlowCallable getCallable() { this.isParameterOf(result, _) } + + /** Gets this parameter's position. */ + int getPosition() { this.isParameterOf(_, result) } } /** @@ -585,12 +583,10 @@ module Public { * already have a parameter nodes. */ class SummarizedParameterNode extends ParameterNode, MkSummarizedParameterNode { - Callable c; + SummarizedCallable c; int i; - SummarizedParameterNode() { - this = MkSummarizedParameterNode(any(DataFlowCallable dfc | c = dfc.asCallable()), i) - } + SummarizedParameterNode() { this = MkSummarizedParameterNode(c, i) } // There are no AST representations of summarized parameter nodes override ControlFlow::Root getRoot() { none() } @@ -603,7 +599,9 @@ module Public { i = -1 and result = c.asFunction().(Method).getReceiverType() } - override predicate isParameterOf(Callable call, int idx) { c = call and i = idx } + override predicate isParameterOf(DataFlowCallable call, int idx) { + c = call.asSummarizedCallable() and i = idx + } override string toString() { result = "parameter " + i + " of " + c.toString() } @@ -622,7 +620,9 @@ module Public { /** Gets the parameter this node initializes. */ override Parameter asParameter() { result = parm } - override predicate isParameterOf(Callable c, int i) { parm.isParameterOf(c.getFuncDef(), i) } + override predicate isParameterOf(DataFlowCallable c, int i) { + parm.isParameterOf(c.asCallable().getFuncDef(), i) + } } /** A representation of a receiver initialization. */ @@ -728,20 +728,18 @@ module Public { */ predicate argumentOf(CallExpr call, int pos) { call = c.asExpr() and - pos = i and - ( - i != -1 - or - exists(c.(MethodCallNode).getTarget().getBody()) - or - hasExternalSpecification(c.(DataFlow::MethodCallNode).getTarget()) - ) + pos = i } /** * Gets the `CallNode` this is an argument to. */ CallNode getCall() { result = c } + + /** + * Gets this argument's position. + */ + int getPosition() { result = i } } /** diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 8e194414811d..d45587aa3d42 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -3,6 +3,7 @@ private import DataFlowUtil private import DataFlowImplCommon private import ContainerFlow private import FlowSummaryImpl as FlowSummaryImpl +private import semmle.go.dataflow.FlowSummary as FlowSummary private import codeql.util.Unit import DataFlowNodes::Private @@ -237,31 +238,55 @@ class DataFlowLocation = Location; private newtype TDataFlowCallable = TCallable(Callable c) or - TFileScope(File f) + TFileScope(File f) or + TSummarizedCallable(FlowSummary::SummarizedCallable c) class DataFlowCallable extends TDataFlowCallable { + /** + * Gets the `Callable` corresponding to this `DataFlowCallable`, if any. + */ Callable asCallable() { this = TCallable(result) } + /** + * Gets the `File` whose root scope corresponds to this `DataFlowCallable`, if any. + */ File asFileScope() { this = TFileScope(result) } - FuncDef getFuncDef() { result = this.asCallable().getFuncDef() } - - Function asFunction() { result = this.asCallable().asFunction() } - - FuncLit asFuncLit() { result = this.asCallable().asFuncLit() } + /** + * Gets the `SummarizedCallable` corresponding to this `DataFlowCallable`, if any. + */ + FlowSummary::SummarizedCallable asSummarizedCallable() { this = TSummarizedCallable(result) } - SignatureType getType() { result = this.asCallable().getType() } + /** + * Gets the type of this callable. + * + * If this is a `File` root scope, this has no value. + */ + SignatureType getType() { result = [this.asCallable(), this.asSummarizedCallable()].getType() } + /** + * Gets a string representation of this callable. + */ string toString() { result = this.asCallable().toString() or - result = "File scope: " + this.asFileScope().toString() + result = "File scope: " + this.asFileScope().toString() or + result = "Summary: " + this.asSummarizedCallable().toString() } + /** + * Holds if this callable is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { this.asCallable().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or - this.asFileScope().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + this.asFileScope().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or + this.asSummarizedCallable() + .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } } @@ -281,6 +306,7 @@ class DataFlowCall extends Expr { /** Gets the enclosing callable of this call. */ DataFlowCallable getEnclosingCallable() { + // NB. At present calls cannot occur inside summarized callables-- this will change if we implement advanced lambda support. result.asCallable().getFuncDef() = this.getEnclosingFunction() or not exists(this.getEnclosingFunction()) and result.asFileScope() = this.getFile() diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 7eedf1f911ec..7d84e645b666 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -17,7 +17,7 @@ private module FlowSummaries { class SummarizedCallableBase = Callable; -DataFlowCallable inject(SummarizedCallable c) { result.asCallable() = c } +DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c } /** Gets the parameter position of the instance parameter. */ ArgumentPosition callbackSelfParameterPosition() { result = -1 } @@ -189,9 +189,7 @@ class InterpretNode extends TInterpretNode { /** Gets the callable that this node corresponds to, if any. */ DataFlowCallable asCallable() { - result.asFunction() = this.asElement().asEntity() - or - result.asFuncLit() = this.asElement().asAstNode() + result.asSummarizedCallable().asFunction() = this.asElement().asEntity() } /** Gets the target of this call, if any. */ diff --git a/go/ql/lib/semmle/go/frameworks/Beego.qll b/go/ql/lib/semmle/go/frameworks/Beego.qll index d76ac8f23a13..edd622ab75a9 100644 --- a/go/ql/lib/semmle/go/frameworks/Beego.qll +++ b/go/ql/lib/semmle/go/frameworks/Beego.qll @@ -7,6 +7,7 @@ import go import semmle.go.security.Xss private import semmle.go.security.SafeUrlFlowCustomizations +// Some TaintTracking::FunctionModel subclasses remain because varargs functions don't work with Models-as-Data sumamries yet. /** * Provides classes for working with untrusted flow sources, sinks and taint propagators * from the [Beego](https://github.com/beego/beego) package. @@ -269,33 +270,6 @@ module Beego { override DataFlow::Node getAMessageComponent() { result = this.getAnArgument() } } - private class TopLevelTaintPropagators extends TaintTracking::FunctionModel { - string name; - - TopLevelTaintPropagators() { - this.hasQualifiedName(packagePath(), name) and - name in ["HTML2str", "Htmlquote", "Htmlunquote", "MapGet", "ParseForm", "Str2html", "Substr"] - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - name in ["HTML2str", "Htmlquote", "Htmlunquote", "MapGet", "Str2html", "Substr"] and - input.isParameter(0) and - output.isResult(0) - or - name = "ParseForm" and - input.isParameter(0) and - output.isParameter(1) - } - } - - private class ContextTaintPropagators extends TaintTracking::FunctionModel { - ContextTaintPropagators() { this.hasQualifiedName(contextPackagePath(), "WriteBody") } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isParameter(2) and output.isParameter(1) - } - } - private class HtmlQuoteSanitizer extends SharedXss::Sanitizer { HtmlQuoteSanitizer() { exists(DataFlow::CallNode c | c.getTarget().hasQualifiedName(packagePath(), "Htmlquote") | @@ -345,42 +319,11 @@ module Beego { } private class UtilsTaintPropagators extends TaintTracking::FunctionModel { - string name; - - UtilsTaintPropagators() { - this.hasQualifiedName(utilsPackagePath(), name) and - name in [ - "GetDisplayString", "SliceChunk", "SliceDiff", "SliceFilter", "SliceIntersect", - "SliceMerge", "SlicePad", "SliceRand", "SliceReduce", "SliceShuffle", "SliceUnique" - ] - } + UtilsTaintPropagators() { this.hasQualifiedName(utilsPackagePath(), "GetDisplayString") } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - name in [ - "GetDisplayString", "SliceIntersect", "SliceMerge", "SlicePad", "SliceRand", - "SliceShuffle", "SliceUnique" - ] and input.isParameter(_) and output.isResult(0) - or - name in ["SliceChunk", "SliceDiff", "SliceFilter", "SliceReduce"] and - input.isParameter(0) and - output.isResult(0) - } - } - - private class BeeMapModels extends TaintTracking::FunctionModel, Method { - string name; - - BeeMapModels() { - this.hasQualifiedName(utilsPackagePath(), "BeeMap", name) and - name in ["Get", "Set", "Items"] - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - name = "Set" and input.isParameter(1) and output.isReceiver() - or - name in ["Get", "Items"] and input.isReceiver() and output.isResult(0) } } } diff --git a/go/ql/lib/semmle/go/frameworks/Couchbase.qll b/go/ql/lib/semmle/go/frameworks/Couchbase.qll index a569cc6b3ab7..5eaa4d20c3ad 100644 --- a/go/ql/lib/semmle/go/frameworks/Couchbase.qll +++ b/go/ql/lib/semmle/go/frameworks/Couchbase.qll @@ -21,43 +21,6 @@ module Couchbase { ], "") } - /** - * Models of methods on `gocb/AnalyticsQuery` and `gocb/N1qlQuery` which which support a fluent - * interface by returning the receiver. They are not inherently relevant to taint. - */ - private class QueryMethodV1 extends TaintTracking::FunctionModel, Method { - QueryMethodV1() { - exists(string queryTypeName, string methodName | - queryTypeName = "AnalyticsQuery" and - methodName in [ - "ContextId", "Deferred", "Pretty", "Priority", "RawParam", "ServerSideTimeout" - ] - or - queryTypeName = "N1qlQuery" and - methodName in [ - "AdHoc", "Consistency", "ConsistentWith", "Custom", "PipelineBatch", "PipelineCap", - "Profile", "ReadOnly", "ScanCap", "Timeout" - ] - | - this.hasQualifiedName(packagePath(), queryTypeName, methodName) - ) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } - } - - private class QueryFromN1qlStatementV1 extends TaintTracking::FunctionModel { - QueryFromN1qlStatementV1() { - this.hasQualifiedName(packagePath(), ["NewAnalyticsQuery", "NewN1qlQuery"]) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isParameter(0) and outp.isResult() - } - } - /** * A query used in an API function acting on a `Bucket` or `Cluster` struct of v1 of * the official Couchbase Go library, gocb. diff --git a/go/ql/lib/semmle/go/frameworks/Echo.qll b/go/ql/lib/semmle/go/frameworks/Echo.qll index 2fde621cf448..3575292a92ad 100644 --- a/go/ql/lib/semmle/go/frameworks/Echo.qll +++ b/go/ql/lib/semmle/go/frameworks/Echo.qll @@ -39,26 +39,6 @@ private module Echo { } } - /** - * Models of `Context.Get/Set`. `Context` behaves like a map, with corresponding taint propagation. - */ - private class ContextMapModels extends TaintTracking::FunctionModel, Method { - FunctionInput input; - FunctionOutput output; - - ContextMapModels() { - exists(string methodName | this.hasQualifiedName(packagePath(), "Context", methodName) | - methodName = "Get" and input.isReceiver() and output.isResult() - or - methodName = "Set" and input.isParameter(1) and output.isReceiver() - ) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp = input and outp = output - } - } - /** * A call to a method on `Context` struct that unmarshals data into a target. */ diff --git a/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll b/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll index 42fb474a5f05..fbbbccb4e054 100644 --- a/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll +++ b/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll @@ -121,22 +121,4 @@ module ElazarlGoproxy { override DataFlow::Node getAMessageComponent() { result = this.getAnArgument() } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // Methods: - // signature: func CertStorage.Fetch(hostname string, gen func() (*tls.Certificate, error)) (*tls.Certificate, error) - // - // `hostname` excluded because if the cert storage or generator function themselves have not - // been tainted, `hostname` would be unlikely to fetch user-controlled data - this.hasQualifiedName(packagePath(), "CertStorage", "Fetch") and - (inp.isReceiver() or inp.isParameter(1)) and - outp.isResult(0) - } - - override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) { i = inp and o = outp } - } } diff --git a/go/ql/lib/semmle/go/frameworks/Email.qll b/go/ql/lib/semmle/go/frameworks/Email.qll index 340cdad3d108..3580aa8d7ae5 100644 --- a/go/ql/lib/semmle/go/frameworks/Email.qll +++ b/go/ql/lib/semmle/go/frameworks/Email.qll @@ -44,17 +44,6 @@ module EmailData { result = package("github.com/sendgrid/sendgrid-go", "helpers/mail") } - private class NewContent extends TaintTracking::FunctionModel { - NewContent() { - // func NewContent(contentType string, value string) *Content - this.hasQualifiedName(sendgridMail(), "NewContent") - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isParameter(1) and output.isResult() - } - } - /** A data-flow node that is written to an email using the sendgrid/sendgrid-go package. */ private class SendGridEmail extends Range { SendGridEmail() { @@ -79,6 +68,7 @@ module EmailData { } } +// These models are not implemented using Models-as-Data because they represent reverse flow. /** * A taint model of the `Writer.CreatePart` method from `mime/multipart`. * diff --git a/go/ql/lib/semmle/go/frameworks/Encoding.qll b/go/ql/lib/semmle/go/frameworks/Encoding.qll index 0bb0152db83c..201e2c9001d5 100644 --- a/go/ql/lib/semmle/go/frameworks/Encoding.qll +++ b/go/ql/lib/semmle/go/frameworks/Encoding.qll @@ -8,9 +8,7 @@ import go private string packagePath() { result = package("github.com/json-iterator/go", "") } /** A model of json-iterator's `Unmarshal` function, propagating taint from the JSON input to the decoded object. */ -private class JsonIteratorUnmarshalFunction extends TaintTracking::FunctionModel, - UnmarshalingFunction::Range -{ +private class JsonIteratorUnmarshalFunction extends UnmarshalingFunction::Range { JsonIteratorUnmarshalFunction() { this.hasQualifiedName(packagePath(), ["Unmarshal", "UnmarshalFromString"]) or @@ -22,8 +20,4 @@ private class JsonIteratorUnmarshalFunction extends TaintTracking::FunctionModel override DataFlow::FunctionOutput getOutput() { result.isParameter(1) } override string getFormat() { result = "JSON" } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } diff --git a/go/ql/lib/semmle/go/frameworks/EvanphxJsonPatch.qll b/go/ql/lib/semmle/go/frameworks/EvanphxJsonPatch.qll deleted file mode 100644 index 6408b3d1d4c2..000000000000 --- a/go/ql/lib/semmle/go/frameworks/EvanphxJsonPatch.qll +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Provides classes modeling `github.com/evanphx/json-patch`. - */ - -import go - -private module EvanphxJsonPatch { - /** Gets the package name `github.com/evanphx/json-patch`. */ - private string packagePath() { result = package("github.com/evanphx/json-patch", "") } - - private class MergeMergePatches extends TaintTracking::FunctionModel { - MergeMergePatches() { this.hasQualifiedName(packagePath(), "MergeMergePatches") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - (inp.isParameter(0) or inp.isParameter(1)) and - outp.isResult(0) - } - } - - private class MergePatch extends TaintTracking::FunctionModel { - MergePatch() { this.hasQualifiedName(packagePath(), "MergePatch") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - (inp.isParameter(0) or inp.isParameter(1)) and - outp.isResult(0) - } - } - - private class CreateMergePatch extends TaintTracking::FunctionModel { - CreateMergePatch() { this.hasQualifiedName(packagePath(), "CreateMergePatch") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - (inp.isParameter(0) or inp.isParameter(1)) and - outp.isResult(0) - } - } - - private class DecodePatch extends TaintTracking::FunctionModel { - DecodePatch() { this.hasQualifiedName(packagePath(), "DecodePatch") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and - outp.isResult(0) - } - } - - private class Apply extends TaintTracking::FunctionModel, Method { - Apply() { - exists(string fn | - fn in ["Apply", "ApplyWithOptions", "ApplyIndent", "ApplyIndentWithOptions"] - | - this.hasQualifiedName(packagePath(), "Patch", fn) - ) - } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - (inp.isParameter(0) or inp.isReceiver()) and - outp.isResult(0) - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/Gin.qll b/go/ql/lib/semmle/go/frameworks/Gin.qll index 87212868ae31..3ecda54c8e7b 100644 --- a/go/ql/lib/semmle/go/frameworks/Gin.qll +++ b/go/ql/lib/semmle/go/frameworks/Gin.qll @@ -35,22 +35,6 @@ private module Gin { } } - private class ParamsGet extends TaintTracking::FunctionModel, Method { - ParamsGet() { this.hasQualifiedName(packagePath(), "Params", "Get") } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult(0) - } - } - - private class ParamsByName extends TaintTracking::FunctionModel, Method { - ParamsByName() { this.hasQualifiedName(packagePath(), "Params", "ByName") } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } - } - /** * A call to a method on `Context` struct that unmarshals data into a target. */ diff --git a/go/ql/lib/semmle/go/frameworks/K8sIoApiCoreV1.qll b/go/ql/lib/semmle/go/frameworks/K8sIoApiCoreV1.qll index 02df3b4c7669..6fe789dccc35 100644 --- a/go/ql/lib/semmle/go/frameworks/K8sIoApiCoreV1.qll +++ b/go/ql/lib/semmle/go/frameworks/K8sIoApiCoreV1.qll @@ -9,27 +9,7 @@ module K8sIoApiCoreV1 { /** Gets the package name `k8s.io/api/core/v1`. */ string packagePath() { result = package("k8s.io/api", "core/v1") } - private class SecretDeepCopy extends TaintTracking::FunctionModel, Method { - FunctionOutput output; - - SecretDeepCopy() { - exists(string methodName | - methodName in ["DeepCopy", "DeepCopyObject"] and output.isResult() - or - methodName = "DeepCopyInto" and output.isParameter(0) - | - this.hasQualifiedName(packagePath(), ["Secret", "SecretList"], methodName) - ) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp = output - } - } - - private class SecretMarshal extends TaintTracking::FunctionModel, Method, - MarshalingFunction::Range - { + private class SecretMarshal extends MarshalingFunction::Range, Method { SecretMarshal() { this.hasQualifiedName(packagePath(), ["Secret", "SecretList"], "Marshal") } override DataFlow::FunctionInput getAnInput() { result.isReceiver() } @@ -37,15 +17,9 @@ module K8sIoApiCoreV1 { override DataFlow::FunctionOutput getOutput() { result.isResult(0) } override string getFormat() { result = "protobuf" } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } - private class SecretUnmarshal extends TaintTracking::FunctionModel, Method, - UnmarshalingFunction::Range - { + private class SecretUnmarshal extends UnmarshalingFunction::Range, Method { SecretUnmarshal() { this.hasQualifiedName(packagePath(), ["Secret", "SecretList"], "Unmarshal") } @@ -55,9 +29,5 @@ module K8sIoApiCoreV1 { override DataFlow::FunctionOutput getOutput() { result.isParameter(0) } override string getFormat() { result = "protobuf" } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } } diff --git a/go/ql/lib/semmle/go/frameworks/K8sIoApimachineryPkgRuntime.qll b/go/ql/lib/semmle/go/frameworks/K8sIoApimachineryPkgRuntime.qll index 081beebe9e9e..5f1a45945e7d 100644 --- a/go/ql/lib/semmle/go/frameworks/K8sIoApimachineryPkgRuntime.qll +++ b/go/ql/lib/semmle/go/frameworks/K8sIoApimachineryPkgRuntime.qll @@ -9,24 +9,7 @@ module K8sIoApimachineryPkgRuntime { /** Gets the package name `k8s.io/apimachinery/pkg/runtime`. */ string packagePath() { result = package("k8s.io/apimachinery", "pkg/runtime") } - private class ConvertTypeToType extends TaintTracking::FunctionModel { - ConvertTypeToType() { - this.hasQualifiedName(packagePath(), - [ - "Convert_Slice_string_To_Pointer_int64", "Convert_Slice_string_To_int", - "Convert_Slice_string_To_int64", "Convert_Slice_string_To_string", - "Convert_runtime_Object_To_runtime_RawExtension", - "Convert_runtime_RawExtension_To_runtime_Object", "Convert_string_To_Pointer_int64", - "Convert_string_To_int64" - ]) - } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isParameter(1) - } - } - - private class DecodeInto extends TaintTracking::FunctionModel, UnmarshalingFunction::Range { + private class DecodeInto extends UnmarshalingFunction::Range { DecodeInto() { this.hasQualifiedName(packagePath(), "DecodeInto") } override DataFlow::FunctionInput getAnInput() { result.isParameter(1) } @@ -37,21 +20,9 @@ module K8sIoApimachineryPkgRuntime { // The format is not fixed. It depends on parameter 1 or 2. none() } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } - private class DeepCopyJson extends TaintTracking::FunctionModel { - DeepCopyJson() { this.hasQualifiedName(packagePath(), ["DeepCopyJSON", "DeepCopyJSONValue"]) } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isResult() - } - } - - private class Encode extends TaintTracking::FunctionModel, MarshalingFunction::Range { + private class Encode extends MarshalingFunction::Range { Encode() { this.hasQualifiedName(packagePath(), ["Encode", "EncodeOrDie"]) } override DataFlow::FunctionInput getAnInput() { result.isParameter(1) } @@ -62,31 +33,9 @@ module K8sIoApimachineryPkgRuntime { // The format is not fixed. It depends on the receiver. none() } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } - } - - private class ReadField extends TaintTracking::FunctionModel { - ReadField() { this.hasQualifiedName(packagePath(), ["Field", "FieldPtr"]) } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isParameter(2) - } - } - - private class SetField extends TaintTracking::FunctionModel { - SetField() { this.hasQualifiedName(packagePath(), "SetField") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isParameter(1) - } } - private class CacheableObjectCacheEncode extends TaintTracking::FunctionModel, Method, - MarshalingFunction::Range - { + private class CacheableObjectCacheEncode extends MarshalingFunction::Range, Method { CacheableObjectCacheEncode() { this.implements(packagePath(), "CacheableObject", "CacheEncode") } @@ -99,23 +48,9 @@ module K8sIoApimachineryPkgRuntime { // The format is not fixed. It depends on the receiver. none() } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } - private class CacheableObjectGetObject extends TaintTracking::FunctionModel, Method { - CacheableObjectGetObject() { this.implements(packagePath(), "CacheableObject", "GetObject") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } - } - - private class DecoderDecode extends TaintTracking::FunctionModel, Method, - UnmarshalingFunction::Range - { + private class DecoderDecode extends Method, UnmarshalingFunction::Range { DecoderDecode() { this.implements(packagePath(), "Decoder", "Decode") or this.hasQualifiedName(packagePath(), "WithoutVersionDecoder", "Decode") @@ -129,15 +64,9 @@ module K8sIoApimachineryPkgRuntime { // The format is not fixed. It depends on the receiver. none() } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } - private class EncoderEncode extends TaintTracking::FunctionModel, Method, - MarshalingFunction::Range - { + private class EncoderEncode extends MarshalingFunction::Range, Method { EncoderEncode() { this.implements(packagePath(), "Encoder", "Encode") or this.hasQualifiedName(packagePath(), "WithVersionEncoder", "Encode") @@ -151,37 +80,9 @@ module K8sIoApimachineryPkgRuntime { // The format is not fixed. It depends on the receiver. none() } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } - } - - private class FramerNewFrameReader extends TaintTracking::FunctionModel, Method { - FramerNewFrameReader() { this.implements(packagePath(), "Framer", "NewFrameReader") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isResult() - } } - private class FramerNewFrameWriter extends TaintTracking::FunctionModel, Method { - FramerNewFrameWriter() { this.implements(packagePath(), "Framer", "NewFrameWriter") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isResult() - } - } - - private class ObjectDeepCopyObject extends TaintTracking::FunctionModel, Method { - ObjectDeepCopyObject() { this.implements(packagePath(), "Object", "DeepCopyObject") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } - } - - private class Decode extends TaintTracking::FunctionModel, UnmarshalingFunction::Range { + private class Decode extends UnmarshalingFunction::Range { Decode() { this.hasQualifiedName(packagePath(), "Decode") } override DataFlow::FunctionInput getAnInput() { result.isParameter(1) } @@ -192,59 +93,9 @@ module K8sIoApimachineryPkgRuntime { // The format is not fixed. It depends on the parameter 0. none() } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } - } - - private class NewEncodable extends TaintTracking::FunctionModel { - NewEncodable() { this.hasQualifiedName(packagePath(), ["NewEncodable", "NewEncodableList"]) } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(1) and outp.isResult() - } } - private class UseOrCreateObject extends TaintTracking::FunctionModel { - UseOrCreateObject() { this.hasQualifiedName(packagePath(), "UseOrCreateObject") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(3) and outp.isResult(0) - } - } - - private class ObjectConvertorConvert extends TaintTracking::FunctionModel, Method { - ObjectConvertorConvert() { this.implements(packagePath(), "ObjectConvertor", "Convert") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isParameter(1) - } - } - - private class ObjectConvertorConvertToVersion extends TaintTracking::FunctionModel, Method { - ObjectConvertorConvertToVersion() { - this.implements(packagePath(), "ObjectConvertor", "ConvertToVersion") - } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isResult(0) - } - } - - private class ObjectVersionerConvertToVersion extends TaintTracking::FunctionModel, Method { - ObjectVersionerConvertToVersion() { - this.implements(packagePath(), "ObjectVersioner", "ConvertToVersion") - } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isResult(0) - } - } - - private class ParameterCodecDecodeParameters extends TaintTracking::FunctionModel, Method, - UnmarshalingFunction::Range - { + private class ParameterCodecDecodeParameters extends Method, UnmarshalingFunction::Range { ParameterCodecDecodeParameters() { this.implements(packagePath(), "ParameterCodec", "DecodeParameters") } @@ -257,15 +108,9 @@ module K8sIoApimachineryPkgRuntime { // The format is not fixed. It depends on parameter 1. none() } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } - private class ParameterCodecEncodeParameters extends TaintTracking::FunctionModel, Method, - MarshalingFunction::Range - { + private class ParameterCodecEncodeParameters extends Method, MarshalingFunction::Range { ParameterCodecEncodeParameters() { this.implements(packagePath(), "ParameterCodec", "EncodeParameters") } @@ -278,15 +123,9 @@ module K8sIoApimachineryPkgRuntime { // The format is not fixed. It depends on parameter 1. none() } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } - private class ProtobufMarshallerMarshalTo extends TaintTracking::FunctionModel, Method, - MarshalingFunction::Range - { + private class ProtobufMarshallerMarshalTo extends Method, MarshalingFunction::Range { ProtobufMarshallerMarshalTo() { this.implements(packagePath(), "ProtobufMarshaller", "MarshalTo") or this.implements(packagePath(), "ProtobufReverseMarshaller", "MarshalToSizedBuffer") @@ -297,33 +136,9 @@ module K8sIoApimachineryPkgRuntime { override DataFlow::FunctionOutput getOutput() { result.isParameter(0) } override string getFormat() { result = "protobuf" } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } - } - - private class RawExtensionDeepCopy extends TaintTracking::FunctionModel, Method { - RawExtensionDeepCopy() { this.hasQualifiedName(packagePath(), "RawExtension", "DeepCopy") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } - } - - private class RawExtensionDeepCopyInto extends TaintTracking::FunctionModel, Method { - RawExtensionDeepCopyInto() { - this.hasQualifiedName(packagePath(), "RawExtension", "DeepCopyInto") - } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isReceiver() and outp.isParameter(0) - } } - private class RawExtensionMarshal extends TaintTracking::FunctionModel, Method, - MarshalingFunction::Range - { + private class RawExtensionMarshal extends Method, MarshalingFunction::Range { RawExtensionMarshal() { this.hasQualifiedName(packagePath(), "RawExtension", "Marshal") } override DataFlow::FunctionInput getAnInput() { result.isReceiver() } @@ -331,15 +146,9 @@ module K8sIoApimachineryPkgRuntime { override DataFlow::FunctionOutput getOutput() { result.isResult(0) } override string getFormat() { result = "protobuf" } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } - private class RawExtensionUnmarshal extends TaintTracking::FunctionModel, Method, - UnmarshalingFunction::Range - { + private class RawExtensionUnmarshal extends Method, UnmarshalingFunction::Range { RawExtensionUnmarshal() { this.hasQualifiedName(packagePath(), "RawExtension", "Unmarshal") } override DataFlow::FunctionInput getAnInput() { result.isReceiver() } @@ -347,33 +156,9 @@ module K8sIoApimachineryPkgRuntime { override DataFlow::FunctionOutput getOutput() { result.isParameter(0) } override string getFormat() { result = "protobuf" } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } - } - - private class UnknownDeepCopy extends TaintTracking::FunctionModel, Method { - UnknownDeepCopy() { - this.hasQualifiedName(packagePath(), "Unknown", ["DeepCopy", "DeepCopyObject"]) - } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } } - private class UnknownDeepCopyInto extends TaintTracking::FunctionModel, Method { - UnknownDeepCopyInto() { this.hasQualifiedName(packagePath(), "Unknown", "DeepCopyInto") } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isReceiver() and outp.isParameter(0) - } - } - - private class UnknownMarshal extends TaintTracking::FunctionModel, Method, - MarshalingFunction::Range - { + private class UnknownMarshal extends Method, MarshalingFunction::Range { string methodName; UnknownMarshal() { @@ -390,15 +175,9 @@ module K8sIoApimachineryPkgRuntime { } override string getFormat() { result = "protobuf" } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } } - private class UnknownUnmarshal extends TaintTracking::FunctionModel, Method, - UnmarshalingFunction::Range - { + private class UnknownUnmarshal extends Method, UnmarshalingFunction::Range { UnknownUnmarshal() { this.hasQualifiedName(packagePath(), "Unknown", "Unmarshal") } override DataFlow::FunctionInput getAnInput() { result.isReceiver() } @@ -406,29 +185,5 @@ module K8sIoApimachineryPkgRuntime { override DataFlow::FunctionOutput getOutput() { result.isParameter(0) } override string getFormat() { result = "protobuf" } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } - } - - private class UnstructuredUnstructuredContent extends TaintTracking::FunctionModel, Method { - UnstructuredUnstructuredContent() { - this.implements(packagePath(), "Unstructured", "UnstructuredContent") - } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } - } - - private class UnstructuredSetUnstructuredContent extends TaintTracking::FunctionModel, Method { - UnstructuredSetUnstructuredContent() { - this.implements(packagePath(), "Unstructured", "SetUnstructuredContent") - } - - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp.isParameter(0) and outp.isReceiver() - } } } diff --git a/go/ql/lib/semmle/go/frameworks/Protobuf.qll b/go/ql/lib/semmle/go/frameworks/Protobuf.qll index e1ad94907f62..550f99175604 100644 --- a/go/ql/lib/semmle/go/frameworks/Protobuf.qll +++ b/go/ql/lib/semmle/go/frameworks/Protobuf.qll @@ -23,7 +23,7 @@ module Protobuf { } /** The `Marshal` and `MarshalAppend` functions in the protobuf packages. */ - private class MarshalFunction extends TaintTracking::FunctionModel, MarshalingFunction::Range { + private class MarshalFunction extends MarshalingFunction::Range { string name; MarshalFunction() { @@ -34,10 +34,6 @@ module Protobuf { ) } - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } - override DataFlow::FunctionInput getAnInput() { if name = "MarshalAppend" then result.isParameter(1) else result.isParameter(0) } @@ -82,16 +78,12 @@ module Protobuf { } /** The `Unmarshal` function in the protobuf packages. */ - class UnmarshalFunction extends TaintTracking::FunctionModel, UnmarshalingFunction::Range { + class UnmarshalFunction extends UnmarshalingFunction::Range { UnmarshalFunction() { this.hasQualifiedName(protobufPackages(), "Unmarshal") or this.(Method).hasQualifiedName(modernProtobufPackage(), "UnmarshalOptions", "Unmarshal") } - override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { - inp = this.getAnInput() and outp = this.getOutput() - } - override DataFlow::FunctionInput getAnInput() { result.isParameter(0) } override DataFlow::FunctionOutput getOutput() { result.isParameter(1) } @@ -99,29 +91,11 @@ module Protobuf { override string getFormat() { result = "protobuf" } } - /** The `Merge` function in the protobuf packages. */ - private class MergeFunction extends TaintTracking::FunctionModel { - MergeFunction() { this.hasQualifiedName(protobufPackages(), "Merge") } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isParameter(1) and outp.isParameter(0) - } - } - /** A protobuf `Message` type. */ class MessageType extends Type { MessageType() { this.implements(protobufReflectPackage(), "ProtoMessage") } } - /** The `Clone` function in the protobuf packages. */ - private class MessageCloneFunction extends TaintTracking::FunctionModel { - MessageCloneFunction() { this.hasQualifiedName(protobufPackages(), "Clone") } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isParameter(0) and outp.isResult() - } - } - /** A `Get` method of a protobuf `Message` type. */ class GetMethod extends TaintTracking::FunctionModel, Method { GetMethod() { diff --git a/go/ql/lib/semmle/go/frameworks/Revel.qll b/go/ql/lib/semmle/go/frameworks/Revel.qll index c23cf87fba23..ea873a3972a6 100644 --- a/go/ql/lib/semmle/go/frameworks/Revel.qll +++ b/go/ql/lib/semmle/go/frameworks/Revel.qll @@ -8,7 +8,9 @@ private import semmle.go.security.OpenUrlRedirectCustomizations /** Provides classes and methods modeling the Revel web framework. */ module Revel { /** Gets the package name `github.com/revel/revel`. */ - string packagePath() { result = package(["github.com/revel", "github.com/robfig"], "revel") } + string packagePath() { + result = package(["github.com/revel", "github.com/robfig"] + "/revel", "") + } private class ControllerParams extends UntrustedFlowSource::Range, DataFlow::FieldReadNode { ControllerParams() { @@ -30,14 +32,6 @@ module Revel { } } - private class ParamsBind extends TaintTracking::FunctionModel, Method { - ParamsBind() { this.hasQualifiedName(packagePath(), "Params", ["Bind", "BindJSON"]) } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isParameter(0) - } - } - private class RouteMatchParams extends UntrustedFlowSource::Range, DataFlow::FieldReadNode { RouteMatchParams() { exists(Field f | @@ -75,24 +69,6 @@ module Revel { } } - private class ServerCookieGetValue extends TaintTracking::FunctionModel, Method { - ServerCookieGetValue() { this.implements(packagePath(), "ServerCookie", "GetValue") } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } - } - - private class ServerMultipartFormGetFiles extends TaintTracking::FunctionModel, Method { - ServerMultipartFormGetFiles() { - this.implements(packagePath(), "ServerMultipartForm", ["GetFiles", "GetValues"]) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } - } - private string contentTypeFromFilename(DataFlow::Node filename) { if filename.getStringValue().regexpMatch("(?i).*\\.html?") then result = "text/html" @@ -189,34 +165,6 @@ module Revel { override Http::ResponseWriter getResponseWriter() { none() } } - /** - * The getter and setter methods of `revel.RevelHeader`. - * - * Note we currently don't implement `HeaderWrite` and related concepts, as they are currently only used - * to track content-type, and directly setting headers does not seem to be the usual way to set the response - * content-type for this framework. If and when the `HeaderWrite` concept has a more abstract idea of the - * relationship between header-writes and HTTP responses than looking for a particular `http.ResponseWriter` - * instance connecting the two, then we may implement it here for completeness. - */ - private class RevelHeaderMethods extends TaintTracking::FunctionModel { - FunctionInput input; - FunctionOutput output; - - RevelHeaderMethods() { - exists(string name | this.(Method).hasQualifiedName(packagePath(), "RevelHeader", name) | - name = ["Add", "Set"] and input.isParameter([0, 1]) and output.isReceiver() - or - name = ["Get", "GetAll"] and input.isReceiver() and output.isResult() - or - name = "SetCookie" and input.isParameter(0) and output.isReceiver() - ) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp = input and outp = output - } - } - /** * A read in a Revel template that uses Revel's `raw` function. */ diff --git a/go/ql/lib/semmle/go/frameworks/SQL.qll b/go/ql/lib/semmle/go/frameworks/SQL.qll index b8b85d634c87..9e9e48550fc7 100644 --- a/go/ql/lib/semmle/go/frameworks/SQL.qll +++ b/go/ql/lib/semmle/go/frameworks/SQL.qll @@ -218,27 +218,6 @@ module SQL { ) } } - - /** A taint model for various methods on the struct `Formatter` of `go-pg/pg/orm`. */ - private class PgOrmFormatterFunction extends TaintTracking::FunctionModel, Method { - FunctionInput i; - FunctionOutput o; - - PgOrmFormatterFunction() { - exists(string m | this.hasQualifiedName(gopgorm(), "Formatter", m) | - // func (f Formatter) Append(dst []byte, src string, params ...interface{}) []byte - // func (f Formatter) AppendBytes(dst, src []byte, params ...interface{}) []byte - // func (f Formatter) FormatQuery(dst []byte, query string, params ...interface{}) []byte - (m = "Append" or m = "AppendBytes" or m = "FormatQuery") and - i.isParameter(1) and - (o.isParameter(0) or o.isResult()) - ) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp = i and outp = o - } - } } /** A model for sinks of GORM. */ diff --git a/go/ql/lib/semmle/go/frameworks/Spew.qll b/go/ql/lib/semmle/go/frameworks/Spew.qll index 6d44a33e97f8..7c4133dfd04a 100644 --- a/go/ql/lib/semmle/go/frameworks/Spew.qll +++ b/go/ql/lib/semmle/go/frameworks/Spew.qll @@ -45,6 +45,7 @@ module Spew { } } + // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. /** The `Sprint` function or one of its variants. */ class Sprinter extends TaintTracking::FunctionModel { Sprinter() { this.hasQualifiedName(packagePath(), ["Sdump", "Sprint", "Sprintln", "Sprintf"]) } diff --git a/go/ql/lib/semmle/go/frameworks/Stdlib.qll b/go/ql/lib/semmle/go/frameworks/Stdlib.qll index 232055ca7517..07648d027302 100644 --- a/go/ql/lib/semmle/go/frameworks/Stdlib.qll +++ b/go/ql/lib/semmle/go/frameworks/Stdlib.qll @@ -6,36 +6,19 @@ import go import semmle.go.frameworks.stdlib.ArchiveTar import semmle.go.frameworks.stdlib.ArchiveZip import semmle.go.frameworks.stdlib.Bufio -import semmle.go.frameworks.stdlib.Bytes -import semmle.go.frameworks.stdlib.CompressBzip2 import semmle.go.frameworks.stdlib.CompressFlate import semmle.go.frameworks.stdlib.CompressGzip import semmle.go.frameworks.stdlib.CompressLzw import semmle.go.frameworks.stdlib.CompressZlib -import semmle.go.frameworks.stdlib.ContainerHeap -import semmle.go.frameworks.stdlib.ContainerList -import semmle.go.frameworks.stdlib.ContainerRing -import semmle.go.frameworks.stdlib.Context -import semmle.go.frameworks.stdlib.Crypto -import semmle.go.frameworks.stdlib.CryptoCipher -import semmle.go.frameworks.stdlib.CryptoRsa import semmle.go.frameworks.stdlib.CryptoTls -import semmle.go.frameworks.stdlib.CryptoX509 import semmle.go.frameworks.stdlib.DatabaseSql -import semmle.go.frameworks.stdlib.Encoding -import semmle.go.frameworks.stdlib.EncodingAscii85 import semmle.go.frameworks.stdlib.EncodingAsn1 -import semmle.go.frameworks.stdlib.EncodingBase32 -import semmle.go.frameworks.stdlib.EncodingBase64 -import semmle.go.frameworks.stdlib.EncodingBinary import semmle.go.frameworks.stdlib.EncodingCsv import semmle.go.frameworks.stdlib.EncodingGob -import semmle.go.frameworks.stdlib.EncodingHex import semmle.go.frameworks.stdlib.EncodingJson import semmle.go.frameworks.stdlib.EncodingPem import semmle.go.frameworks.stdlib.EncodingXml import semmle.go.frameworks.stdlib.Errors -import semmle.go.frameworks.stdlib.Expvar import semmle.go.frameworks.stdlib.Fmt import semmle.go.frameworks.stdlib.Html import semmle.go.frameworks.stdlib.HtmlTemplate @@ -43,43 +26,26 @@ import semmle.go.frameworks.stdlib.Io import semmle.go.frameworks.stdlib.IoFs import semmle.go.frameworks.stdlib.IoIoutil import semmle.go.frameworks.stdlib.Log -import semmle.go.frameworks.stdlib.Mime import semmle.go.frameworks.stdlib.MimeMultipart import semmle.go.frameworks.stdlib.MimeQuotedprintable import semmle.go.frameworks.stdlib.Net import semmle.go.frameworks.stdlib.NetHttp import semmle.go.frameworks.stdlib.NetHttpHttputil -import semmle.go.frameworks.stdlib.NetMail import semmle.go.frameworks.stdlib.NetTextproto import semmle.go.frameworks.stdlib.Os import semmle.go.frameworks.stdlib.Path import semmle.go.frameworks.stdlib.PathFilepath import semmle.go.frameworks.stdlib.Reflect import semmle.go.frameworks.stdlib.Regexp -import semmle.go.frameworks.stdlib.Sort import semmle.go.frameworks.stdlib.Strconv import semmle.go.frameworks.stdlib.Strings -import semmle.go.frameworks.stdlib.Sync -import semmle.go.frameworks.stdlib.SyncAtomic import semmle.go.frameworks.stdlib.Syscall -import semmle.go.frameworks.stdlib.TextScanner import semmle.go.frameworks.stdlib.TextTabwriter import semmle.go.frameworks.stdlib.TextTemplate import semmle.go.frameworks.stdlib.Unsafe -/** A `String()` method. */ -class StringMethod extends TaintTracking::FunctionModel, Method { - StringMethod() { - this.getName() = "String" and - this.getNumParameter() = 0 and - this.getResultType(0) = Builtin::string_().getType() - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } -} - +// These are modeled using TaintTracking::FunctionModel because they doesn't have real type signatures, +// and therefore currently have an InvalidType, not a SignatureType, which breaks Models as Data. /** * A model of the built-in `append` function, which propagates taint from its arguments to its * result. @@ -130,49 +96,7 @@ module IntegerParser { /** Provides models of commonly used functions in the `net/url` package. */ module Url { - /** The `PathEscape` or `QueryEscape` function. */ - class Escaper extends TaintTracking::FunctionModel { - Escaper() { - this.hasQualifiedName("net/url", "PathEscape") or - this.hasQualifiedName("net/url", "QueryEscape") - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isParameter(0) and outp.isResult() - } - } - - /** The `PathUnescape` or `QueryUnescape` function. */ - class Unescaper extends TaintTracking::FunctionModel { - Unescaper() { - this.hasQualifiedName("net/url", "PathUnescape") or - this.hasQualifiedName("net/url", "QueryUnescape") - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isParameter(0) and outp.isResult(0) - } - } - - /** The `Parse`, `ParseQuery` or `ParseRequestURI` function, or the `URL.Parse` method. */ - class Parser extends TaintTracking::FunctionModel { - Parser() { - this.hasQualifiedName("net/url", "Parse") or - this.(Method).hasQualifiedName("net/url", "URL", "Parse") or - this.hasQualifiedName("net/url", "ParseQuery") or - this.hasQualifiedName("net/url", "ParseRequestURI") - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isParameter(0) and - outp.isResult(0) - or - this instanceof Method and - inp.isReceiver() and - outp.isResult(0) - } - } - + // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. /** The `JoinPath` function. */ class JoinPath extends TaintTracking::FunctionModel { JoinPath() { this.hasQualifiedName("net/url", "JoinPath") } @@ -193,75 +117,12 @@ module Url { } /** A method that returns a part of a URL. */ - class UrlGetter extends TaintTracking::FunctionModel, Method { + class UrlGetter extends Method { UrlGetter() { exists(string m | this.hasQualifiedName("net/url", "URL", m) | m = ["EscapedPath", "Hostname", "Port", "Query", "RequestURI"] ) } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } - } - - /** The method `URL.MarshalBinary`. */ - class UrlMarshalBinary extends TaintTracking::FunctionModel, Method { - UrlMarshalBinary() { this.hasQualifiedName("net/url", "URL", "MarshalBinary") } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult(0) - } - } - - /** The method `URL.ResolveReference`. */ - class UrlResolveReference extends TaintTracking::FunctionModel, Method { - UrlResolveReference() { this.hasQualifiedName("net/url", "URL", "ResolveReference") } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - (inp.isReceiver() or inp.isParameter(0)) and - outp.isResult() - } - } - - /** The function `User` or `UserPassword`. */ - class UserinfoConstructor extends TaintTracking::FunctionModel { - UserinfoConstructor() { - this.hasQualifiedName("net/url", "User") or - this.hasQualifiedName("net/url", "UserPassword") - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isParameter(_) and outp.isResult() - } - } - - /** A method that returns a part of a Userinfo struct. */ - class UserinfoGetter extends TaintTracking::FunctionModel, Method { - UserinfoGetter() { - exists(string m | this.hasQualifiedName("net/url", "Userinfo", m) | - m = "Password" or - m = "Username" - ) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult(0) - } - } - - /** A method that returns all or part of a Values map. */ - class ValuesGetter extends TaintTracking::FunctionModel, Method { - ValuesGetter() { - exists(string m | this.hasQualifiedName("net/url", "Values", m) | - m = "Encode" or - m = "Get" - ) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isReceiver() and outp.isResult() - } } } diff --git a/go/ql/lib/semmle/go/frameworks/Twirp.qll b/go/ql/lib/semmle/go/frameworks/Twirp.qll index 047280bc48a9..c4fc0737ac14 100644 --- a/go/ql/lib/semmle/go/frameworks/Twirp.qll +++ b/go/ql/lib/semmle/go/frameworks/Twirp.qll @@ -165,8 +165,8 @@ module Twirp { */ class Request extends UntrustedFlowSource::Range instanceof DataFlow::ParameterNode { Request() { - exists(Callable c, ServiceHandler handler | c.asFunction() = handler | - this.isParameterOf(c, 1) and + exists(FuncDef c, ServiceHandler handler | handler.getFuncDecl() = c | + this.asParameter().isParameterOf(c, 1) and handler.getParameterType(0).hasQualifiedName("context", "Context") and this.getType().(PointerType).getBaseType() instanceof ProtobufMessageType ) diff --git a/go/ql/lib/semmle/go/frameworks/XNetHtml.qll b/go/ql/lib/semmle/go/frameworks/XNetHtml.qll index f583b4dedba5..003c0e8570e1 100644 --- a/go/ql/lib/semmle/go/frameworks/XNetHtml.qll +++ b/go/ql/lib/semmle/go/frameworks/XNetHtml.qll @@ -14,47 +14,9 @@ module XNetHtml { /** Gets the package name `golang.org/x/net/html`. */ string packagePath() { result = package("golang.org/x/net", "html") } - private class EscapeString extends HtmlEscapeFunction, TaintTracking::FunctionModel { + private class EscapeString extends EscapeFunction::Range { EscapeString() { this.hasQualifiedName(packagePath(), "EscapeString") } - override predicate hasTaintFlow(DataFlow::FunctionInput input, DataFlow::FunctionOutput output) { - input.isParameter(0) and output.isResult() - } - } - - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionModels() { this.hasQualifiedName(packagePath(), _) } - - override predicate hasTaintFlow(DataFlow::FunctionInput input, DataFlow::FunctionOutput output) { - this.getName() = - [ - "UnescapeString", "Parse", "ParseFragment", "ParseFragmentWithOptions", - "ParseWithOptions", "NewTokenizer", "NewTokenizerFragment" - ] and - input.isParameter(0) and - output.isResult(0) - or - this.getName() = ["AppendChild", "InsertBefore"] and - input.isParameter(0) and - output.isReceiver() - or - this.getName() = "Render" and - input.isParameter(1) and - output.isParameter(0) - } - } - - private class TokenizerMethodModels extends Method, TaintTracking::FunctionModel { - TokenizerMethodModels() { this.hasQualifiedName(packagePath(), "Tokenizer", _) } - - // Note that `TagName` and the key part of `TagAttr` are not sources by default under the assumption - // that their character-set restrictions usually rule them out as useful attack routes. - override predicate hasTaintFlow(DataFlow::FunctionInput input, DataFlow::FunctionOutput output) { - this.getName() = ["Buffered", "Raw", "Text", "Token"] and - input.isReceiver() and - output.isResult(0) - or - this.getName() = "TagAttr" and input.isReceiver() and output.isResult(1) - } + override string kind() { result = "html" } } } diff --git a/go/ql/lib/semmle/go/frameworks/Yaml.qll b/go/ql/lib/semmle/go/frameworks/Yaml.qll index 583591c5e65c..22fc4f8c58c1 100644 --- a/go/ql/lib/semmle/go/frameworks/Yaml.qll +++ b/go/ql/lib/semmle/go/frameworks/Yaml.qll @@ -11,13 +11,9 @@ module Yaml { /** Gets a package path for the Yaml package. */ string packagePath() { result = package("gopkg.in/yaml", "") } - private class MarshalFunction extends TaintTracking::FunctionModel, MarshalingFunction::Range { + private class MarshalFunction extends MarshalingFunction::Range { MarshalFunction() { this.hasQualifiedName(packagePath(), "Marshal") } - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = this.getAnInput() and output = this.getOutput() - } - override DataFlow::FunctionInput getAnInput() { result.isParameter(0) } override DataFlow::FunctionOutput getOutput() { result.isResult(0) } @@ -25,13 +21,9 @@ module Yaml { override string getFormat() { result = "yaml" } } - private class UnmarshalFunction extends TaintTracking::FunctionModel, UnmarshalingFunction::Range { + private class UnmarshalFunction extends UnmarshalingFunction::Range { UnmarshalFunction() { this.hasQualifiedName(packagePath(), ["Unmarshal", "UnmarshalStrict"]) } - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = this.getAnInput() and output = this.getOutput() - } - override DataFlow::FunctionInput getAnInput() { result.isParameter(0) } override DataFlow::FunctionOutput getOutput() { result.isParameter(1) } @@ -39,27 +31,14 @@ module Yaml { override string getFormat() { result = "yaml" } } + // These models are not implemented using Models-as-Data because they represent reverse flow. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; FunctionOutput outp; FunctionModels() { - this.hasQualifiedName(packagePath(), "NewDecoder") and - (inp.isParameter(0) and outp.isResult()) - or this.hasQualifiedName(packagePath(), "NewEncoder") and (inp.isResult() and outp.isParameter(0)) - or - exists(Method m | this = m | - m.hasQualifiedName(packagePath(), ["Decoder", "Node"], "Decode") and - (inp.isReceiver() and outp.isParameter(0)) - or - m.hasQualifiedName(packagePath(), ["Encoder", "Node"], "Encode") and - (inp.isParameter(0) and outp.isReceiver()) - or - m.hasQualifiedName(packagePath(), "Node", "SetString") and - (inp.isParameter(0) and outp.isReceiver()) - ) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/Zap.qll b/go/ql/lib/semmle/go/frameworks/Zap.qll index 7ed7fcac064a..7041c45a3c69 100644 --- a/go/ql/lib/semmle/go/frameworks/Zap.qll +++ b/go/ql/lib/semmle/go/frameworks/Zap.qll @@ -48,24 +48,7 @@ module Zap { override DataFlow::Node getAMessageComponent() { result = this.getAnArgument() } } - /** A function that creates a `Field` that can be logged. */ - class FieldFunction extends TaintTracking::FunctionModel { - FieldFunction() { - exists(string fn | - fn in [ - "Any", "Binary", "ByteString", "ByteStrings", "Error", "Errors", "NamedError", - "Reflect", "String", "Stringp", "Strings" - ] - | - this.hasQualifiedName(packagePath(), fn) - ) - } - - override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { - inp.isParameter(_) and outp.isResult() - } - } - + // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. /** The function `Fields` that creates an `Option` that can be added to the logger out of `Field`s. */ class FieldsFunction extends TaintTracking::FunctionModel { FieldsFunction() { this.hasQualifiedName(packagePath(), "Fields") } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/ArchiveTar.qll b/go/ql/lib/semmle/go/frameworks/stdlib/ArchiveTar.qll index 81bae84c052d..1f7116ca8bb8 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/ArchiveTar.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/ArchiveTar.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `archive/tar` package. */ module ArchiveTar { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,10 +12,6 @@ module ArchiveTar { FunctionOutput outp; FunctionModels() { - // signature: func NewReader(r io.Reader) *Reader - hasQualifiedName("archive/tar", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewWriter(w io.Writer) *Writer hasQualifiedName("archive/tar", "NewWriter") and (inp.isResult() and outp.isParameter(0)) @@ -24,28 +21,4 @@ module ArchiveTar { input = inp and output = outp } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // Methods: - // signature: func (*Header) FileInfo() os.FileInfo - hasQualifiedName("archive/tar", "Header", "FileInfo") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Reader) Next() (*Header, error) - hasQualifiedName("archive/tar", "Reader", "Next") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Writer) WriteHeader(hdr *Header) error - hasQualifiedName("archive/tar", "Writer", "WriteHeader") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/ArchiveZip.qll b/go/ql/lib/semmle/go/frameworks/stdlib/ArchiveZip.qll index 8b25fd334fc9..bb09793768f1 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/ArchiveZip.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/ArchiveZip.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `archive/zip` package. */ module ArchiveZip { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,21 +12,9 @@ module ArchiveZip { FunctionOutput outp; FunctionModels() { - // signature: func FileInfoHeader(fi os.FileInfo) (*FileHeader, error) - hasQualifiedName("archive/zip", "FileInfoHeader") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func NewReader(r io.ReaderAt, size int64) (*Reader, error) - hasQualifiedName("archive/zip", "NewReader") and - (inp.isParameter(0) and outp.isResult(0)) - or // signature: func NewWriter(w io.Writer) *Writer hasQualifiedName("archive/zip", "NewWriter") and (inp.isResult() and outp.isParameter(0)) - or - // signature: func OpenReader(name string) (*ReadCloser, error) - hasQualifiedName("archive/zip", "OpenReader") and - (inp.isParameter(0) and outp.isResult(0)) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -38,18 +27,6 @@ module ArchiveZip { FunctionOutput outp; MethodModels() { - // signature: func (*File) Open() (io.ReadCloser, error) - hasQualifiedName("archive/zip", "File", "Open") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*File) OpenRaw() (io.Reader, error) - hasQualifiedName("archive/zip", "File", "OpenRaw") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Writer) Copy(f *File) error - hasQualifiedName("archive/zip", "Writer", "Copy") and - (inp.isParameter(0) and outp.isReceiver()) - or // signature: func (*Writer) Create(name string) (io.Writer, error) hasQualifiedName("archive/zip", "Writer", "Create") and (inp.isResult(0) and outp.isReceiver()) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Bufio.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Bufio.qll index dc0fa3a5cc6e..642e066eebab 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Bufio.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Bufio.qll @@ -19,6 +19,7 @@ module Bufio { FunctionInput getReader() { result.isParameter(0) } } + // These models are not implemented using Models-as-Data because they represent reverse flow. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; FunctionOutput outp; @@ -26,23 +27,7 @@ module Bufio { FunctionModels() { // signature: func NewReadWriter(r *Reader, w *Writer) *ReadWriter hasQualifiedName("bufio", "NewReadWriter") and - ( - inp.isParameter(0) and outp.isResult() - or - inp.isResult() and outp.isParameter(1) - ) - or - // signature: func NewReader(rd io.Reader) *Reader - hasQualifiedName("bufio", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func NewReaderSize(rd io.Reader, size int) *Reader - hasQualifiedName("bufio", "NewReaderSize") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func NewScanner(r io.Reader) *Scanner - hasQualifiedName("bufio", "NewScanner") and - (inp.isParameter(0) and outp.isResult()) + (inp.isResult() and outp.isParameter(1)) or // signature: func NewWriter(w io.Writer) *Writer hasQualifiedName("bufio", "NewWriter") and @@ -51,69 +36,6 @@ module Bufio { // signature: func NewWriterSize(w io.Writer, size int) *Writer hasQualifiedName("bufio", "NewWriterSize") and (inp.isResult() and outp.isParameter(0)) - or - // signature: func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) - hasQualifiedName("bufio", "ScanBytes") and - (inp.isParameter(0) and outp.isResult(1)) - or - // signature: func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) - hasQualifiedName("bufio", "ScanLines") and - (inp.isParameter(0) and outp.isResult(1)) - or - // signature: func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) - hasQualifiedName("bufio", "ScanRunes") and - (inp.isParameter(0) and outp.isResult(1)) - or - // signature: func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) - hasQualifiedName("bufio", "ScanWords") and - (inp.isParameter(0) and outp.isResult(1)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Reader) Peek(n int) ([]byte, error) - hasQualifiedName("bufio", "Reader", "Peek") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadBytes(delim byte) ([]byte, error) - hasQualifiedName("bufio", "Reader", "ReadBytes") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadLine() (line []byte, isPrefix bool, err error) - hasQualifiedName("bufio", "Reader", "ReadLine") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadSlice(delim byte) (line []byte, err error) - hasQualifiedName("bufio", "Reader", "ReadSlice") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadString(delim byte) (string, error) - hasQualifiedName("bufio", "Reader", "ReadString") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) Reset(r io.Reader) - hasQualifiedName("bufio", "Reader", "Reset") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Scanner) Bytes() []byte - hasQualifiedName("bufio", "Scanner", "Bytes") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Scanner) Text() string - hasQualifiedName("bufio", "Scanner", "Text") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Writer) Reset(w io.Writer) - hasQualifiedName("bufio", "Writer", "Reset") and - (inp.isReceiver() and outp.isParameter(0)) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Bytes.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Bytes.qll deleted file mode 100644 index 3d8df63f5fa6..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Bytes.qll +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `bytes` package. - */ - -import go - -/** Provides models of commonly used functions in the `bytes` package. */ -module Bytes { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - hasQualifiedName("bytes", "Clone") and - (inp.isParameter(0) and outp.isResult()) - or - hasQualifiedName("bytes", "Cut") and - (inp.isParameter(0) and outp.isResult([0, 1])) - or - hasQualifiedName("bytes", ["CutPrefix", "CutSuffix"]) and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func Fields(s []byte) [][]byte - hasQualifiedName("bytes", "Fields") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func FieldsFunc(s []byte, f func(rune) bool) [][]byte - hasQualifiedName("bytes", "FieldsFunc") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Join(s [][]byte, sep []byte) []byte - hasQualifiedName("bytes", "Join") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func Map(mapping func(r rune) rune, s []byte) []byte - hasQualifiedName("bytes", "Map") and - (inp.isParameter(1) and outp.isResult()) - or - // signature: func NewBuffer(buf []byte) *Buffer - hasQualifiedName("bytes", "NewBuffer") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func NewBufferString(s string) *Buffer - hasQualifiedName("bytes", "NewBufferString") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func NewReader(b []byte) *Reader - hasQualifiedName("bytes", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Repeat(b []byte, count int) []byte - hasQualifiedName("bytes", "Repeat") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Replace(s []byte, old []byte, new []byte, n int) []byte - hasQualifiedName("bytes", "Replace") and - (inp.isParameter([0, 2]) and outp.isResult()) - or - // signature: func ReplaceAll(s []byte, old []byte, new []byte) []byte - hasQualifiedName("bytes", "ReplaceAll") and - (inp.isParameter([0, 2]) and outp.isResult()) - or - // signature: func Runes(s []byte) []rune - hasQualifiedName("bytes", "Runes") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Split(s []byte, sep []byte) [][]byte - hasQualifiedName("bytes", "Split") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func SplitAfter(s []byte, sep []byte) [][]byte - hasQualifiedName("bytes", "SplitAfter") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func SplitAfterN(s []byte, sep []byte, n int) [][]byte - hasQualifiedName("bytes", "SplitAfterN") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func SplitN(s []byte, sep []byte, n int) [][]byte - hasQualifiedName("bytes", "SplitN") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Title(s []byte) []byte - hasQualifiedName("bytes", "Title") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ToLower(s []byte) []byte - hasQualifiedName("bytes", "ToLower") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte - hasQualifiedName("bytes", "ToLowerSpecial") and - (inp.isParameter(1) and outp.isResult()) - or - // signature: func ToTitle(s []byte) []byte - hasQualifiedName("bytes", "ToTitle") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte - hasQualifiedName("bytes", "ToTitleSpecial") and - (inp.isParameter(1) and outp.isResult()) - or - // signature: func ToUpper(s []byte) []byte - hasQualifiedName("bytes", "ToUpper") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte - hasQualifiedName("bytes", "ToUpperSpecial") and - (inp.isParameter(1) and outp.isResult()) - or - // signature: func ToValidUTF8(s []byte, replacement []byte) []byte - hasQualifiedName("bytes", "ToValidUTF8") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func Trim(s []byte, cutset string) []byte - hasQualifiedName("bytes", "Trim") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimFunc(s []byte, f func(r rune) bool) []byte - hasQualifiedName("bytes", "TrimFunc") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimLeft(s []byte, cutset string) []byte - hasQualifiedName("bytes", "TrimLeft") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimLeftFunc(s []byte, f func(r rune) bool) []byte - hasQualifiedName("bytes", "TrimLeftFunc") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimPrefix(s []byte, prefix []byte) []byte - hasQualifiedName("bytes", "TrimPrefix") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimRight(s []byte, cutset string) []byte - hasQualifiedName("bytes", "TrimRight") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimRightFunc(s []byte, f func(r rune) bool) []byte - hasQualifiedName("bytes", "TrimRightFunc") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimSpace(s []byte) []byte - hasQualifiedName("bytes", "TrimSpace") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimSuffix(s []byte, suffix []byte) []byte - hasQualifiedName("bytes", "TrimSuffix") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Buffer) Bytes() []byte - hasQualifiedName("bytes", "Buffer", "Bytes") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Buffer) Next(n int) []byte - hasQualifiedName("bytes", "Buffer", "Next") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Buffer) ReadBytes(delim byte) (line []byte, err error) - hasQualifiedName("bytes", "Buffer", "ReadBytes") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Buffer) ReadString(delim byte) (line string, err error) - hasQualifiedName("bytes", "Buffer", "ReadString") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) Reset(b []byte) - hasQualifiedName("bytes", "Reader", "Reset") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/CompressBzip2.qll b/go/ql/lib/semmle/go/frameworks/stdlib/CompressBzip2.qll deleted file mode 100644 index ff2818434fc4..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/CompressBzip2.qll +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `compress/bzip2` package. - */ - -import go - -/** Provides models of commonly used functions in the `compress/bzip2` package. */ -module CompressBzip2 { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func NewReader(r io.Reader) io.Reader - hasQualifiedName("compress/bzip2", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/CompressFlate.qll b/go/ql/lib/semmle/go/frameworks/stdlib/CompressFlate.qll index a26ad9676990..461f101162c3 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/CompressFlate.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/CompressFlate.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `compress/flate` package. */ module CompressFlate { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,14 +12,6 @@ module CompressFlate { FunctionOutput outp; FunctionModels() { - // signature: func NewReader(r io.Reader) io.ReadCloser - hasQualifiedName("compress/flate", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser - hasQualifiedName("compress/flate", "NewReaderDict") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewWriter(w io.Writer, level int) (*Writer, error) hasQualifiedName("compress/flate", "NewWriter") and (inp.isResult(0) and outp.isParameter(0)) @@ -32,23 +25,4 @@ module CompressFlate { input = inp and output = outp } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Writer) Reset(dst io.Writer) - hasQualifiedName("compress/flate", "Writer", "Reset") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (Resetter) Reset(r io.Reader, dict []byte) error - implements("compress/flate", "Resetter", "Reset") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/CompressGzip.qll b/go/ql/lib/semmle/go/frameworks/stdlib/CompressGzip.qll index 366f8c7a6348..86f6824ec5e3 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/CompressGzip.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/CompressGzip.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `compress/gzip` package. */ module CompressGzip { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,10 +12,6 @@ module CompressGzip { FunctionOutput outp; FunctionModels() { - // signature: func NewReader(r io.Reader) (*Reader, error) - hasQualifiedName("compress/gzip", "NewReader") and - (inp.isParameter(0) and outp.isResult(0)) - or // signature: func NewWriter(w io.Writer) *Writer hasQualifiedName("compress/gzip", "NewWriter") and (inp.isResult() and outp.isParameter(0)) @@ -28,23 +25,4 @@ module CompressGzip { input = inp and output = outp } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Reader) Reset(r io.Reader) error - hasQualifiedName("compress/gzip", "Reader", "Reset") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Writer) Reset(w io.Writer) - hasQualifiedName("compress/gzip", "Writer", "Reset") and - (inp.isReceiver() and outp.isParameter(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/CompressLzw.qll b/go/ql/lib/semmle/go/frameworks/stdlib/CompressLzw.qll index 1861d4991fd4..f17dac3941c2 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/CompressLzw.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/CompressLzw.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `compress/lzw` package. */ module CompressLzw { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,10 +12,6 @@ module CompressLzw { FunctionOutput outp; FunctionModels() { - // signature: func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser - hasQualifiedName("compress/lzw", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewWriter(w io.Writer, order Order, litWidth int) io.WriteCloser hasQualifiedName("compress/lzw", "NewWriter") and (inp.isResult() and outp.isParameter(0)) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/CompressZlib.qll b/go/ql/lib/semmle/go/frameworks/stdlib/CompressZlib.qll index ab88b6319aab..9614f3ee77b0 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/CompressZlib.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/CompressZlib.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `compress/zlib` package. */ module CompressZlib { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,14 +12,6 @@ module CompressZlib { FunctionOutput outp; FunctionModels() { - // signature: func NewReader(r io.Reader) (io.ReadCloser, error) - hasQualifiedName("compress/zlib", "NewReader") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) - hasQualifiedName("compress/zlib", "NewReaderDict") and - (inp.isParameter(0) and outp.isResult(0)) - or // signature: func NewWriter(w io.Writer) *Writer hasQualifiedName("compress/zlib", "NewWriter") and (inp.isResult() and outp.isParameter(0)) @@ -36,23 +29,4 @@ module CompressZlib { input = inp and output = outp } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Writer) Reset(w io.Writer) - hasQualifiedName("compress/zlib", "Writer", "Reset") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (Resetter) Reset(r io.Reader, dict []byte) error - implements("compress/zlib", "Resetter", "Reset") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/ContainerHeap.qll b/go/ql/lib/semmle/go/frameworks/stdlib/ContainerHeap.qll deleted file mode 100644 index ddd8c602c51e..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/ContainerHeap.qll +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `container/heap` package. - */ - -import go - -/** Provides models of commonly used functions in the `container/heap` package. */ -module ContainerHeap { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func Pop(h Interface) interface{} - hasQualifiedName("container/heap", "Pop") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Push(h Interface, x interface{}) - hasQualifiedName("container/heap", "Push") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func Remove(h Interface, i int) interface{} - hasQualifiedName("container/heap", "Remove") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (Interface) Pop() interface{} - implements("container/heap", "Interface", "Pop") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Interface) Push(x interface{}) - implements("container/heap", "Interface", "Push") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/ContainerList.qll b/go/ql/lib/semmle/go/frameworks/stdlib/ContainerList.qll deleted file mode 100644 index 6efa1e96b8e4..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/ContainerList.qll +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `container/list` package. - */ - -import go - -/** Provides models of commonly used functions in the `container/list` package. */ -module ContainerList { - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Element) Next() *Element - hasQualifiedName("container/list", "Element", "Next") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Element) Prev() *Element - hasQualifiedName("container/list", "Element", "Prev") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*List) Back() *Element - hasQualifiedName("container/list", "List", "Back") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*List) Front() *Element - hasQualifiedName("container/list", "List", "Front") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*List) Init() *List - hasQualifiedName("container/list", "List", "Init") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*List) InsertAfter(v interface{}, mark *Element) *Element - hasQualifiedName("container/list", "List", "InsertAfter") and - ( - inp.isParameter(0) and - (outp.isReceiver() or outp.isResult()) - ) - or - // signature: func (*List) InsertBefore(v interface{}, mark *Element) *Element - hasQualifiedName("container/list", "List", "InsertBefore") and - ( - inp.isParameter(0) and - (outp.isReceiver() or outp.isResult()) - ) - or - // signature: func (*List) MoveAfter(e *Element, mark *Element) - hasQualifiedName("container/list", "List", "MoveAfter") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*List) MoveBefore(e *Element, mark *Element) - hasQualifiedName("container/list", "List", "MoveBefore") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*List) MoveToBack(e *Element) - hasQualifiedName("container/list", "List", "MoveToBack") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*List) MoveToFront(e *Element) - hasQualifiedName("container/list", "List", "MoveToFront") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*List) PushBack(v interface{}) *Element - hasQualifiedName("container/list", "List", "PushBack") and - ( - inp.isParameter(0) and - (outp.isReceiver() or outp.isResult()) - ) - or - // signature: func (*List) PushBackList(other *List) - hasQualifiedName("container/list", "List", "PushBackList") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*List) PushFront(v interface{}) *Element - hasQualifiedName("container/list", "List", "PushFront") and - ( - inp.isParameter(0) and - (outp.isReceiver() or outp.isResult()) - ) - or - // signature: func (*List) PushFrontList(other *List) - hasQualifiedName("container/list", "List", "PushFrontList") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*List) Remove(e *Element) interface{} - hasQualifiedName("container/list", "List", "Remove") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/ContainerRing.qll b/go/ql/lib/semmle/go/frameworks/stdlib/ContainerRing.qll deleted file mode 100644 index 7463c0455f6d..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/ContainerRing.qll +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `container/ring` package. - */ - -import go - -/** Provides models of commonly used functions in the `container/ring` package. */ -module ContainerRing { - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Ring) Link(s *Ring) *Ring - hasQualifiedName("container/ring", "Ring", "Link") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Ring) Move(n int) *Ring - hasQualifiedName("container/ring", "Ring", "Move") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Ring) Next() *Ring - hasQualifiedName("container/ring", "Ring", "Next") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Ring) Prev() *Ring - hasQualifiedName("container/ring", "Ring", "Prev") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Ring) Unlink(n int) *Ring - hasQualifiedName("container/ring", "Ring", "Unlink") and - (inp.isReceiver() and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Context.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Context.qll deleted file mode 100644 index d65aa5c68ddb..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Context.qll +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `context` package. - */ - -import go - -/** Provides models of commonly used functions in the `context` package. */ -module Context { - /** - * Gets the package name `context` or `golang.org/x/net/context`. - * - * The two packages are identical; before Go 1.7 it was only available - * under `golang.org/x`; as of Go 1.7 it is included in the standard library. - */ - private string packagePath() { result = ["context", package("golang.org/x/net", "context")] } - - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func WithCancel(parent Context) (ctx Context, cancel CancelFunc) - hasQualifiedName(packagePath(), "WithCancel") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) - hasQualifiedName(packagePath(), "WithDeadline") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) - hasQualifiedName(packagePath(), "WithTimeout") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func WithValue(parent Context, key interface{}, val interface{}) Context - hasQualifiedName(packagePath(), "WithValue") and - (inp.isParameter(_) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (Context) Value(key interface{}) interface{} - implements(packagePath(), "Context", "Value") and - (inp.isReceiver() and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Crypto.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Crypto.qll deleted file mode 100644 index f1517304f7cb..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Crypto.qll +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `crypto` package. - */ - -import go - -/** Provides models of commonly used functions in the `crypto` package. */ -module Crypto { - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (Decrypter) Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error) - implements("crypto", "Decrypter", "Decrypt") and - (inp.isParameter(1) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/CryptoCipher.qll b/go/ql/lib/semmle/go/frameworks/stdlib/CryptoCipher.qll deleted file mode 100644 index a4817fe03b09..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/CryptoCipher.qll +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `crypto/cipher` package. - */ - -import go - -/** Provides models of commonly used functions in the `crypto/cipher` package. */ -module CryptoCipher { - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (Block) Decrypt(dst []byte, src []byte) - implements("crypto/cipher", "Block", "Decrypt") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func (AEAD) Open(dst []byte, nonce []byte, ciphertext []byte, additionalData []byte) ([]byte, error) - implements("crypto/cipher", "AEAD", "Open") and - ( - inp.isParameter(2) and - (outp.isParameter(0) or outp.isResult(0)) - ) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/CryptoRsa.qll b/go/ql/lib/semmle/go/frameworks/stdlib/CryptoRsa.qll deleted file mode 100644 index 6b48847d6bf6..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/CryptoRsa.qll +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `crypto/rsa` package. - */ - -import go - -/** Provides models of commonly used functions in the `crypto/rsa` package. */ -module CryptoRsa { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) - hasQualifiedName("crypto/rsa", "DecryptOAEP") and - (inp.isParameter(3) and outp.isResult(0)) - or - // signature: func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) - hasQualifiedName("crypto/rsa", "DecryptPKCS1v15") and - (inp.isParameter(2) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) - hasQualifiedName("crypto/rsa", "PrivateKey", "Decrypt") and - (inp.isParameter(1) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/CryptoTls.qll b/go/ql/lib/semmle/go/frameworks/stdlib/CryptoTls.qll index d1d706864087..5ad1f84cabc4 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/CryptoTls.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/CryptoTls.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `crypto/tls` package. */ module CryptoTls { private class FunctionModels extends TaintTracking::FunctionModel { @@ -13,23 +14,11 @@ module CryptoTls { FunctionModels() { // signature: func Client(conn net.Conn, config *Config) *Conn hasQualifiedName("crypto/tls", "Client") and - ( - inp.isParameter(0) and outp.isResult() - or - inp.isResult() and outp.isParameter(0) - ) - or - // signature: func NewListener(inner net.Listener, config *Config) net.Listener - hasQualifiedName("crypto/tls", "NewListener") and - (inp.isParameter(0) and outp.isResult()) + (inp.isResult() and outp.isParameter(0)) or // signature: func Server(conn net.Conn, config *Config) *Conn hasQualifiedName("crypto/tls", "Server") and - ( - inp.isParameter(0) and outp.isResult() - or - inp.isResult() and outp.isParameter(0) - ) + (inp.isResult() and outp.isParameter(0)) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/CryptoX509.qll b/go/ql/lib/semmle/go/frameworks/stdlib/CryptoX509.qll deleted file mode 100644 index 0137dfde5a90..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/CryptoX509.qll +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `crypto/x509` package. - */ - -import go - -/** Provides models of commonly used functions in the `crypto/x509` package. */ -module CryptoX509 { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func DecryptPEMBlock(b *encoding/pem.Block, password []byte) ([]byte, error) - hasQualifiedName("crypto/x509", "DecryptPEMBlock") and - (inp.isParameter(0) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll b/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll index 0f5ee6619df1..845225af5bd2 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/DatabaseSql.qll @@ -108,21 +108,7 @@ module DatabaseSql { } } - private class SqlFunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - SqlFunctionModels() { - // signature: func Named(name string, value interface{}) NamedArg - this.hasQualifiedName("database/sql", "Named") and - (inp.isParameter(_) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - + // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. private class SqlMethodModels extends TaintTracking::FunctionModel, Method { FunctionInput inp; FunctionOutput outp; @@ -135,53 +121,6 @@ module DatabaseSql { // signature: func (*Rows) Scan(dest ...interface{}) error this.hasQualifiedName("database/sql", "Rows", "Scan") and (inp.isReceiver() and outp.isParameter(_)) - or - // signature: func (Scanner) Scan(src interface{}) error - this.implements("database/sql", "Scanner", "Scan") and - (inp.isParameter(0) and outp.isReceiver()) - or - // Prepare methods - this.hasQualifiedName("database/sql", ["Tx", "DB"], "Prepare") and - (inp.isParameter(0) and outp.isResult(0)) - or - // PrepareContext methods - this.hasQualifiedName("database/sql", ["Tx", "DB", "Conn"], "PrepareContext") and - (inp.isParameter(1) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class SqlDriverMethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - SqlDriverMethodModels() { - // signature: func (NotNull) ConvertValue(v interface{}) (Value, error) - this.hasQualifiedName("database/sql/driver", "NotNull", "ConvertValue") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func (Null) ConvertValue(v interface{}) (Value, error) - this.hasQualifiedName("database/sql/driver", "Null", "ConvertValue") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func (ValueConverter) ConvertValue(v interface{}) (Value, error) - this.implements("database/sql/driver", "ValueConverter", "ConvertValue") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func (Conn) Prepare(query string) (Stmt, error) - this.implements("database/sql/driver", "Conn", "Prepare") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func (ConnPrepareContext) PrepareContext(ctx context.Context, query string) (Stmt, error) - this.implements("database/sql/driver", "ConnPrepareContext", "PrepareContext") and - (inp.isParameter(1) and outp.isResult(0)) - or - // signature: func (Valuer) Value() (Value, error) - this.implements("database/sql/driver", "Valuer", "Value") and - (inp.isReceiver() and outp.isResult(0)) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Encoding.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Encoding.qll deleted file mode 100644 index 767d2d64cd84..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Encoding.qll +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `encoding` package. - */ - -import go - -/** Provides models of commonly used functions in the `encoding` package. */ -module Encoding { - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (BinaryMarshaler) MarshalBinary() (data []byte, err error) - implements("encoding", "BinaryMarshaler", "MarshalBinary") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (TextMarshaler) MarshalText() (text []byte, err error) - implements("encoding", "TextMarshaler", "MarshalText") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (BinaryUnmarshaler) UnmarshalBinary(data []byte) error - implements("encoding", "BinaryUnmarshaler", "UnmarshalBinary") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (TextUnmarshaler) UnmarshalText(text []byte) error - implements("encoding", "TextUnmarshaler", "UnmarshalText") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingAscii85.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingAscii85.qll deleted file mode 100644 index 5c9cae933c19..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingAscii85.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `encoding/ascii85` package. - */ - -import go - -/** Provides models of commonly used functions in the `encoding/ascii85` package. */ -module EncodingAscii85 { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func Decode(dst []byte, src []byte, flush bool) (ndst int, nsrc int, err error) - hasQualifiedName("encoding/ascii85", "Decode") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func NewDecoder(r io.Reader) io.Reader - hasQualifiedName("encoding/ascii85", "NewDecoder") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingAsn1.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingAsn1.qll index f0ae25d9fbe0..2e0a07a12c87 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingAsn1.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingAsn1.qll @@ -33,37 +33,4 @@ module EncodingAsn1 { override string getFormat() { result = "ASN1" } } - - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func Marshal(val interface{}) ([]byte, error) - hasQualifiedName("encoding/asn1", "Marshal") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func MarshalWithParams(val interface{}, params string) ([]byte, error) - hasQualifiedName("encoding/asn1", "MarshalWithParams") and - (inp.isParameter(_) and outp.isResult(0)) - or - // signature: func Unmarshal(b []byte, val interface{}) (rest []byte, err error) - hasQualifiedName("encoding/asn1", "Unmarshal") and - ( - inp.isParameter(0) and - (outp.isParameter(1) or outp.isResult(0)) - ) - or - // signature: func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err error) - hasQualifiedName("encoding/asn1", "UnmarshalWithParams") and - ( - inp.isParameter([0, 2]) and - (outp.isParameter(1) or outp.isResult(0)) - ) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingBase32.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingBase32.qll deleted file mode 100644 index d1eae83abc2a..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingBase32.qll +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `encoding/base32` package. - */ - -import go - -/** Provides models of commonly used functions in the `encoding/base32` package. */ -module EncodingBase32 { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func NewDecoder(enc *Encoding, r io.Reader) io.Reader - hasQualifiedName("encoding/base32", "NewDecoder") and - (inp.isParameter(1) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Encoding) Decode(dst []byte, src []byte) (n int, err error) - hasQualifiedName("encoding/base32", "Encoding", "Decode") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func (*Encoding) DecodeString(s string) ([]byte, error) - hasQualifiedName("encoding/base32", "Encoding", "DecodeString") and - (inp.isParameter(0) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingBase64.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingBase64.qll deleted file mode 100644 index 82a68b5d0c24..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingBase64.qll +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `encoding/base64` package. - */ - -import go - -/** Provides models of commonly used functions in the `encoding/base64` package. */ -module EncodingBase64 { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func NewDecoder(enc *Encoding, r io.Reader) io.Reader - hasQualifiedName("encoding/base64", "NewDecoder") and - (inp.isParameter(1) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Encoding) Decode(dst []byte, src []byte) (n int, err error) - hasQualifiedName("encoding/base64", "Encoding", "Decode") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func (*Encoding) DecodeString(s string) ([]byte, error) - hasQualifiedName("encoding/base64", "Encoding", "DecodeString") and - (inp.isParameter(0) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingBinary.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingBinary.qll deleted file mode 100644 index 71c3c55987bf..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingBinary.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `encoding/binary` package. - */ - -import go - -/** Provides models of commonly used functions in the `encoding/binary` package. */ -module EncodingBinary { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func Read(r io.Reader, order ByteOrder, data interface{}) error - hasQualifiedName("encoding/binary", "Read") and - (inp.isParameter(0) and outp.isParameter(2)) - or - // signature: func Write(w io.Writer, order ByteOrder, data interface{}) error - hasQualifiedName("encoding/binary", "Write") and - (inp.isParameter(2) and outp.isParameter(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingCsv.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingCsv.qll index 481dce5a5fd4..0949cbf62e7c 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingCsv.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingCsv.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `encoding/csv` package. */ module EncodingCsv { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,10 +12,6 @@ module EncodingCsv { FunctionOutput outp; FunctionModels() { - // signature: func NewReader(r io.Reader) *Reader - hasQualifiedName("encoding/csv", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewWriter(w io.Writer) *Writer hasQualifiedName("encoding/csv", "NewWriter") and (inp.isResult() and outp.isParameter(0)) @@ -24,31 +21,4 @@ module EncodingCsv { input = inp and output = outp } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Reader) Read() (record []string, err error) - hasQualifiedName("encoding/csv", "Reader", "Read") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadAll() (records [][]string, err error) - hasQualifiedName("encoding/csv", "Reader", "ReadAll") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Writer) Write(record []string) error - hasQualifiedName("encoding/csv", "Writer", "Write") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Writer) WriteAll(records [][]string) error - hasQualifiedName("encoding/csv", "Writer", "WriteAll") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingGob.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingGob.qll index 19f7c1c60042..a19f4689cf1f 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingGob.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingGob.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `encoding/gob` package. */ module EncodingGob { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,10 +12,6 @@ module EncodingGob { FunctionOutput outp; FunctionModels() { - // signature: func NewDecoder(r io.Reader) *Decoder - hasQualifiedName("encoding/gob", "NewDecoder") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewEncoder(w io.Writer) *Encoder hasQualifiedName("encoding/gob", "NewEncoder") and (inp.isResult() and outp.isParameter(0)) @@ -24,39 +21,4 @@ module EncodingGob { input = inp and output = outp } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Decoder) Decode(e interface{}) error - hasQualifiedName("encoding/gob", "Decoder", "Decode") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Decoder) DecodeValue(v reflect.Value) error - hasQualifiedName("encoding/gob", "Decoder", "DecodeValue") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Encoder) Encode(e interface{}) error - hasQualifiedName("encoding/gob", "Encoder", "Encode") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Encoder) EncodeValue(value reflect.Value) error - hasQualifiedName("encoding/gob", "Encoder", "EncodeValue") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (GobDecoder) GobDecode([]byte) error - implements("encoding/gob", "GobDecoder", "GobDecode") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (GobEncoder) GobEncode() ([]byte, error) - implements("encoding/gob", "GobEncoder", "GobEncode") and - (inp.isReceiver() and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingHex.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingHex.qll deleted file mode 100644 index c76c414a5a6e..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingHex.qll +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `encoding/hex` package. - */ - -import go - -/** Provides models of commonly used functions in the `encoding/hex` package. */ -module EncodingHex { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func Decode(dst []byte, src []byte) (int, error) - hasQualifiedName("encoding/hex", "Decode") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func DecodeString(s string) ([]byte, error) - hasQualifiedName("encoding/hex", "DecodeString") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func NewDecoder(r io.Reader) io.Reader - hasQualifiedName("encoding/hex", "NewDecoder") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingJson.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingJson.qll index 9e82a838ab09..f38db392bd01 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingJson.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingJson.qll @@ -33,81 +33,15 @@ module EncodingJson { override string getFormat() { result = "JSON" } } + // These models are not implemented using Models-as-Data because they represent reverse flow. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; FunctionOutput outp; FunctionModels() { - // signature: func Compact(dst *bytes.Buffer, src []byte) error - this.hasQualifiedName("encoding/json", "Compact") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func HTMLEscape(dst *bytes.Buffer, src []byte) - this.hasQualifiedName("encoding/json", "HTMLEscape") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func Indent(dst *bytes.Buffer, src []byte, prefix string, indent string) error - this.hasQualifiedName("encoding/json", "Indent") and - (inp.isParameter([1, 2, 3]) and outp.isParameter(0)) - or - // signature: func Marshal(v interface{}) ([]byte, error) - this.hasQualifiedName("encoding/json", "Marshal") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func MarshalIndent(v interface{}, prefix string, indent string) ([]byte, error) - this.hasQualifiedName("encoding/json", "MarshalIndent") and - (inp.isParameter(_) and outp.isResult(0)) - or - // signature: func NewDecoder(r io.Reader) *Decoder - this.hasQualifiedName("encoding/json", "NewDecoder") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewEncoder(w io.Writer) *Encoder this.hasQualifiedName("encoding/json", "NewEncoder") and (inp.isResult() and outp.isParameter(0)) - or - // signature: func Unmarshal(data []byte, v interface{}) error - this.hasQualifiedName("encoding/json", "Unmarshal") and - (inp.isParameter(0) and outp.isParameter(1)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Decoder) Buffered() io.Reader - this.hasQualifiedName("encoding/json", "Decoder", "Buffered") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Decoder) Decode(v interface{}) error - this.hasQualifiedName("encoding/json", "Decoder", "Decode") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Decoder) Token() (Token, error) - this.hasQualifiedName("encoding/json", "Decoder", "Token") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Encoder) Encode(v interface{}) error - this.hasQualifiedName("encoding/json", "Encoder", "Encode") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Encoder) SetIndent(prefix string, indent string) - this.hasQualifiedName("encoding/json", "Encoder", "SetIndent") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (Marshaler) MarshalJSON() ([]byte, error) - this.implements("encoding/json", "Marshaler", "MarshalJSON") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (Unmarshaler) UnmarshalJSON([]byte) error - this.implements("encoding/json", "Unmarshaler", "UnmarshalJSON") and - (inp.isParameter(0) and outp.isReceiver()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingPem.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingPem.qll index 6dd126468551..0c582f5a211a 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingPem.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingPem.qll @@ -38,27 +38,4 @@ module EncodingPem { override string getFormat() { result = "PEM" } } - - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func Decode(data []byte) (p *Block, rest []byte) - hasQualifiedName("encoding/pem", "Decode") and - (inp.isParameter(0) and outp.isResult(_)) - or - // signature: func Encode(out io.Writer, b *Block) error - hasQualifiedName("encoding/pem", "Encode") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func EncodeToMemory(b *Block) []byte - hasQualifiedName("encoding/pem", "EncodeToMemory") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingXml.qll b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingXml.qll index 5e2e311b4ef6..b36f9007084c 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/EncodingXml.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/EncodingXml.qll @@ -30,121 +30,15 @@ module EncodingXml { override string getFormat() { result = "XML" } } + // These models are not implemented using Models-as-Data because they represent reverse flow. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; FunctionOutput outp; FunctionModels() { - // signature: func CopyToken(t Token) Token - this.hasQualifiedName("encoding/xml", "CopyToken") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Escape(w io.Writer, s []byte) - this.hasQualifiedName("encoding/xml", "Escape") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func EscapeText(w io.Writer, s []byte) error - this.hasQualifiedName("encoding/xml", "EscapeText") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func Marshal(v interface{}) ([]byte, error) - this.hasQualifiedName("encoding/xml", "Marshal") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func MarshalIndent(v interface{}, prefix string, indent string) ([]byte, error) - this.hasQualifiedName("encoding/xml", "MarshalIndent") and - (inp.isParameter(_) and outp.isResult(0)) - or - // signature: func NewDecoder(r io.Reader) *Decoder - this.hasQualifiedName("encoding/xml", "NewDecoder") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewEncoder(w io.Writer) *Encoder this.hasQualifiedName("encoding/xml", "NewEncoder") and (inp.isResult() and outp.isParameter(0)) - or - // signature: func NewTokenDecoder(t TokenReader) *Decoder - this.hasQualifiedName("encoding/xml", "NewTokenDecoder") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Unmarshal(data []byte, v interface{}) error - this.hasQualifiedName("encoding/xml", "Unmarshal") and - (inp.isParameter(0) and outp.isParameter(1)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (CharData) Copy() CharData - this.hasQualifiedName("encoding/xml", "CharData", "Copy") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Comment) Copy() Comment - this.hasQualifiedName("encoding/xml", "Comment", "Copy") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Decoder) Decode(v interface{}) error - this.hasQualifiedName("encoding/xml", "Decoder", "Decode") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Decoder) DecodeElement(v interface{}, start *StartElement) error - this.hasQualifiedName("encoding/xml", "Decoder", "DecodeElement") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Decoder) RawToken() (Token, error) - this.hasQualifiedName("encoding/xml", "Decoder", "RawToken") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Decoder) Token() (Token, error) - this.hasQualifiedName("encoding/xml", "Decoder", "Token") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (Directive) Copy() Directive - this.hasQualifiedName("encoding/xml", "Directive", "Copy") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Encoder) Encode(v interface{}) error - this.hasQualifiedName("encoding/xml", "Encoder", "Encode") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Encoder) EncodeElement(v interface{}, start StartElement) error - this.hasQualifiedName("encoding/xml", "Encoder", "EncodeElement") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Encoder) EncodeToken(t Token) error - this.hasQualifiedName("encoding/xml", "Encoder", "EncodeToken") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Encoder) Indent(prefix string, indent string) - this.hasQualifiedName("encoding/xml", "Encoder", "Indent") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (ProcInst) Copy() ProcInst - this.hasQualifiedName("encoding/xml", "ProcInst", "Copy") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (StartElement) Copy() StartElement - this.hasQualifiedName("encoding/xml", "StartElement", "Copy") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Marshaler) MarshalXML(e *Encoder, start StartElement) error - this.implements("encoding/xml", "Marshaler", "MarshalXML") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (TokenReader) Token() (Token, error) - this.implements("encoding/xml", "TokenReader", "Token") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (Unmarshaler) UnmarshalXML(d *Decoder, start StartElement) error - this.implements("encoding/xml", "Unmarshaler", "UnmarshalXML") and - (inp.isParameter(0) and outp.isReceiver()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Errors.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Errors.qll index b38584f1e925..c0995b3322ac 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Errors.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Errors.qll @@ -6,23 +6,12 @@ import go /** Provides models of commonly used functions in the `errors` package. */ module Errors { + // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; FunctionOutput outp; FunctionModels() { - // signature: func As(err error, target interface{}) bool - hasQualifiedName("errors", "As") and - (inp.isParameter(0) and outp.isParameter(1)) - or - // signature: func New(text string) error - hasQualifiedName("errors", "New") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Unwrap(err error) error - hasQualifiedName("errors", "Unwrap") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func Join(errs ...error) error hasQualifiedName("errors", "Join") and (inp.isParameter(_) and outp.isResult()) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Expvar.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Expvar.qll deleted file mode 100644 index 01fbda900f42..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Expvar.qll +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `expvar` package. - */ - -import go - -/** Provides models of commonly used functions in the `expvar` package. */ -module Expvar { - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (Func) Value() interface{} - hasQualifiedName("expvar", "Func", "Value") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Map) Get(key string) Var - hasQualifiedName("expvar", "Map", "Get") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Map) Set(key string, av Var) - hasQualifiedName("expvar", "Map", "Set") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (*String) Set(value string) - hasQualifiedName("expvar", "String", "Set") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*String) Value() string - hasQualifiedName("expvar", "String", "Value") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Var) String() string - implements("expvar", "Var", "String") and - (inp.isReceiver() and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll index bc89557e437d..dd65aee23a4a 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll @@ -4,6 +4,7 @@ import go +// Some TaintTracking::FunctionModel subclasses remain because varargs functions don't work with Models-as-Data sumamries yet. /** Provides models of commonly used functions in the `fmt` package. */ module Fmt { /** The `Sprint` or `Append` functions or one of their variants. */ @@ -138,35 +139,4 @@ module Fmt { input = inp and output = outp } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (GoStringer) GoString() string - this.implements("fmt", "GoStringer", "GoString") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (ScanState) Read(buf []byte) (n int, err error) - this.implements("fmt", "ScanState", "Read") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (Stringer) String() string - this.implements("fmt", "Stringer", "String") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (ScanState) Token(skipSpace bool, f func(rune) bool) (token []byte, err error) - this.implements("fmt", "ScanState", "Token") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (State) Write(b []byte) (n int, err error) - this.implements("fmt", "State", "Write") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Html.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Html.qll index f47cadf5a989..c3f7bfe71f25 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Html.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Html.qll @@ -11,23 +11,4 @@ module Html { override string kind() { result = "html" } } - - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func EscapeString(s string) string - hasQualifiedName("html", "EscapeString") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func UnescapeString(s string) string - hasQualifiedName("html", "UnescapeString") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/HtmlTemplate.qll b/go/ql/lib/semmle/go/frameworks/stdlib/HtmlTemplate.qll index 0b69abfec433..19d6dfd0c552 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/HtmlTemplate.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/HtmlTemplate.qll @@ -24,31 +24,16 @@ module HtmlTemplate { override string kind() { result = kind } } + // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; FunctionOutput outp; FunctionModels() { - // signature: func HTMLEscape(w io.Writer, b []byte) - this.hasQualifiedName("html/template", "HTMLEscape") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func HTMLEscapeString(s string) string - this.hasQualifiedName("html/template", "HTMLEscapeString") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func HTMLEscaper(args ...interface{}) string this.hasQualifiedName("html/template", "HTMLEscaper") and (inp.isParameter(_) and outp.isResult()) or - // signature: func JSEscape(w io.Writer, b []byte) - this.hasQualifiedName("html/template", "JSEscape") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func JSEscapeString(s string) string - this.hasQualifiedName("html/template", "JSEscapeString") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func JSEscaper(args ...interface{}) string this.hasQualifiedName("html/template", "JSEscaper") and (inp.isParameter(_) and outp.isResult()) @@ -63,25 +48,6 @@ module HtmlTemplate { } } - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Template) Execute(wr io.Writer, data interface{}) error - this.hasQualifiedName("html/template", "Template", "Execute") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func (*Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error - this.hasQualifiedName("html/template", "Template", "ExecuteTemplate") and - (inp.isParameter(2) and outp.isParameter(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - private newtype TTemplateStmt = MkTemplateStmt(HTML::TextNode parent, int idx, string text) { text = parent.getText().regexpFind("(?s)\\{\\{.*?\\}\\}", idx, _) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Io.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Io.qll index ffd95a660e07..a9a0df3de847 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Io.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Io.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow, or are variadic. /** Provides models of commonly used functions in the `io` package. */ module Io { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,22 +12,6 @@ module Io { FunctionOutput outp; FunctionModels() { - // signature: func Copy(dst Writer, src Reader) (written int64, err error) - hasQualifiedName("io", "Copy") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) - hasQualifiedName("io", "CopyBuffer") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func CopyN(dst Writer, src Reader, n int64) (written int64, err error) - hasQualifiedName("io", "CopyN") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func LimitReader(r Reader, n int64) Reader - hasQualifiedName("io", "LimitReader") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func MultiReader(readers ...Reader) Reader hasQualifiedName("io", "MultiReader") and (inp.isParameter(_) and outp.isResult()) @@ -35,79 +20,9 @@ module Io { hasQualifiedName("io", "MultiWriter") and (inp.isResult() and outp.isParameter(_)) or - // signature: func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader - hasQualifiedName("io", "NewSectionReader") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func Pipe() (*PipeReader, *PipeWriter) hasQualifiedName("io", "Pipe") and (inp.isResult(1) and outp.isResult(0)) - or - // signature: func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) - hasQualifiedName("io", "ReadAtLeast") and - (inp.isParameter(0) and outp.isParameter(1)) - or - // signature: func ReadFull(r Reader, buf []byte) (n int, err error) - hasQualifiedName("io", "ReadFull") and - (inp.isParameter(0) and outp.isParameter(1)) - or - // signature: func TeeReader(r Reader, w Writer) Reader - hasQualifiedName("io", "TeeReader") and - ( - inp.isParameter(0) and - (outp.isParameter(1) or outp.isResult()) - ) - or - // signature: func WriteString(w Writer, s string) (n int, err error) - hasQualifiedName("io", "WriteString") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func NopCloser(r io.Reader) io.ReadCloser - hasQualifiedName("io", "NopCloser") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ReadAll(r io.Reader) ([]byte, error) - hasQualifiedName("io", "ReadAll") and - (inp.isParameter(0) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (Reader) Read(p []byte) (n int, err error) - implements("io", "Reader", "Read") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (ReaderAt) ReadAt(p []byte, off int64) (n int, err error) - implements("io", "ReaderAt", "ReadAt") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (ReaderFrom) ReadFrom(r Reader) (n int64, err error) - implements("io", "ReaderFrom", "ReadFrom") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (Writer) Write(p []byte) (n int, err error) - implements("io", "Writer", "Write") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (WriterAt) WriteAt(p []byte, off int64) (n int, err error) - implements("io", "WriterAt", "WriteAt") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (StringWriter) WriteString(s string) (n int, err error) - implements("io", "StringWriter", "WriteString") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (WriterTo) WriteTo(w Writer) (n int64, err error) - implements("io", "WriterTo", "WriteTo") and - (inp.isReceiver() and outp.isParameter(0)) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/IoFs.qll b/go/ql/lib/semmle/go/frameworks/stdlib/IoFs.qll index ea6f1be33b0d..de7fafc514f6 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/IoFs.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/IoFs.qll @@ -11,37 +11,6 @@ module IoFs { /** Gets the package name `io/fs`. */ string packagePath() { result = "io/fs" } - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - //signature: func FileInfoToDirEntry(info FileInfo) DirEntry - this.hasQualifiedName(packagePath(), "FileInfoToDirEntry") and - (inp.isParameter(0) and outp.isResult()) - or - //signature: func Glob(fsys FS, pattern string) (matches []string, err error) - this.hasQualifiedName(packagePath(), "Glob") and - (inp.isParameter(0) and outp.isResult(0)) - or - //signature: func ReadFile(fsys FS, name string) ([]byte, error) - this.hasQualifiedName(packagePath(), "ReadFile") and - (inp.isParameter(0) and outp.isResult(0)) - or - //signature: func ReadDir(fsys FS, name string) ([]DirEntry, error) - this.hasQualifiedName(packagePath(), "ReadDir") and - (inp.isParameter(0) and outp.isResult(0)) - or - //signature: func Sub(fsys FS, dir string) (FS, error) - this.hasQualifiedName(packagePath(), "Sub") and - (inp.isParameter(0) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - /** * Models a step from `fs` to `path` and `d` in * `fs.WalkDir(fs, "root", func(path string, d DirEntry, err error) {}` @@ -58,47 +27,4 @@ module IoFs { ) } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - //signature: func (DirEntry) Name() string - this.implements(packagePath(), "DirEntry", "Name") and - (inp.isReceiver() and outp.isResult()) - or - //signature: func (DirEntry) Info() (FileInfo, error) - this.implements(packagePath(), "DirEntry", "Info") and - (inp.isReceiver() and outp.isResult(0)) - or - //signature: func (FS) Open(name string) (File, error) - this.implements(packagePath(), "FS", "Open") and - (inp.isReceiver() and outp.isResult(0)) - or - //signature: func (GlobFS) Glob(pattern string) ([]string, error) - this.implements(packagePath(), "GlobFS", "Glob") and - (inp.isReceiver() and outp.isResult(0)) - or - //signature: func (ReadDirFS) ReadDir(name string) ([]DirEntry, error) - this.implements(packagePath(), "ReadDirFS", "ReadDir") and - (inp.isReceiver() and outp.isResult(0)) - or - //signature: func (ReadFileFS) ReadFile(name string) ([]byte, error) - this.implements(packagePath(), "ReadFileFS", "ReadFile") and - (inp.isReceiver() and outp.isResult(0)) - or - //signature: func (SubFS) Sub(dir string) (FS, error) - this.implements(packagePath(), "SubFS", "Sub") and - (inp.isReceiver() and outp.isResult(0)) - or - //signature: func (File) Read([]byte) (int, error) - this.implements(packagePath(), "File", "Read") and - (inp.isReceiver() and outp.isParameter(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/IoIoutil.qll b/go/ql/lib/semmle/go/frameworks/stdlib/IoIoutil.qll index 4a3de941211b..7eb159226c91 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/IoIoutil.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/IoIoutil.qll @@ -15,23 +15,4 @@ module IoIoutil { override DataFlow::Node getAPathArgument() { result = getAnArgument() } } - - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func NopCloser(r io.Reader) io.ReadCloser - hasQualifiedName("io/ioutil", "NopCloser") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ReadAll(r io.Reader) ([]byte, error) - hasQualifiedName("io/ioutil", "ReadAll") and - (inp.isParameter(0) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll index 959118045b3f..f465009a2551 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll @@ -39,6 +39,7 @@ module Log { override predicate mayReturnNormally() { none() } } + // These models are not implemented using Models-as-Data because they represent reverse flow. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; FunctionOutput outp; @@ -54,6 +55,7 @@ module Log { } } + // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. private class MethodModels extends TaintTracking::FunctionModel, Method { FunctionInput inp; FunctionOutput outp; @@ -94,18 +96,6 @@ module Log { // signature: func (*Logger) Println(v ...interface{}) this.hasQualifiedName("log", "Logger", "Println") and (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (*Logger) SetOutput(w io.Writer) - this.hasQualifiedName("log", "Logger", "SetOutput") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Logger) SetPrefix(prefix string) - this.hasQualifiedName("log", "Logger", "SetPrefix") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Logger) Writer() io.Writer - this.hasQualifiedName("log", "Logger", "Writer") and - (inp.isReceiver() and outp.isResult()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Mime.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Mime.qll deleted file mode 100644 index b04acdf4e6f9..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Mime.qll +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `mime` package. - */ - -import go - -/** Provides models of commonly used functions in the `mime` package. */ -module Mime { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func FormatMediaType(t string, param map[string]string) string - hasQualifiedName("mime", "FormatMediaType") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func ParseMediaType(v string) (mediatype string, params map[string]string, err error) - hasQualifiedName("mime", "ParseMediaType") and - (inp.isParameter(0) and outp.isResult([0, 1])) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*WordDecoder) Decode(word string) (string, error) - hasQualifiedName("mime", "WordDecoder", "Decode") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func (*WordDecoder) DecodeHeader(header string) (string, error) - hasQualifiedName("mime", "WordDecoder", "DecodeHeader") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func (WordEncoder) Encode(charset string, s string) string - hasQualifiedName("mime", "WordEncoder", "Encode") and - (inp.isParameter(1) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/MimeMultipart.qll b/go/ql/lib/semmle/go/frameworks/stdlib/MimeMultipart.qll index 3f384b29454b..4331a707a333 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/MimeMultipart.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/MimeMultipart.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `mime/multipart` package. */ module MimeMultipart { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,10 +12,6 @@ module MimeMultipart { FunctionOutput outp; FunctionModels() { - // signature: func NewReader(r io.Reader, boundary string) *Reader - hasQualifiedName("mime/multipart", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewWriter(w io.Writer) *Writer hasQualifiedName("mime/multipart", "NewWriter") and (inp.isResult() and outp.isParameter(0)) @@ -30,30 +27,6 @@ module MimeMultipart { FunctionOutput outp; MethodModels() { - // signature: func (*FileHeader) Open() (File, error) - hasQualifiedName("mime/multipart", "FileHeader", "Open") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Part) FileName() string - hasQualifiedName("mime/multipart", "Part", "FileName") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Part) FormName() string - hasQualifiedName("mime/multipart", "Part", "FormName") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) NextPart() (*Part, error) - hasQualifiedName("mime/multipart", "Reader", "NextPart") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) NextRawPart() (*Part, error) - hasQualifiedName("mime/multipart", "Reader", "NextRawPart") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadForm(maxMemory int64) (*Form, error) - hasQualifiedName("mime/multipart", "Reader", "ReadForm") and - (inp.isReceiver() and outp.isResult(0)) - or // signature: func (*Writer) CreateFormField(fieldname string) (io.Writer, error) hasQualifiedName("mime/multipart", "Writer", "CreateFormField") and (inp.isResult(0) and outp.isReceiver()) @@ -65,10 +38,6 @@ module MimeMultipart { // signature: func (*Writer) CreatePart(header net/textproto.MIMEHeader) (io.Writer, error) hasQualifiedName("mime/multipart", "Writer", "CreatePart") and (inp.isResult(0) and outp.isReceiver()) - or - // signature: func (*Writer) WriteField(fieldname string, value string) error - hasQualifiedName("mime/multipart", "Writer", "WriteField") and - (inp.isParameter(_) and outp.isReceiver()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/MimeQuotedprintable.qll b/go/ql/lib/semmle/go/frameworks/stdlib/MimeQuotedprintable.qll index 62e2768b1437..a43b81b32d0c 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/MimeQuotedprintable.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/MimeQuotedprintable.qll @@ -11,10 +11,6 @@ module MimeQuotedprintable { FunctionOutput outp; FunctionModels() { - // signature: func NewReader(r io.Reader) *Reader - hasQualifiedName("mime/quotedprintable", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewWriter(w io.Writer) *Writer hasQualifiedName("mime/quotedprintable", "NewWriter") and (inp.isResult() and outp.isParameter(0)) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Net.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Net.qll index 96cf161ade65..75d3c7f9bb95 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Net.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Net.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `net` package. */ module Net { private class FunctionModels extends TaintTracking::FunctionModel { @@ -13,23 +14,11 @@ module Net { FunctionModels() { // signature: func FileConn(f *os.File) (c Conn, err error) hasQualifiedName("net", "FileConn") and - ( - inp.isParameter(0) and outp.isResult(0) - or - inp.isResult(0) and outp.isParameter(0) - ) + (inp.isResult(0) and outp.isParameter(0)) or // signature: func FilePacketConn(f *os.File) (c PacketConn, err error) hasQualifiedName("net", "FilePacketConn") and - ( - inp.isParameter(0) and outp.isResult(0) - or - inp.isResult(0) and outp.isParameter(0) - ) - or - // signature: func JoinHostPort(host string, port string) string - hasQualifiedName("net", "JoinHostPort") and - (inp.isParameter(_) and outp.isResult()) + (inp.isResult(0) and outp.isParameter(0)) or // signature: func Pipe() (Conn, Conn) hasQualifiedName("net", "Pipe") and @@ -38,10 +27,6 @@ module Net { or inp.isResult(1) and outp.isResult(0) ) - or - // signature: func SplitHostPort(hostport string) (host string, port string, err error) - hasQualifiedName("net", "SplitHostPort") and - (inp.isParameter(0) and outp.isResult([0, 1])) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -54,137 +39,37 @@ module Net { FunctionOutput outp; MethodModels() { - // signature: func (*IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) - hasQualifiedName("net", "IPConn", "ReadFromIP") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*IPConn) ReadMsgIP(b []byte, oob []byte) (n int, oobn int, flags int, addr *IPAddr, err error) - hasQualifiedName("net", "IPConn", "ReadMsgIP") and - (inp.isReceiver() and outp.isParameter(_)) - or // signature: func (*IPConn) SyscallConn() (syscall.RawConn, error) hasQualifiedName("net", "IPConn", "SyscallConn") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) - or - // signature: func (*IPConn) WriteMsgIP(b []byte, oob []byte, addr *IPAddr) (n int, oobn int, err error) - hasQualifiedName("net", "IPConn", "WriteMsgIP") and - (inp.isParameter([0, 1]) and outp.isReceiver()) - or - // signature: func (*IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) - hasQualifiedName("net", "IPConn", "WriteToIP") and - (inp.isParameter(0) and outp.isReceiver()) + (inp.isResult(0) and outp.isReceiver()) or // signature: func (*TCPConn) SyscallConn() (syscall.RawConn, error) hasQualifiedName("net", "TCPConn", "SyscallConn") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) + (inp.isResult(0) and outp.isReceiver()) or // signature: func (*TCPListener) File() (f *os.File, err error) hasQualifiedName("net", "TCPListener", "File") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) + (inp.isResult(0) and outp.isReceiver()) or // signature: func (*TCPListener) SyscallConn() (syscall.RawConn, error) hasQualifiedName("net", "TCPListener", "SyscallConn") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) - or - // signature: func (*UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error) - hasQualifiedName("net", "UDPConn", "ReadFromUDP") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*UDPConn) ReadMsgUDP(b []byte, oob []byte) (n int, oobn int, flags int, addr *UDPAddr, err error) - hasQualifiedName("net", "UDPConn", "ReadMsgUDP") and - (inp.isReceiver() and outp.isParameter(_)) + (inp.isResult(0) and outp.isReceiver()) or // signature: func (*UDPConn) SyscallConn() (syscall.RawConn, error) hasQualifiedName("net", "UDPConn", "SyscallConn") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) - or - // signature: func (*UDPConn) WriteMsgUDP(b []byte, oob []byte, addr *UDPAddr) (n int, oobn int, err error) - hasQualifiedName("net", "UDPConn", "WriteMsgUDP") and - (inp.isParameter([0, 1]) and outp.isReceiver()) - or - // signature: func (*UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) - hasQualifiedName("net", "UDPConn", "WriteToUDP") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) - hasQualifiedName("net", "UnixConn", "ReadFromUnix") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*UnixConn) ReadMsgUnix(b []byte, oob []byte) (n int, oobn int, flags int, addr *UnixAddr, err error) - hasQualifiedName("net", "UnixConn", "ReadMsgUnix") and - (inp.isReceiver() and outp.isParameter(_)) + (inp.isResult(0) and outp.isReceiver()) or // signature: func (*UnixConn) SyscallConn() (syscall.RawConn, error) hasQualifiedName("net", "UnixConn", "SyscallConn") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) - or - // signature: func (*UnixConn) WriteMsgUnix(b []byte, oob []byte, addr *UnixAddr) (n int, oobn int, err error) - hasQualifiedName("net", "UnixConn", "WriteMsgUnix") and - (inp.isParameter([0, 1]) and outp.isReceiver()) - or - // signature: func (*UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) - hasQualifiedName("net", "UnixConn", "WriteToUnix") and - (inp.isParameter(0) and outp.isReceiver()) + (inp.isResult(0) and outp.isReceiver()) or // signature: func (*UnixListener) File() (f *os.File, err error) hasQualifiedName("net", "UnixListener", "File") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) + (inp.isResult(0) and outp.isReceiver()) or // signature: func (*UnixListener) SyscallConn() (syscall.RawConn, error) hasQualifiedName("net", "UnixListener", "SyscallConn") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) - or - // signature: func (Conn) Read(b []byte) (n int, err error) - implements("net", "Conn", "Read") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (PacketConn) ReadFrom(p []byte) (n int, addr Addr, err error) - implements("net", "PacketConn", "ReadFrom") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (Addr) String() string - implements("net", "Addr", "String") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Conn) Write(b []byte) (n int, err error) - implements("net", "Conn", "Write") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (PacketConn) WriteTo(p []byte, addr Addr) (n int, err error) - implements("net", "PacketConn", "WriteTo") and - (inp.isParameter(0) and outp.isReceiver()) + (inp.isResult(0) and outp.isReceiver()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll index ced661cba646..51db02a5cbe6 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll @@ -3,6 +3,8 @@ */ import go +private import semmle.go.dataflow.FlowSummary +private import semmle.go.dataflow.internal.DataFlowPrivate /** Provides models of commonly used functions in the `net/http` package. */ module NetHttp { @@ -120,6 +122,18 @@ module NetHttp { } } + private DataFlow::Node getSummaryInputOrOutputNode( + DataFlow::CallNode call, SummaryComponentStack stack + ) { + exists(int n | + stack = SummaryComponentStack::argument(n) and + result = call.getArgument(n) + ) + or + stack = SummaryComponentStack::argument(-1) and + result = call.getReceiver() + } + private class ResponseBody extends Http::ResponseBody::Range, DataFlow::ArgumentNode { DataFlow::Node responseWriter; @@ -137,6 +151,24 @@ module NetHttp { model.taintStep(this, responseWriter) and responseWriter.getType().implements("net/http", "ResponseWriter") ) + or + exists( + SummarizedCallable callable, DataFlow::CallNode call, SummaryComponentStack input, + SummaryComponentStack output + | + callable = call.getACalleeIncludingExternals() and callable.propagatesFlow(input, output, _) + | + // A modeled function conveying taint from some input to the response writer, + // e.g. `io.Copy(responseWriter, someTaintedReader)` + // NB. SummarizedCallables do not implement a direct call-site-crossing flow step; instead + // they are implemented by a function body with internal dataflow nodes, so we mimic the + // one-step style for the particular case of taint propagation direct from an argument or receiver + // to another argument, receiver or return value, matching the behavior for a `TaintTracking::FunctionModel`. + this = getSummaryInputOrOutputNode(call, input) and + responseWriter.(DataFlow::PostUpdateNode).getPreUpdateNode() = + getSummaryInputOrOutputNode(call, output) and + responseWriter.getType().implements("net/http", "ResponseWriter") + ) } override Http::ResponseWriter getResponseWriter() { result.getANode() = responseWriter } @@ -253,118 +285,4 @@ module NetHttp { override predicate guardedBy(DataFlow::Node check) { check = handlerReg.getArgument(0) } } - - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func CanonicalHeaderKey(s string) string - this.hasQualifiedName("net/http", "CanonicalHeaderKey") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Error(w ResponseWriter, error string, code int) - this.hasQualifiedName("net/http", "Error") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser - this.hasQualifiedName("net/http", "MaxBytesReader") and - (inp.isParameter(1) and outp.isResult()) - or - // signature: func NewRequest(method, url string, body io.Reader) (*Request, error) - this.hasQualifiedName("net/http", "NewRequest") and - (inp.isParameter(1) and outp.isResult(0)) - or - // signature: func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error) - this.hasQualifiedName("net/http", "NewRequestWithContext") and - (inp.isParameter(2) and outp.isResult(0)) - or - // signature: func ReadRequest(b *bufio.Reader) (*Request, error) - this.hasQualifiedName("net/http", "ReadRequest") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) - this.hasQualifiedName("net/http", "ReadResponse") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func SetCookie(w ResponseWriter, cookie *Cookie) - this.hasQualifiedName("net/http", "SetCookie") and - (inp.isParameter(1) and outp.isParameter(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (Header) Add(key string, value string) - this.hasQualifiedName("net/http", "Header", "Add") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (Header) Clone() Header - this.hasQualifiedName("net/http", "Header", "Clone") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Header) Get(key string) string - this.hasQualifiedName("net/http", "Header", "Get") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Header) Set(key string, value string) - this.hasQualifiedName("net/http", "Header", "Set") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (Header) Values(key string) []string - this.hasQualifiedName("net/http", "Header", "Values") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Header) Write(w io.Writer) error - this.hasQualifiedName("net/http", "Header", "Write") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (Header) WriteSubset(w io.Writer, exclude map[string]bool) error - this.hasQualifiedName("net/http", "Header", "WriteSubset") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Request) AddCookie(c *Cookie) - this.hasQualifiedName("net/http", "Request", "AddCookie") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Request) Clone(ctx context.Context) *Request - this.hasQualifiedName("net/http", "Request", "Clone") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Request) Write(w io.Writer) error - this.hasQualifiedName("net/http", "Request", "Write") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Request) WriteProxy(w io.Writer) error - this.hasQualifiedName("net/http", "Request", "WriteProxy") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Response) Write(w io.Writer) error - this.hasQualifiedName("net/http", "Response", "Write") and - (inp.isReceiver() and outp.isParameter(0)) - or - // signature: func (*Transport) Clone() *Transport - this.hasQualifiedName("net/http", "Transport", "Clone") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Hijacker) Hijack() (net.Conn, *bufio.ReadWriter, error) - this.implements("net/http", "Hijacker", "Hijack") and - (inp.isReceiver() and outp.isResult([0, 1])) - or - // signature: func (ResponseWriter) Write([]byte) (int, error) - this.implements("net/http", "ResponseWriter", "Write") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttpHttputil.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttpHttputil.qll index aa7668d46b82..08b89a86359c 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttpHttputil.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttpHttputil.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `net/http/httputil` package. */ module NetHttpHttputil { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,41 +12,17 @@ module NetHttpHttputil { FunctionOutput outp; FunctionModels() { - // signature: func DumpRequest(req *net/http.Request, body bool) ([]byte, error) - hasQualifiedName("net/http/httputil", "DumpRequest") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func DumpRequestOut(req *net/http.Request, body bool) ([]byte, error) - hasQualifiedName("net/http/httputil", "DumpRequestOut") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func DumpResponse(resp *net/http.Response, body bool) ([]byte, error) - hasQualifiedName("net/http/httputil", "DumpResponse") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func NewChunkedReader(r io.Reader) io.Reader - hasQualifiedName("net/http/httputil", "NewChunkedReader") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewChunkedWriter(w io.Writer) io.WriteCloser hasQualifiedName("net/http/httputil", "NewChunkedWriter") and (inp.isResult() and outp.isParameter(0)) or // signature: func NewClientConn(c net.Conn, r *bufio.Reader) *ClientConn hasQualifiedName("net/http/httputil", "NewClientConn") and - ( - inp.isParameter(_) and outp.isResult() - or - inp.isResult() and outp.isParameter(0) - ) + (inp.isResult() and outp.isParameter(0)) or // signature: func NewProxyClientConn(c net.Conn, r *bufio.Reader) *ClientConn hasQualifiedName("net/http/httputil", "NewProxyClientConn") and - ( - inp.isParameter(_) and outp.isResult() - or - inp.isResult() and outp.isParameter(0) - ) + (inp.isResult() and outp.isParameter(0)) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -60,27 +37,11 @@ module NetHttpHttputil { MethodModels() { // signature: func (*ClientConn) Hijack() (c net.Conn, r *bufio.Reader) hasQualifiedName("net/http/httputil", "ClientConn", "Hijack") and - ( - inp.isReceiver() and outp.isResult(_) - or - inp.isResult(0) and outp.isReceiver() - ) + (inp.isResult(0) and outp.isReceiver()) or // signature: func (*ServerConn) Hijack() (net.Conn, *bufio.Reader) hasQualifiedName("net/http/httputil", "ServerConn", "Hijack") and - ( - inp.isReceiver() and outp.isResult(_) - or - inp.isResult(0) and outp.isReceiver() - ) - or - // signature: func (BufferPool) Get() []byte - implements("net/http/httputil", "BufferPool", "Get") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (BufferPool) Put([]byte) - implements("net/http/httputil", "BufferPool", "Put") and - (inp.isParameter(0) and outp.isReceiver()) + (inp.isResult(0) and outp.isReceiver()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetMail.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetMail.qll deleted file mode 100644 index 20e942197529..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetMail.qll +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `net/mail` package. - */ - -import go - -/** Provides models of commonly used functions in the `net/mail` package. */ -module NetMail { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func ParseAddress(address string) (*Address, error) - hasQualifiedName("net/mail", "ParseAddress") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func ParseAddressList(list string) ([]*Address, error) - hasQualifiedName("net/mail", "ParseAddressList") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func ReadMessage(r io.Reader) (msg *Message, err error) - hasQualifiedName("net/mail", "ReadMessage") and - (inp.isParameter(0) and outp.isResult(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*AddressParser) Parse(address string) (*Address, error) - hasQualifiedName("net/mail", "AddressParser", "Parse") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func (*AddressParser) ParseList(list string) ([]*Address, error) - hasQualifiedName("net/mail", "AddressParser", "ParseList") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func (Header) Get(key string) string - hasQualifiedName("net/mail", "Header", "Get") and - (inp.isReceiver() and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetTextproto.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetTextproto.qll index 7704b5486f93..13143a78b069 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetTextproto.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/NetTextproto.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow or are variadic. /** Provides models of commonly used functions in the `net/textproto` package. */ module NetTextproto { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,33 +12,13 @@ module NetTextproto { FunctionOutput outp; FunctionModels() { - // signature: func CanonicalMIMEHeaderKey(s string) string - hasQualifiedName("net/textproto", "CanonicalMIMEHeaderKey") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewConn(conn io.ReadWriteCloser) *Conn hasQualifiedName("net/textproto", "NewConn") and - ( - inp.isParameter(0) and outp.isResult() - or - inp.isResult() and outp.isParameter(0) - ) - or - // signature: func NewReader(r *bufio.Reader) *Reader - hasQualifiedName("net/textproto", "NewReader") and - (inp.isParameter(0) and outp.isResult()) + (inp.isResult() and outp.isParameter(0)) or // signature: func NewWriter(w *bufio.Writer) *Writer hasQualifiedName("net/textproto", "NewWriter") and (inp.isResult() and outp.isParameter(0)) - or - // signature: func TrimBytes(b []byte) []byte - hasQualifiedName("net/textproto", "TrimBytes") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimString(s string) string - hasQualifiedName("net/textproto", "TrimString") and - (inp.isParameter(0) and outp.isResult()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -50,62 +31,6 @@ module NetTextproto { FunctionOutput outp; MethodModels() { - // signature: func (MIMEHeader) Add(key string, value string) - hasQualifiedName("net/textproto", "MIMEHeader", "Add") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (MIMEHeader) Get(key string) string - hasQualifiedName("net/textproto", "MIMEHeader", "Get") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (MIMEHeader) Set(key string, value string) - hasQualifiedName("net/textproto", "MIMEHeader", "Set") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (MIMEHeader) Values(key string) []string - hasQualifiedName("net/textproto", "MIMEHeader", "Values") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Reader) DotReader() io.Reader - hasQualifiedName("net/textproto", "Reader", "DotReader") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Reader) ReadCodeLine(expectCode int) (code int, message string, err error) - hasQualifiedName("net/textproto", "Reader", "ReadCodeLine") and - (inp.isReceiver() and outp.isResult(1)) - or - // signature: func (*Reader) ReadContinuedLine() (string, error) - hasQualifiedName("net/textproto", "Reader", "ReadContinuedLine") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadContinuedLineBytes() ([]byte, error) - hasQualifiedName("net/textproto", "Reader", "ReadContinuedLineBytes") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadDotBytes() ([]byte, error) - hasQualifiedName("net/textproto", "Reader", "ReadDotBytes") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadDotLines() ([]string, error) - hasQualifiedName("net/textproto", "Reader", "ReadDotLines") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadLine() (string, error) - hasQualifiedName("net/textproto", "Reader", "ReadLine") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadLineBytes() ([]byte, error) - hasQualifiedName("net/textproto", "Reader", "ReadLineBytes") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadMIMEHeader() (MIMEHeader, error) - hasQualifiedName("net/textproto", "Reader", "ReadMIMEHeader") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Reader) ReadResponse(expectCode int) (code int, message string, err error) - hasQualifiedName("net/textproto", "Reader", "ReadResponse") and - (inp.isReceiver() and outp.isResult(1)) - or // signature: func (*Writer) DotWriter() io.WriteCloser hasQualifiedName("net/textproto", "Writer", "DotWriter") and (inp.isResult() and outp.isReceiver()) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll index a022b416d9e4..94daae0c1904 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Os.qll @@ -78,23 +78,12 @@ module Os { override predicate mayReturnNormally() { none() } } + // These models are not implemented using Models-as-Data because they represent reverse flow. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; FunctionOutput outp; FunctionModels() { - // signature: func Expand(s string, mapping func(string) string) string - hasQualifiedName("os", "Expand") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ExpandEnv(s string) string - hasQualifiedName("os", "ExpandEnv") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func NewFile(fd uintptr, name string) *File - hasQualifiedName("os", "NewFile") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func Pipe() (r *File, w *File, err error) hasQualifiedName("os", "Pipe") and (inp.isResult(1) and outp.isResult(0)) @@ -110,17 +99,9 @@ module Os { FunctionOutput outp; MethodModels() { - // signature: func (*File) Fd() uintptr - hasQualifiedName("os", "File", "Fd") and - (inp.isReceiver() and outp.isResult()) - or // signature: func (*File) SyscallConn() (syscall.RawConn, error) hasQualifiedName("os", "File", "SyscallConn") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) + (inp.isResult(0) and outp.isReceiver()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Path.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Path.qll index 0ec1baa5e698..d7efd793d417 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Path.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Path.qll @@ -4,6 +4,7 @@ import go +// These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. /** Provides models of commonly used functions in the `path` package. */ module Path { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,29 +12,9 @@ module Path { FunctionOutput outp; FunctionModels() { - // signature: func Base(path string) string - hasQualifiedName("path", "Base") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Clean(path string) string - hasQualifiedName("path", "Clean") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Dir(path string) string - hasQualifiedName("path", "Dir") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Ext(path string) string - hasQualifiedName("path", "Ext") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func Join(elem ...string) string hasQualifiedName("path", "Join") and (inp.isParameter(_) and outp.isResult()) - or - // signature: func Split(path string) (dir string, file string) - hasQualifiedName("path", "Split") and - (inp.isParameter(0) and outp.isResult(_)) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/PathFilepath.qll b/go/ql/lib/semmle/go/frameworks/stdlib/PathFilepath.qll index 6f9eb2629e3e..914e803aaf17 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/PathFilepath.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/PathFilepath.qll @@ -4,6 +4,7 @@ import go +// These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. /** Provides models of commonly used functions in the `path/filepath` package. */ module PathFilepath { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,61 +12,9 @@ module PathFilepath { FunctionOutput outp; FunctionModels() { - // signature: func Abs(path string) (string, error) - hasQualifiedName("path/filepath", "Abs") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func Base(path string) string - hasQualifiedName("path/filepath", "Base") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Clean(path string) string - hasQualifiedName("path/filepath", "Clean") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Dir(path string) string - hasQualifiedName("path/filepath", "Dir") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func EvalSymlinks(path string) (string, error) - hasQualifiedName("path/filepath", "EvalSymlinks") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func Ext(path string) string - hasQualifiedName("path/filepath", "Ext") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func FromSlash(path string) string - hasQualifiedName("path/filepath", "FromSlash") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Glob(pattern string) (matches []string, err error) - hasQualifiedName("path/filepath", "Glob") and - (inp.isParameter(0) and outp.isResult(0)) - or // signature: func Join(elem ...string) string hasQualifiedName("path/filepath", "Join") and (inp.isParameter(_) and outp.isResult()) - or - // signature: func Rel(basepath string, targpath string) (string, error) - hasQualifiedName("path/filepath", "Rel") and - (inp.isParameter(_) and outp.isResult(0)) - or - // signature: func Split(path string) (dir string, file string) - hasQualifiedName("path/filepath", "Split") and - (inp.isParameter(0) and outp.isResult(_)) - or - // signature: func SplitList(path string) []string - hasQualifiedName("path/filepath", "SplitList") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ToSlash(path string) string - hasQualifiedName("path/filepath", "ToSlash") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func VolumeName(path string) string - hasQualifiedName("path/filepath", "VolumeName") and - (inp.isParameter(0) and outp.isResult()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Reflect.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Reflect.qll index 150c3ae798e6..541b212a769d 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Reflect.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Reflect.qll @@ -4,6 +4,7 @@ import go +// These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. /** Provides models of commonly used functions in the `reflect` package. */ module Reflect { private class FunctionModels extends TaintTracking::FunctionModel { @@ -14,169 +15,6 @@ module Reflect { // signature: func Append(s Value, x ...Value) Value hasQualifiedName("reflect", "Append") and (inp.isParameter(_) and outp.isResult()) - or - // signature: func AppendSlice(s Value, t Value) Value - hasQualifiedName("reflect", "AppendSlice") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func Copy(dst Value, src Value) int - hasQualifiedName("reflect", "Copy") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func Indirect(v Value) Value - hasQualifiedName("reflect", "Indirect") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ValueOf(i interface{}) Value - hasQualifiedName("reflect", "ValueOf") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*MapIter) Key() Value - hasQualifiedName("reflect", "MapIter", "Key") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*MapIter) Value() Value - hasQualifiedName("reflect", "MapIter", "Value") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (StructTag) Get(key string) string - hasQualifiedName("reflect", "StructTag", "Get") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (StructTag) Lookup(key string) (value string, ok bool) - hasQualifiedName("reflect", "StructTag", "Lookup") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (Value) Addr() Value - hasQualifiedName("reflect", "Value", "Addr") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Bytes() []byte - hasQualifiedName("reflect", "Value", "Bytes") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Convert(t Type) Value - hasQualifiedName("reflect", "Value", "Convert") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Elem() Value - hasQualifiedName("reflect", "Value", "Elem") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Field(i int) Value - hasQualifiedName("reflect", "Value", "Field") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) FieldByIndex(index []int) Value - hasQualifiedName("reflect", "Value", "FieldByIndex") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) FieldByName(name string) Value - hasQualifiedName("reflect", "Value", "FieldByName") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) FieldByNameFunc(match func(string) bool) Value - hasQualifiedName("reflect", "Value", "FieldByNameFunc") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Index(i int) Value - hasQualifiedName("reflect", "Value", "Index") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Interface() (i interface{}) - hasQualifiedName("reflect", "Value", "Interface") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) InterfaceData() [2]uintptr - hasQualifiedName("reflect", "Value", "InterfaceData") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) MapIndex(key Value) Value - hasQualifiedName("reflect", "Value", "MapIndex") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) MapKeys() []Value - hasQualifiedName("reflect", "Value", "MapKeys") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) MapRange() *MapIter - hasQualifiedName("reflect", "Value", "MapRange") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Method(i int) Value - hasQualifiedName("reflect", "Value", "Method") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) MethodByName(name string) Value - hasQualifiedName("reflect", "Value", "MethodByName") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Pointer() uintptr - hasQualifiedName("reflect", "Value", "Pointer") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Recv() (x Value, ok bool) - hasQualifiedName("reflect", "Value", "Recv") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (Value) Send(x Value) - hasQualifiedName("reflect", "Value", "Send") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (Value) Set(x Value) - hasQualifiedName("reflect", "Value", "Set") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (Value) SetBytes(x []byte) - hasQualifiedName("reflect", "Value", "SetBytes") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (Value) SetMapIndex(key Value, elem Value) - hasQualifiedName("reflect", "Value", "SetMapIndex") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (Value) SetPointer(x unsafe.Pointer) - hasQualifiedName("reflect", "Value", "SetPointer") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (Value) SetString(x string) - hasQualifiedName("reflect", "Value", "SetString") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (Value) Slice(i int, j int) Value - hasQualifiedName("reflect", "Value", "Slice") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) Slice3(i int, j int, k int) Value - hasQualifiedName("reflect", "Value", "Slice3") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) String() string - hasQualifiedName("reflect", "Value", "String") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (Value) TryRecv() (x Value, ok bool) - hasQualifiedName("reflect", "Value", "TryRecv") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (Value) TrySend(x Value) bool - hasQualifiedName("reflect", "Value", "TrySend") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (Value) UnsafeAddr() uintptr - hasQualifiedName("reflect", "Value", "UnsafeAddr") and - (inp.isReceiver() and outp.isResult()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll index ca6ce487c266..570aa9d4e7bc 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll @@ -66,104 +66,4 @@ module Regexp { override FunctionOutput getResult() { result.isResult() } } - - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func QuoteMeta(s string) string - this.hasQualifiedName("regexp", "QuoteMeta") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte - this.hasQualifiedName("regexp", "Regexp", "Expand") and - ( - inp.isParameter([1, 2]) and - (outp.isParameter(0) or outp.isResult()) - ) - or - // signature: func (*Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte - this.hasQualifiedName("regexp", "Regexp", "ExpandString") and - ( - inp.isParameter([1, 2]) and - (outp.isParameter(0) or outp.isResult()) - ) - or - // signature: func (*Regexp) Find(b []byte) []byte - this.hasQualifiedName("regexp", "Regexp", "Find") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Regexp) FindAll(b []byte, n int) [][]byte - this.hasQualifiedName("regexp", "Regexp", "FindAll") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Regexp) FindAllString(s string, n int) []string - this.hasQualifiedName("regexp", "Regexp", "FindAllString") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Regexp) FindAllStringSubmatch(s string, n int) [][]string - this.hasQualifiedName("regexp", "Regexp", "FindAllStringSubmatch") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Regexp) FindAllSubmatch(b []byte, n int) [][][]byte - this.hasQualifiedName("regexp", "Regexp", "FindAllSubmatch") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Regexp) FindString(s string) string - this.hasQualifiedName("regexp", "Regexp", "FindString") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Regexp) FindStringSubmatch(s string) []string - this.hasQualifiedName("regexp", "Regexp", "FindStringSubmatch") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Regexp) FindSubmatch(b []byte) [][]byte - this.hasQualifiedName("regexp", "Regexp", "FindSubmatch") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Regexp) ReplaceAll(src []byte, repl []byte) []byte - this.hasQualifiedName("regexp", "Regexp", "ReplaceAll") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func (*Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte - this.hasQualifiedName("regexp", "Regexp", "ReplaceAllFunc") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func (*Regexp) ReplaceAllLiteral(src []byte, repl []byte) []byte - this.hasQualifiedName("regexp", "Regexp", "ReplaceAllLiteral") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func (*Regexp) ReplaceAllLiteralString(src string, repl string) string - this.hasQualifiedName("regexp", "Regexp", "ReplaceAllLiteralString") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func (*Regexp) ReplaceAllString(src string, repl string) string - this.hasQualifiedName("regexp", "Regexp", "ReplaceAllString") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func (*Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string - this.hasQualifiedName("regexp", "Regexp", "ReplaceAllStringFunc") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func (*Regexp) Split(s string, n int) []string - this.hasQualifiedName("regexp", "Regexp", "Split") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Sort.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Sort.qll deleted file mode 100644 index 859a63238ac5..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Sort.qll +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `sort` package. - */ - -import go - -/** Provides models of commonly used functions in the `sort` package. */ -module Sort { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func Reverse(data Interface) Interface - hasQualifiedName("sort", "Reverse") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Strconv.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Strconv.qll index 453fcc43b397..34981f0af43a 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Strconv.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Strconv.qll @@ -34,51 +34,4 @@ module Strconv { class IntSize extends DeclaredConstant { IntSize() { this.hasQualifiedName("strconv", "IntSize") } } - - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func AppendQuote(dst []byte, s string) []byte - this.hasQualifiedName("strconv", "AppendQuote") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func AppendQuoteToASCII(dst []byte, s string) []byte - this.hasQualifiedName("strconv", "AppendQuoteToASCII") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func AppendQuoteToGraphic(dst []byte, s string) []byte - this.hasQualifiedName("strconv", "AppendQuoteToGraphic") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func Quote(s string) string - this.hasQualifiedName("strconv", "Quote") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func QuotedPrefix(s string) (string, error) - this.hasQualifiedName("strconv", "QuotedPrefix") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func QuoteToASCII(s string) string - this.hasQualifiedName("strconv", "QuoteToASCII") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func QuoteToGraphic(s string) string - this.hasQualifiedName("strconv", "QuoteToGraphic") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Unquote(s string) (string, error) - this.hasQualifiedName("strconv", "Unquote") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) - this.hasQualifiedName("strconv", "UnquoteChar") and - (inp.isParameter(0) and outp.isResult(2)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Strings.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Strings.qll index 07a2dcf23dff..ca67d4905571 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Strings.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Strings.qll @@ -4,6 +4,7 @@ import go +// These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. /** Provides models of commonly used functions in the `strings` package. */ module Strings { private class FunctionModels extends TaintTracking::FunctionModel { @@ -11,148 +12,9 @@ module Strings { FunctionOutput outp; FunctionModels() { - // signature: func Fields(s string) []string - hasQualifiedName("strings", "Fields") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func FieldsFunc(s string, f func(rune) bool) []string - hasQualifiedName("strings", "FieldsFunc") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Join(elems []string, sep string) string - hasQualifiedName("strings", "Join") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func Map(mapping func(rune) rune, s string) string - hasQualifiedName("strings", "Map") and - (inp.isParameter(1) and outp.isResult()) - or - // signature: func NewReader(s string) *Reader - hasQualifiedName("strings", "NewReader") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func NewReplacer(oldnew ...string) *Replacer hasQualifiedName("strings", "NewReplacer") and (inp.isParameter(_) and outp.isResult()) - or - // signature: func Repeat(s string, count int) string - hasQualifiedName("strings", "Repeat") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Replace(s string, old string, new string, n int) string - hasQualifiedName("strings", "Replace") and - (inp.isParameter([0, 2]) and outp.isResult()) - or - // signature: func ReplaceAll(s string, old string, new string) string - hasQualifiedName("strings", "ReplaceAll") and - (inp.isParameter([0, 2]) and outp.isResult()) - or - // signature: func Split(s string, sep string) []string - hasQualifiedName("strings", "Split") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func SplitAfter(s string, sep string) []string - hasQualifiedName("strings", "SplitAfter") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func SplitAfterN(s string, sep string, n int) []string - hasQualifiedName("strings", "SplitAfterN") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func SplitN(s string, sep string, n int) []string - hasQualifiedName("strings", "SplitN") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func Title(s string) string - hasQualifiedName("strings", "Title") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ToLower(s string) string - hasQualifiedName("strings", "ToLower") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ToLowerSpecial(c unicode.SpecialCase, s string) string - hasQualifiedName("strings", "ToLowerSpecial") and - (inp.isParameter(1) and outp.isResult()) - or - // signature: func ToTitle(s string) string - hasQualifiedName("strings", "ToTitle") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ToTitleSpecial(c unicode.SpecialCase, s string) string - hasQualifiedName("strings", "ToTitleSpecial") and - (inp.isParameter(1) and outp.isResult()) - or - // signature: func ToUpper(s string) string - hasQualifiedName("strings", "ToUpper") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func ToUpperSpecial(c unicode.SpecialCase, s string) string - hasQualifiedName("strings", "ToUpperSpecial") and - (inp.isParameter(1) and outp.isResult()) - or - // signature: func ToValidUTF8(s string, replacement string) string - hasQualifiedName("strings", "ToValidUTF8") and - (inp.isParameter(_) and outp.isResult()) - or - // signature: func Trim(s string, cutset string) string - hasQualifiedName("strings", "Trim") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimFunc(s string, f func(rune) bool) string - hasQualifiedName("strings", "TrimFunc") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimLeft(s string, cutset string) string - hasQualifiedName("strings", "TrimLeft") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimLeftFunc(s string, f func(rune) bool) string - hasQualifiedName("strings", "TrimLeftFunc") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimPrefix(s string, prefix string) string - hasQualifiedName("strings", "TrimPrefix") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimRight(s string, cutset string) string - hasQualifiedName("strings", "TrimRight") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimRightFunc(s string, f func(rune) bool) string - hasQualifiedName("strings", "TrimRightFunc") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimSpace(s string) string - hasQualifiedName("strings", "TrimSpace") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func TrimSuffix(s string, suffix string) string - hasQualifiedName("strings", "TrimSuffix") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Reader) Reset(s string) - hasQualifiedName("strings", "Reader", "Reset") and - (inp.isParameter(0) and outp.isReceiver()) - or - // signature: func (*Replacer) Replace(s string) string - hasQualifiedName("strings", "Replacer", "Replace") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func (*Replacer) WriteString(w io.Writer, s string) (n int, err error) - hasQualifiedName("strings", "Replacer", "WriteString") and - (inp.isParameter(1) and outp.isParameter(0)) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Sync.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Sync.qll deleted file mode 100644 index fcdb7660441d..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Sync.qll +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `sync` package. - */ - -import go - -/** Provides models of commonly used functions in the `sync` package. */ -module Sync { - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - hasQualifiedName("sync", "Map", "CompareAndSwap") and - (inp.isParameter(2) and outp.isReceiver()) - or - // signature: func (*Map) Load(key interface{}) (value interface{}, ok bool) - hasQualifiedName("sync", "Map", "Load") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*Map) LoadOrStore(key interface{}, value interface{}) (actual interface{}, loaded bool) - hasQualifiedName("sync", "Map", "LoadOrStore") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isParameter(_) and - (outp.isReceiver() or outp.isResult(0)) - ) - or - // signature: func (*Map) Store(key interface{}, value interface{}) - hasQualifiedName("sync", "Map", "Store") and - (inp.isParameter(_) and outp.isReceiver()) - or - hasQualifiedName("sync", "Map", "Swap") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isParameter(_) and outp.isReceiver() - ) - or - // signature: func (*Pool) Get() interface{} - hasQualifiedName("sync", "Pool", "Get") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Pool) Put(x interface{}) - hasQualifiedName("sync", "Pool", "Put") and - (inp.isParameter(0) and outp.isReceiver()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/SyncAtomic.qll b/go/ql/lib/semmle/go/frameworks/stdlib/SyncAtomic.qll deleted file mode 100644 index df86fe53df76..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/SyncAtomic.qll +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `sync/atomic` package. - */ - -import go - -/** Provides models of commonly used functions in the `sync/atomic` package. */ -module SyncAtomic { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func AddUintptr(addr *uintptr, delta uintptr) (new uintptr) - hasQualifiedName("sync/atomic", "AddUintptr") and - ( - inp.isParameter(1) and - (outp.isParameter(0) or outp.isResult()) - ) - or - // signature: func CompareAndSwapPointer(addr *unsafe.Pointer, old unsafe.Pointer, new unsafe.Pointer) (swapped bool) - hasQualifiedName("sync/atomic", "CompareAndSwapPointer") and - (inp.isParameter(2) and outp.isParameter(0)) - or - // signature: func CompareAndSwapUintptr(addr *uintptr, old uintptr, new uintptr) (swapped bool) - hasQualifiedName("sync/atomic", "CompareAndSwapUintptr") and - (inp.isParameter(2) and outp.isParameter(0)) - or - // signature: func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) - hasQualifiedName("sync/atomic", "LoadPointer") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func LoadUintptr(addr *uintptr) (val uintptr) - hasQualifiedName("sync/atomic", "LoadUintptr") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) - hasQualifiedName("sync/atomic", "StorePointer") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func StoreUintptr(addr *uintptr, val uintptr) - hasQualifiedName("sync/atomic", "StoreUintptr") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer) - hasQualifiedName("sync/atomic", "SwapPointer") and - ( - inp.isParameter(1) and outp.isParameter(0) - or - inp.isParameter(0) and outp.isResult() - ) - or - // signature: func SwapUintptr(addr *uintptr, new uintptr) (old uintptr) - hasQualifiedName("sync/atomic", "SwapUintptr") and - ( - inp.isParameter(1) and outp.isParameter(0) - or - inp.isParameter(0) and outp.isResult() - ) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - exists(string containerType | containerType = ["Value", "Pointer", "Uintptr"] | - // signature: func (*Containertype) Load/Swap() (x containedtype) - hasQualifiedName("sync/atomic", containerType, ["Load", "Swap"]) and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Containertype) Store/Swap(x containedtype) [(x containedtype)] - hasQualifiedName("sync/atomic", containerType, ["Store", "Swap"]) and - (inp.isParameter(0) and outp.isReceiver()) - ) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Syscall.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Syscall.qll index 7652a58b6e4a..244119c47f58 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Syscall.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Syscall.qll @@ -4,59 +4,17 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `syscall` package. */ module Syscall { - private class FunctionModels extends TaintTracking::FunctionModel { - FunctionInput inp; - FunctionOutput outp; - - FunctionModels() { - // signature: func BytePtrFromString(s string) (*byte, error) - hasQualifiedName("syscall", "BytePtrFromString") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func ByteSliceFromString(s string) ([]byte, error) - hasQualifiedName("syscall", "ByteSliceFromString") and - (inp.isParameter(0) and outp.isResult(0)) - or - // signature: func StringBytePtr(s string) *byte - hasQualifiedName("syscall", "StringBytePtr") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func StringByteSlice(s string) []byte - hasQualifiedName("syscall", "StringByteSlice") and - (inp.isParameter(0) and outp.isResult()) - or - // signature: func StringSlicePtr(ss []string) []*byte - hasQualifiedName("syscall", "StringSlicePtr") and - (inp.isParameter(0) and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } - private class MethodModels extends TaintTracking::FunctionModel, Method { FunctionInput inp; FunctionOutput outp; MethodModels() { - // signature: func (RawConn) Read(f func(fd uintptr) (done bool)) error - implements("syscall", "RawConn", "Read") and - (inp.isReceiver() and outp.isParameter(0)) - or // signature: func (Conn) SyscallConn() (RawConn, error) implements("syscall", "Conn", "SyscallConn") and - ( - inp.isReceiver() and outp.isResult(0) - or - inp.isResult(0) and outp.isReceiver() - ) - or - // signature: func (RawConn) Write(f func(fd uintptr) (done bool)) error - implements("syscall", "RawConn", "Write") and - (inp.isParameter(0) and outp.isReceiver()) + (inp.isResult(0) and outp.isReceiver()) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/TextScanner.qll b/go/ql/lib/semmle/go/frameworks/stdlib/TextScanner.qll deleted file mode 100644 index 54864078e49d..000000000000 --- a/go/ql/lib/semmle/go/frameworks/stdlib/TextScanner.qll +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the `text/scanner` package. - */ - -import go - -/** Provides models of commonly used functions in the `text/scanner` package. */ -module TextScanner { - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Scanner) Init(src io.Reader) *Scanner - hasQualifiedName("text/scanner", "Scanner", "Init") and - ( - inp.isParameter(0) and - (outp.isReceiver() or outp.isResult()) - ) - or - // signature: func (*Scanner) TokenText() string - hasQualifiedName("text/scanner", "Scanner", "TokenText") and - (inp.isReceiver() and outp.isResult()) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } -} diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/TextTabwriter.qll b/go/ql/lib/semmle/go/frameworks/stdlib/TextTabwriter.qll index 5d40f38b72e8..c362baaf4414 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/TextTabwriter.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/TextTabwriter.qll @@ -4,6 +4,7 @@ import go +// These models are not implemented using Models-as-Data because they represent reverse flow. /** Provides models of commonly used functions in the `text/tabwriter` package. */ module TextTabwriter { private class FunctionModels extends TaintTracking::FunctionModel { @@ -29,7 +30,7 @@ module TextTabwriter { // signature: func (*Writer) Init(output io.Writer, minwidth int, tabwidth int, padding int, padchar byte, flags uint) *Writer hasQualifiedName("text/tabwriter", "Writer", "Init") and ( - (inp.isReceiver() or inp.isResult()) and + inp.isResult() and outp.isParameter(0) ) } diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/TextTemplate.qll b/go/ql/lib/semmle/go/frameworks/stdlib/TextTemplate.qll index dbb6dd195cb2..4ef4da058395 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/TextTemplate.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/TextTemplate.qll @@ -44,31 +44,16 @@ module TextTemplate { override DataFlow::Node getADataArgument() { result = this.getArgument(dataArg) } } + // These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; FunctionOutput outp; FunctionModels() { - // signature: func HTMLEscape(w io.Writer, b []byte) - this.hasQualifiedName("text/template", "HTMLEscape") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func HTMLEscapeString(s string) string - this.hasQualifiedName("text/template", "HTMLEscapeString") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func HTMLEscaper(args ...interface{}) string this.hasQualifiedName("text/template", "HTMLEscaper") and (inp.isParameter(_) and outp.isResult()) or - // signature: func JSEscape(w io.Writer, b []byte) - this.hasQualifiedName("text/template", "JSEscape") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func JSEscapeString(s string) string - this.hasQualifiedName("text/template", "JSEscapeString") and - (inp.isParameter(0) and outp.isResult()) - or // signature: func JSEscaper(args ...interface{}) string this.hasQualifiedName("text/template", "JSEscaper") and (inp.isParameter(_) and outp.isResult()) @@ -82,23 +67,4 @@ module TextTemplate { input = inp and output = outp } } - - private class MethodModels extends TaintTracking::FunctionModel, Method { - FunctionInput inp; - FunctionOutput outp; - - MethodModels() { - // signature: func (*Template) Execute(wr io.Writer, data interface{}) error - this.hasQualifiedName("text/template", "Template", "Execute") and - (inp.isParameter(1) and outp.isParameter(0)) - or - // signature: func (*Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error - this.hasQualifiedName("text/template", "Template", "ExecuteTemplate") and - (inp.isParameter(2) and outp.isParameter(0)) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input = inp and output = outp - } - } } diff --git a/go/ql/lib/semmle/go/security/ExternalAPIs.qll b/go/ql/lib/semmle/go/security/ExternalAPIs.qll index f2e588ab5deb..8a27ce28c2a7 100644 --- a/go/ql/lib/semmle/go/security/ExternalAPIs.qll +++ b/go/ql/lib/semmle/go/security/ExternalAPIs.qll @@ -4,6 +4,7 @@ */ import go +private import semmle.go.dataflow.FlowSummary private import Xss private import SqlInjectionCustomizations private import RequestForgeryCustomizations @@ -148,10 +149,17 @@ Package getAPackageWithFunctionModels() { exists(getAMethodModelInPackage(result)) } +/** Gets the name of a package that has at least one SummarizedCallable. */ +Package getAPackageWithSummarizedCallables() { + result = any(SummarizedCallable c).asFunction().getPackage() +} + /** Gets the name of a package which has models. */ Package getAPackageWithModels() { result = getAPackageWithFunctionModels() or + result = getAPackageWithSummarizedCallables() + or // An incomplete list of packages which have been modeled but do not have any function models result.getPath() in [ Logrus::packagePath(), GolangOrgXNetWebsocket::packagePath(), GorillaWebsocket::packagePath() diff --git a/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll b/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll index ec567167487c..efe063fddcab 100644 --- a/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll +++ b/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll @@ -33,6 +33,6 @@ module SafeUrlFlow { /** A function model step using `UnsafeUrlMethod`, considered as a sanitizer for safe URL flow. */ private class UnsafeUrlMethodEdge extends SanitizerEdge { - UnsafeUrlMethodEdge() { this = any(UnsafeUrlMethod um).getAnInputNode(_) } + UnsafeUrlMethodEdge() { this = any(UnsafeUrlMethod um).getACall().getReceiver() } } } diff --git a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql index 89f013b93481..9a5cb10b84f5 100644 --- a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql +++ b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql @@ -106,7 +106,11 @@ class PrivateUrlFlowsToAuthCodeUrlCall extends DataFlow::Configuration { TaintTracking::referenceStep(pred, succ) or // Propagate across Sprintf and similar calls - any(Fmt::AppenderOrSprinter s).taintStep(pred, succ) + exists(DataFlow::CallNode cn | + cn.getACalleeIncludingExternals().asFunction() instanceof Fmt::AppenderOrSprinter + | + pred = cn.getAnArgument() and succ = cn.getResult() + ) } predicate isSinkCall(DataFlow::Node sink, DataFlow::CallNode call) { diff --git a/go/ql/test/example-tests/snippets/typeinfo.expected b/go/ql/test/example-tests/snippets/typeinfo.expected index c78f79a49c36..c3b63b1b25b1 100644 --- a/go/ql/test/example-tests/snippets/typeinfo.expected +++ b/go/ql/test/example-tests/snippets/typeinfo.expected @@ -1,3 +1,7 @@ +| file://:0:0:0:0 | parameter -1 of AddCookie | +| file://:0:0:0:0 | parameter -1 of Clone | +| file://:0:0:0:0 | parameter -1 of Write | +| file://:0:0:0:0 | parameter -1 of WriteProxy | | main.go:18:12:18:14 | argument corresponding to req | | main.go:18:12:18:14 | definition of req | | main.go:20:5:20:7 | req | diff --git a/go/ql/test/experimental/CWE-369/DivideByZero.expected b/go/ql/test/experimental/CWE-369/DivideByZero.expected index 081dac5ec377..0fcc31dd1c58 100644 --- a/go/ql/test/experimental/CWE-369/DivideByZero.expected +++ b/go/ql/test/experimental/CWE-369/DivideByZero.expected @@ -1,25 +1,37 @@ edges -| DivideByZero.go:10:12:10:16 | selection of URL | DivideByZero.go:12:16:12:20 | value | -| DivideByZero.go:17:12:17:16 | selection of URL | DivideByZero.go:18:11:18:24 | type conversion | +| DivideByZero.go:10:12:10:16 | selection of URL | DivideByZero.go:10:12:10:24 | call to Query | +| DivideByZero.go:10:12:10:24 | call to Query | DivideByZero.go:12:16:12:20 | value | +| DivideByZero.go:17:12:17:16 | selection of URL | DivideByZero.go:17:12:17:24 | call to Query | +| DivideByZero.go:17:12:17:24 | call to Query | DivideByZero.go:18:11:18:24 | type conversion | | DivideByZero.go:18:11:18:24 | type conversion | DivideByZero.go:19:16:19:20 | value | -| DivideByZero.go:24:12:24:16 | selection of URL | DivideByZero.go:26:16:26:20 | value | -| DivideByZero.go:31:12:31:16 | selection of URL | DivideByZero.go:33:16:33:20 | value | -| DivideByZero.go:38:12:38:16 | selection of URL | DivideByZero.go:40:16:40:20 | value | -| DivideByZero.go:54:12:54:16 | selection of URL | DivideByZero.go:55:11:55:24 | type conversion | +| DivideByZero.go:24:12:24:16 | selection of URL | DivideByZero.go:24:12:24:24 | call to Query | +| DivideByZero.go:24:12:24:24 | call to Query | DivideByZero.go:26:16:26:20 | value | +| DivideByZero.go:31:12:31:16 | selection of URL | DivideByZero.go:31:12:31:24 | call to Query | +| DivideByZero.go:31:12:31:24 | call to Query | DivideByZero.go:33:16:33:20 | value | +| DivideByZero.go:38:12:38:16 | selection of URL | DivideByZero.go:38:12:38:24 | call to Query | +| DivideByZero.go:38:12:38:24 | call to Query | DivideByZero.go:40:16:40:20 | value | +| DivideByZero.go:54:12:54:16 | selection of URL | DivideByZero.go:54:12:54:24 | call to Query | +| DivideByZero.go:54:12:54:24 | call to Query | DivideByZero.go:55:11:55:24 | type conversion | | DivideByZero.go:55:11:55:24 | type conversion | DivideByZero.go:57:17:57:21 | value | nodes | DivideByZero.go:10:12:10:16 | selection of URL | semmle.label | selection of URL | +| DivideByZero.go:10:12:10:24 | call to Query | semmle.label | call to Query | | DivideByZero.go:12:16:12:20 | value | semmle.label | value | | DivideByZero.go:17:12:17:16 | selection of URL | semmle.label | selection of URL | +| DivideByZero.go:17:12:17:24 | call to Query | semmle.label | call to Query | | DivideByZero.go:18:11:18:24 | type conversion | semmle.label | type conversion | | DivideByZero.go:19:16:19:20 | value | semmle.label | value | | DivideByZero.go:24:12:24:16 | selection of URL | semmle.label | selection of URL | +| DivideByZero.go:24:12:24:24 | call to Query | semmle.label | call to Query | | DivideByZero.go:26:16:26:20 | value | semmle.label | value | | DivideByZero.go:31:12:31:16 | selection of URL | semmle.label | selection of URL | +| DivideByZero.go:31:12:31:24 | call to Query | semmle.label | call to Query | | DivideByZero.go:33:16:33:20 | value | semmle.label | value | | DivideByZero.go:38:12:38:16 | selection of URL | semmle.label | selection of URL | +| DivideByZero.go:38:12:38:24 | call to Query | semmle.label | call to Query | | DivideByZero.go:40:16:40:20 | value | semmle.label | value | | DivideByZero.go:54:12:54:16 | selection of URL | semmle.label | selection of URL | +| DivideByZero.go:54:12:54:24 | call to Query | semmle.label | call to Query | | DivideByZero.go:55:11:55:24 | type conversion | semmle.label | type conversion | | DivideByZero.go:57:17:57:21 | value | semmle.label | value | subpaths diff --git a/go/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected b/go/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected index 77cd46d64e63..8c5673db6a40 100644 --- a/go/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected +++ b/go/ql/test/experimental/CWE-79/HTMLTemplateEscapingPassthrough.expected @@ -92,7 +92,7 @@ edges | HTMLTemplateEscapingPassthrough.go:74:17:74:31 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:75:38:75:44 | escaped | | HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:81:16:81:33 | type conversion | | HTMLTemplateEscapingPassthrough.go:80:10:80:24 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:83:38:83:40 | src | -| HTMLTemplateEscapingPassthrough.go:88:10:88:24 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | +| HTMLTemplateEscapingPassthrough.go:88:10:88:24 | call to UserAgent | HTMLTemplateEscapingPassthrough.go:90:64:90:66 | src | | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | @@ -100,6 +100,8 @@ edges | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | +| HTMLTemplateEscapingPassthrough.go:90:38:90:67 | call to HTMLEscapeString | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:64:90:66 | src | HTMLTemplateEscapingPassthrough.go:90:38:90:67 | call to HTMLEscapeString | nodes | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | | HTMLTemplateEscapingPassthrough.go:28:12:28:41 | type conversion | semmle.label | type conversion | @@ -287,6 +289,8 @@ nodes | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | | HTMLTemplateEscapingPassthrough.go:90:16:90:77 | type conversion | semmle.label | type conversion | +| HTMLTemplateEscapingPassthrough.go:90:38:90:67 | call to HTMLEscapeString | semmle.label | call to HTMLEscapeString | +| HTMLTemplateEscapingPassthrough.go:90:64:90:66 | src | semmle.label | src | | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | | HTMLTemplateEscapingPassthrough.go:91:38:91:46 | converted | semmle.label | converted | diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index 6617c2ee4748..5ba4e98208ea 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -9,11 +9,18 @@ edges | new-tests.go:26:26:26:30 | &... | new-tests.go:35:12:35:58 | call to Sprintf | | new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | | new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | -| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:68:11:68:57 | call to Sprintf | -| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:69:11:69:57 | call to Sprintf | -| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:74:12:74:58 | call to Sprintf | -| new-tests.go:78:18:78:24 | selection of URL | new-tests.go:79:11:79:46 | ...+... | -| new-tests.go:81:37:81:43 | selection of URL | new-tests.go:82:11:82:46 | ...+... | +| new-tests.go:62:2:62:39 | ... := ...[0] | new-tests.go:63:17:63:23 | reqBody | +| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | +| new-tests.go:63:17:63:23 | reqBody | new-tests.go:63:26:63:30 | &... | +| new-tests.go:63:26:63:30 | &... | new-tests.go:68:11:68:57 | call to Sprintf | +| new-tests.go:63:26:63:30 | &... | new-tests.go:69:11:69:57 | call to Sprintf | +| new-tests.go:63:26:63:30 | &... | new-tests.go:74:12:74:58 | call to Sprintf | +| new-tests.go:78:18:78:24 | selection of URL | new-tests.go:78:18:78:32 | call to Query | +| new-tests.go:78:18:78:32 | call to Query | new-tests.go:78:18:78:46 | call to Get | +| new-tests.go:78:18:78:46 | call to Get | new-tests.go:79:11:79:46 | ...+... | +| new-tests.go:81:18:81:67 | call to TrimPrefix | new-tests.go:82:11:82:46 | ...+... | +| new-tests.go:81:37:81:43 | selection of URL | new-tests.go:81:37:81:48 | selection of Path | +| new-tests.go:81:37:81:48 | selection of Path | new-tests.go:81:18:81:67 | call to TrimPrefix | | new-tests.go:86:10:86:20 | call to Vars | new-tests.go:88:11:88:46 | ...+... | | new-tests.go:95:18:95:45 | call to URLParam | new-tests.go:96:11:96:46 | ...+... | nodes @@ -35,13 +42,20 @@ nodes | new-tests.go:47:11:47:46 | ...+... | semmle.label | ...+... | | new-tests.go:49:18:49:30 | call to Query | semmle.label | call to Query | | new-tests.go:50:11:50:46 | ...+... | semmle.label | ...+... | +| new-tests.go:62:2:62:39 | ... := ...[0] | semmle.label | ... := ...[0] | | new-tests.go:62:31:62:38 | selection of Body | semmle.label | selection of Body | +| new-tests.go:63:17:63:23 | reqBody | semmle.label | reqBody | +| new-tests.go:63:26:63:30 | &... | semmle.label | &... | | new-tests.go:68:11:68:57 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:69:11:69:57 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:74:12:74:58 | call to Sprintf | semmle.label | call to Sprintf | | new-tests.go:78:18:78:24 | selection of URL | semmle.label | selection of URL | +| new-tests.go:78:18:78:32 | call to Query | semmle.label | call to Query | +| new-tests.go:78:18:78:46 | call to Get | semmle.label | call to Get | | new-tests.go:79:11:79:46 | ...+... | semmle.label | ...+... | +| new-tests.go:81:18:81:67 | call to TrimPrefix | semmle.label | call to TrimPrefix | | new-tests.go:81:37:81:43 | selection of URL | semmle.label | selection of URL | +| new-tests.go:81:37:81:48 | selection of Path | semmle.label | selection of Path | | new-tests.go:82:11:82:46 | ...+... | semmle.label | ...+... | | new-tests.go:86:10:86:20 | call to Vars | semmle.label | call to Vars | | new-tests.go:88:11:88:46 | ...+... | semmle.label | ...+... | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.ql b/go/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.ql index e258145d2d16..5c157e7fffa1 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.ql @@ -17,10 +17,10 @@ string metadata(Locatable l, string key) { query predicate missingCallee(DataFlow::CallNode call, FuncDef callee) { metadata(call.asExpr(), "callee") = metadata(callee, "name") and - not viableCallable(call.asExpr()).getFuncDef() = callee + not viableCallable(call.asExpr()).asCallable().getFuncDef() = callee } query predicate spuriousCallee(DataFlow::CallNode call, FuncDef callee) { - viableCallable(call.asExpr()).getFuncDef() = callee and + viableCallable(call.asExpr()).asCallable().getFuncDef() = callee and not metadata(call.asExpr(), "callee") = metadata(callee, "name") } diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected index 1397e71759d2..a5be0fa2d734 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected @@ -1,3 +1,289 @@ +| file://:0:0:0:0 | parameter 0 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | +| file://:0:0:0:0 | parameter 0 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | +| file://:0:0:0:0 | parameter 0 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | +| file://:0:0:0:0 | parameter 0 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | +| file://:0:0:0:0 | parameter 0 of As | file://:0:0:0:0 | [summary] to write: argument 1 in As | +| file://:0:0:0:0 | parameter 0 of Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base | +| file://:0:0:0:0 | parameter 0 of BytePtrFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in BytePtrFromString | +| file://:0:0:0:0 | parameter 0 of ByteSliceFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ByteSliceFromString | +| file://:0:0:0:0 | parameter 0 of Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean | +| file://:0:0:0:0 | parameter 0 of Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir | +| file://:0:0:0:0 | parameter 0 of Expand | file://:0:0:0:0 | [summary] to write: return (return[0]) in Expand | +| file://:0:0:0:0 | parameter 0 of ExpandEnv | file://:0:0:0:0 | [summary] to write: return (return[0]) in ExpandEnv | +| file://:0:0:0:0 | parameter 0 of Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext | +| file://:0:0:0:0 | parameter 0 of Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields | +| file://:0:0:0:0 | parameter 0 of FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc | +| file://:0:0:0:0 | parameter 0 of FileInfoToDirEntry | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileInfoToDirEntry | +| file://:0:0:0:0 | parameter 0 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | parameter 0 of Indirect | file://:0:0:0:0 | [summary] to write: return (return[0]) in Indirect | +| file://:0:0:0:0 | parameter 0 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | parameter 0 of LimitReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in LimitReader | +| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | +| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | parameter 0 of LoadPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadPointer | +| file://:0:0:0:0 | parameter 0 of LoadUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadUintptr | +| file://:0:0:0:0 | parameter 0 of New | file://:0:0:0:0 | [summary] to write: return (return[0]) in New | +| file://:0:0:0:0 | parameter 0 of NewFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewFile | +| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | parameter 0 of NewSectionReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewSectionReader | +| file://:0:0:0:0 | parameter 0 of NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser | +| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | parameter 0 of ParseQuery | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseQuery | +| file://:0:0:0:0 | parameter 0 of ParseRequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseRequestURI | +| file://:0:0:0:0 | parameter 0 of PathEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathEscape | +| file://:0:0:0:0 | parameter 0 of PathUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathUnescape | +| file://:0:0:0:0 | parameter 0 of Put | file://:0:0:0:0 | [summary] to write: argument -1 in Put | +| file://:0:0:0:0 | parameter 0 of QueryEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryEscape | +| file://:0:0:0:0 | parameter 0 of QueryUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryUnescape | +| file://:0:0:0:0 | parameter 0 of Quote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Quote | +| file://:0:0:0:0 | parameter 0 of QuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToASCII | +| file://:0:0:0:0 | parameter 0 of QuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToGraphic | +| file://:0:0:0:0 | parameter 0 of QuotedPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuotedPrefix | +| file://:0:0:0:0 | parameter 0 of ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll | +| file://:0:0:0:0 | parameter 0 of ReadAtLeast | file://:0:0:0:0 | [summary] to write: argument 1 in ReadAtLeast | +| file://:0:0:0:0 | parameter 0 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | parameter 0 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFull | file://:0:0:0:0 | [summary] to write: argument 1 in ReadFull | +| file://:0:0:0:0 | parameter 0 of Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat | +| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | parameter 0 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | parameter 0 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | +| file://:0:0:0:0 | parameter 0 of Reverse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Reverse | +| file://:0:0:0:0 | parameter 0 of Send | file://:0:0:0:0 | [summary] to write: argument -1 in Send | +| file://:0:0:0:0 | parameter 0 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | parameter 0 of SetBytes | file://:0:0:0:0 | [summary] to write: argument -1 in SetBytes | +| file://:0:0:0:0 | parameter 0 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | +| file://:0:0:0:0 | parameter 0 of SetPointer | file://:0:0:0:0 | [summary] to write: argument -1 in SetPointer | +| file://:0:0:0:0 | parameter 0 of SetString | file://:0:0:0:0 | [summary] to write: argument -1 in SetString | +| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split | +| file://:0:0:0:0 | parameter 0 of SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter | +| file://:0:0:0:0 | parameter 0 of SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN | +| file://:0:0:0:0 | parameter 0 of SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN | +| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 0 of StringBytePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringBytePtr | +| file://:0:0:0:0 | parameter 0 of StringByteSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringByteSlice | +| file://:0:0:0:0 | parameter 0 of StringSlicePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringSlicePtr | +| file://:0:0:0:0 | parameter 0 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 0 of SwapPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapPointer | +| file://:0:0:0:0 | parameter 0 of SwapUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapUintptr | +| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: argument 1 in TeeReader | +| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in TeeReader | +| file://:0:0:0:0 | parameter 0 of Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title | +| file://:0:0:0:0 | parameter 0 of ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower | +| file://:0:0:0:0 | parameter 0 of ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle | +| file://:0:0:0:0 | parameter 0 of ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper | +| file://:0:0:0:0 | parameter 0 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | parameter 0 of Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim | +| file://:0:0:0:0 | parameter 0 of TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc | +| file://:0:0:0:0 | parameter 0 of TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft | +| file://:0:0:0:0 | parameter 0 of TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc | +| file://:0:0:0:0 | parameter 0 of TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix | +| file://:0:0:0:0 | parameter 0 of TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight | +| file://:0:0:0:0 | parameter 0 of TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc | +| file://:0:0:0:0 | parameter 0 of TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace | +| file://:0:0:0:0 | parameter 0 of TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix | +| file://:0:0:0:0 | parameter 0 of TrySend | file://:0:0:0:0 | [summary] to write: argument -1 in TrySend | +| file://:0:0:0:0 | parameter 0 of Unquote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unquote | +| file://:0:0:0:0 | parameter 0 of UnquoteChar | file://:0:0:0:0 | [summary] to write: return (return[2]) in UnquoteChar | +| file://:0:0:0:0 | parameter 0 of Unwrap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unwrap | +| file://:0:0:0:0 | parameter 0 of User | file://:0:0:0:0 | [summary] to write: return (return[0]) in User | +| file://:0:0:0:0 | parameter 0 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | +| file://:0:0:0:0 | parameter 0 of ValueOf | file://:0:0:0:0 | [summary] to write: return (return[0]) in ValueOf | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in AddUintptr | +| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in AddUintptr | +| file://:0:0:0:0 | parameter 1 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | +| file://:0:0:0:0 | parameter 1 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | +| file://:0:0:0:0 | parameter 1 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | +| file://:0:0:0:0 | parameter 1 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | +| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | +| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | +| file://:0:0:0:0 | parameter 1 of CopyBuffer | file://:0:0:0:0 | [summary] to write: argument 0 in CopyBuffer | +| file://:0:0:0:0 | parameter 1 of CopyN | file://:0:0:0:0 | [summary] to write: argument 0 in CopyN | +| file://:0:0:0:0 | parameter 1 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | +| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | parameter 1 of Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map | +| file://:0:0:0:0 | parameter 1 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | +| file://:0:0:0:0 | parameter 1 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 1 of StorePointer | file://:0:0:0:0 | [summary] to write: argument 0 in StorePointer | +| file://:0:0:0:0 | parameter 1 of StoreUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in StoreUintptr | +| file://:0:0:0:0 | parameter 1 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 1 of SwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in SwapPointer | +| file://:0:0:0:0 | parameter 1 of SwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in SwapUintptr | +| file://:0:0:0:0 | parameter 1 of ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial | +| file://:0:0:0:0 | parameter 1 of ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial | +| file://:0:0:0:0 | parameter 1 of ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial | +| file://:0:0:0:0 | parameter 1 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | parameter 1 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | +| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | +| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | +| file://:0:0:0:0 | parameter 2 of CompareAndSwap | file://:0:0:0:0 | [summary] to write: argument -1 in CompareAndSwap | +| file://:0:0:0:0 | parameter 2 of CompareAndSwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapPointer | +| file://:0:0:0:0 | parameter 2 of CompareAndSwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapUintptr | +| file://:0:0:0:0 | parameter 2 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | parameter 2 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | parameter -1 of Addr | file://:0:0:0:0 | [summary] to write: return (return[0]) in Addr | +| file://:0:0:0:0 | parameter -1 of Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | +| file://:0:0:0:0 | parameter -1 of Convert | file://:0:0:0:0 | [summary] to write: return (return[0]) in Convert | +| file://:0:0:0:0 | parameter -1 of Elem | file://:0:0:0:0 | [summary] to write: return (return[0]) in Elem | +| file://:0:0:0:0 | parameter -1 of Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode | +| file://:0:0:0:0 | parameter -1 of EscapedPath | file://:0:0:0:0 | [summary] to write: return (return[0]) in EscapedPath | +| file://:0:0:0:0 | parameter -1 of Fd | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fd | +| file://:0:0:0:0 | parameter -1 of Field | file://:0:0:0:0 | [summary] to write: return (return[0]) in Field | +| file://:0:0:0:0 | parameter -1 of FieldByIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByIndex | +| file://:0:0:0:0 | parameter -1 of FieldByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByName | +| file://:0:0:0:0 | parameter -1 of FieldByNameFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByNameFunc | +| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of Hostname | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hostname | +| file://:0:0:0:0 | parameter -1 of Index | file://:0:0:0:0 | [summary] to write: return (return[0]) in Index | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Interface | file://:0:0:0:0 | [summary] to write: return (return[0]) in Interface | +| file://:0:0:0:0 | parameter -1 of InterfaceData | file://:0:0:0:0 | [summary] to write: return (return[0]) in InterfaceData | +| file://:0:0:0:0 | parameter -1 of Key | file://:0:0:0:0 | [summary] to write: return (return[0]) in Key | +| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | parameter -1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | parameter -1 of Lookup | file://:0:0:0:0 | [summary] to write: return (return[0]) in Lookup | +| file://:0:0:0:0 | parameter -1 of MapIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapIndex | +| file://:0:0:0:0 | parameter -1 of MapKeys | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapKeys | +| file://:0:0:0:0 | parameter -1 of MapRange | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapRange | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of Method | file://:0:0:0:0 | [summary] to write: return (return[0]) in Method | +| file://:0:0:0:0 | parameter -1 of MethodByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in MethodByName | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter -1 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | parameter -1 of Password | file://:0:0:0:0 | [summary] to write: return (return[0]) in Password | +| file://:0:0:0:0 | parameter -1 of Pointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Pointer | +| file://:0:0:0:0 | parameter -1 of Port | file://:0:0:0:0 | [summary] to write: return (return[0]) in Port | +| file://:0:0:0:0 | parameter -1 of Query | file://:0:0:0:0 | [summary] to write: return (return[0]) in Query | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | parameter -1 of Recv | file://:0:0:0:0 | [summary] to write: return (return[0]) in Recv | +| file://:0:0:0:0 | parameter -1 of RequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in RequestURI | +| file://:0:0:0:0 | parameter -1 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | +| file://:0:0:0:0 | parameter -1 of Slice | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice | +| file://:0:0:0:0 | parameter -1 of Slice3 | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice3 | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | parameter -1 of TryRecv | file://:0:0:0:0 | [summary] to write: return (return[0]) in TryRecv | +| file://:0:0:0:0 | parameter -1 of UnsafeAddr | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnsafeAddr | +| file://:0:0:0:0 | parameter -1 of Username | file://:0:0:0:0 | [summary] to write: return (return[0]) in Username | +| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | | main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[0] | | main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[1] | | main.go:38:13:38:13 | 1 | main.go:38:7:38:20 | slice literal | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionModelStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionModelStep.expected index 80f34d73dbae..f9b4b8106f11 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionModelStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionModelStep.expected @@ -1,4 +1,3 @@ -| file://:0:0:0:0 | Encode | tst2.go:10:35:10:38 | data | tst2.go:10:9:10:26 | call to NewEncoder | | file://:0:0:0:0 | NewEncoder | tst2.go:10:9:10:26 | call to NewEncoder | tst2.go:9:6:9:6 | definition of w | | file://:0:0:0:0 | ReadFrom | tst.go:10:23:10:28 | reader | tst.go:9:2:9:12 | definition of bytesBuffer | | file://:0:0:0:0 | Reset | reset.go:12:15:12:20 | source | reset.go:11:6:11:11 | definition of reader | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected index 37feb5ef6f5c..2d29d2b23570 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected @@ -18,14 +18,27 @@ edges | test.go:108:14:108:25 | call to Data | test.go:108:14:108:45 | type assertion | | test.go:120:14:120:25 | call to Data | test.go:120:14:120:45 | type assertion | | test.go:137:23:137:42 | call to Data | test.go:137:23:137:62 | type assertion | -| test.go:193:15:193:26 | call to Data | test.go:194:14:194:55 | type conversion | -| test.go:193:15:193:26 | call to Data | test.go:195:14:195:58 | type conversion | -| test.go:193:15:193:26 | call to Data | test.go:197:14:197:28 | type assertion | -| test.go:193:15:193:26 | call to Data | test.go:198:14:198:55 | type conversion | -| test.go:193:15:193:26 | call to Data | test.go:199:14:199:59 | type conversion | -| test.go:202:18:202:33 | selection of Form | test.go:203:14:203:28 | type conversion | -| test.go:217:2:217:34 | ... := ...[0] | test.go:220:14:220:20 | content | +| test.go:193:15:193:26 | call to Data | test.go:194:36:194:53 | type assertion | +| test.go:193:15:193:26 | call to Data | test.go:195:39:195:56 | type assertion | +| test.go:193:15:193:26 | call to Data | test.go:196:28:196:56 | type assertion | +| test.go:193:15:193:26 | call to Data | test.go:198:36:198:53 | type assertion | +| test.go:193:15:193:26 | call to Data | test.go:199:34:199:51 | type assertion | +| test.go:194:21:194:54 | call to HTML2str | test.go:194:14:194:55 | type conversion | +| test.go:194:36:194:53 | type assertion | test.go:194:21:194:54 | call to HTML2str | +| test.go:195:21:195:57 | call to Htmlunquote | test.go:195:14:195:58 | type conversion | +| test.go:195:39:195:56 | type assertion | test.go:195:21:195:57 | call to Htmlunquote | +| test.go:196:2:196:68 | ... := ...[0] | test.go:197:14:197:28 | type assertion | +| test.go:196:28:196:56 | type assertion | test.go:196:2:196:68 | ... := ...[0] | +| test.go:198:21:198:54 | call to Str2html | test.go:198:14:198:55 | type conversion | +| test.go:198:36:198:53 | type assertion | test.go:198:21:198:54 | call to Str2html | +| test.go:199:21:199:58 | call to Substr | test.go:199:14:199:59 | type conversion | +| test.go:199:34:199:51 | type assertion | test.go:199:21:199:58 | call to Substr | +| test.go:201:6:201:6 | definition of s | test.go:203:14:203:28 | type conversion | +| test.go:202:18:202:33 | selection of Form | test.go:201:6:201:6 | definition of s | +| test.go:217:2:217:34 | ... := ...[0] | test.go:219:31:219:31 | f | | test.go:217:2:217:34 | ... := ...[1] | test.go:218:14:218:32 | type conversion | +| test.go:219:2:219:32 | ... := ...[0] | test.go:220:14:220:20 | content | +| test.go:219:31:219:31 | f | test.go:219:2:219:32 | ... := ...[0] | | test.go:222:2:222:40 | ... := ...[0] | test.go:223:14:223:38 | type conversion | | test.go:225:7:225:28 | call to GetString | test.go:226:14:226:22 | type conversion | | test.go:228:8:228:35 | call to GetStrings | test.go:229:14:229:26 | type conversion | @@ -35,21 +48,53 @@ edges | test.go:253:23:253:44 | call to GetCookie | test.go:253:16:253:45 | type conversion | | test.go:264:62:264:83 | call to GetCookie | test.go:264:55:264:84 | type conversion | | test.go:269:2:269:40 | ... := ...[0] | test.go:277:21:277:61 | call to GetDisplayString | -| test.go:269:2:269:40 | ... := ...[0] | test.go:278:21:278:92 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:279:21:279:96 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:284:3:286:80 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:287:21:287:101 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:288:21:288:101 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:289:21:289:97 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:290:21:290:97 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:291:21:291:102 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:292:21:292:102 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:293:21:293:82 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:295:21:295:133 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:296:21:296:88 | selection of Filename | -| test.go:269:2:269:40 | ... := ...[0] | test.go:297:21:297:87 | selection of Filename | -| test.go:303:15:303:36 | call to GetString | test.go:305:21:305:48 | type assertion | -| test.go:303:15:303:36 | call to GetString | test.go:306:21:306:52 | type assertion | +| test.go:269:2:269:40 | ... := ...[0] | test.go:278:38:278:49 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:279:37:279:48 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:285:4:285:15 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:287:42:287:53 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:288:53:288:64 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:289:38:289:49 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:290:49:290:60 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:291:51:291:65 | index expression | +| test.go:269:2:269:40 | ... := ...[0] | test.go:292:36:292:47 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:293:37:293:48 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:295:39:295:50 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:296:40:296:51 | genericFiles | +| test.go:269:2:269:40 | ... := ...[0] | test.go:297:39:297:50 | genericFiles | +| test.go:278:21:278:53 | call to SliceChunk | test.go:278:21:278:92 | selection of Filename | +| test.go:278:38:278:49 | genericFiles | test.go:278:21:278:53 | call to SliceChunk | +| test.go:279:21:279:60 | call to SliceDiff | test.go:279:21:279:96 | selection of Filename | +| test.go:279:37:279:48 | genericFiles | test.go:279:21:279:60 | call to SliceDiff | +| test.go:284:3:286:44 | call to SliceFilter | test.go:284:3:286:80 | selection of Filename | +| test.go:285:4:285:15 | genericFiles | test.go:284:3:286:44 | call to SliceFilter | +| test.go:287:21:287:65 | call to SliceIntersect | test.go:287:21:287:101 | selection of Filename | +| test.go:287:42:287:53 | genericFiles | test.go:287:21:287:65 | call to SliceIntersect | +| test.go:288:21:288:65 | call to SliceIntersect | test.go:288:21:288:101 | selection of Filename | +| test.go:288:53:288:64 | genericFiles | test.go:288:21:288:65 | call to SliceIntersect | +| test.go:289:21:289:61 | call to SliceMerge | test.go:289:21:289:97 | selection of Filename | +| test.go:289:38:289:49 | genericFiles | test.go:289:21:289:61 | call to SliceMerge | +| test.go:290:21:290:61 | call to SliceMerge | test.go:290:21:290:97 | selection of Filename | +| test.go:290:49:290:60 | genericFiles | test.go:290:21:290:61 | call to SliceMerge | +| test.go:291:21:291:66 | call to SlicePad | test.go:291:21:291:102 | selection of Filename | +| test.go:291:51:291:65 | index expression | test.go:291:21:291:66 | call to SlicePad | +| test.go:292:21:292:66 | call to SlicePad | test.go:292:21:292:102 | selection of Filename | +| test.go:292:36:292:47 | genericFiles | test.go:292:21:292:66 | call to SlicePad | +| test.go:293:21:293:49 | call to SliceRand | test.go:293:21:293:82 | selection of Filename | +| test.go:293:37:293:48 | genericFiles | test.go:293:21:293:49 | call to SliceRand | +| test.go:295:21:295:97 | call to SliceReduce | test.go:295:21:295:133 | selection of Filename | +| test.go:295:39:295:50 | genericFiles | test.go:295:21:295:97 | call to SliceReduce | +| test.go:296:21:296:52 | call to SliceShuffle | test.go:296:21:296:88 | selection of Filename | +| test.go:296:40:296:51 | genericFiles | test.go:296:21:296:52 | call to SliceShuffle | +| test.go:297:21:297:51 | call to SliceUnique | test.go:297:21:297:87 | selection of Filename | +| test.go:297:39:297:50 | genericFiles | test.go:297:21:297:51 | call to SliceUnique | +| test.go:302:2:302:5 | definition of bMap | test.go:305:21:305:24 | bMap | +| test.go:302:2:302:5 | definition of bMap | test.go:306:21:306:24 | bMap | +| test.go:303:15:303:36 | call to GetString | test.go:304:22:304:30 | untrusted | +| test.go:304:22:304:30 | untrusted | test.go:302:2:302:5 | definition of bMap | +| test.go:305:21:305:24 | bMap | test.go:305:21:305:39 | call to Get | +| test.go:305:21:305:39 | call to Get | test.go:305:21:305:48 | type assertion | +| test.go:306:21:306:24 | bMap | test.go:306:21:306:32 | call to Items | +| test.go:306:21:306:32 | call to Items | test.go:306:21:306:52 | type assertion | nodes | test.go:27:6:27:10 | definition of bound | semmle.label | definition of bound | | test.go:29:13:29:30 | type conversion | semmle.label | type conversion | @@ -89,15 +134,28 @@ nodes | test.go:137:23:137:62 | type assertion | semmle.label | type assertion | | test.go:193:15:193:26 | call to Data | semmle.label | call to Data | | test.go:194:14:194:55 | type conversion | semmle.label | type conversion | +| test.go:194:21:194:54 | call to HTML2str | semmle.label | call to HTML2str | +| test.go:194:36:194:53 | type assertion | semmle.label | type assertion | | test.go:195:14:195:58 | type conversion | semmle.label | type conversion | +| test.go:195:21:195:57 | call to Htmlunquote | semmle.label | call to Htmlunquote | +| test.go:195:39:195:56 | type assertion | semmle.label | type assertion | +| test.go:196:2:196:68 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:196:28:196:56 | type assertion | semmle.label | type assertion | | test.go:197:14:197:28 | type assertion | semmle.label | type assertion | | test.go:198:14:198:55 | type conversion | semmle.label | type conversion | +| test.go:198:21:198:54 | call to Str2html | semmle.label | call to Str2html | +| test.go:198:36:198:53 | type assertion | semmle.label | type assertion | | test.go:199:14:199:59 | type conversion | semmle.label | type conversion | +| test.go:199:21:199:58 | call to Substr | semmle.label | call to Substr | +| test.go:199:34:199:51 | type assertion | semmle.label | type assertion | +| test.go:201:6:201:6 | definition of s | semmle.label | definition of s | | test.go:202:18:202:33 | selection of Form | semmle.label | selection of Form | | test.go:203:14:203:28 | type conversion | semmle.label | type conversion | | test.go:217:2:217:34 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:217:2:217:34 | ... := ...[1] | semmle.label | ... := ...[1] | | test.go:218:14:218:32 | type conversion | semmle.label | type conversion | +| test.go:219:2:219:32 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:219:31:219:31 | f | semmle.label | f | | test.go:220:14:220:20 | content | semmle.label | content | | test.go:222:2:222:40 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:223:14:223:38 | type conversion | semmle.label | type conversion | @@ -119,21 +177,53 @@ nodes | test.go:264:62:264:83 | call to GetCookie | semmle.label | call to GetCookie | | test.go:269:2:269:40 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:277:21:277:61 | call to GetDisplayString | semmle.label | call to GetDisplayString | +| test.go:278:21:278:53 | call to SliceChunk | semmle.label | call to SliceChunk | | test.go:278:21:278:92 | selection of Filename | semmle.label | selection of Filename | +| test.go:278:38:278:49 | genericFiles | semmle.label | genericFiles | +| test.go:279:21:279:60 | call to SliceDiff | semmle.label | call to SliceDiff | | test.go:279:21:279:96 | selection of Filename | semmle.label | selection of Filename | +| test.go:279:37:279:48 | genericFiles | semmle.label | genericFiles | +| test.go:284:3:286:44 | call to SliceFilter | semmle.label | call to SliceFilter | | test.go:284:3:286:80 | selection of Filename | semmle.label | selection of Filename | +| test.go:285:4:285:15 | genericFiles | semmle.label | genericFiles | +| test.go:287:21:287:65 | call to SliceIntersect | semmle.label | call to SliceIntersect | | test.go:287:21:287:101 | selection of Filename | semmle.label | selection of Filename | +| test.go:287:42:287:53 | genericFiles | semmle.label | genericFiles | +| test.go:288:21:288:65 | call to SliceIntersect | semmle.label | call to SliceIntersect | | test.go:288:21:288:101 | selection of Filename | semmle.label | selection of Filename | +| test.go:288:53:288:64 | genericFiles | semmle.label | genericFiles | +| test.go:289:21:289:61 | call to SliceMerge | semmle.label | call to SliceMerge | | test.go:289:21:289:97 | selection of Filename | semmle.label | selection of Filename | +| test.go:289:38:289:49 | genericFiles | semmle.label | genericFiles | +| test.go:290:21:290:61 | call to SliceMerge | semmle.label | call to SliceMerge | | test.go:290:21:290:97 | selection of Filename | semmle.label | selection of Filename | +| test.go:290:49:290:60 | genericFiles | semmle.label | genericFiles | +| test.go:291:21:291:66 | call to SlicePad | semmle.label | call to SlicePad | | test.go:291:21:291:102 | selection of Filename | semmle.label | selection of Filename | +| test.go:291:51:291:65 | index expression | semmle.label | index expression | +| test.go:292:21:292:66 | call to SlicePad | semmle.label | call to SlicePad | | test.go:292:21:292:102 | selection of Filename | semmle.label | selection of Filename | +| test.go:292:36:292:47 | genericFiles | semmle.label | genericFiles | +| test.go:293:21:293:49 | call to SliceRand | semmle.label | call to SliceRand | | test.go:293:21:293:82 | selection of Filename | semmle.label | selection of Filename | +| test.go:293:37:293:48 | genericFiles | semmle.label | genericFiles | +| test.go:295:21:295:97 | call to SliceReduce | semmle.label | call to SliceReduce | | test.go:295:21:295:133 | selection of Filename | semmle.label | selection of Filename | +| test.go:295:39:295:50 | genericFiles | semmle.label | genericFiles | +| test.go:296:21:296:52 | call to SliceShuffle | semmle.label | call to SliceShuffle | | test.go:296:21:296:88 | selection of Filename | semmle.label | selection of Filename | +| test.go:296:40:296:51 | genericFiles | semmle.label | genericFiles | +| test.go:297:21:297:51 | call to SliceUnique | semmle.label | call to SliceUnique | | test.go:297:21:297:87 | selection of Filename | semmle.label | selection of Filename | +| test.go:297:39:297:50 | genericFiles | semmle.label | genericFiles | +| test.go:302:2:302:5 | definition of bMap | semmle.label | definition of bMap | | test.go:303:15:303:36 | call to GetString | semmle.label | call to GetString | +| test.go:304:22:304:30 | untrusted | semmle.label | untrusted | +| test.go:305:21:305:24 | bMap | semmle.label | bMap | +| test.go:305:21:305:39 | call to Get | semmle.label | call to Get | | test.go:305:21:305:48 | type assertion | semmle.label | type assertion | +| test.go:306:21:306:24 | bMap | semmle.label | bMap | +| test.go:306:21:306:32 | call to Items | semmle.label | call to Items | | test.go:306:21:306:52 | type assertion | semmle.label | type assertion | subpaths #select diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected index a84489df5bcd..25839baff4d6 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/TaintedPath.expected @@ -2,13 +2,15 @@ edges | test.go:209:15:209:26 | call to Data | test.go:210:18:210:26 | untrusted | | test.go:209:15:209:26 | call to Data | test.go:211:10:211:18 | untrusted | | test.go:209:15:209:26 | call to Data | test.go:212:35:212:43 | untrusted | -| test.go:318:17:318:37 | selection of RequestBody | test.go:320:35:320:43 | untrusted | +| test.go:318:17:318:37 | selection of RequestBody | test.go:318:40:318:43 | &... | +| test.go:318:40:318:43 | &... | test.go:320:35:320:43 | untrusted | nodes | test.go:209:15:209:26 | call to Data | semmle.label | call to Data | | test.go:210:18:210:26 | untrusted | semmle.label | untrusted | | test.go:211:10:211:18 | untrusted | semmle.label | untrusted | | test.go:212:35:212:43 | untrusted | semmle.label | untrusted | | test.go:318:17:318:37 | selection of RequestBody | semmle.label | selection of RequestBody | +| test.go:318:40:318:43 | &... | semmle.label | &... | | test.go:320:35:320:43 | untrusted | semmle.label | untrusted | subpaths #select diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected index 5bdc5910dc31..a69978148331 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected @@ -1,8 +1,11 @@ edges | test.go:170:11:170:32 | call to Param | test.go:171:20:171:24 | param | | test.go:176:11:176:32 | call to Param | test.go:180:20:180:28 | ...+... | +| test.go:188:10:188:26 | selection of URL | test.go:191:21:191:23 | url | +| test.go:188:10:188:26 | selection of URL | test.go:191:21:191:23 | url | | test.go:188:10:188:26 | selection of URL | test.go:191:21:191:32 | call to String | -| test.go:188:10:188:26 | selection of URL | test.go:191:21:191:32 | call to String | +| test.go:191:21:191:23 | url | test.go:191:21:191:32 | call to String | +| test.go:191:21:191:23 | url | test.go:191:21:191:32 | call to String | nodes | test.go:170:11:170:32 | call to Param | semmle.label | call to Param | | test.go:171:20:171:24 | param | semmle.label | param | @@ -10,6 +13,8 @@ nodes | test.go:180:20:180:28 | ...+... | semmle.label | ...+... | | test.go:188:10:188:26 | selection of URL | semmle.label | selection of URL | | test.go:188:10:188:26 | selection of URL | semmle.label | selection of URL | +| test.go:191:21:191:23 | url | semmle.label | url | +| test.go:191:21:191:23 | url | semmle.label | url | | test.go:191:21:191:32 | call to String | semmle.label | call to String | | test.go:191:21:191:32 | call to String | semmle.label | call to String | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected index 641ceddb08f4..7903ecc04eae 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.expected @@ -6,17 +6,30 @@ edges | test.go:37:10:37:26 | call to QueryString | test.go:38:16:38:19 | qstr | | test.go:43:9:43:34 | call to FormValue | test.go:44:16:44:18 | val | | test.go:49:2:49:30 | ... := ...[0] | test.go:50:16:50:37 | index expression | -| test.go:55:2:55:46 | ... := ...[0] | test.go:59:20:59:25 | buffer | +| test.go:55:2:55:46 | ... := ...[0] | test.go:56:13:56:22 | fileHeader | +| test.go:56:2:56:29 | ... := ...[0] | test.go:58:2:58:5 | file | +| test.go:56:13:56:22 | fileHeader | test.go:56:2:56:29 | ... := ...[0] | +| test.go:57:2:57:7 | definition of buffer | test.go:59:20:59:25 | buffer | +| test.go:58:2:58:5 | file | test.go:57:2:57:7 | definition of buffer | | test.go:64:2:64:31 | ... := ...[0] | test.go:65:16:65:41 | index expression | -| test.go:70:2:70:31 | ... := ...[0] | test.go:75:20:75:25 | buffer | +| test.go:70:2:70:31 | ... := ...[0] | test.go:72:13:72:22 | fileHeader | +| test.go:72:2:72:29 | ... := ...[0] | test.go:74:2:74:5 | file | +| test.go:72:13:72:22 | fileHeader | test.go:72:2:72:29 | ... := ...[0] | +| test.go:73:2:73:7 | definition of buffer | test.go:75:20:75:25 | buffer | +| test.go:74:2:74:5 | file | test.go:73:2:73:7 | definition of buffer | | test.go:80:2:80:32 | ... := ...[0] | test.go:81:16:81:24 | selection of Value | | test.go:86:13:86:25 | call to Cookies | test.go:87:16:87:31 | selection of Value | | test.go:97:11:97:15 | &... | test.go:98:16:98:21 | selection of s | -| test.go:111:21:111:42 | call to Param | test.go:112:16:112:42 | type assertion | +| test.go:110:17:110:19 | definition of ctx | test.go:112:16:112:18 | ctx | +| test.go:111:21:111:42 | call to Param | test.go:110:17:110:19 | definition of ctx | +| test.go:112:16:112:18 | ctx | test.go:112:16:112:33 | call to Get | +| test.go:112:16:112:33 | call to Get | test.go:112:16:112:42 | type assertion | | test.go:122:11:122:32 | call to Param | test.go:123:16:123:20 | param | | test.go:128:11:128:32 | call to Param | test.go:129:20:129:32 | type conversion | | test.go:134:11:134:32 | call to Param | test.go:135:29:135:41 | type conversion | -| test.go:146:11:146:32 | call to Param | test.go:148:31:148:36 | reader | +| test.go:146:11:146:32 | call to Param | test.go:147:30:147:34 | param | +| test.go:147:12:147:35 | call to NewReader | test.go:148:31:148:36 | reader | +| test.go:147:30:147:34 | param | test.go:147:12:147:35 | call to NewReader | | test.go:162:11:162:32 | call to Param | test.go:163:23:163:35 | type conversion | nodes | test.go:13:11:13:32 | call to Param | semmle.label | call to Param | @@ -34,10 +47,18 @@ nodes | test.go:49:2:49:30 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:50:16:50:37 | index expression | semmle.label | index expression | | test.go:55:2:55:46 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:56:2:56:29 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:56:13:56:22 | fileHeader | semmle.label | fileHeader | +| test.go:57:2:57:7 | definition of buffer | semmle.label | definition of buffer | +| test.go:58:2:58:5 | file | semmle.label | file | | test.go:59:20:59:25 | buffer | semmle.label | buffer | | test.go:64:2:64:31 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:65:16:65:41 | index expression | semmle.label | index expression | | test.go:70:2:70:31 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:72:2:72:29 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:72:13:72:22 | fileHeader | semmle.label | fileHeader | +| test.go:73:2:73:7 | definition of buffer | semmle.label | definition of buffer | +| test.go:74:2:74:5 | file | semmle.label | file | | test.go:75:20:75:25 | buffer | semmle.label | buffer | | test.go:80:2:80:32 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:81:16:81:24 | selection of Value | semmle.label | selection of Value | @@ -45,7 +66,10 @@ nodes | test.go:87:16:87:31 | selection of Value | semmle.label | selection of Value | | test.go:97:11:97:15 | &... | semmle.label | &... | | test.go:98:16:98:21 | selection of s | semmle.label | selection of s | +| test.go:110:17:110:19 | definition of ctx | semmle.label | definition of ctx | | test.go:111:21:111:42 | call to Param | semmle.label | call to Param | +| test.go:112:16:112:18 | ctx | semmle.label | ctx | +| test.go:112:16:112:33 | call to Get | semmle.label | call to Get | | test.go:112:16:112:42 | type assertion | semmle.label | type assertion | | test.go:122:11:122:32 | call to Param | semmle.label | call to Param | | test.go:123:16:123:20 | param | semmle.label | param | @@ -54,6 +78,8 @@ nodes | test.go:134:11:134:32 | call to Param | semmle.label | call to Param | | test.go:135:29:135:41 | type conversion | semmle.label | type conversion | | test.go:146:11:146:32 | call to Param | semmle.label | call to Param | +| test.go:147:12:147:35 | call to NewReader | semmle.label | call to NewReader | +| test.go:147:30:147:34 | param | semmle.label | param | | test.go:148:31:148:36 | reader | semmle.label | reader | | test.go:162:11:162:32 | call to Param | semmle.label | call to Param | | test.go:163:23:163:35 | type conversion | semmle.label | type conversion | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/main.go b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/main.go index 521e5968221a..f7287c351e0a 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/main.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/main.go @@ -3,6 +3,7 @@ package main import ( + "crypto/tls" "fmt" "net/http" @@ -23,6 +24,25 @@ func handler1(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Resp return r, goproxy.TextResponse(r, "Hello!") // $ headerwrite=status:200 headerwrite=content-type:text/plain } +func taintedCertStorage() *goproxy.CertStorage { + return nil +} + +func taintedFunction() func() (*tls.Certificate, error) { + return nil +} + +func sink(_ *tls.Certificate) {} + +func testCertStorageFetch() { + cert, _ := (*taintedCertStorage()).Fetch("myhostname.org", nil) + sink(cert) // $ taintflow + + var storage goproxy.CertStorage + cert2, _ := storage.Fetch("myhostname.org", taintedFunction()) + sink(cert2) // $ taintflow +} + func main() { } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql index 0b07a0a20f02..e8c68c1c3e1d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql @@ -47,3 +47,33 @@ class LoggerTest extends InlineExpectationsTest { ) } } + +class Config extends TaintTracking::Configuration { + Config() { this = "goproxy config" } + + override predicate isSource(DataFlow::Node n) { + n = any(DataFlow::CallNode c | c.getCalleeName().matches("tainted%")).getResult() + } + + override predicate isSink(DataFlow::Node n) { + n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument() + } +} + +class TaintFlow extends InlineExpectationsTest { + TaintFlow() { this = "goproxy flow" } + + override string getARelevantTag() { result = "taintflow" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "taintflow" and + value = "" and + element = "" and + exists(Config c, DataFlow::Node toNode | + toNode + .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + c.hasFlowTo(toNode) + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/main.go b/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/main.go index 5f53dafcc0ee..49619e105f2a 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/main.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/main.go @@ -61,4 +61,18 @@ func main() { b11, _ := getTaintedPatch().ApplyIndent(untaintedByteArray, " ") sinkByteArray(b11) // $ taintflow + + // func (p Patch) ApplyWithOptions(doc []byte, options *ApplyOptions) ([]byte, error) + b12, _ := untaintedPatch.ApplyWithOptions(getTaintedByteArray(), nil) + sinkByteArray(b12) // $ taintflow + + b13, _ := getTaintedPatch().ApplyWithOptions(untaintedByteArray, nil) + sinkByteArray(b13) // $ taintflow + + // func (p Patch) ApplyIndentWithOptions(doc []byte, indent string, options *ApplyOptions) ([]byte, error) + b14, _ := untaintedPatch.ApplyIndentWithOptions(getTaintedByteArray(), " ", nil) + sinkByteArray(b14) // $ taintflow + + b15, _ := getTaintedPatch().ApplyIndentWithOptions(untaintedByteArray, " ", nil) + sinkByteArray(b15) // $ taintflow } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/vendor/github.com/evanphx/json-patch/v5/stub.go b/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/vendor/github.com/evanphx/json-patch/v5/stub.go index a997411ca0e7..029b4abc8c99 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/vendor/github.com/evanphx/json-patch/v5/stub.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/vendor/github.com/evanphx/json-patch/v5/stub.go @@ -54,3 +54,14 @@ func (_ Patch) Apply(_ []byte) ([]byte, error) { func (_ Patch) ApplyIndent(_ []byte, _ string) ([]byte, error) { return nil, nil } + +type ApplyOptions struct { +} + +func (_ Patch) ApplyWithOptions(_ []byte, _ *ApplyOptions) ([]byte, error) { + return nil, nil +} + +func (_ Patch) ApplyIndentWithOptions(_ []byte, _ string, _ *ApplyOptions) ([]byte, error) { + return nil, nil +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected index a2321bb16fad..22d78141d3fe 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected @@ -1,7 +1,10 @@ edges +| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:32 | selection of Form | | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | +| EndToEnd.go:94:20:94:32 | selection of Form | EndToEnd.go:94:20:94:49 | call to Get | nodes | EndToEnd.go:94:20:94:27 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:94:20:94:32 | selection of Form | semmle.label | selection of Form | | EndToEnd.go:94:20:94:49 | call to Get | semmle.label | call to Get | subpaths #select diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected index 7a11d9bd08ed..5352f0569bd9 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected @@ -1,13 +1,21 @@ edges -| EndToEnd.go:36:18:36:25 | selection of Params | EndToEnd.go:37:24:37:26 | buf | -| EndToEnd.go:69:22:69:29 | selection of Params | EndToEnd.go:69:22:69:51 | call to Get | +| EndToEnd.go:35:2:35:4 | definition of buf | EndToEnd.go:37:24:37:26 | buf | +| EndToEnd.go:36:18:36:25 | selection of Params | EndToEnd.go:36:18:36:30 | selection of Form | +| EndToEnd.go:36:18:36:30 | selection of Form | EndToEnd.go:36:18:36:47 | call to Get | +| EndToEnd.go:36:18:36:47 | call to Get | EndToEnd.go:35:2:35:4 | definition of buf | +| EndToEnd.go:69:22:69:29 | selection of Params | EndToEnd.go:69:22:69:34 | selection of Form | +| EndToEnd.go:69:22:69:34 | selection of Form | EndToEnd.go:69:22:69:51 | call to Get | | Revel.go:70:22:70:29 | selection of Params | Revel.go:70:22:70:35 | selection of Query | | examples/booking/app/init.go:36:44:36:48 | selection of URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | | examples/booking/app/init.go:40:49:40:53 | selection of URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | nodes +| EndToEnd.go:35:2:35:4 | definition of buf | semmle.label | definition of buf | | EndToEnd.go:36:18:36:25 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:36:18:36:30 | selection of Form | semmle.label | selection of Form | +| EndToEnd.go:36:18:36:47 | call to Get | semmle.label | call to Get | | EndToEnd.go:37:24:37:26 | buf | semmle.label | buf | | EndToEnd.go:69:22:69:29 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:69:22:69:34 | selection of Form | semmle.label | selection of Form | | EndToEnd.go:69:22:69:51 | call to Get | semmle.label | call to Get | | Revel.go:70:22:70:29 | selection of Params | semmle.label | selection of Params | | Revel.go:70:22:70:35 | selection of Query | semmle.label | selection of Query | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go b/go/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go index 80e529374655..f09dcd6fa586 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go @@ -128,3 +128,27 @@ func accessingHeaders(c *revel.Controller) { tainted2 := c.Request.Header.GetAll("somekey") sink(tainted2[0]) } + +func headerMutators(c *revel.Controller) { + tainted := c.Request.UserAgent() + + var cleanHeaders revel.RevelHeader + cleanHeaders.Set(tainted, "clean") + sink(cleanHeaders.Get("clean")) + + var cleanHeaders2 revel.RevelHeader + cleanHeaders2.Set("clean", tainted) + sink(cleanHeaders2.Get("clean")) + + var cleanHeaders3 revel.RevelHeader + cleanHeaders3.Add(tainted, "clean") + sink(cleanHeaders3.Get("clean")) + + var cleanHeaders4 revel.RevelHeader + cleanHeaders4.Add("clean", tainted) + sink(cleanHeaders4.Get("clean")) + + var cleanHeaders5 revel.RevelHeader + cleanHeaders5.SetCookie(tainted) + sink(cleanHeaders5.Get("clean")) +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected index 5cce1e37d95b..c9b3a4bbe584 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected @@ -1,10 +1,14 @@ edges -| EndToEnd.go:58:18:58:25 | selection of Params | EndToEnd.go:58:18:58:47 | call to Get | -| EndToEnd.go:64:26:64:33 | selection of Params | EndToEnd.go:64:26:64:55 | call to Get | +| EndToEnd.go:58:18:58:25 | selection of Params | EndToEnd.go:58:18:58:30 | selection of Form | +| EndToEnd.go:58:18:58:30 | selection of Form | EndToEnd.go:58:18:58:47 | call to Get | +| EndToEnd.go:64:26:64:33 | selection of Params | EndToEnd.go:64:26:64:38 | selection of Form | +| EndToEnd.go:64:26:64:38 | selection of Form | EndToEnd.go:64:26:64:55 | call to Get | nodes | EndToEnd.go:58:18:58:25 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:58:18:58:30 | selection of Form | semmle.label | selection of Form | | EndToEnd.go:58:18:58:47 | call to Get | semmle.label | call to Get | | EndToEnd.go:64:26:64:33 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:64:26:64:38 | selection of Form | semmle.label | selection of Form | | EndToEnd.go:64:26:64:55 | call to Get | semmle.label | call to Get | subpaths #select diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql index 9cde1ad1fbea..31852f1b8624 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql @@ -32,3 +32,31 @@ class QueryString extends InlineExpectationsTest { ) } } + +class Config extends TaintTracking::Configuration { + Config() { this = "pg-orm config" } + + override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit } + + override predicate isSink(DataFlow::Node n) { + n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument() + } +} + +class TaintFlow extends InlineExpectationsTest { + TaintFlow() { this = "pg-orm flow" } + + override string getARelevantTag() { result = "flowfrom" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "flowfrom" and + element = "" and + exists(Config c, DataFlow::Node fromNode, DataFlow::Node toNode | + toNode + .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + c.hasFlow(fromNode, toNode) and + value = fromNode.asExpr().(StringLit).getValue() + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/pg.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/pg.go index 24c381b06ef4..09ffa084fe0e 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/pg.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/pg.go @@ -28,6 +28,9 @@ func newpgtest(query string, conn newpg.Conn, db newpg.DB, tx newpg.Tx) { db.Prepare(query) // $ querystring=query tx.Prepare(query) // $ querystring=query } + +func sink(x interface{}) {} + func pgormtest(query string, q orm.Query) { orm.Q(query) // $ querystring=query q.ColumnExpr(query) // $ querystring=query @@ -38,4 +41,16 @@ func pgormtest(query string, q orm.Query) { q.Where(query) // $ querystring=query q.WhereInMulti(query) // $ querystring=query q.WhereOr(query) // $ querystring=query + + var formatter orm.Formatter + var sink1 []byte + + sink2 := formatter.Append(sink1, "Appended1") + sink3 := formatter.AppendBytes(sink1, []byte("Appended2")) + sink4 := formatter.FormatQuery(sink1, "Query") + + sink(sink1) // $ flowfrom=Appended1 $ flowfrom=Appended2 $ flowfrom=Query + sink(sink2) // $ flowfrom=Appended1 + sink(sink3) // $ flowfrom=Appended2 + sink(sink4) // $ flowfrom=Query } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/vendor/github.com/go-pg/pg/orm/stub.go b/go/ql/test/library-tests/semmle/go/frameworks/SQL/vendor/github.com/go-pg/pg/orm/stub.go index b4cedc671bf5..1d049c8a9a3c 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/vendor/github.com/go-pg/pg/orm/stub.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/vendor/github.com/go-pg/pg/orm/stub.go @@ -2,7 +2,7 @@ // This is a simple stub for github.com/go-pg/pg/orm, strictly for use in testing. // See the LICENSE file for information about the licensing of the original library. -// Source: github.com/go-pg/pg/orm (exports: Query; functions: Q) +// Source: github.com/go-pg/pg/orm (exports: Query, Formatter; functions: Q) // Package orm is a stub of github.com/go-pg/pg/orm, generated by depstubber. package orm @@ -491,3 +491,18 @@ type TableModel interface { Table() *Table Value() reflect.Value } + +type Formatter struct { +} + +func (f Formatter) Append(dst []byte, src string, params ...interface{}) []byte { + return nil +} + +func (f Formatter) AppendBytes(dst, src []byte, params ...interface{}) []byte { + return nil +} + +func (f Formatter) FormatQuery(dst []byte, query string, params ...interface{}) []byte { + return nil +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/MimeMultipart.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/MimeMultipart.go index ffa6659638a6..06a7e8040939 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/MimeMultipart.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/MimeMultipart.go @@ -90,6 +90,16 @@ func TaintStepTest_MimeMultipartWriterWriteField_B0I1O0(sourceCQL interface{}) i return intoWriter409 } +func TaintStepTest_MimeMultipartPartFileName(sourceCQL interface{}) interface{} { + fromPart520 := sourceCQL.(multipart.Part) + return fromPart520.FileName() +} + +func TaintStepTest_MimeMultipartPartFormName(sourceCQL interface{}) interface{} { + fromPart520 := sourceCQL.(multipart.Part) + return fromPart520.FormName() +} + func RunAllTaints_MimeMultipart() { { source := newSource(0) @@ -151,4 +161,14 @@ func RunAllTaints_MimeMultipart() { out := TaintStepTest_MimeMultipartWriterWriteField_B0I1O0(source) sink(11, out) } + { + source := newSource(12) + out := TaintStepTest_MimeMultipartPartFileName(source) + sink(12, out) + } + { + source := newSource(13) + out := TaintStepTest_MimeMultipartPartFormName(source) + sink(13, out) + } } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/go.mod b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/go.mod index e3de230e2bf4..1481ec9caf63 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/go.mod +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/go.mod @@ -1,6 +1,6 @@ module example.com/m -go 1.14 +go 1.20 require ( golang.org/x/net v0.0.0-20201010224723-4f7140c49acb diff --git a/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected b/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected index 92676e9f5601..4d86bb15d4a2 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected @@ -5,60 +5,924 @@ | crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | ... := ...[0] | | crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | ... := ...[1] | | crypto.go:11:42:11:51 | ciphertext | crypto.go:11:2:11:57 | ... := ...[0] | -| io.go:13:31:13:43 | "some string" | io.go:13:13:13:44 | call to NewReader | -| io.go:15:3:15:3 | definition of w | io.go:15:23:15:27 | &... | -| io.go:15:3:15:3 | definition of w | io.go:15:30:15:34 | &... | -| io.go:15:23:15:27 | &... | io.go:14:7:14:10 | definition of buf1 | -| io.go:15:24:15:27 | buf1 | io.go:15:23:15:27 | &... | -| io.go:15:30:15:34 | &... | io.go:14:13:14:16 | definition of buf2 | -| io.go:15:31:15:34 | buf2 | io.go:15:30:15:34 | &... | -| io.go:17:14:17:19 | reader | io.go:15:3:15:3 | definition of w | -| io.go:21:31:21:43 | "some string" | io.go:21:13:21:44 | call to NewReader | -| io.go:24:19:24:23 | &... | io.go:22:7:22:10 | definition of buf1 | -| io.go:24:20:24:23 | buf1 | io.go:24:19:24:23 | &... | -| io.go:26:21:26:26 | reader | io.go:24:3:24:4 | definition of w2 | -| io.go:30:31:30:43 | "some string" | io.go:30:13:30:44 | call to NewReader | -| io.go:32:19:32:23 | &... | io.go:31:7:31:10 | definition of buf1 | -| io.go:32:20:32:23 | buf1 | io.go:32:19:32:23 | &... | -| io.go:34:16:34:21 | reader | io.go:32:3:32:4 | definition of w2 | -| io.go:38:6:38:6 | definition of w | io.go:38:3:38:19 | ... := ...[0] | -| io.go:38:11:38:19 | call to Pipe | io.go:38:3:38:19 | ... := ...[0] | -| io.go:38:11:38:19 | call to Pipe | io.go:38:3:38:19 | ... := ...[1] | -| io.go:39:17:39:31 | "some string\\n" | io.go:38:6:38:6 | definition of w | -| io.go:42:16:42:16 | r | io.go:41:3:41:5 | definition of buf | -| io.go:43:13:43:15 | buf | io.go:43:13:43:24 | call to String | -| io.go:47:31:47:43 | "some string" | io.go:47:13:47:44 | call to NewReader | -| io.go:49:18:49:23 | reader | io.go:48:3:48:5 | definition of buf | -| io.go:53:31:53:43 | "some string" | io.go:53:13:53:44 | call to NewReader | -| io.go:55:15:55:20 | reader | io.go:54:3:54:5 | definition of buf | -| io.go:60:18:60:21 | &... | io.go:59:7:59:9 | definition of buf | -| io.go:60:19:60:21 | buf | io.go:60:18:60:21 | &... | -| io.go:61:21:61:26 | "test" | io.go:60:3:60:3 | definition of w | -| io.go:64:31:64:43 | "some string" | io.go:64:13:64:44 | call to NewReader | -| io.go:66:3:66:8 | reader | io.go:65:3:65:5 | definition of buf | -| io.go:69:31:69:43 | "some string" | io.go:69:13:69:44 | call to NewReader | -| io.go:71:3:71:8 | reader | io.go:70:3:70:5 | definition of buf | -| io.go:75:31:75:43 | "some string" | io.go:75:13:75:44 | call to NewReader | -| io.go:76:24:76:29 | reader | io.go:76:9:76:33 | call to LimitReader | -| io.go:77:22:77:23 | lr | io.go:77:11:77:19 | selection of Stdout | -| io.go:81:27:81:36 | "reader1 " | io.go:81:9:81:37 | call to NewReader | -| io.go:82:27:82:36 | "reader2 " | io.go:82:9:82:37 | call to NewReader | -| io.go:83:27:83:35 | "reader3" | io.go:83:9:83:36 | call to NewReader | -| io.go:84:23:84:24 | r1 | io.go:84:8:84:33 | call to MultiReader | -| io.go:84:27:84:28 | r2 | io.go:84:8:84:33 | call to MultiReader | -| io.go:84:31:84:32 | r3 | io.go:84:8:84:33 | call to MultiReader | -| io.go:85:22:85:22 | r | io.go:85:11:85:19 | selection of Stdout | -| io.go:88:26:88:38 | "some string" | io.go:88:8:88:39 | call to NewReader | -| io.go:90:23:90:23 | r | io.go:90:10:90:30 | call to TeeReader | -| io.go:90:23:90:23 | r | io.go:90:26:90:29 | &... | -| io.go:90:26:90:29 | &... | io.go:89:7:89:9 | definition of buf | -| io.go:90:27:90:29 | buf | io.go:90:26:90:29 | &... | -| io.go:92:22:92:24 | tee | io.go:92:11:92:19 | selection of Stdout | -| io.go:95:26:95:38 | "some string" | io.go:95:8:95:39 | call to NewReader | -| io.go:96:28:96:28 | r | io.go:96:8:96:36 | call to NewSectionReader | -| io.go:97:22:97:22 | s | io.go:97:11:97:19 | selection of Stdout | -| io.go:100:26:100:38 | "some string" | io.go:100:8:100:39 | call to NewReader | -| io.go:101:3:101:3 | r | io.go:101:13:101:21 | selection of Stdout | +| file://:0:0:0:0 | parameter 0 of Abs | file://:0:0:0:0 | [summary] to write: return (return[0]) in Abs | +| file://:0:0:0:0 | parameter 0 of Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | +| file://:0:0:0:0 | parameter 0 of Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | +| file://:0:0:0:0 | parameter 0 of AddCookie | file://:0:0:0:0 | [summary] to write: argument -1 in AddCookie | +| file://:0:0:0:0 | parameter 0 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | +| file://:0:0:0:0 | parameter 0 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | +| file://:0:0:0:0 | parameter 0 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | +| file://:0:0:0:0 | parameter 0 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | +| file://:0:0:0:0 | parameter 0 of As | file://:0:0:0:0 | [summary] to write: argument 1 in As | +| file://:0:0:0:0 | parameter 0 of Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base | +| file://:0:0:0:0 | parameter 0 of Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base | +| file://:0:0:0:0 | parameter 0 of BytePtrFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in BytePtrFromString | +| file://:0:0:0:0 | parameter 0 of ByteSliceFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ByteSliceFromString | +| file://:0:0:0:0 | parameter 0 of CanonicalHeaderKey | file://:0:0:0:0 | [summary] to write: return (return[0]) in CanonicalHeaderKey | +| file://:0:0:0:0 | parameter 0 of CanonicalMIMEHeaderKey | file://:0:0:0:0 | [summary] to write: return (return[0]) in CanonicalMIMEHeaderKey | +| file://:0:0:0:0 | parameter 0 of Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean | +| file://:0:0:0:0 | parameter 0 of Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean | +| file://:0:0:0:0 | parameter 0 of Client | file://:0:0:0:0 | [summary] to write: return (return[0]) in Client | +| file://:0:0:0:0 | parameter 0 of Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | +| file://:0:0:0:0 | parameter 0 of Cut | file://:0:0:0:0 | [summary] to write: return (return[0]) in Cut | +| file://:0:0:0:0 | parameter 0 of Cut | file://:0:0:0:0 | [summary] to write: return (return[1]) in Cut | +| file://:0:0:0:0 | parameter 0 of CutPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in CutPrefix | +| file://:0:0:0:0 | parameter 0 of CutSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in CutSuffix | +| file://:0:0:0:0 | parameter 0 of Decode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decode | +| file://:0:0:0:0 | parameter 0 of Decode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decode | +| file://:0:0:0:0 | parameter 0 of Decode | file://:0:0:0:0 | [summary] to write: return (return[1]) in Decode | +| file://:0:0:0:0 | parameter 0 of DecodeHeader | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecodeHeader | +| file://:0:0:0:0 | parameter 0 of DecodeString | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecodeString | +| file://:0:0:0:0 | parameter 0 of DecodeString | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecodeString | +| file://:0:0:0:0 | parameter 0 of DecryptPEMBlock | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecryptPEMBlock | +| file://:0:0:0:0 | parameter 0 of Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir | +| file://:0:0:0:0 | parameter 0 of Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir | +| file://:0:0:0:0 | parameter 0 of Encode | file://:0:0:0:0 | [summary] to write: argument -1 in Encode | +| file://:0:0:0:0 | parameter 0 of EncodeToMemory | file://:0:0:0:0 | [summary] to write: return (return[0]) in EncodeToMemory | +| file://:0:0:0:0 | parameter 0 of EvalSymlinks | file://:0:0:0:0 | [summary] to write: return (return[0]) in EvalSymlinks | +| file://:0:0:0:0 | parameter 0 of Expand | file://:0:0:0:0 | [summary] to write: return (return[0]) in Expand | +| file://:0:0:0:0 | parameter 0 of ExpandEnv | file://:0:0:0:0 | [summary] to write: return (return[0]) in ExpandEnv | +| file://:0:0:0:0 | parameter 0 of Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext | +| file://:0:0:0:0 | parameter 0 of Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext | +| file://:0:0:0:0 | parameter 0 of Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields | +| file://:0:0:0:0 | parameter 0 of Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields | +| file://:0:0:0:0 | parameter 0 of FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc | +| file://:0:0:0:0 | parameter 0 of FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc | +| file://:0:0:0:0 | parameter 0 of FileConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileConn | +| file://:0:0:0:0 | parameter 0 of FileInfoToDirEntry | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileInfoToDirEntry | +| file://:0:0:0:0 | parameter 0 of FilePacketConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in FilePacketConn | +| file://:0:0:0:0 | parameter 0 of FormatMediaType | file://:0:0:0:0 | [summary] to write: return (return[0]) in FormatMediaType | +| file://:0:0:0:0 | parameter 0 of FromSlash | file://:0:0:0:0 | [summary] to write: return (return[0]) in FromSlash | +| file://:0:0:0:0 | parameter 0 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | parameter 0 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | parameter 0 of Indirect | file://:0:0:0:0 | [summary] to write: return (return[0]) in Indirect | +| file://:0:0:0:0 | parameter 0 of InsertAfter | file://:0:0:0:0 | [summary] to write: argument -1 in InsertAfter | +| file://:0:0:0:0 | parameter 0 of InsertAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in InsertAfter | +| file://:0:0:0:0 | parameter 0 of InsertBefore | file://:0:0:0:0 | [summary] to write: argument -1 in InsertBefore | +| file://:0:0:0:0 | parameter 0 of InsertBefore | file://:0:0:0:0 | [summary] to write: return (return[0]) in InsertBefore | +| file://:0:0:0:0 | parameter 0 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | parameter 0 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | parameter 0 of JoinHostPort | file://:0:0:0:0 | [summary] to write: return (return[0]) in JoinHostPort | +| file://:0:0:0:0 | parameter 0 of LimitReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in LimitReader | +| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | +| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | parameter 0 of LoadPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadPointer | +| file://:0:0:0:0 | parameter 0 of LoadUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadUintptr | +| file://:0:0:0:0 | parameter 0 of Marshal | file://:0:0:0:0 | [summary] to write: return (return[0]) in Marshal | +| file://:0:0:0:0 | parameter 0 of Marshal | file://:0:0:0:0 | [summary] to write: return (return[0]) in Marshal | +| file://:0:0:0:0 | parameter 0 of MarshalIndent | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalIndent | +| file://:0:0:0:0 | parameter 0 of MarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalWithParams | +| file://:0:0:0:0 | parameter 0 of MoveAfter | file://:0:0:0:0 | [summary] to write: argument -1 in MoveAfter | +| file://:0:0:0:0 | parameter 0 of MoveBefore | file://:0:0:0:0 | [summary] to write: argument -1 in MoveBefore | +| file://:0:0:0:0 | parameter 0 of MoveToBack | file://:0:0:0:0 | [summary] to write: argument -1 in MoveToBack | +| file://:0:0:0:0 | parameter 0 of MoveToFront | file://:0:0:0:0 | [summary] to write: argument -1 in MoveToFront | +| file://:0:0:0:0 | parameter 0 of New | file://:0:0:0:0 | [summary] to write: return (return[0]) in New | +| file://:0:0:0:0 | parameter 0 of NewBuffer | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewBuffer | +| file://:0:0:0:0 | parameter 0 of NewBufferString | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewBufferString | +| file://:0:0:0:0 | parameter 0 of NewConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewConn | +| file://:0:0:0:0 | parameter 0 of NewDecoder | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewDecoder | +| file://:0:0:0:0 | parameter 0 of NewDecoder | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewDecoder | +| file://:0:0:0:0 | parameter 0 of NewFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewFile | +| file://:0:0:0:0 | parameter 0 of NewListener | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewListener | +| file://:0:0:0:0 | parameter 0 of NewReadWriter | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReadWriter | +| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | parameter 0 of NewReaderDict | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReaderDict | +| file://:0:0:0:0 | parameter 0 of NewReaderSize | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReaderSize | +| file://:0:0:0:0 | parameter 0 of NewScanner | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewScanner | +| file://:0:0:0:0 | parameter 0 of NewSectionReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewSectionReader | +| file://:0:0:0:0 | parameter 0 of NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser | +| file://:0:0:0:0 | parameter 0 of NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser | +| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | parameter 0 of ParseMediaType | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseMediaType | +| file://:0:0:0:0 | parameter 0 of ParseMediaType | file://:0:0:0:0 | [summary] to write: return (return[1]) in ParseMediaType | +| file://:0:0:0:0 | parameter 0 of ParseQuery | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseQuery | +| file://:0:0:0:0 | parameter 0 of ParseRequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseRequestURI | +| file://:0:0:0:0 | parameter 0 of PathEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathEscape | +| file://:0:0:0:0 | parameter 0 of PathUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathUnescape | +| file://:0:0:0:0 | parameter 0 of PushBack | file://:0:0:0:0 | [summary] to write: argument -1 in PushBack | +| file://:0:0:0:0 | parameter 0 of PushBack | file://:0:0:0:0 | [summary] to write: return (return[0]) in PushBack | +| file://:0:0:0:0 | parameter 0 of PushBackList | file://:0:0:0:0 | [summary] to write: argument -1 in PushBackList | +| file://:0:0:0:0 | parameter 0 of PushFront | file://:0:0:0:0 | [summary] to write: argument -1 in PushFront | +| file://:0:0:0:0 | parameter 0 of PushFront | file://:0:0:0:0 | [summary] to write: return (return[0]) in PushFront | +| file://:0:0:0:0 | parameter 0 of PushFrontList | file://:0:0:0:0 | [summary] to write: argument -1 in PushFrontList | +| file://:0:0:0:0 | parameter 0 of Put | file://:0:0:0:0 | [summary] to write: argument -1 in Put | +| file://:0:0:0:0 | parameter 0 of QueryEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryEscape | +| file://:0:0:0:0 | parameter 0 of QueryUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryUnescape | +| file://:0:0:0:0 | parameter 0 of Quote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Quote | +| file://:0:0:0:0 | parameter 0 of QuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToASCII | +| file://:0:0:0:0 | parameter 0 of QuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToGraphic | +| file://:0:0:0:0 | parameter 0 of QuotedPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuotedPrefix | +| file://:0:0:0:0 | parameter 0 of Read | file://:0:0:0:0 | [summary] to write: argument 2 in Read | +| file://:0:0:0:0 | parameter 0 of ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll | +| file://:0:0:0:0 | parameter 0 of ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll | +| file://:0:0:0:0 | parameter 0 of ReadAtLeast | file://:0:0:0:0 | [summary] to write: argument 1 in ReadAtLeast | +| file://:0:0:0:0 | parameter 0 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | parameter 0 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | parameter 0 of ReadFull | file://:0:0:0:0 | [summary] to write: argument 1 in ReadFull | +| file://:0:0:0:0 | parameter 0 of ReadRequest | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadRequest | +| file://:0:0:0:0 | parameter 0 of ReadResponse | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadResponse | +| file://:0:0:0:0 | parameter 0 of Rel | file://:0:0:0:0 | [summary] to write: return (return[0]) in Rel | +| file://:0:0:0:0 | parameter 0 of Remove | file://:0:0:0:0 | [summary] to write: return (return[0]) in Remove | +| file://:0:0:0:0 | parameter 0 of Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat | +| file://:0:0:0:0 | parameter 0 of Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat | +| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | parameter 0 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | parameter 0 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | parameter 0 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | +| file://:0:0:0:0 | parameter 0 of Reverse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Reverse | +| file://:0:0:0:0 | parameter 0 of Runes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Runes | +| file://:0:0:0:0 | parameter 0 of ScanBytes | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanBytes | +| file://:0:0:0:0 | parameter 0 of ScanLines | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanLines | +| file://:0:0:0:0 | parameter 0 of ScanRunes | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanRunes | +| file://:0:0:0:0 | parameter 0 of ScanWords | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanWords | +| file://:0:0:0:0 | parameter 0 of Send | file://:0:0:0:0 | [summary] to write: argument -1 in Send | +| file://:0:0:0:0 | parameter 0 of Server | file://:0:0:0:0 | [summary] to write: return (return[0]) in Server | +| file://:0:0:0:0 | parameter 0 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | parameter 0 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | parameter 0 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | parameter 0 of SetBytes | file://:0:0:0:0 | [summary] to write: argument -1 in SetBytes | +| file://:0:0:0:0 | parameter 0 of SetIndent | file://:0:0:0:0 | [summary] to write: argument -1 in SetIndent | +| file://:0:0:0:0 | parameter 0 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | +| file://:0:0:0:0 | parameter 0 of SetPointer | file://:0:0:0:0 | [summary] to write: argument -1 in SetPointer | +| file://:0:0:0:0 | parameter 0 of SetPrefix | file://:0:0:0:0 | [summary] to write: argument -1 in SetPrefix | +| file://:0:0:0:0 | parameter 0 of SetString | file://:0:0:0:0 | [summary] to write: argument -1 in SetString | +| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split | +| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split | +| file://:0:0:0:0 | parameter 0 of SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter | +| file://:0:0:0:0 | parameter 0 of SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter | +| file://:0:0:0:0 | parameter 0 of SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN | +| file://:0:0:0:0 | parameter 0 of SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN | +| file://:0:0:0:0 | parameter 0 of SplitHostPort | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitHostPort | +| file://:0:0:0:0 | parameter 0 of SplitHostPort | file://:0:0:0:0 | [summary] to write: return (return[1]) in SplitHostPort | +| file://:0:0:0:0 | parameter 0 of SplitList | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitList | +| file://:0:0:0:0 | parameter 0 of SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN | +| file://:0:0:0:0 | parameter 0 of SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN | +| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 0 of StringBytePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringBytePtr | +| file://:0:0:0:0 | parameter 0 of StringByteSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringByteSlice | +| file://:0:0:0:0 | parameter 0 of StringSlicePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringSlicePtr | +| file://:0:0:0:0 | parameter 0 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 0 of SwapPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapPointer | +| file://:0:0:0:0 | parameter 0 of SwapUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapUintptr | +| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: argument 1 in TeeReader | +| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in TeeReader | +| file://:0:0:0:0 | parameter 0 of Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title | +| file://:0:0:0:0 | parameter 0 of Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title | +| file://:0:0:0:0 | parameter 0 of ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower | +| file://:0:0:0:0 | parameter 0 of ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower | +| file://:0:0:0:0 | parameter 0 of ToSlash | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToSlash | +| file://:0:0:0:0 | parameter 0 of ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle | +| file://:0:0:0:0 | parameter 0 of ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle | +| file://:0:0:0:0 | parameter 0 of ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper | +| file://:0:0:0:0 | parameter 0 of ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper | +| file://:0:0:0:0 | parameter 0 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | parameter 0 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | parameter 0 of Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim | +| file://:0:0:0:0 | parameter 0 of Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim | +| file://:0:0:0:0 | parameter 0 of TrimBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimBytes | +| file://:0:0:0:0 | parameter 0 of TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc | +| file://:0:0:0:0 | parameter 0 of TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc | +| file://:0:0:0:0 | parameter 0 of TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft | +| file://:0:0:0:0 | parameter 0 of TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft | +| file://:0:0:0:0 | parameter 0 of TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc | +| file://:0:0:0:0 | parameter 0 of TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc | +| file://:0:0:0:0 | parameter 0 of TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix | +| file://:0:0:0:0 | parameter 0 of TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix | +| file://:0:0:0:0 | parameter 0 of TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight | +| file://:0:0:0:0 | parameter 0 of TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight | +| file://:0:0:0:0 | parameter 0 of TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc | +| file://:0:0:0:0 | parameter 0 of TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc | +| file://:0:0:0:0 | parameter 0 of TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace | +| file://:0:0:0:0 | parameter 0 of TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace | +| file://:0:0:0:0 | parameter 0 of TrimString | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimString | +| file://:0:0:0:0 | parameter 0 of TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix | +| file://:0:0:0:0 | parameter 0 of TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix | +| file://:0:0:0:0 | parameter 0 of TrySend | file://:0:0:0:0 | [summary] to write: argument -1 in TrySend | +| file://:0:0:0:0 | parameter 0 of Unmarshal | file://:0:0:0:0 | [summary] to write: argument 1 in Unmarshal | +| file://:0:0:0:0 | parameter 0 of Unmarshal | file://:0:0:0:0 | [summary] to write: argument 1 in Unmarshal | +| file://:0:0:0:0 | parameter 0 of Unmarshal | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unmarshal | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | parameter 0 of UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | +| file://:0:0:0:0 | parameter 0 of UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | +| file://:0:0:0:0 | parameter 0 of UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | +| file://:0:0:0:0 | parameter 0 of UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | +| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | parameter 0 of UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: argument 1 in UnmarshalWithParams | +| file://:0:0:0:0 | parameter 0 of UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnmarshalWithParams | +| file://:0:0:0:0 | parameter 0 of Unquote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unquote | +| file://:0:0:0:0 | parameter 0 of UnquoteChar | file://:0:0:0:0 | [summary] to write: return (return[2]) in UnquoteChar | +| file://:0:0:0:0 | parameter 0 of Unwrap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unwrap | +| file://:0:0:0:0 | parameter 0 of User | file://:0:0:0:0 | [summary] to write: return (return[0]) in User | +| file://:0:0:0:0 | parameter 0 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | +| file://:0:0:0:0 | parameter 0 of ValueOf | file://:0:0:0:0 | [summary] to write: return (return[0]) in ValueOf | +| file://:0:0:0:0 | parameter 0 of VolumeName | file://:0:0:0:0 | [summary] to write: return (return[0]) in VolumeName | +| file://:0:0:0:0 | parameter 0 of WithCancel | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithCancel | +| file://:0:0:0:0 | parameter 0 of WithDeadline | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithDeadline | +| file://:0:0:0:0 | parameter 0 of WithTimeout | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithTimeout | +| file://:0:0:0:0 | parameter 0 of WithValue | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithValue | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | parameter 0 of WriteField | file://:0:0:0:0 | [summary] to write: argument -1 in WriteField | +| file://:0:0:0:0 | parameter 0 of WriteMsgIP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgIP | +| file://:0:0:0:0 | parameter 0 of WriteMsgUDP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUDP | +| file://:0:0:0:0 | parameter 0 of WriteMsgUnix | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUnix | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | parameter 0 of WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | +| file://:0:0:0:0 | parameter 0 of WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | +| file://:0:0:0:0 | parameter 0 of WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | +| file://:0:0:0:0 | parameter 0 of WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | +| file://:0:0:0:0 | parameter 0 of WriteToIP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteToIP | +| file://:0:0:0:0 | parameter 0 of WriteToUDP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteToUDP | +| file://:0:0:0:0 | parameter 0 of WriteToUnix | file://:0:0:0:0 | [summary] to write: argument -1 in WriteToUnix | +| file://:0:0:0:0 | parameter 1 of Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | +| file://:0:0:0:0 | parameter 1 of Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | +| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in AddUintptr | +| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in AddUintptr | +| file://:0:0:0:0 | parameter 1 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | +| file://:0:0:0:0 | parameter 1 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | +| file://:0:0:0:0 | parameter 1 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | +| file://:0:0:0:0 | parameter 1 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | +| file://:0:0:0:0 | parameter 1 of Compact | file://:0:0:0:0 | [summary] to write: argument 0 in Compact | +| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | +| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | +| file://:0:0:0:0 | parameter 1 of CopyBuffer | file://:0:0:0:0 | [summary] to write: argument 0 in CopyBuffer | +| file://:0:0:0:0 | parameter 1 of CopyN | file://:0:0:0:0 | [summary] to write: argument 0 in CopyN | +| file://:0:0:0:0 | parameter 1 of Decode | file://:0:0:0:0 | [summary] to write: argument 0 in Decode | +| file://:0:0:0:0 | parameter 1 of Decode | file://:0:0:0:0 | [summary] to write: argument 0 in Decode | +| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decrypt | +| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decrypt | +| file://:0:0:0:0 | parameter 1 of Encode | file://:0:0:0:0 | [summary] to write: argument 0 in Encode | +| file://:0:0:0:0 | parameter 1 of Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode | +| file://:0:0:0:0 | parameter 1 of Error | file://:0:0:0:0 | [summary] to write: argument 0 in Error | +| file://:0:0:0:0 | parameter 1 of FormatMediaType | file://:0:0:0:0 | [summary] to write: return (return[0]) in FormatMediaType | +| file://:0:0:0:0 | parameter 1 of HTMLEscape | file://:0:0:0:0 | [summary] to write: argument 0 in HTMLEscape | +| file://:0:0:0:0 | parameter 1 of Indent | file://:0:0:0:0 | [summary] to write: argument 0 in Indent | +| file://:0:0:0:0 | parameter 1 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | parameter 1 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | parameter 1 of JoinHostPort | file://:0:0:0:0 | [summary] to write: return (return[0]) in JoinHostPort | +| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | +| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | parameter 1 of Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map | +| file://:0:0:0:0 | parameter 1 of Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map | +| file://:0:0:0:0 | parameter 1 of MarshalIndent | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalIndent | +| file://:0:0:0:0 | parameter 1 of MarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalWithParams | +| file://:0:0:0:0 | parameter 1 of MaxBytesReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in MaxBytesReader | +| file://:0:0:0:0 | parameter 1 of NewDecoder | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewDecoder | +| file://:0:0:0:0 | parameter 1 of NewRequest | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewRequest | +| file://:0:0:0:0 | parameter 1 of Rel | file://:0:0:0:0 | [summary] to write: return (return[0]) in Rel | +| file://:0:0:0:0 | parameter 1 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | parameter 1 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | parameter 1 of SetCookie | file://:0:0:0:0 | [summary] to write: argument 0 in SetCookie | +| file://:0:0:0:0 | parameter 1 of SetIndent | file://:0:0:0:0 | [summary] to write: argument -1 in SetIndent | +| file://:0:0:0:0 | parameter 1 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | +| file://:0:0:0:0 | parameter 1 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | parameter 1 of StorePointer | file://:0:0:0:0 | [summary] to write: argument 0 in StorePointer | +| file://:0:0:0:0 | parameter 1 of StoreUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in StoreUintptr | +| file://:0:0:0:0 | parameter 1 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | parameter 1 of SwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in SwapPointer | +| file://:0:0:0:0 | parameter 1 of SwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in SwapUintptr | +| file://:0:0:0:0 | parameter 1 of ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial | +| file://:0:0:0:0 | parameter 1 of ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial | +| file://:0:0:0:0 | parameter 1 of ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial | +| file://:0:0:0:0 | parameter 1 of ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial | +| file://:0:0:0:0 | parameter 1 of ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial | +| file://:0:0:0:0 | parameter 1 of ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial | +| file://:0:0:0:0 | parameter 1 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | parameter 1 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | parameter 1 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | +| file://:0:0:0:0 | parameter 1 of WithValue | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithValue | +| file://:0:0:0:0 | parameter 1 of WriteField | file://:0:0:0:0 | [summary] to write: argument -1 in WriteField | +| file://:0:0:0:0 | parameter 1 of WriteMsgIP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgIP | +| file://:0:0:0:0 | parameter 1 of WriteMsgUDP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUDP | +| file://:0:0:0:0 | parameter 1 of WriteMsgUnix | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUnix | +| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | +| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | +| file://:0:0:0:0 | parameter 2 of CompareAndSwap | file://:0:0:0:0 | [summary] to write: argument -1 in CompareAndSwap | +| file://:0:0:0:0 | parameter 2 of CompareAndSwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapPointer | +| file://:0:0:0:0 | parameter 2 of CompareAndSwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapUintptr | +| file://:0:0:0:0 | parameter 2 of DecryptPKCS1v15 | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecryptPKCS1v15 | +| file://:0:0:0:0 | parameter 2 of Indent | file://:0:0:0:0 | [summary] to write: argument 0 in Indent | +| file://:0:0:0:0 | parameter 2 of MarshalIndent | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalIndent | +| file://:0:0:0:0 | parameter 2 of NewRequestWithContext | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewRequestWithContext | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter 2 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | parameter 2 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | parameter 2 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | parameter 2 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | parameter 2 of UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: argument 1 in UnmarshalWithParams | +| file://:0:0:0:0 | parameter 2 of UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnmarshalWithParams | +| file://:0:0:0:0 | parameter 2 of WithValue | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithValue | +| file://:0:0:0:0 | parameter 2 of Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | +| file://:0:0:0:0 | parameter 3 of DecryptOAEP | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecryptOAEP | +| file://:0:0:0:0 | parameter 3 of Indent | file://:0:0:0:0 | [summary] to write: argument 0 in Indent | +| file://:0:0:0:0 | parameter -1 of Addr | file://:0:0:0:0 | [summary] to write: return (return[0]) in Addr | +| file://:0:0:0:0 | parameter -1 of Back | file://:0:0:0:0 | [summary] to write: return (return[0]) in Back | +| file://:0:0:0:0 | parameter -1 of Buffered | file://:0:0:0:0 | [summary] to write: return (return[0]) in Buffered | +| file://:0:0:0:0 | parameter -1 of Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | +| file://:0:0:0:0 | parameter -1 of Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | +| file://:0:0:0:0 | parameter -1 of Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | +| file://:0:0:0:0 | parameter -1 of Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | +| file://:0:0:0:0 | parameter -1 of Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | +| file://:0:0:0:0 | parameter -1 of Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | +| file://:0:0:0:0 | parameter -1 of Convert | file://:0:0:0:0 | [summary] to write: return (return[0]) in Convert | +| file://:0:0:0:0 | parameter -1 of Decode | file://:0:0:0:0 | [summary] to write: argument 0 in Decode | +| file://:0:0:0:0 | parameter -1 of DotReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in DotReader | +| file://:0:0:0:0 | parameter -1 of Elem | file://:0:0:0:0 | [summary] to write: return (return[0]) in Elem | +| file://:0:0:0:0 | parameter -1 of Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode | +| file://:0:0:0:0 | parameter -1 of EscapedPath | file://:0:0:0:0 | [summary] to write: return (return[0]) in EscapedPath | +| file://:0:0:0:0 | parameter -1 of Fd | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fd | +| file://:0:0:0:0 | parameter -1 of Field | file://:0:0:0:0 | [summary] to write: return (return[0]) in Field | +| file://:0:0:0:0 | parameter -1 of FieldByIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByIndex | +| file://:0:0:0:0 | parameter -1 of FieldByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByName | +| file://:0:0:0:0 | parameter -1 of FieldByNameFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByNameFunc | +| file://:0:0:0:0 | parameter -1 of File | file://:0:0:0:0 | [summary] to write: return (return[0]) in File | +| file://:0:0:0:0 | parameter -1 of File | file://:0:0:0:0 | [summary] to write: return (return[0]) in File | +| file://:0:0:0:0 | parameter -1 of FileName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileName | +| file://:0:0:0:0 | parameter -1 of FormName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FormName | +| file://:0:0:0:0 | parameter -1 of Front | file://:0:0:0:0 | [summary] to write: return (return[0]) in Front | +| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hijack | +| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hijack | +| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hijack | +| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[1]) in Hijack | +| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[1]) in Hijack | +| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[1]) in Hijack | +| file://:0:0:0:0 | parameter -1 of Hostname | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hostname | +| file://:0:0:0:0 | parameter -1 of Index | file://:0:0:0:0 | [summary] to write: return (return[0]) in Index | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | parameter -1 of Init | file://:0:0:0:0 | [summary] to write: return (return[0]) in Init | +| file://:0:0:0:0 | parameter -1 of Interface | file://:0:0:0:0 | [summary] to write: return (return[0]) in Interface | +| file://:0:0:0:0 | parameter -1 of InterfaceData | file://:0:0:0:0 | [summary] to write: return (return[0]) in InterfaceData | +| file://:0:0:0:0 | parameter -1 of Key | file://:0:0:0:0 | [summary] to write: return (return[0]) in Key | +| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | parameter -1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | parameter -1 of Lookup | file://:0:0:0:0 | [summary] to write: return (return[0]) in Lookup | +| file://:0:0:0:0 | parameter -1 of MapIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapIndex | +| file://:0:0:0:0 | parameter -1 of MapKeys | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapKeys | +| file://:0:0:0:0 | parameter -1 of MapRange | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapRange | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | parameter -1 of MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | +| file://:0:0:0:0 | parameter -1 of MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | +| file://:0:0:0:0 | parameter -1 of MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | +| file://:0:0:0:0 | parameter -1 of MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | +| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | parameter -1 of Method | file://:0:0:0:0 | [summary] to write: return (return[0]) in Method | +| file://:0:0:0:0 | parameter -1 of MethodByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in MethodByName | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | parameter -1 of Next | file://:0:0:0:0 | [summary] to write: return (return[0]) in Next | +| file://:0:0:0:0 | parameter -1 of Next | file://:0:0:0:0 | [summary] to write: return (return[0]) in Next | +| file://:0:0:0:0 | parameter -1 of NextPart | file://:0:0:0:0 | [summary] to write: return (return[0]) in NextPart | +| file://:0:0:0:0 | parameter -1 of NextRawPart | file://:0:0:0:0 | [summary] to write: return (return[0]) in NextRawPart | +| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | parameter -1 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | parameter -1 of Password | file://:0:0:0:0 | [summary] to write: return (return[0]) in Password | +| file://:0:0:0:0 | parameter -1 of Peek | file://:0:0:0:0 | [summary] to write: return (return[0]) in Peek | +| file://:0:0:0:0 | parameter -1 of Pointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Pointer | +| file://:0:0:0:0 | parameter -1 of Port | file://:0:0:0:0 | [summary] to write: return (return[0]) in Port | +| file://:0:0:0:0 | parameter -1 of Prev | file://:0:0:0:0 | [summary] to write: return (return[0]) in Prev | +| file://:0:0:0:0 | parameter -1 of Query | file://:0:0:0:0 | [summary] to write: return (return[0]) in Query | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | parameter -1 of ReadBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadBytes | +| file://:0:0:0:0 | parameter -1 of ReadBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadBytes | +| file://:0:0:0:0 | parameter -1 of ReadCodeLine | file://:0:0:0:0 | [summary] to write: return (return[1]) in ReadCodeLine | +| file://:0:0:0:0 | parameter -1 of ReadContinuedLine | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadContinuedLine | +| file://:0:0:0:0 | parameter -1 of ReadContinuedLineBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadContinuedLineBytes | +| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | parameter -1 of ReadDotBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDotBytes | +| file://:0:0:0:0 | parameter -1 of ReadDotLines | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDotLines | +| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | parameter -1 of ReadForm | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadForm | +| file://:0:0:0:0 | parameter -1 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | +| file://:0:0:0:0 | parameter -1 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | +| file://:0:0:0:0 | parameter -1 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | +| file://:0:0:0:0 | parameter -1 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | +| file://:0:0:0:0 | parameter -1 of ReadFromIP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFromIP | +| file://:0:0:0:0 | parameter -1 of ReadFromUDP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFromUDP | +| file://:0:0:0:0 | parameter -1 of ReadFromUnix | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFromUnix | +| file://:0:0:0:0 | parameter -1 of ReadLine | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadLine | +| file://:0:0:0:0 | parameter -1 of ReadLine | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadLine | +| file://:0:0:0:0 | parameter -1 of ReadLineBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadLineBytes | +| file://:0:0:0:0 | parameter -1 of ReadMIMEHeader | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadMIMEHeader | +| file://:0:0:0:0 | parameter -1 of ReadMsgIP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadMsgIP | +| file://:0:0:0:0 | parameter -1 of ReadMsgIP | file://:0:0:0:0 | [summary] to write: argument 1 in ReadMsgIP | +| file://:0:0:0:0 | parameter -1 of ReadMsgUDP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadMsgUDP | +| file://:0:0:0:0 | parameter -1 of ReadMsgUDP | file://:0:0:0:0 | [summary] to write: argument 1 in ReadMsgUDP | +| file://:0:0:0:0 | parameter -1 of ReadMsgUnix | file://:0:0:0:0 | [summary] to write: argument 0 in ReadMsgUnix | +| file://:0:0:0:0 | parameter -1 of ReadMsgUnix | file://:0:0:0:0 | [summary] to write: argument 1 in ReadMsgUnix | +| file://:0:0:0:0 | parameter -1 of ReadResponse | file://:0:0:0:0 | [summary] to write: return (return[1]) in ReadResponse | +| file://:0:0:0:0 | parameter -1 of ReadSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadSlice | +| file://:0:0:0:0 | parameter -1 of ReadString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadString | +| file://:0:0:0:0 | parameter -1 of ReadString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadString | +| file://:0:0:0:0 | parameter -1 of Recv | file://:0:0:0:0 | [summary] to write: return (return[0]) in Recv | +| file://:0:0:0:0 | parameter -1 of RequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in RequestURI | +| file://:0:0:0:0 | parameter -1 of Reset | file://:0:0:0:0 | [summary] to write: argument 0 in Reset | +| file://:0:0:0:0 | parameter -1 of Reset | file://:0:0:0:0 | [summary] to write: argument 0 in Reset | +| file://:0:0:0:0 | parameter -1 of Reset | file://:0:0:0:0 | [summary] to write: argument 0 in Reset | +| file://:0:0:0:0 | parameter -1 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | +| file://:0:0:0:0 | parameter -1 of SetOutput | file://:0:0:0:0 | [summary] to write: argument 0 in SetOutput | +| file://:0:0:0:0 | parameter -1 of Slice | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice | +| file://:0:0:0:0 | parameter -1 of Slice3 | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice3 | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | parameter -1 of Text | file://:0:0:0:0 | [summary] to write: return (return[0]) in Text | +| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | parameter -1 of TryRecv | file://:0:0:0:0 | [summary] to write: return (return[0]) in TryRecv | +| file://:0:0:0:0 | parameter -1 of UnsafeAddr | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnsafeAddr | +| file://:0:0:0:0 | parameter -1 of Username | file://:0:0:0:0 | [summary] to write: return (return[0]) in Username | +| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | parameter -1 of Values | file://:0:0:0:0 | [summary] to write: return (return[0]) in Values | +| file://:0:0:0:0 | parameter -1 of Values | file://:0:0:0:0 | [summary] to write: return (return[0]) in Values | +| file://:0:0:0:0 | parameter -1 of Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | +| file://:0:0:0:0 | parameter -1 of Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | +| file://:0:0:0:0 | parameter -1 of Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | +| file://:0:0:0:0 | parameter -1 of WriteProxy | file://:0:0:0:0 | [summary] to write: argument 0 in WriteProxy | +| file://:0:0:0:0 | parameter -1 of WriteSubset | file://:0:0:0:0 | [summary] to write: argument 0 in WriteSubset | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | parameter -1 of Writer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Writer | +| io.go:14:31:14:43 | "some string" | io.go:14:13:14:44 | call to NewReader | +| io.go:16:3:16:3 | definition of w | io.go:16:23:16:27 | &... | +| io.go:16:3:16:3 | definition of w | io.go:16:30:16:34 | &... | +| io.go:16:23:16:27 | &... | io.go:15:7:15:10 | definition of buf1 | +| io.go:16:24:16:27 | buf1 | io.go:16:23:16:27 | &... | +| io.go:16:30:16:34 | &... | io.go:15:13:15:16 | definition of buf2 | +| io.go:16:31:16:34 | buf2 | io.go:16:30:16:34 | &... | +| io.go:18:14:18:19 | reader | io.go:16:3:16:3 | definition of w | +| io.go:22:31:22:43 | "some string" | io.go:22:13:22:44 | call to NewReader | +| io.go:25:19:25:23 | &... | io.go:23:7:23:10 | definition of buf1 | +| io.go:25:20:25:23 | buf1 | io.go:25:19:25:23 | &... | +| io.go:27:21:27:26 | reader | io.go:25:3:25:4 | definition of w2 | +| io.go:31:31:31:43 | "some string" | io.go:31:13:31:44 | call to NewReader | +| io.go:33:19:33:23 | &... | io.go:32:7:32:10 | definition of buf1 | +| io.go:33:20:33:23 | buf1 | io.go:33:19:33:23 | &... | +| io.go:35:16:35:21 | reader | io.go:33:3:33:4 | definition of w2 | +| io.go:39:6:39:6 | definition of w | io.go:39:3:39:19 | ... := ...[0] | +| io.go:39:11:39:19 | call to Pipe | io.go:39:3:39:19 | ... := ...[0] | +| io.go:39:11:39:19 | call to Pipe | io.go:39:3:39:19 | ... := ...[1] | +| io.go:40:17:40:31 | "some string\\n" | io.go:39:6:39:6 | definition of w | +| io.go:43:16:43:16 | r | io.go:42:3:42:5 | definition of buf | +| io.go:44:13:44:15 | buf | io.go:44:13:44:24 | call to String | +| io.go:48:31:48:43 | "some string" | io.go:48:13:48:44 | call to NewReader | +| io.go:50:18:50:23 | reader | io.go:49:3:49:5 | definition of buf | +| io.go:54:31:54:43 | "some string" | io.go:54:13:54:44 | call to NewReader | +| io.go:56:15:56:20 | reader | io.go:55:3:55:5 | definition of buf | +| io.go:61:18:61:21 | &... | io.go:60:7:60:9 | definition of buf | +| io.go:61:19:61:21 | buf | io.go:61:18:61:21 | &... | +| io.go:62:21:62:26 | "test" | io.go:61:3:61:3 | definition of w | +| io.go:65:31:65:43 | "some string" | io.go:65:13:65:44 | call to NewReader | +| io.go:67:3:67:8 | reader | io.go:66:3:66:5 | definition of buf | +| io.go:70:31:70:43 | "some string" | io.go:70:13:70:44 | call to NewReader | +| io.go:72:3:72:8 | reader | io.go:71:3:71:5 | definition of buf | +| io.go:76:31:76:43 | "some string" | io.go:76:13:76:44 | call to NewReader | +| io.go:77:24:77:29 | reader | io.go:77:9:77:33 | call to LimitReader | +| io.go:78:22:78:23 | lr | io.go:78:11:78:19 | selection of Stdout | +| io.go:82:27:82:36 | "reader1 " | io.go:82:9:82:37 | call to NewReader | +| io.go:83:27:83:36 | "reader2 " | io.go:83:9:83:37 | call to NewReader | +| io.go:84:27:84:35 | "reader3" | io.go:84:9:84:36 | call to NewReader | +| io.go:85:23:85:24 | r1 | io.go:85:8:85:33 | call to MultiReader | +| io.go:85:27:85:28 | r2 | io.go:85:8:85:33 | call to MultiReader | +| io.go:85:31:85:32 | r3 | io.go:85:8:85:33 | call to MultiReader | +| io.go:86:22:86:22 | r | io.go:86:11:86:19 | selection of Stdout | +| io.go:89:26:89:38 | "some string" | io.go:89:8:89:39 | call to NewReader | +| io.go:91:23:91:23 | r | io.go:91:10:91:30 | call to TeeReader | +| io.go:91:23:91:23 | r | io.go:91:26:91:29 | &... | +| io.go:91:26:91:29 | &... | io.go:90:7:90:9 | definition of buf | +| io.go:91:27:91:29 | buf | io.go:91:26:91:29 | &... | +| io.go:93:22:93:24 | tee | io.go:93:11:93:19 | selection of Stdout | +| io.go:96:26:96:38 | "some string" | io.go:96:8:96:39 | call to NewReader | +| io.go:97:28:97:28 | r | io.go:97:8:97:36 | call to NewSectionReader | +| io.go:98:22:98:22 | s | io.go:98:11:98:19 | selection of Stdout | +| io.go:101:26:101:38 | "some string" | io.go:101:8:101:39 | call to NewReader | +| io.go:102:3:102:3 | r | io.go:102:13:102:21 | selection of Stdout | +| io.go:108:30:108:42 | "some string" | io.go:108:12:108:43 | call to NewReader | +| io.go:109:12:109:33 | call to ReadAll | io.go:109:2:109:33 | ... := ...[0] | +| io.go:109:12:109:33 | call to ReadAll | io.go:109:2:109:33 | ... := ...[1] | +| io.go:109:27:109:32 | reader | io.go:109:2:109:33 | ... := ...[0] | +| io.go:110:18:110:20 | buf | io.go:110:2:110:10 | selection of Stdout | | main.go:11:12:11:26 | call to Marshal | main.go:11:2:11:26 | ... := ...[0] | | main.go:11:12:11:26 | call to Marshal | main.go:11:2:11:26 | ... := ...[1] | | main.go:11:25:11:25 | v | main.go:11:2:11:26 | ... := ...[0] | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/io.go b/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/io.go index 3fdca3a7b15d..98437917d357 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/io.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/io.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "io" + "io/ioutil" "os" "strings" ) @@ -102,3 +103,9 @@ func io2() { } } + +func utiltest() { + reader := strings.NewReader("some string") + buf, _ := ioutil.ReadAll(reader) + os.Stdout.Write(buf) +} diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected index aa0daf2d591c..21c6a94e4ad4 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected @@ -1,36 +1,113 @@ edges -| test.go:10:2:10:42 | ... := ...[0] | test.go:14:15:14:55 | type conversion | -| test.go:16:24:16:35 | selection of Body | test.go:17:15:17:31 | type conversion | -| test.go:16:24:16:35 | selection of Body | test.go:28:22:28:25 | node | -| test.go:19:36:19:47 | selection of Body | test.go:20:15:20:32 | type conversion | -| test.go:22:33:22:44 | selection of Body | test.go:23:15:23:35 | type conversion | -| test.go:25:45:25:56 | selection of Body | test.go:26:15:26:36 | type conversion | -| test.go:30:33:30:44 | selection of Body | test.go:31:15:31:34 | call to Buffered | -| test.go:30:33:30:44 | selection of Body | test.go:32:15:32:29 | call to Raw | -| test.go:30:33:30:44 | selection of Body | test.go:34:15:34:19 | value | -| test.go:30:33:30:44 | selection of Body | test.go:35:15:35:30 | call to Text | -| test.go:30:33:30:44 | selection of Body | test.go:36:15:36:44 | type conversion | +| test.go:11:2:11:42 | ... := ...[0] | test.go:14:42:14:53 | selection of Value | +| test.go:14:22:14:54 | call to UnescapeString | test.go:14:15:14:55 | type conversion | +| test.go:14:42:14:53 | selection of Value | test.go:14:22:14:54 | call to UnescapeString | +| test.go:16:2:16:36 | ... := ...[0] | test.go:17:15:17:31 | type conversion | +| test.go:16:2:16:36 | ... := ...[0] | test.go:28:22:28:25 | node | +| test.go:16:24:16:35 | selection of Body | test.go:16:2:16:36 | ... := ...[0] | +| test.go:19:2:19:48 | ... := ...[0] | test.go:20:15:20:32 | type conversion | +| test.go:19:36:19:47 | selection of Body | test.go:19:2:19:48 | ... := ...[0] | +| test.go:22:2:22:50 | ... := ...[0] | test.go:23:15:23:35 | type conversion | +| test.go:22:33:22:44 | selection of Body | test.go:22:2:22:50 | ... := ...[0] | +| test.go:25:2:25:62 | ... := ...[0] | test.go:26:15:26:36 | type conversion | +| test.go:25:45:25:56 | selection of Body | test.go:25:2:25:62 | ... := ...[0] | +| test.go:30:15:30:45 | call to NewTokenizer | test.go:31:15:31:23 | tokenizer | +| test.go:30:15:30:45 | call to NewTokenizer | test.go:32:15:32:23 | tokenizer | +| test.go:30:15:30:45 | call to NewTokenizer | test.go:33:17:33:25 | tokenizer | +| test.go:30:15:30:45 | call to NewTokenizer | test.go:35:15:35:23 | tokenizer | +| test.go:30:15:30:45 | call to NewTokenizer | test.go:36:22:36:30 | tokenizer | +| test.go:30:33:30:44 | selection of Body | test.go:30:15:30:45 | call to NewTokenizer | +| test.go:31:15:31:23 | tokenizer | test.go:31:15:31:34 | call to Buffered | +| test.go:32:15:32:23 | tokenizer | test.go:32:15:32:29 | call to Raw | +| test.go:33:2:33:35 | ... := ...[1] | test.go:34:15:34:19 | value | +| test.go:33:17:33:25 | tokenizer | test.go:33:2:33:35 | ... := ...[1] | +| test.go:35:15:35:23 | tokenizer | test.go:35:15:35:30 | call to Text | +| test.go:36:22:36:30 | tokenizer | test.go:36:22:36:38 | call to Token | +| test.go:36:22:36:38 | call to Token | test.go:36:15:36:44 | type conversion | +| test.go:38:23:38:77 | call to NewTokenizerFragment | test.go:39:15:39:31 | tokenizerFragment | +| test.go:38:49:38:60 | selection of Body | test.go:38:23:38:77 | call to NewTokenizerFragment | +| test.go:39:15:39:31 | tokenizerFragment | test.go:39:15:39:42 | call to Buffered | +| test.go:41:6:41:14 | definition of cleanNode | test.go:44:22:44:31 | &... | +| test.go:41:6:41:14 | definition of cleanNode | test.go:44:22:44:31 | &... | +| test.go:41:6:41:14 | definition of cleanNode | test.go:44:23:44:31 | cleanNode | +| test.go:42:2:42:43 | ... := ...[0] | test.go:43:24:43:34 | taintedNode | +| test.go:42:31:42:42 | selection of Body | test.go:42:2:42:43 | ... := ...[0] | +| test.go:43:24:43:34 | taintedNode | test.go:41:6:41:14 | definition of cleanNode | +| test.go:44:22:44:31 | &... | test.go:44:22:44:31 | &... | +| test.go:44:22:44:31 | &... | test.go:44:22:44:31 | &... | +| test.go:44:22:44:31 | &... | test.go:44:23:44:31 | cleanNode | +| test.go:44:22:44:31 | &... [pointer] | test.go:44:22:44:31 | &... | +| test.go:44:22:44:31 | &... [pointer] | test.go:44:22:44:31 | &... | +| test.go:44:22:44:31 | &... [pointer] | test.go:44:23:44:31 | cleanNode | +| test.go:44:23:44:31 | cleanNode | test.go:44:22:44:31 | &... [pointer] | +| test.go:46:6:46:15 | definition of cleanNode2 | test.go:49:22:49:32 | &... | +| test.go:46:6:46:15 | definition of cleanNode2 | test.go:49:22:49:32 | &... | +| test.go:46:6:46:15 | definition of cleanNode2 | test.go:49:23:49:32 | cleanNode2 | +| test.go:47:2:47:44 | ... := ...[0] | test.go:48:26:48:37 | taintedNode2 | +| test.go:47:32:47:43 | selection of Body | test.go:47:2:47:44 | ... := ...[0] | +| test.go:48:26:48:37 | taintedNode2 | test.go:46:6:46:15 | definition of cleanNode2 | +| test.go:49:22:49:32 | &... | test.go:49:22:49:32 | &... | +| test.go:49:22:49:32 | &... | test.go:49:22:49:32 | &... | +| test.go:49:22:49:32 | &... | test.go:49:23:49:32 | cleanNode2 | +| test.go:49:22:49:32 | &... [pointer] | test.go:49:22:49:32 | &... | +| test.go:49:22:49:32 | &... [pointer] | test.go:49:22:49:32 | &... | +| test.go:49:22:49:32 | &... [pointer] | test.go:49:23:49:32 | cleanNode2 | +| test.go:49:23:49:32 | cleanNode2 | test.go:49:22:49:32 | &... [pointer] | nodes -| test.go:10:2:10:42 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:11:2:11:42 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:14:15:14:55 | type conversion | semmle.label | type conversion | +| test.go:14:22:14:54 | call to UnescapeString | semmle.label | call to UnescapeString | +| test.go:14:42:14:53 | selection of Value | semmle.label | selection of Value | +| test.go:16:2:16:36 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:16:24:16:35 | selection of Body | semmle.label | selection of Body | | test.go:17:15:17:31 | type conversion | semmle.label | type conversion | +| test.go:19:2:19:48 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:19:36:19:47 | selection of Body | semmle.label | selection of Body | | test.go:20:15:20:32 | type conversion | semmle.label | type conversion | +| test.go:22:2:22:50 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:22:33:22:44 | selection of Body | semmle.label | selection of Body | | test.go:23:15:23:35 | type conversion | semmle.label | type conversion | +| test.go:25:2:25:62 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:25:45:25:56 | selection of Body | semmle.label | selection of Body | | test.go:26:15:26:36 | type conversion | semmle.label | type conversion | | test.go:28:22:28:25 | node | semmle.label | node | +| test.go:30:15:30:45 | call to NewTokenizer | semmle.label | call to NewTokenizer | | test.go:30:33:30:44 | selection of Body | semmle.label | selection of Body | +| test.go:31:15:31:23 | tokenizer | semmle.label | tokenizer | | test.go:31:15:31:34 | call to Buffered | semmle.label | call to Buffered | +| test.go:32:15:32:23 | tokenizer | semmle.label | tokenizer | | test.go:32:15:32:29 | call to Raw | semmle.label | call to Raw | +| test.go:33:2:33:35 | ... := ...[1] | semmle.label | ... := ...[1] | +| test.go:33:17:33:25 | tokenizer | semmle.label | tokenizer | | test.go:34:15:34:19 | value | semmle.label | value | +| test.go:35:15:35:23 | tokenizer | semmle.label | tokenizer | | test.go:35:15:35:30 | call to Text | semmle.label | call to Text | | test.go:36:15:36:44 | type conversion | semmle.label | type conversion | +| test.go:36:22:36:30 | tokenizer | semmle.label | tokenizer | +| test.go:36:22:36:38 | call to Token | semmle.label | call to Token | +| test.go:38:23:38:77 | call to NewTokenizerFragment | semmle.label | call to NewTokenizerFragment | +| test.go:38:49:38:60 | selection of Body | semmle.label | selection of Body | +| test.go:39:15:39:31 | tokenizerFragment | semmle.label | tokenizerFragment | +| test.go:39:15:39:42 | call to Buffered | semmle.label | call to Buffered | +| test.go:41:6:41:14 | definition of cleanNode | semmle.label | definition of cleanNode | +| test.go:42:2:42:43 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:42:31:42:42 | selection of Body | semmle.label | selection of Body | +| test.go:43:24:43:34 | taintedNode | semmle.label | taintedNode | +| test.go:44:22:44:31 | &... | semmle.label | &... | +| test.go:44:22:44:31 | &... | semmle.label | &... | +| test.go:44:22:44:31 | &... [pointer] | semmle.label | &... [pointer] | +| test.go:44:23:44:31 | cleanNode | semmle.label | cleanNode | +| test.go:46:6:46:15 | definition of cleanNode2 | semmle.label | definition of cleanNode2 | +| test.go:47:2:47:44 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:47:32:47:43 | selection of Body | semmle.label | selection of Body | +| test.go:48:26:48:37 | taintedNode2 | semmle.label | taintedNode2 | +| test.go:49:22:49:32 | &... | semmle.label | &... | +| test.go:49:22:49:32 | &... | semmle.label | &... | +| test.go:49:22:49:32 | &... [pointer] | semmle.label | &... [pointer] | +| test.go:49:23:49:32 | cleanNode2 | semmle.label | cleanNode2 | subpaths #select -| test.go:14:15:14:55 | type conversion | test.go:10:2:10:42 | ... := ...[0] | test.go:14:15:14:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:10:2:10:42 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:14:15:14:55 | type conversion | test.go:11:2:11:42 | ... := ...[0] | test.go:14:15:14:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:11:2:11:42 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:17:15:17:31 | type conversion | test.go:16:24:16:35 | selection of Body | test.go:17:15:17:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:16:24:16:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:20:15:20:32 | type conversion | test.go:19:36:19:47 | selection of Body | test.go:20:15:20:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:19:36:19:47 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:23:15:23:35 | type conversion | test.go:22:33:22:44 | selection of Body | test.go:23:15:23:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:22:33:22:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | @@ -41,3 +118,6 @@ subpaths | test.go:34:15:34:19 | value | test.go:30:33:30:44 | selection of Body | test.go:34:15:34:19 | value | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:35:15:35:30 | call to Text | test.go:30:33:30:44 | selection of Body | test.go:35:15:35:30 | call to Text | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | | test.go:36:15:36:44 | type conversion | test.go:30:33:30:44 | selection of Body | test.go:36:15:36:44 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:39:15:39:42 | call to Buffered | test.go:38:49:38:60 | selection of Body | test.go:39:15:39:42 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:38:49:38:60 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:44:22:44:31 | &... | test.go:42:31:42:42 | selection of Body | test.go:44:22:44:31 | &... | Cross-site scripting vulnerability due to $@. | test.go:42:31:42:42 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:49:22:49:32 | &... | test.go:47:32:47:43 | selection of Body | test.go:49:22:49:32 | &... | Cross-site scripting vulnerability due to $@. | test.go:47:32:47:43 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected new file mode 100644 index 000000000000..33a8ca661908 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected @@ -0,0 +1,10 @@ +edges +| test.go:55:2:55:42 | ... := ...[0] | test.go:56:29:56:40 | selection of Value | +| test.go:56:29:56:40 | selection of Value | test.go:56:11:56:41 | call to EscapeString | +nodes +| test.go:55:2:55:42 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:56:11:56:41 | call to EscapeString | semmle.label | call to EscapeString | +| test.go:56:29:56:40 | selection of Value | semmle.label | selection of Value | +subpaths +#select +| test.go:56:11:56:41 | call to EscapeString | test.go:55:2:55:42 | ... := ...[0] | test.go:56:11:56:41 | call to EscapeString | This query depends on a $@. | test.go:55:2:55:42 | ... := ...[0] | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.qlref b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.qlref new file mode 100644 index 000000000000..d1d02cbe8d37 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.qlref @@ -0,0 +1 @@ +Security/CWE-089/SqlInjection.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go index 466eba3cc2d6..0ecf7e6b27a7 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go @@ -1,6 +1,7 @@ package test import ( + "database/sql" "golang.org/x/net/html" "net/http" ) @@ -8,7 +9,6 @@ import ( func test(request *http.Request, writer http.ResponseWriter) { cookie, _ := request.Cookie("SomeCookie") - writer.Write([]byte(html.EscapeString(cookie.Value))) // GOOD: escaped. writer.Write([]byte(html.UnescapeString(cookie.Value))) // BAD: unescaped. @@ -35,4 +35,23 @@ func test(request *http.Request, writer http.ResponseWriter) { writer.Write(tokenizer.Text()) // BAD: writing unescaped HTML data writer.Write([]byte(tokenizer.Token().Data)) // BAD: writing unescaped HTML data + tokenizerFragment := html.NewTokenizerFragment(request.Body, "some context") + writer.Write(tokenizerFragment.Buffered()) // BAD: writing unescaped HTML data + + var cleanNode html.Node + taintedNode, _ := html.Parse(request.Body) + cleanNode.AppendChild(taintedNode) + html.Render(writer, &cleanNode) // BAD: writing unescaped HTML data + + var cleanNode2 html.Node + taintedNode2, _ := html.Parse(request.Body) + cleanNode2.InsertBefore(taintedNode2, &cleanNode2) + html.Render(writer, &cleanNode2) // BAD: writing unescaped HTML data + +} + +func sqlTest(request *http.Request, db *sql.DB) { + // Ensure EscapeString is a taint propagator for non-XSS queries, e.g. SQL injection: + cookie, _ := request.Cookie("SomeCookie") + db.Query(html.EscapeString(cookie.Value)) } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/vendor/golang.org/x/net/html/stub.go b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/vendor/golang.org/x/net/html/stub.go index 02d4a4fa55b8..d46225fce3fb 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/vendor/golang.org/x/net/html/stub.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/vendor/golang.org/x/net/html/stub.go @@ -125,6 +125,10 @@ func NewTokenizer(r io.Reader) *Tokenizer { return nil } +func NewTokenizerFragment(r io.Reader, contextTag string) *Tokenizer { + return nil +} + func Render(w io.Writer, n *Node) error { return nil } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql index 3d7196f038a3..e79681d60b40 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql @@ -1,6 +1,36 @@ import go import TestUtilities.InlineExpectationsTest +predicate isYamlFunction(Function f) { + f.hasQualifiedName(package("gopkg.in/yaml", ""), _) + or + f.(Method).hasQualifiedName(package("gopkg.in/yaml", ""), _, _) +} + +DataFlow::CallNode getAYamlCall() { + isYamlFunction(result.getACalleeIncludingExternals().asFunction()) +} + +class TaintTransitsFunctionConfig extends TaintTracking::Configuration { + TaintTransitsFunctionConfig() { this = "TaintTransitsFunctionConfig" } + + predicate isSourceSinkPair(DataFlow::Node inNode, DataFlow::Node outNode) { + exists(DataFlow::CallNode cn | cn = getAYamlCall() | + inNode = [cn.getAnArgument(), cn.getReceiver()] and + ( + outNode.(DataFlow::PostUpdateNode).getPreUpdateNode() = + [cn.getAnArgument(), cn.getReceiver()] + or + outNode = cn.getAResult() + ) + ) + } + + override predicate isSource(DataFlow::Node n) { isSourceSinkPair(n, _) } + + override predicate isSink(DataFlow::Node n) { isSourceSinkPair(_, n) } +} + class TaintFunctionModelTest extends InlineExpectationsTest { TaintFunctionModelTest() { this = "TaintFunctionModelTest" } @@ -8,11 +38,22 @@ class TaintFunctionModelTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "ttfnmodelstep" and - exists(TaintTracking::FunctionModel model, DataFlow::CallNode call | call = model.getACall() | - call.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), - location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and - element = call.toString() and - value = "\"" + model.getAnInputNode(call) + " -> " + model.getAnOutputNode(call) + "\"" + ( + exists(TaintTracking::FunctionModel model, DataFlow::CallNode call | call = model.getACall() | + call.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = call.toString() and + value = "\"" + model.getAnInputNode(call) + " -> " + model.getAnOutputNode(call) + "\"" + ) + or + exists(TaintTransitsFunctionConfig config, DataFlow::Node arg, DataFlow::Node output | + config.hasFlow(arg, output) and + config.isSourceSinkPair(arg, output) and + arg.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = arg.toString() and + value = "\"" + arg + " -> " + output + "\"" + ) ) } } diff --git a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected index 3e26f767b5e8..2e7a965b5142 100644 --- a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected +++ b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected @@ -1,9 +1,11 @@ edges -| TaintedPath.go:13:18:13:22 | selection of URL | TaintedPath.go:16:29:16:40 | tainted_path | -| TaintedPath.go:13:18:13:22 | selection of URL | TaintedPath.go:20:28:20:69 | call to Join | +| TaintedPath.go:13:18:13:22 | selection of URL | TaintedPath.go:13:18:13:30 | call to Query | +| TaintedPath.go:13:18:13:30 | call to Query | TaintedPath.go:16:29:16:40 | tainted_path | +| TaintedPath.go:13:18:13:30 | call to Query | TaintedPath.go:20:28:20:69 | call to Join | | tst.go:14:2:14:39 | ... := ...[1] | tst.go:17:41:17:56 | selection of Filename | nodes | TaintedPath.go:13:18:13:22 | selection of URL | semmle.label | selection of URL | +| TaintedPath.go:13:18:13:30 | call to Query | semmle.label | call to Query | | TaintedPath.go:16:29:16:40 | tainted_path | semmle.label | tainted_path | | TaintedPath.go:20:28:20:69 | call to Join | semmle.label | call to Join | | tst.go:14:2:14:39 | ... := ...[1] | semmle.label | ... := ...[1] | diff --git a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected index 1506632f5c50..1c3a46096c26 100644 --- a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected +++ b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected @@ -4,8 +4,11 @@ edges | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | -| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:14:20:14:20 | p | -| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:14:16:34 | call to Dir | +| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:12:24:12:29 | selection of Name | +| ZipSlip.go:12:3:12:30 | ... := ...[0] | ZipSlip.go:14:20:14:20 | p | +| ZipSlip.go:12:24:12:29 | selection of Name | ZipSlip.go:12:3:12:30 | ... := ...[0] | +| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:23:16:33 | selection of Name | +| tarslip.go:16:23:16:33 | selection of Name | tarslip.go:16:14:16:34 | call to Dir | | tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | nodes | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | semmle.label | definition of candidate | @@ -14,9 +17,12 @@ nodes | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | semmle.label | selection of Linkname | | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | semmle.label | selection of Name | | ZipSlip.go:11:2:15:2 | range statement[1] | semmle.label | range statement[1] | +| ZipSlip.go:12:3:12:30 | ... := ...[0] | semmle.label | ... := ...[0] | +| ZipSlip.go:12:24:12:29 | selection of Name | semmle.label | selection of Name | | ZipSlip.go:14:20:14:20 | p | semmle.label | p | | tarslip.go:15:2:15:30 | ... := ...[0] | semmle.label | ... := ...[0] | | tarslip.go:16:14:16:34 | call to Dir | semmle.label | call to Dir | +| tarslip.go:16:23:16:33 | selection of Name | semmle.label | selection of Name | | tst.go:23:2:43:2 | range statement[1] | semmle.label | range statement[1] | | tst.go:29:20:29:23 | path | semmle.label | path | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index b55f04d6eedd..cfc49180bba6 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -1,48 +1,58 @@ edges -| ArgumentInjection.go:9:10:9:16 | selection of URL | ArgumentInjection.go:10:31:10:34 | path | -| CommandInjection.go:9:13:9:19 | selection of URL | CommandInjection.go:10:22:10:28 | cmdName | -| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:12:31:12:37 | tainted | -| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:13:31:13:37 | tainted | -| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:14:30:14:36 | tainted | -| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:15:35:15:41 | tainted | -| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:16:36:16:42 | tainted | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:14:23:14:33 | slice expression | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | -| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:80:23:80:29 | tainted | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:96:24:96:34 | slice expression | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:101:24:101:34 | slice expression | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:105:30:105:36 | tainted | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:137:24:137:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:148:30:148:36 | tainted | -| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:152:24:152:30 | tainted | +| ArgumentInjection.go:9:10:9:16 | selection of URL | ArgumentInjection.go:9:10:9:24 | call to Query | +| ArgumentInjection.go:9:10:9:24 | call to Query | ArgumentInjection.go:10:31:10:34 | path | +| CommandInjection.go:9:13:9:19 | selection of URL | CommandInjection.go:9:13:9:27 | call to Query | +| CommandInjection.go:9:13:9:27 | call to Query | CommandInjection.go:10:22:10:28 | cmdName | +| GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:10:13:10:27 | call to Query | +| GitSubcommands.go:10:13:10:27 | call to Query | GitSubcommands.go:12:31:12:37 | tainted | +| GitSubcommands.go:10:13:10:27 | call to Query | GitSubcommands.go:13:31:13:37 | tainted | +| GitSubcommands.go:10:13:10:27 | call to Query | GitSubcommands.go:14:30:14:36 | tainted | +| GitSubcommands.go:10:13:10:27 | call to Query | GitSubcommands.go:15:35:15:41 | tainted | +| GitSubcommands.go:10:13:10:27 | call to Query | GitSubcommands.go:16:36:16:42 | tainted | +| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:9:13:9:27 | call to Query | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:14:23:14:33 | slice expression | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:80:23:80:29 | tainted | +| SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:92:13:92:27 | call to Query | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:96:24:96:34 | slice expression | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:101:24:101:34 | slice expression | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:105:30:105:36 | tainted | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:137:24:137:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:148:30:148:36 | tainted | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:152:24:152:30 | tainted | | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | | SanitizingDoubleDash.go:105:30:105:36 | tainted | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | nodes | ArgumentInjection.go:9:10:9:16 | selection of URL | semmle.label | selection of URL | +| ArgumentInjection.go:9:10:9:24 | call to Query | semmle.label | call to Query | | ArgumentInjection.go:10:31:10:34 | path | semmle.label | path | | CommandInjection.go:9:13:9:19 | selection of URL | semmle.label | selection of URL | +| CommandInjection.go:9:13:9:27 | call to Query | semmle.label | call to Query | | CommandInjection.go:10:22:10:28 | cmdName | semmle.label | cmdName | | GitSubcommands.go:10:13:10:19 | selection of URL | semmle.label | selection of URL | +| GitSubcommands.go:10:13:10:27 | call to Query | semmle.label | call to Query | | GitSubcommands.go:12:31:12:37 | tainted | semmle.label | tainted | | GitSubcommands.go:13:31:13:37 | tainted | semmle.label | tainted | | GitSubcommands.go:14:30:14:36 | tainted | semmle.label | tainted | | GitSubcommands.go:15:35:15:41 | tainted | semmle.label | tainted | | GitSubcommands.go:16:36:16:42 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | semmle.label | selection of URL | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | semmle.label | call to Query | | SanitizingDoubleDash.go:14:23:14:33 | slice expression | semmle.label | slice expression | | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:80:23:80:29 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | semmle.label | selection of URL | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | semmle.label | call to Query | | SanitizingDoubleDash.go:96:24:96:34 | slice expression | semmle.label | slice expression | | SanitizingDoubleDash.go:101:24:101:34 | slice expression | semmle.label | slice expression | | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | semmle.label | slice literal [array] | diff --git a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index 428f3e9edd37..4f3ee95ffe82 100644 --- a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -1,19 +1,35 @@ edges -| ReflectedXss.go:11:15:11:20 | selection of Form | ReflectedXss.go:14:44:14:51 | username | -| contenttype.go:11:11:11:16 | selection of Form | contenttype.go:17:11:17:22 | type conversion | -| contenttype.go:49:11:49:16 | selection of Form | contenttype.go:53:34:53:37 | data | +| ReflectedXss.go:11:15:11:20 | selection of Form | ReflectedXss.go:11:15:11:36 | call to Get | +| ReflectedXss.go:11:15:11:36 | call to Get | ReflectedXss.go:14:44:14:51 | username | +| contenttype.go:11:11:11:16 | selection of Form | contenttype.go:11:11:11:28 | call to Get | +| contenttype.go:11:11:11:28 | call to Get | contenttype.go:17:11:17:22 | type conversion | +| contenttype.go:49:11:49:16 | selection of Form | contenttype.go:49:11:49:28 | call to Get | +| contenttype.go:49:11:49:28 | call to Get | contenttype.go:53:34:53:37 | data | | contenttype.go:63:10:63:28 | call to FormValue | contenttype.go:64:52:64:55 | data | | contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data | | contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data | | contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | | reflectedxsstest.go:27:2:27:38 | ... := ...[0] | reflectedxsstest.go:28:10:28:57 | type conversion | -| reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:33:10:33:57 | type conversion | +| reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:32:34:32:37 | file | | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:10:34:62 | type conversion | -| reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:44:10:44:55 | type conversion | -| reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:45:10:45:18 | byteSlice | -| reflectedxsstest.go:51:14:51:18 | selection of URL | reflectedxsstest.go:54:11:54:21 | type conversion | -| tst.go:14:15:14:20 | selection of Form | tst.go:18:12:18:39 | type conversion | -| tst.go:48:14:48:19 | selection of Form | tst.go:53:12:53:26 | type conversion | +| reflectedxsstest.go:32:2:32:38 | ... := ...[0] | reflectedxsstest.go:33:10:33:57 | type conversion | +| reflectedxsstest.go:32:34:32:37 | file | reflectedxsstest.go:32:2:32:38 | ... := ...[0] | +| reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:39:16:39:21 | reader | +| reflectedxsstest.go:39:2:39:32 | ... := ...[0] | reflectedxsstest.go:40:14:40:17 | part | +| reflectedxsstest.go:39:2:39:32 | ... := ...[0] | reflectedxsstest.go:42:2:42:5 | part | +| reflectedxsstest.go:39:16:39:21 | reader | reflectedxsstest.go:39:2:39:32 | ... := ...[0] | +| reflectedxsstest.go:40:14:40:17 | part | reflectedxsstest.go:40:14:40:28 | call to FileName | +| reflectedxsstest.go:40:14:40:28 | call to FileName | reflectedxsstest.go:44:10:44:55 | type conversion | +| reflectedxsstest.go:41:2:41:10 | definition of byteSlice | reflectedxsstest.go:45:10:45:18 | byteSlice | +| reflectedxsstest.go:42:2:42:5 | part | reflectedxsstest.go:41:2:41:10 | definition of byteSlice | +| reflectedxsstest.go:51:14:51:18 | selection of URL | reflectedxsstest.go:51:14:51:26 | call to Query | +| reflectedxsstest.go:51:14:51:26 | call to Query | reflectedxsstest.go:54:11:54:21 | type conversion | +| tst.go:14:15:14:20 | selection of Form | tst.go:14:15:14:36 | call to Get | +| tst.go:14:15:14:36 | call to Get | tst.go:18:32:18:32 | a | +| tst.go:18:19:18:38 | call to Join | tst.go:18:12:18:39 | type conversion | +| tst.go:18:32:18:32 | a | tst.go:18:19:18:38 | call to Join | +| tst.go:48:14:48:19 | selection of Form | tst.go:48:14:48:34 | call to Get | +| tst.go:48:14:48:34 | call to Get | tst.go:53:12:53:26 | type conversion | | websocketXss.go:30:7:30:10 | definition of xnet | websocketXss.go:32:24:32:27 | xnet | | websocketXss.go:34:3:34:7 | definition of xnet2 | websocketXss.go:36:24:36:28 | xnet2 | | websocketXss.go:40:3:40:40 | ... := ...[1] | websocketXss.go:41:24:41:29 | nhooyr | @@ -22,10 +38,13 @@ edges | websocketXss.go:54:3:54:38 | ... := ...[1] | websocketXss.go:55:24:55:31 | gorilla3 | nodes | ReflectedXss.go:11:15:11:20 | selection of Form | semmle.label | selection of Form | +| ReflectedXss.go:11:15:11:36 | call to Get | semmle.label | call to Get | | ReflectedXss.go:14:44:14:51 | username | semmle.label | username | | contenttype.go:11:11:11:16 | selection of Form | semmle.label | selection of Form | +| contenttype.go:11:11:11:28 | call to Get | semmle.label | call to Get | | contenttype.go:17:11:17:22 | type conversion | semmle.label | type conversion | | contenttype.go:49:11:49:16 | selection of Form | semmle.label | selection of Form | +| contenttype.go:49:11:49:28 | call to Get | semmle.label | call to Get | | contenttype.go:53:34:53:37 | data | semmle.label | data | | contenttype.go:63:10:63:28 | call to FormValue | semmle.label | call to FormValue | | contenttype.go:64:52:64:55 | data | semmle.label | data | @@ -39,16 +58,29 @@ nodes | reflectedxsstest.go:28:10:28:57 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | semmle.label | ... := ...[1] | +| reflectedxsstest.go:32:2:32:38 | ... := ...[0] | semmle.label | ... := ...[0] | +| reflectedxsstest.go:32:34:32:37 | file | semmle.label | file | | reflectedxsstest.go:33:10:33:57 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:34:10:34:62 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | semmle.label | ... := ...[0] | +| reflectedxsstest.go:39:2:39:32 | ... := ...[0] | semmle.label | ... := ...[0] | +| reflectedxsstest.go:39:16:39:21 | reader | semmle.label | reader | +| reflectedxsstest.go:40:14:40:17 | part | semmle.label | part | +| reflectedxsstest.go:40:14:40:28 | call to FileName | semmle.label | call to FileName | +| reflectedxsstest.go:41:2:41:10 | definition of byteSlice | semmle.label | definition of byteSlice | +| reflectedxsstest.go:42:2:42:5 | part | semmle.label | part | | reflectedxsstest.go:44:10:44:55 | type conversion | semmle.label | type conversion | | reflectedxsstest.go:45:10:45:18 | byteSlice | semmle.label | byteSlice | | reflectedxsstest.go:51:14:51:18 | selection of URL | semmle.label | selection of URL | +| reflectedxsstest.go:51:14:51:26 | call to Query | semmle.label | call to Query | | reflectedxsstest.go:54:11:54:21 | type conversion | semmle.label | type conversion | | tst.go:14:15:14:20 | selection of Form | semmle.label | selection of Form | +| tst.go:14:15:14:36 | call to Get | semmle.label | call to Get | | tst.go:18:12:18:39 | type conversion | semmle.label | type conversion | +| tst.go:18:19:18:38 | call to Join | semmle.label | call to Join | +| tst.go:18:32:18:32 | a | semmle.label | a | | tst.go:48:14:48:19 | selection of Form | semmle.label | selection of Form | +| tst.go:48:14:48:34 | call to Get | semmle.label | call to Get | | tst.go:53:12:53:26 | type conversion | semmle.label | type conversion | | websocketXss.go:30:7:30:10 | definition of xnet | semmle.label | definition of xnet | | websocketXss.go:32:24:32:27 | xnet | semmle.label | xnet | diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 7f9f8a8f19f6..93d447e40ab3 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -1,15 +1,27 @@ edges -| SqlInjection.go:11:3:11:9 | selection of URL | SqlInjection.go:12:11:12:11 | q | -| issue48.go:17:25:17:32 | selection of Body | issue48.go:22:11:22:12 | q3 | -| issue48.go:27:26:27:33 | selection of Body | issue48.go:32:11:32:12 | q4 | -| issue48.go:37:17:37:50 | type conversion | issue48.go:41:11:41:12 | q5 | -| issue48.go:37:24:37:30 | selection of URL | issue48.go:37:17:37:50 | type conversion | +| SqlInjection.go:11:3:11:9 | selection of URL | SqlInjection.go:11:3:11:17 | call to Query | +| SqlInjection.go:11:3:11:17 | call to Query | SqlInjection.go:12:11:12:11 | q | +| issue48.go:17:2:17:33 | ... := ...[0] | issue48.go:18:17:18:17 | b | +| issue48.go:17:25:17:32 | selection of Body | issue48.go:17:2:17:33 | ... := ...[0] | +| issue48.go:18:17:18:17 | b | issue48.go:18:20:18:39 | &... | +| issue48.go:18:20:18:39 | &... | issue48.go:22:11:22:12 | q3 | +| issue48.go:27:2:27:34 | ... := ...[0] | issue48.go:28:17:28:18 | b2 | +| issue48.go:27:26:27:33 | selection of Body | issue48.go:27:2:27:34 | ... := ...[0] | +| issue48.go:28:17:28:18 | b2 | issue48.go:28:21:28:41 | &... | +| issue48.go:28:21:28:41 | &... | issue48.go:32:11:32:12 | q4 | +| issue48.go:37:17:37:50 | type conversion | issue48.go:37:53:37:73 | &... | +| issue48.go:37:24:37:30 | selection of URL | issue48.go:37:24:37:38 | call to Query | +| issue48.go:37:24:37:38 | call to Query | issue48.go:37:17:37:50 | type conversion | +| issue48.go:37:53:37:73 | &... | issue48.go:41:11:41:12 | q5 | | main.go:10:11:10:16 | selection of Form | main.go:10:11:10:28 | index expression | -| main.go:14:63:14:67 | selection of URL | main.go:14:11:14:84 | call to Sprintf | -| main.go:15:63:15:70 | selection of Header | main.go:15:11:15:85 | call to Sprintf | +| main.go:14:63:14:67 | selection of URL | main.go:14:63:14:75 | call to Query | +| main.go:14:63:14:75 | call to Query | main.go:14:11:14:84 | call to Sprintf | +| main.go:15:63:15:70 | selection of Header | main.go:15:63:15:84 | call to Get | +| main.go:15:63:15:84 | call to Get | main.go:15:11:15:85 | call to Sprintf | | main.go:27:17:30:2 | &... [pointer, Category] | main.go:33:3:33:13 | RequestData [pointer, Category] | | main.go:27:18:30:2 | struct literal [Category] | main.go:27:17:30:2 | &... [pointer, Category] | -| main.go:29:13:29:19 | selection of URL | main.go:29:13:29:39 | index expression | +| main.go:29:13:29:19 | selection of URL | main.go:29:13:29:27 | call to Query | +| main.go:29:13:29:27 | call to Query | main.go:29:13:29:39 | index expression | | main.go:29:13:29:39 | index expression | main.go:27:18:30:2 | struct literal [Category] | | main.go:33:3:33:13 | RequestData [pointer, Category] | main.go:33:3:33:13 | implicit dereference [Category] | | main.go:33:3:33:13 | implicit dereference [Category] | main.go:33:3:33:22 | selection of Category | @@ -18,7 +30,8 @@ edges | main.go:38:2:38:12 | definition of RequestData [pointer, Category] | main.go:42:3:42:13 | RequestData [pointer, Category] | | main.go:39:2:39:12 | RequestData [pointer, Category] | main.go:39:2:39:12 | implicit dereference [Category] | | main.go:39:2:39:12 | implicit dereference [Category] | main.go:38:2:38:12 | definition of RequestData [pointer, Category] | -| main.go:39:25:39:31 | selection of URL | main.go:39:25:39:51 | index expression | +| main.go:39:25:39:31 | selection of URL | main.go:39:25:39:39 | call to Query | +| main.go:39:25:39:39 | call to Query | main.go:39:25:39:51 | index expression | | main.go:39:25:39:51 | index expression | main.go:39:2:39:12 | implicit dereference [Category] | | main.go:42:3:42:13 | RequestData [pointer, Category] | main.go:42:3:42:13 | implicit dereference [Category] | | main.go:42:3:42:13 | implicit dereference [Category] | main.go:42:3:42:22 | selection of Category | @@ -27,7 +40,8 @@ edges | main.go:47:2:47:12 | definition of RequestData [pointer, Category] | main.go:51:3:51:13 | RequestData [pointer, Category] | | main.go:48:3:48:14 | star expression [Category] | main.go:47:2:47:12 | definition of RequestData [pointer, Category] | | main.go:48:4:48:14 | RequestData [pointer, Category] | main.go:48:3:48:14 | star expression [Category] | -| main.go:48:28:48:34 | selection of URL | main.go:48:28:48:54 | index expression | +| main.go:48:28:48:34 | selection of URL | main.go:48:28:48:42 | call to Query | +| main.go:48:28:48:42 | call to Query | main.go:48:28:48:54 | index expression | | main.go:48:28:48:54 | index expression | main.go:48:3:48:14 | star expression [Category] | | main.go:51:3:51:13 | RequestData [pointer, Category] | main.go:51:3:51:13 | implicit dereference [Category] | | main.go:51:3:51:13 | implicit dereference [Category] | main.go:51:3:51:22 | selection of Category | @@ -36,7 +50,8 @@ edges | main.go:56:2:56:12 | definition of RequestData [pointer, Category] | main.go:60:5:60:15 | RequestData [pointer, Category] | | main.go:57:3:57:14 | star expression [Category] | main.go:56:2:56:12 | definition of RequestData [pointer, Category] | | main.go:57:4:57:14 | RequestData [pointer, Category] | main.go:57:3:57:14 | star expression [Category] | -| main.go:57:28:57:34 | selection of URL | main.go:57:28:57:54 | index expression | +| main.go:57:28:57:34 | selection of URL | main.go:57:28:57:42 | call to Query | +| main.go:57:28:57:42 | call to Query | main.go:57:28:57:54 | index expression | | main.go:57:28:57:54 | index expression | main.go:57:3:57:14 | star expression [Category] | | main.go:60:3:60:25 | selection of Category | main.go:61:11:61:11 | q | | main.go:60:4:60:15 | star expression [Category] | main.go:60:3:60:25 | selection of Category | @@ -57,23 +72,35 @@ edges | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:81:18:81:25 | pipeline | nodes | SqlInjection.go:11:3:11:9 | selection of URL | semmle.label | selection of URL | +| SqlInjection.go:11:3:11:17 | call to Query | semmle.label | call to Query | | SqlInjection.go:12:11:12:11 | q | semmle.label | q | +| issue48.go:17:2:17:33 | ... := ...[0] | semmle.label | ... := ...[0] | | issue48.go:17:25:17:32 | selection of Body | semmle.label | selection of Body | +| issue48.go:18:17:18:17 | b | semmle.label | b | +| issue48.go:18:20:18:39 | &... | semmle.label | &... | | issue48.go:22:11:22:12 | q3 | semmle.label | q3 | +| issue48.go:27:2:27:34 | ... := ...[0] | semmle.label | ... := ...[0] | | issue48.go:27:26:27:33 | selection of Body | semmle.label | selection of Body | +| issue48.go:28:17:28:18 | b2 | semmle.label | b2 | +| issue48.go:28:21:28:41 | &... | semmle.label | &... | | issue48.go:32:11:32:12 | q4 | semmle.label | q4 | | issue48.go:37:17:37:50 | type conversion | semmle.label | type conversion | | issue48.go:37:24:37:30 | selection of URL | semmle.label | selection of URL | +| issue48.go:37:24:37:38 | call to Query | semmle.label | call to Query | +| issue48.go:37:53:37:73 | &... | semmle.label | &... | | issue48.go:41:11:41:12 | q5 | semmle.label | q5 | | main.go:10:11:10:16 | selection of Form | semmle.label | selection of Form | | main.go:10:11:10:28 | index expression | semmle.label | index expression | | main.go:14:11:14:84 | call to Sprintf | semmle.label | call to Sprintf | | main.go:14:63:14:67 | selection of URL | semmle.label | selection of URL | +| main.go:14:63:14:75 | call to Query | semmle.label | call to Query | | main.go:15:11:15:85 | call to Sprintf | semmle.label | call to Sprintf | | main.go:15:63:15:70 | selection of Header | semmle.label | selection of Header | +| main.go:15:63:15:84 | call to Get | semmle.label | call to Get | | main.go:27:17:30:2 | &... [pointer, Category] | semmle.label | &... [pointer, Category] | | main.go:27:18:30:2 | struct literal [Category] | semmle.label | struct literal [Category] | | main.go:29:13:29:19 | selection of URL | semmle.label | selection of URL | +| main.go:29:13:29:27 | call to Query | semmle.label | call to Query | | main.go:29:13:29:39 | index expression | semmle.label | index expression | | main.go:33:3:33:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:33:3:33:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | @@ -83,6 +110,7 @@ nodes | main.go:39:2:39:12 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:39:2:39:12 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | | main.go:39:25:39:31 | selection of URL | semmle.label | selection of URL | +| main.go:39:25:39:39 | call to Query | semmle.label | call to Query | | main.go:39:25:39:51 | index expression | semmle.label | index expression | | main.go:42:3:42:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:42:3:42:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | @@ -92,6 +120,7 @@ nodes | main.go:48:3:48:14 | star expression [Category] | semmle.label | star expression [Category] | | main.go:48:4:48:14 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:48:28:48:34 | selection of URL | semmle.label | selection of URL | +| main.go:48:28:48:42 | call to Query | semmle.label | call to Query | | main.go:48:28:48:54 | index expression | semmle.label | index expression | | main.go:51:3:51:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:51:3:51:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | @@ -101,6 +130,7 @@ nodes | main.go:57:3:57:14 | star expression [Category] | semmle.label | star expression [Category] | | main.go:57:4:57:14 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:57:28:57:34 | selection of URL | semmle.label | selection of URL | +| main.go:57:28:57:42 | call to Query | semmle.label | call to Query | | main.go:57:28:57:54 | index expression | semmle.label | index expression | | main.go:60:3:60:25 | selection of Category | semmle.label | selection of Category | | main.go:60:4:60:15 | star expression [Category] | semmle.label | star expression [Category] | diff --git a/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected b/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected index 52c76ed52cef..de5b7c7a833b 100644 --- a/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected +++ b/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected @@ -1,16 +1,20 @@ edges | StringBreak.go:10:2:10:40 | ... := ...[0] | StringBreak.go:14:47:14:57 | versionJSON | | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | StringBreakMismatched.go:13:29:13:47 | type conversion | -| StringBreakMismatched.go:13:29:13:47 | type conversion | StringBreakMismatched.go:17:26:17:32 | escaped | +| StringBreakMismatched.go:13:13:13:62 | call to Replace | StringBreakMismatched.go:17:26:17:32 | escaped | +| StringBreakMismatched.go:13:29:13:47 | type conversion | StringBreakMismatched.go:13:13:13:62 | call to Replace | | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | StringBreakMismatched.go:25:29:25:47 | type conversion | -| StringBreakMismatched.go:25:29:25:47 | type conversion | StringBreakMismatched.go:29:27:29:33 | escaped | +| StringBreakMismatched.go:25:13:25:61 | call to Replace | StringBreakMismatched.go:29:27:29:33 | escaped | +| StringBreakMismatched.go:25:29:25:47 | type conversion | StringBreakMismatched.go:25:13:25:61 | call to Replace | nodes | StringBreak.go:10:2:10:40 | ... := ...[0] | semmle.label | ... := ...[0] | | StringBreak.go:14:47:14:57 | versionJSON | semmle.label | versionJSON | | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | semmle.label | ... := ...[0] | +| StringBreakMismatched.go:13:13:13:62 | call to Replace | semmle.label | call to Replace | | StringBreakMismatched.go:13:29:13:47 | type conversion | semmle.label | type conversion | | StringBreakMismatched.go:17:26:17:32 | escaped | semmle.label | escaped | | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | semmle.label | ... := ...[0] | +| StringBreakMismatched.go:25:13:25:61 | call to Replace | semmle.label | call to Replace | | StringBreakMismatched.go:25:29:25:47 | type conversion | semmle.label | type conversion | | StringBreakMismatched.go:29:27:29:33 | escaped | semmle.label | escaped | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 5daa517378ef..d6ee7c045973 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -15,6 +15,8 @@ edges | passwords.go:107:34:107:41 | password | passwords.go:107:16:107:41 | ...+... | | passwords.go:112:33:112:40 | password | passwords.go:112:15:112:40 | ...+... | | passwords.go:116:28:116:36 | password1 | passwords.go:116:14:116:45 | ...+... | +| passwords.go:116:28:116:36 | password1 | passwords.go:116:28:116:45 | call to String | +| passwords.go:116:28:116:45 | call to String | passwords.go:116:14:116:45 | ...+... | | passwords.go:118:12:123:2 | struct literal [x] | passwords.go:126:14:126:19 | config [x] | | passwords.go:118:12:123:2 | struct literal [y] | passwords.go:127:14:127:19 | config [y] | | passwords.go:119:13:119:13 | x | passwords.go:125:14:125:19 | config | @@ -77,6 +79,7 @@ nodes | passwords.go:112:33:112:40 | password | semmle.label | password | | passwords.go:116:14:116:45 | ...+... | semmle.label | ...+... | | passwords.go:116:28:116:36 | password1 | semmle.label | password1 | +| passwords.go:116:28:116:45 | call to String | semmle.label | call to String | | passwords.go:118:12:123:2 | struct literal [x] | semmle.label | struct literal [x] | | passwords.go:118:12:123:2 | struct literal [y] | semmle.label | struct literal [y] | | passwords.go:119:13:119:13 | x | semmle.label | x | diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected index 9e767daf1865..59af6f287871 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected @@ -2,15 +2,19 @@ edges | sample.go:15:24:15:63 | type conversion | sample.go:16:9:16:15 | slice expression | | sample.go:15:49:15:61 | call to Uint32 | sample.go:15:24:15:63 | type conversion | | sample.go:16:9:16:15 | slice expression | sample.go:26:25:26:30 | call to Guid | -| sample.go:34:12:34:40 | call to New | sample.go:37:25:37:29 | nonce | -| sample.go:34:12:34:40 | call to New | sample.go:37:32:37:36 | nonce | +| sample.go:33:2:33:6 | definition of nonce | sample.go:37:25:37:29 | nonce | +| sample.go:33:2:33:6 | definition of nonce | sample.go:37:32:37:36 | nonce | +| sample.go:34:12:34:40 | call to New | sample.go:35:14:35:19 | random | +| sample.go:35:14:35:19 | random | sample.go:33:2:33:6 | definition of nonce | nodes | InsecureRandomness.go:12:18:12:40 | call to Intn | semmle.label | call to Intn | | sample.go:15:24:15:63 | type conversion | semmle.label | type conversion | | sample.go:15:49:15:61 | call to Uint32 | semmle.label | call to Uint32 | | sample.go:16:9:16:15 | slice expression | semmle.label | slice expression | | sample.go:26:25:26:30 | call to Guid | semmle.label | call to Guid | +| sample.go:33:2:33:6 | definition of nonce | semmle.label | definition of nonce | | sample.go:34:12:34:40 | call to New | semmle.label | call to New | +| sample.go:35:14:35:19 | random | semmle.label | random | | sample.go:37:25:37:29 | nonce | semmle.label | nonce | | sample.go:37:32:37:36 | nonce | semmle.label | nonce | | sample.go:43:17:43:39 | call to Intn | semmle.label | call to Intn | diff --git a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected index df3c6383bc45..da1b8886574b 100644 --- a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected +++ b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected @@ -9,9 +9,11 @@ edges | main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | definition of redir | | main.go:11:37:11:44 | redirect | main.go:11:25:11:45 | call to sanitizeUrl | | main.go:32:24:32:26 | argument corresponding to url | main.go:34:26:34:28 | url | -| main.go:68:17:68:24 | argument corresponding to redirect | main.go:73:9:73:28 | call to Clean | -| main.go:68:17:68:24 | definition of redirect | main.go:73:9:73:28 | call to Clean | +| main.go:68:17:68:24 | argument corresponding to redirect | main.go:73:20:73:27 | redirect | +| main.go:68:17:68:24 | definition of redirect | main.go:73:20:73:27 | redirect | | main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 | +| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | +| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | | main.go:76:19:76:21 | argument corresponding to url | main.go:77:36:77:38 | url | | main.go:77:36:77:38 | url | main.go:68:17:68:24 | definition of redirect | | main.go:77:36:77:38 | url | main.go:77:25:77:39 | call to getTarget1 | @@ -36,6 +38,8 @@ nodes | main.go:68:17:68:24 | definition of redirect | semmle.label | definition of redirect | | main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean | | main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean | +| main.go:73:20:73:27 | redirect | semmle.label | redirect | +| main.go:73:20:73:27 | redirect | semmle.label | redirect | | main.go:76:19:76:21 | argument corresponding to url | semmle.label | argument corresponding to url | | main.go:77:25:77:39 | call to getTarget1 | semmle.label | call to getTarget1 | | main.go:77:36:77:38 | url | semmle.label | url | diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index d4de75b2cc67..2b12a344d17d 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -1,11 +1,23 @@ edges | OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | +| stdlib.go:13:13:13:18 | selection of Form | stdlib.go:13:13:13:32 | call to Get | | stdlib.go:13:13:13:18 | selection of Form | stdlib.go:15:30:15:35 | target | +| stdlib.go:13:13:13:32 | call to Get | stdlib.go:15:30:15:35 | target | +| stdlib.go:22:13:22:18 | selection of Form | stdlib.go:22:13:22:32 | call to Get | | stdlib.go:22:13:22:18 | selection of Form | stdlib.go:24:30:24:35 | target | +| stdlib.go:22:13:22:32 | call to Get | stdlib.go:24:30:24:35 | target | +| stdlib.go:31:13:31:18 | selection of Form | stdlib.go:31:13:31:32 | call to Get | | stdlib.go:31:13:31:18 | selection of Form | stdlib.go:35:30:35:39 | ...+... | +| stdlib.go:31:13:31:32 | call to Get | stdlib.go:35:30:35:39 | ...+... | +| stdlib.go:44:13:44:18 | selection of Form | stdlib.go:44:13:44:32 | call to Get | | stdlib.go:44:13:44:18 | selection of Form | stdlib.go:46:23:46:28 | target | +| stdlib.go:44:13:44:32 | call to Get | stdlib.go:46:23:46:28 | target | +| stdlib.go:64:13:64:18 | selection of Form | stdlib.go:64:13:64:32 | call to Get | | stdlib.go:64:13:64:18 | selection of Form | stdlib.go:67:23:67:40 | ...+... | +| stdlib.go:64:13:64:32 | call to Get | stdlib.go:67:23:67:40 | ...+... | +| stdlib.go:89:13:89:18 | selection of Form | stdlib.go:89:13:89:32 | call to Get | | stdlib.go:89:13:89:18 | selection of Form | stdlib.go:92:23:92:28 | target | +| stdlib.go:89:13:89:32 | call to Get | stdlib.go:92:23:92:28 | target | | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | | stdlib.go:107:54:107:54 | definition of r [pointer, URL] | stdlib.go:112:4:112:4 | r [pointer, URL] | @@ -46,28 +58,48 @@ edges | stdlib.go:113:24:113:24 | r [pointer, URL] | stdlib.go:113:24:113:24 | implicit dereference [URL] | | stdlib.go:113:24:113:28 | selection of URL | stdlib.go:113:24:113:37 | call to String | | stdlib.go:113:24:113:28 | selection of URL | stdlib.go:113:24:113:37 | call to String | +| stdlib.go:146:13:146:18 | selection of Form | stdlib.go:146:13:146:32 | call to Get | | stdlib.go:146:13:146:18 | selection of Form | stdlib.go:152:23:152:28 | target | +| stdlib.go:146:13:146:32 | call to Get | stdlib.go:152:23:152:28 | target | +| stdlib.go:159:11:159:15 | selection of URL | stdlib.go:162:24:162:26 | url | +| stdlib.go:159:11:159:15 | selection of URL | stdlib.go:162:24:162:26 | url | | stdlib.go:159:11:159:15 | selection of URL | stdlib.go:162:24:162:35 | call to String | -| stdlib.go:159:11:159:15 | selection of URL | stdlib.go:162:24:162:35 | call to String | -| stdlib.go:173:35:173:39 | selection of URL | stdlib.go:173:24:173:52 | ...+... | +| stdlib.go:162:24:162:26 | url | stdlib.go:162:24:162:35 | call to String | +| stdlib.go:162:24:162:26 | url | stdlib.go:162:24:162:35 | call to String | | stdlib.go:173:35:173:39 | selection of URL | stdlib.go:173:24:173:52 | ...+... | +| stdlib.go:173:35:173:39 | selection of URL | stdlib.go:173:35:173:52 | call to RequestURI | +| stdlib.go:173:35:173:39 | selection of URL | stdlib.go:173:35:173:52 | call to RequestURI | +| stdlib.go:173:35:173:52 | call to RequestURI | stdlib.go:173:24:173:52 | ...+... | +| stdlib.go:173:35:173:52 | call to RequestURI | stdlib.go:173:24:173:52 | ...+... | | stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | +| stdlib.go:190:3:190:57 | ... := ...[0] | stdlib.go:192:23:192:33 | selection of Path | +| stdlib.go:190:3:190:57 | ... := ...[0] | stdlib.go:194:23:194:28 | target | +| stdlib.go:190:3:190:57 | ... := ...[0] | stdlib.go:194:23:194:42 | call to EscapedPath | +| stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:190:3:190:57 | ... := ...[0] | | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:192:23:192:33 | selection of Path | +| stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:194:23:194:28 | target | | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:194:23:194:42 | call to EscapedPath | +| stdlib.go:194:23:194:28 | target | stdlib.go:194:23:194:42 | call to EscapedPath | nodes | OpenUrlRedirect.go:10:23:10:28 | selection of Form | semmle.label | selection of Form | | OpenUrlRedirect.go:10:23:10:42 | call to Get | semmle.label | call to Get | | stdlib.go:13:13:13:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:13:13:13:32 | call to Get | semmle.label | call to Get | | stdlib.go:15:30:15:35 | target | semmle.label | target | | stdlib.go:22:13:22:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:22:13:22:32 | call to Get | semmle.label | call to Get | | stdlib.go:24:30:24:35 | target | semmle.label | target | | stdlib.go:31:13:31:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:31:13:31:32 | call to Get | semmle.label | call to Get | | stdlib.go:35:30:35:39 | ...+... | semmle.label | ...+... | | stdlib.go:44:13:44:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:44:13:44:32 | call to Get | semmle.label | call to Get | | stdlib.go:46:23:46:28 | target | semmle.label | target | | stdlib.go:64:13:64:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:64:13:64:32 | call to Get | semmle.label | call to Get | | stdlib.go:67:23:67:40 | ...+... | semmle.label | ...+... | | stdlib.go:89:13:89:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:89:13:89:32 | call to Get | semmle.label | call to Get | | stdlib.go:92:23:92:28 | target | semmle.label | target | | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | semmle.label | definition of r [pointer, URL, pointer] | | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | semmle.label | definition of r [pointer, URL, pointer] | @@ -96,19 +128,26 @@ nodes | stdlib.go:113:24:113:37 | call to String | semmle.label | call to String | | stdlib.go:113:24:113:37 | call to String | semmle.label | call to String | | stdlib.go:146:13:146:18 | selection of Form | semmle.label | selection of Form | +| stdlib.go:146:13:146:32 | call to Get | semmle.label | call to Get | | stdlib.go:152:23:152:28 | target | semmle.label | target | | stdlib.go:159:11:159:15 | selection of URL | semmle.label | selection of URL | | stdlib.go:159:11:159:15 | selection of URL | semmle.label | selection of URL | +| stdlib.go:162:24:162:26 | url | semmle.label | url | +| stdlib.go:162:24:162:26 | url | semmle.label | url | | stdlib.go:162:24:162:35 | call to String | semmle.label | call to String | | stdlib.go:162:24:162:35 | call to String | semmle.label | call to String | | stdlib.go:173:24:173:52 | ...+... | semmle.label | ...+... | | stdlib.go:173:24:173:52 | ...+... | semmle.label | ...+... | | stdlib.go:173:35:173:39 | selection of URL | semmle.label | selection of URL | | stdlib.go:173:35:173:39 | selection of URL | semmle.label | selection of URL | +| stdlib.go:173:35:173:52 | call to RequestURI | semmle.label | call to RequestURI | +| stdlib.go:173:35:173:52 | call to RequestURI | semmle.label | call to RequestURI | | stdlib.go:182:13:182:33 | call to FormValue | semmle.label | call to FormValue | | stdlib.go:184:23:184:28 | target | semmle.label | target | +| stdlib.go:190:3:190:57 | ... := ...[0] | semmle.label | ... := ...[0] | | stdlib.go:190:36:190:56 | call to FormValue | semmle.label | call to FormValue | | stdlib.go:192:23:192:33 | selection of Path | semmle.label | selection of Path | +| stdlib.go:194:23:194:28 | target | semmle.label | target | | stdlib.go:194:23:194:42 | call to EscapedPath | semmle.label | call to EscapedPath | subpaths #select diff --git a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected index 797d06f208e9..ec7b13e00eb5 100644 --- a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected @@ -1,33 +1,49 @@ edges -| EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:12:56:12:67 | type conversion | +| EmailBad.go:9:10:9:17 | selection of Header | EmailBad.go:9:10:9:29 | call to Get | +| EmailBad.go:9:10:9:29 | call to Get | EmailBad.go:12:56:12:67 | type conversion | | main.go:29:21:29:31 | call to Referer | main.go:31:57:31:78 | type conversion | -| main.go:37:21:37:31 | call to Referer | main.go:40:3:40:7 | definition of write | +| main.go:37:21:37:31 | call to Referer | main.go:41:25:41:38 | untrustedInput | +| main.go:41:25:41:38 | untrustedInput | main.go:40:3:40:7 | definition of write | | main.go:46:21:46:31 | call to Referer | main.go:52:46:52:59 | untrustedInput | | main.go:46:21:46:31 | call to Referer | main.go:53:52:53:65 | untrustedInput | -| main.go:58:21:58:31 | call to Referer | main.go:63:16:63:22 | content | -| main.go:68:21:68:31 | call to Referer | main.go:76:50:76:56 | content | -| main.go:68:21:68:31 | call to Referer | main.go:76:59:76:65 | content | -| main.go:68:21:68:31 | call to Referer | main.go:77:16:77:22 | content | +| main.go:58:21:58:31 | call to Referer | main.go:60:47:60:60 | untrustedInput | +| main.go:60:14:60:61 | call to NewContent | main.go:63:16:63:22 | content | +| main.go:60:47:60:60 | untrustedInput | main.go:60:14:60:61 | call to NewContent | +| main.go:68:21:68:31 | call to Referer | main.go:74:47:74:60 | untrustedInput | +| main.go:74:14:74:61 | call to NewContent | main.go:76:50:76:56 | content | +| main.go:74:14:74:61 | call to NewContent | main.go:76:59:76:65 | content | +| main.go:74:14:74:61 | call to NewContent | main.go:77:16:77:22 | content | +| main.go:74:47:74:60 | untrustedInput | main.go:74:14:74:61 | call to NewContent | | main.go:82:21:82:31 | call to Referer | main.go:89:37:89:50 | untrustedInput | -| main.go:82:21:82:31 | call to Referer | main.go:93:16:93:23 | content2 | +| main.go:82:21:82:31 | call to Referer | main.go:91:48:91:61 | untrustedInput | +| main.go:91:15:91:62 | call to NewContent | main.go:93:16:93:23 | content2 | +| main.go:91:48:91:61 | untrustedInput | main.go:91:15:91:62 | call to NewContent | nodes | EmailBad.go:9:10:9:17 | selection of Header | semmle.label | selection of Header | +| EmailBad.go:9:10:9:29 | call to Get | semmle.label | call to Get | | EmailBad.go:12:56:12:67 | type conversion | semmle.label | type conversion | | main.go:29:21:29:31 | call to Referer | semmle.label | call to Referer | | main.go:31:57:31:78 | type conversion | semmle.label | type conversion | | main.go:37:21:37:31 | call to Referer | semmle.label | call to Referer | | main.go:40:3:40:7 | definition of write | semmle.label | definition of write | +| main.go:41:25:41:38 | untrustedInput | semmle.label | untrustedInput | | main.go:46:21:46:31 | call to Referer | semmle.label | call to Referer | | main.go:52:46:52:59 | untrustedInput | semmle.label | untrustedInput | | main.go:53:52:53:65 | untrustedInput | semmle.label | untrustedInput | | main.go:58:21:58:31 | call to Referer | semmle.label | call to Referer | +| main.go:60:14:60:61 | call to NewContent | semmle.label | call to NewContent | +| main.go:60:47:60:60 | untrustedInput | semmle.label | untrustedInput | | main.go:63:16:63:22 | content | semmle.label | content | | main.go:68:21:68:31 | call to Referer | semmle.label | call to Referer | +| main.go:74:14:74:61 | call to NewContent | semmle.label | call to NewContent | +| main.go:74:47:74:60 | untrustedInput | semmle.label | untrustedInput | | main.go:76:50:76:56 | content | semmle.label | content | | main.go:76:59:76:65 | content | semmle.label | content | | main.go:77:16:77:22 | content | semmle.label | content | | main.go:82:21:82:31 | call to Referer | semmle.label | call to Referer | | main.go:89:37:89:50 | untrustedInput | semmle.label | untrustedInput | +| main.go:91:15:91:62 | call to NewContent | semmle.label | call to NewContent | +| main.go:91:48:91:61 | untrustedInput | semmle.label | untrustedInput | | main.go:93:16:93:23 | content2 | semmle.label | content2 | subpaths #select diff --git a/go/ql/test/query-tests/Security/CWE-643/XPathInjection.expected b/go/ql/test/query-tests/Security/CWE-643/XPathInjection.expected index a391fe96b64d..6d69dadf438e 100644 --- a/go/ql/test/query-tests/Security/CWE-643/XPathInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-643/XPathInjection.expected @@ -1,57 +1,72 @@ edges -| XPathInjection.go:13:14:13:19 | selection of Form | XPathInjection.go:16:29:16:91 | ...+... | -| tst.go:32:14:32:19 | selection of Form | tst.go:35:23:35:85 | ...+... | -| tst.go:32:14:32:19 | selection of Form | tst.go:38:24:38:86 | ...+... | -| tst.go:32:14:32:19 | selection of Form | tst.go:41:24:41:82 | ...+... | -| tst.go:46:14:46:19 | selection of Form | tst.go:49:26:49:84 | ...+... | -| tst.go:46:14:46:19 | selection of Form | tst.go:52:29:52:87 | ...+... | -| tst.go:46:14:46:19 | selection of Form | tst.go:55:33:55:91 | ...+... | -| tst.go:46:14:46:19 | selection of Form | tst.go:58:30:58:88 | ...+... | -| tst.go:63:14:63:19 | selection of Form | tst.go:66:25:66:83 | ...+... | -| tst.go:63:14:63:19 | selection of Form | tst.go:69:28:69:86 | ...+... | -| tst.go:63:14:63:19 | selection of Form | tst.go:72:25:72:83 | ...+... | -| tst.go:63:14:63:19 | selection of Form | tst.go:75:34:75:92 | ...+... | -| tst.go:63:14:63:19 | selection of Form | tst.go:78:32:78:90 | ...+... | -| tst.go:63:14:63:19 | selection of Form | tst.go:81:29:81:87 | ...+... | -| tst.go:63:14:63:19 | selection of Form | tst.go:84:23:84:85 | ...+... | -| tst.go:63:14:63:19 | selection of Form | tst.go:87:22:87:84 | ...+... | -| tst.go:92:14:92:19 | selection of Form | tst.go:95:26:95:84 | ...+... | -| tst.go:92:14:92:19 | selection of Form | tst.go:98:29:98:87 | ...+... | -| tst.go:92:14:92:19 | selection of Form | tst.go:101:33:101:91 | ...+... | -| tst.go:92:14:92:19 | selection of Form | tst.go:104:30:104:88 | ...+... | -| tst.go:109:14:109:19 | selection of Form | tst.go:112:25:112:87 | ...+... | -| tst.go:109:14:109:19 | selection of Form | tst.go:115:26:115:88 | ...+... | -| tst.go:120:14:120:19 | selection of Form | tst.go:124:23:124:126 | ...+... | -| tst.go:120:14:120:19 | selection of Form | tst.go:127:24:127:127 | ...+... | -| tst.go:120:14:120:19 | selection of Form | tst.go:130:27:130:122 | ...+... | -| tst.go:121:14:121:19 | selection of Form | tst.go:124:23:124:126 | ...+... | -| tst.go:121:14:121:19 | selection of Form | tst.go:127:24:127:127 | ...+... | -| tst.go:121:14:121:19 | selection of Form | tst.go:130:27:130:122 | ...+... | -| tst.go:138:14:138:19 | selection of Form | tst.go:141:27:141:89 | ...+... | -| tst.go:138:14:138:19 | selection of Form | tst.go:144:28:144:90 | ...+... | -| tst.go:149:14:149:19 | selection of Form | tst.go:153:33:153:136 | ...+... | -| tst.go:149:14:149:19 | selection of Form | tst.go:156:18:156:121 | ...+... | -| tst.go:149:14:149:19 | selection of Form | tst.go:162:31:162:126 | ...+... | -| tst.go:149:14:149:19 | selection of Form | tst.go:171:21:171:116 | ...+... | -| tst.go:149:14:149:19 | selection of Form | tst.go:180:27:180:122 | ...+... | -| tst.go:150:14:150:19 | selection of Form | tst.go:153:33:153:136 | ...+... | -| tst.go:150:14:150:19 | selection of Form | tst.go:156:18:156:121 | ...+... | -| tst.go:150:14:150:19 | selection of Form | tst.go:162:31:162:126 | ...+... | -| tst.go:150:14:150:19 | selection of Form | tst.go:171:21:171:116 | ...+... | -| tst.go:150:14:150:19 | selection of Form | tst.go:180:27:180:122 | ...+... | +| XPathInjection.go:13:14:13:19 | selection of Form | XPathInjection.go:13:14:13:35 | call to Get | +| XPathInjection.go:13:14:13:35 | call to Get | XPathInjection.go:16:29:16:91 | ...+... | +| tst.go:32:14:32:19 | selection of Form | tst.go:32:14:32:35 | call to Get | +| tst.go:32:14:32:35 | call to Get | tst.go:35:23:35:85 | ...+... | +| tst.go:32:14:32:35 | call to Get | tst.go:38:24:38:86 | ...+... | +| tst.go:32:14:32:35 | call to Get | tst.go:41:24:41:82 | ...+... | +| tst.go:46:14:46:19 | selection of Form | tst.go:46:14:46:35 | call to Get | +| tst.go:46:14:46:35 | call to Get | tst.go:49:26:49:84 | ...+... | +| tst.go:46:14:46:35 | call to Get | tst.go:52:29:52:87 | ...+... | +| tst.go:46:14:46:35 | call to Get | tst.go:55:33:55:91 | ...+... | +| tst.go:46:14:46:35 | call to Get | tst.go:58:30:58:88 | ...+... | +| tst.go:63:14:63:19 | selection of Form | tst.go:63:14:63:35 | call to Get | +| tst.go:63:14:63:35 | call to Get | tst.go:66:25:66:83 | ...+... | +| tst.go:63:14:63:35 | call to Get | tst.go:69:28:69:86 | ...+... | +| tst.go:63:14:63:35 | call to Get | tst.go:72:25:72:83 | ...+... | +| tst.go:63:14:63:35 | call to Get | tst.go:75:34:75:92 | ...+... | +| tst.go:63:14:63:35 | call to Get | tst.go:78:32:78:90 | ...+... | +| tst.go:63:14:63:35 | call to Get | tst.go:81:29:81:87 | ...+... | +| tst.go:63:14:63:35 | call to Get | tst.go:84:23:84:85 | ...+... | +| tst.go:63:14:63:35 | call to Get | tst.go:87:22:87:84 | ...+... | +| tst.go:92:14:92:19 | selection of Form | tst.go:92:14:92:35 | call to Get | +| tst.go:92:14:92:35 | call to Get | tst.go:95:26:95:84 | ...+... | +| tst.go:92:14:92:35 | call to Get | tst.go:98:29:98:87 | ...+... | +| tst.go:92:14:92:35 | call to Get | tst.go:101:33:101:91 | ...+... | +| tst.go:92:14:92:35 | call to Get | tst.go:104:30:104:88 | ...+... | +| tst.go:109:14:109:19 | selection of Form | tst.go:109:14:109:35 | call to Get | +| tst.go:109:14:109:35 | call to Get | tst.go:112:25:112:87 | ...+... | +| tst.go:109:14:109:35 | call to Get | tst.go:115:26:115:88 | ...+... | +| tst.go:120:14:120:19 | selection of Form | tst.go:120:14:120:35 | call to Get | +| tst.go:120:14:120:35 | call to Get | tst.go:124:23:124:126 | ...+... | +| tst.go:120:14:120:35 | call to Get | tst.go:127:24:127:127 | ...+... | +| tst.go:120:14:120:35 | call to Get | tst.go:130:27:130:122 | ...+... | +| tst.go:121:14:121:19 | selection of Form | tst.go:121:14:121:35 | call to Get | +| tst.go:121:14:121:35 | call to Get | tst.go:124:23:124:126 | ...+... | +| tst.go:121:14:121:35 | call to Get | tst.go:127:24:127:127 | ...+... | +| tst.go:121:14:121:35 | call to Get | tst.go:130:27:130:122 | ...+... | +| tst.go:138:14:138:19 | selection of Form | tst.go:138:14:138:35 | call to Get | +| tst.go:138:14:138:35 | call to Get | tst.go:141:27:141:89 | ...+... | +| tst.go:138:14:138:35 | call to Get | tst.go:144:28:144:90 | ...+... | +| tst.go:149:14:149:19 | selection of Form | tst.go:149:14:149:35 | call to Get | +| tst.go:149:14:149:35 | call to Get | tst.go:153:33:153:136 | ...+... | +| tst.go:149:14:149:35 | call to Get | tst.go:156:18:156:121 | ...+... | +| tst.go:149:14:149:35 | call to Get | tst.go:162:31:162:126 | ...+... | +| tst.go:149:14:149:35 | call to Get | tst.go:171:21:171:116 | ...+... | +| tst.go:149:14:149:35 | call to Get | tst.go:180:27:180:122 | ...+... | +| tst.go:150:14:150:19 | selection of Form | tst.go:150:14:150:35 | call to Get | +| tst.go:150:14:150:35 | call to Get | tst.go:153:33:153:136 | ...+... | +| tst.go:150:14:150:35 | call to Get | tst.go:156:18:156:121 | ...+... | +| tst.go:150:14:150:35 | call to Get | tst.go:162:31:162:126 | ...+... | +| tst.go:150:14:150:35 | call to Get | tst.go:171:21:171:116 | ...+... | +| tst.go:150:14:150:35 | call to Get | tst.go:180:27:180:122 | ...+... | nodes | XPathInjection.go:13:14:13:19 | selection of Form | semmle.label | selection of Form | +| XPathInjection.go:13:14:13:35 | call to Get | semmle.label | call to Get | | XPathInjection.go:16:29:16:91 | ...+... | semmle.label | ...+... | | tst.go:32:14:32:19 | selection of Form | semmle.label | selection of Form | +| tst.go:32:14:32:35 | call to Get | semmle.label | call to Get | | tst.go:35:23:35:85 | ...+... | semmle.label | ...+... | | tst.go:38:24:38:86 | ...+... | semmle.label | ...+... | | tst.go:41:24:41:82 | ...+... | semmle.label | ...+... | | tst.go:46:14:46:19 | selection of Form | semmle.label | selection of Form | +| tst.go:46:14:46:35 | call to Get | semmle.label | call to Get | | tst.go:49:26:49:84 | ...+... | semmle.label | ...+... | | tst.go:52:29:52:87 | ...+... | semmle.label | ...+... | | tst.go:55:33:55:91 | ...+... | semmle.label | ...+... | | tst.go:58:30:58:88 | ...+... | semmle.label | ...+... | | tst.go:63:14:63:19 | selection of Form | semmle.label | selection of Form | +| tst.go:63:14:63:35 | call to Get | semmle.label | call to Get | | tst.go:66:25:66:83 | ...+... | semmle.label | ...+... | | tst.go:69:28:69:86 | ...+... | semmle.label | ...+... | | tst.go:72:25:72:83 | ...+... | semmle.label | ...+... | @@ -61,23 +76,30 @@ nodes | tst.go:84:23:84:85 | ...+... | semmle.label | ...+... | | tst.go:87:22:87:84 | ...+... | semmle.label | ...+... | | tst.go:92:14:92:19 | selection of Form | semmle.label | selection of Form | +| tst.go:92:14:92:35 | call to Get | semmle.label | call to Get | | tst.go:95:26:95:84 | ...+... | semmle.label | ...+... | | tst.go:98:29:98:87 | ...+... | semmle.label | ...+... | | tst.go:101:33:101:91 | ...+... | semmle.label | ...+... | | tst.go:104:30:104:88 | ...+... | semmle.label | ...+... | | tst.go:109:14:109:19 | selection of Form | semmle.label | selection of Form | +| tst.go:109:14:109:35 | call to Get | semmle.label | call to Get | | tst.go:112:25:112:87 | ...+... | semmle.label | ...+... | | tst.go:115:26:115:88 | ...+... | semmle.label | ...+... | | tst.go:120:14:120:19 | selection of Form | semmle.label | selection of Form | +| tst.go:120:14:120:35 | call to Get | semmle.label | call to Get | | tst.go:121:14:121:19 | selection of Form | semmle.label | selection of Form | +| tst.go:121:14:121:35 | call to Get | semmle.label | call to Get | | tst.go:124:23:124:126 | ...+... | semmle.label | ...+... | | tst.go:127:24:127:127 | ...+... | semmle.label | ...+... | | tst.go:130:27:130:122 | ...+... | semmle.label | ...+... | | tst.go:138:14:138:19 | selection of Form | semmle.label | selection of Form | +| tst.go:138:14:138:35 | call to Get | semmle.label | call to Get | | tst.go:141:27:141:89 | ...+... | semmle.label | ...+... | | tst.go:144:28:144:90 | ...+... | semmle.label | ...+... | | tst.go:149:14:149:19 | selection of Form | semmle.label | selection of Form | +| tst.go:149:14:149:35 | call to Get | semmle.label | call to Get | | tst.go:150:14:150:19 | selection of Form | semmle.label | selection of Form | +| tst.go:150:14:150:35 | call to Get | semmle.label | call to Get | | tst.go:153:33:153:136 | ...+... | semmle.label | ...+... | | tst.go:156:18:156:121 | ...+... | semmle.label | ...+... | | tst.go:162:31:162:126 | ...+... | semmle.label | ...+... | diff --git a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index 74ec75c02f3f..dacc8e4d46f4 100644 --- a/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -6,7 +6,8 @@ edges | tst.go:10:13:10:35 | call to FormValue | tst.go:24:66:24:72 | tainted | | tst.go:10:13:10:35 | call to FormValue | tst.go:27:11:27:29 | ...+... | | tst.go:10:13:10:35 | call to FormValue | tst.go:29:11:29:40 | ...+... | -| tst.go:10:13:10:35 | call to FormValue | tst.go:37:11:37:20 | call to String | +| tst.go:10:13:10:35 | call to FormValue | tst.go:37:11:37:11 | u | +| tst.go:37:11:37:11 | u | tst.go:37:11:37:20 | call to String | | websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | | websocket.go:74:21:74:31 | call to Referer | websocket.go:78:36:78:49 | untrustedInput | | websocket.go:88:21:88:31 | call to Referer | websocket.go:91:31:91:44 | untrustedInput | @@ -26,6 +27,7 @@ nodes | tst.go:24:66:24:72 | tainted | semmle.label | tainted | | tst.go:27:11:27:29 | ...+... | semmle.label | ...+... | | tst.go:29:11:29:40 | ...+... | semmle.label | ...+... | +| tst.go:37:11:37:11 | u | semmle.label | u | | tst.go:37:11:37:20 | call to String | semmle.label | call to String | | websocket.go:60:21:60:31 | call to Referer | semmle.label | call to Referer | | websocket.go:65:27:65:40 | untrustedInput | semmle.label | untrustedInput | diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll index 875fbd439213..5802a198ba08 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll @@ -171,6 +171,16 @@ private module DispatchImpl { /** Holds if arguments at position `apos` match parameters at position `ppos`. */ pragma[inline] predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } + + /** + * Holds if flow from `call`'s argument `arg` to parameter `p` is permissible. + * + * This is a temporary hook to support technical debt in the Go language; do not use. + */ + pragma[inline] + predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + any() + } } import DispatchImpl diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll index e6fce328326c..648d5c2b073a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @@ -425,7 +425,8 @@ private module Cached { exists(ParameterPosition ppos | viableParam(call, ppos, p) and argumentPositionMatch(call, arg, ppos) and - compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) + compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and + golangSpecificParamArgFilter(call, p, arg) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index db2f84d71e54..d82931aff004 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1614,3 +1614,13 @@ private module OutNodes { * `kind`. */ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { call = result.getCall(kind) } + +/** + * Holds if flow from `call`'s argument `arg` to parameter `p` is permissible. + * + * This is a temporary hook to support technical debt in the Go language; do not use. + */ +pragma[inline] +predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + any() +} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll index e6fce328326c..648d5c2b073a 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll @@ -425,7 +425,8 @@ private module Cached { exists(ParameterPosition ppos | viableParam(call, ppos, p) and argumentPositionMatch(call, arg, ppos) and - compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) + compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and + golangSpecificParamArgFilter(call, p, arg) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index 9af984f7619c..e81c83a0b6d2 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -1380,3 +1380,13 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { or apos.isAnyNamed() and ppos.isKeyword(_) } + +/** + * Holds if flow from `call`'s argument `arg` to parameter `p` is permissible. + * + * This is a temporary hook to support technical debt in the Go language; do not use. + */ +pragma[inline] +predicate golangSpecificParamArgFilter(DataFlowCall call, DataFlow::Node p, ArgumentNode arg) { + any() +} diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll index e6fce328326c..648d5c2b073a 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll @@ -425,7 +425,8 @@ private module Cached { exists(ParameterPosition ppos | viableParam(call, ppos, p) and argumentPositionMatch(call, arg, ppos) and - compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) + compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and + golangSpecificParamArgFilter(call, p, arg) ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll index 404bd6dfa732..9bd9ba78a181 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll @@ -333,3 +333,13 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { or ppos.(PositionalParameterPosition).getIndex() = apos.(PositionalArgumentPosition).getIndex() } + +/** + * Holds if flow from `call`'s argument `arg` to parameter `p` is permissible. + * + * This is a temporary hook to support technical debt in the Go language; do not use. + */ +pragma[inline] +predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + any() +} diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll index e6fce328326c..648d5c2b073a 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll @@ -425,7 +425,8 @@ private module Cached { exists(ParameterPosition ppos | viableParam(call, ppos, p) and argumentPositionMatch(call, arg, ppos) and - compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) + compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and + golangSpecificParamArgFilter(call, p, arg) ) }