Skip to content

Commit edfcc0c

Browse files
authored
Merge pull request github#11487 from jcogs33/jcogs33/supportedexternalapis-telemetry-query
Java/C#: add SupportedExternalApis telemetry query
2 parents a11756b + 0e3e849 commit edfcc0c

File tree

11 files changed

+157
-0
lines changed

11 files changed

+157
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @name Usage of supported APIs coming from external libraries
3+
* @description A list of supported 3rd party APIs used in the codebase. Excludes APIs exposed by test libraries.
4+
* @kind metric
5+
* @tags summary telemetry
6+
* @id csharp/telemetry/supported-external-api
7+
*/
8+
9+
private import csharp
10+
private import semmle.code.csharp.dispatch.Dispatch
11+
private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
12+
private import ExternalApi
13+
14+
private predicate relevant(ExternalApi api) {
15+
not api.isUninteresting() and
16+
(
17+
api.isSupported() or
18+
api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable
19+
)
20+
}
21+
22+
from string info, int usages
23+
where Results<relevant/1>::restrict(info, usages)
24+
select info, usages order by usages desc
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: newQuery
3+
---
4+
* Added a new query, `csharp/telemetry/supported-external-api`, to detect supported 3rd party APIs used in a codebase.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Web;
4+
5+
public class SupportedExternalApis
6+
{
7+
public void M1()
8+
{
9+
var l = new List<object>(); // Uninteresting parameterless constructor
10+
var o = new object(); // Uninteresting parameterless constructor
11+
l.Add(o); // Has flow summary
12+
l.Add(o); // Has flow summary
13+
}
14+
15+
public void M2()
16+
{
17+
var d0 = new DateTime(); // Uninteresting parameterless constructor
18+
var next0 = d0.AddYears(30); // Has no flow summary, supported as negative summary
19+
20+
var d1 = new DateTime(2000, 1, 1); // Interesting constructor, supported as negative summary
21+
var next1 = next0.AddDays(3); // Has no flow summary, supported as negative summary
22+
var next2 = next1.AddYears(5); // Has no flow summary, supported as negative summary
23+
}
24+
25+
public void M3()
26+
{
27+
var guid1 = Guid.Parse("{12345678-1234-1234-1234-123456789012}"); // Has no flow summary, supported as negative summary
28+
}
29+
30+
public void M4()
31+
{
32+
var o = new object(); // Uninteresting parameterless constructor
33+
var response = new HttpResponse(); // Uninteresting parameterless constructor
34+
response.AddHeader("header", "value"); // Unsupported
35+
response.AppendHeader("header", "value"); // Unsupported
36+
response.Write(o); // Known sink
37+
response.WriteFile("filename"); // Known sink
38+
response.Write(o); // Known sink
39+
}
40+
41+
public void M5()
42+
{
43+
var l1 = Console.ReadLine(); // Known source
44+
var l2 = Console.ReadLine(); // Known source
45+
Console.SetError(Console.Out); // Has no flow summary, supported as negative summary
46+
var x = Console.Read(); // Known source
47+
}
48+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
| System#Console.ReadLine() | 2 |
2+
| System#DateTime.AddYears(System.Int32) | 2 |
3+
| System.Collections.Generic#List<>.Add(T) | 2 |
4+
| System.Web#HttpResponse.Write(System.Object) | 2 |
5+
| System#Console.Read() | 1 |
6+
| System#Console.SetError(System.IO.TextWriter) | 1 |
7+
| System#Console.get_Out() | 1 |
8+
| System#DateTime.AddDays(System.Double) | 1 |
9+
| System#DateTime.DateTime(System.Int32,System.Int32,System.Int32) | 1 |
10+
| System#Guid.Parse(System.String) | 1 |
11+
| System.Web#HttpResponse.WriteFile(System.String) | 1 |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Telemetry/SupportedExternalApis.ql
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
semmle-extractor-options: /r:System.Collections.Specialized.dll
2+
semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @name Usage of supported APIs coming from external libraries
3+
* @description A list of supported 3rd party APIs used in the codebase. Excludes test and generated code.
4+
* @kind metric
5+
* @tags summary telemetry
6+
* @id java/telemetry/supported-external-api
7+
*/
8+
9+
import java
10+
import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
11+
import ExternalApi
12+
13+
private predicate relevant(ExternalApi api) {
14+
not api.isUninteresting() and
15+
(
16+
api.isSupported() or
17+
api = any(FlowSummaryImpl::Public::NegativeSummarizedCallable nsc).asCallable()
18+
)
19+
}
20+
21+
from string apiName, int usages
22+
where Results<relevant/1>::restrict(apiName, usages)
23+
select apiName, usages order by usages desc
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: newQuery
3+
---
4+
* Added a new query, `java/telemetry/supported-external-api`, to detect supported 3rd party APIs used in a codebase.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
| java.io.File#File(String) | 2 |
2+
| java.net.URL#URL(String) | 2 |
3+
| java.io.FileWriter#FileWriter(File) | 1 |
4+
| java.lang.StringBuilder#append(String) | 1 |
5+
| java.lang.StringBuilder#toString() | 1 |
6+
| java.net.URL#openConnection() | 1 |
7+
| java.net.URL#openStream() | 1 |
8+
| java.net.URLConnection#getInputStream() | 1 |
9+
| java.util.Map#put(Object,Object) | 1 |
10+
| org.apache.commons.io.FileUtils#deleteDirectory(File) | 1 |
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import java.time.Duration;
2+
import java.util.HashMap;
3+
import java.util.Map;
4+
import java.io.InputStream;
5+
import java.net.URL;
6+
import java.io.File;
7+
import java.io.FileWriter;
8+
import org.apache.commons.io.FileUtils;
9+
10+
class SupportedExternalApis {
11+
public static void main(String[] args) throws Exception {
12+
StringBuilder builder = new StringBuilder(); // uninteresting (parameterless constructor)
13+
builder.append("foo"); // supported summary
14+
builder.toString(); // supported summary
15+
16+
Map<String, Object> map = new HashMap<>(); // uninteresting (parameterless constructor)
17+
map.put("foo", new Object()); // supported summary
18+
19+
Duration d = java.time.Duration.ofMillis(1000); // not supported
20+
21+
URL github = new URL("https://www.github.com/"); // supported summary
22+
InputStream stream = github.openConnection().getInputStream(); // supported source (getInputStream), supported sink (openConnection)
23+
24+
new FileWriter(new File("foo")); // supported sink (FileWriter), supported summary (File)
25+
new URL("http://foo").openStream(); // supported sink (openStream), supported summary (URL)
26+
27+
FileUtils.deleteDirectory(new File("foo")); // supported negative summary (deleteDirectory), supported summary (File)
28+
}
29+
}

0 commit comments

Comments
 (0)