Skip to content

Commit e1d289f

Browse files
authored
Merge pull request #759 from calumgrant/cs/interface-tostring
C#: Remove FPs from cs/call-to-object-tostring
2 parents f3b4cb4 + d63df71 commit e1d289f

File tree

11 files changed

+44
-8
lines changed

11 files changed

+44
-8
lines changed

change-notes/1.20/analysis-csharp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
| Dereferenced variable may be null (cs/dereferenced-value-may-be-null) | Improved results | The query has been rewritten from scratch, and the analysis is now based on static single assignment (SSA) forms. The query is now enabled by default in LGTM. |
1717
| SQL query built from user-controlled sources (cs/sql-injection), Improper control of generation of code (cs/code-injection), Uncontrolled format string (cs/uncontrolled-format-string), Clear text storage of sensitive information (cs/cleartext-storage-of-sensitive-information), Exposure of private information (cs/exposure-of-sensitive-information) | More results | Data sources have been added from user controls in `System.Windows.Forms`. |
1818
| Use of default ToString() (cs/call-to-object-tostring) | Fewer false positives | Results have been removed for `char` arrays passed to `StringBuilder.Append()`, which were incorrectly marked as using `ToString`. |
19+
| Use of default ToString() (cs/call-to-object-tostring) | Fewer results | Results have been removed when the object is an interface or an abstract class. |
1920

2021
## Changes to code extraction
2122

csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@ where
3636
canBeReadonly(f) and
3737
not f.isConst() and
3838
not f.isReadOnly() and
39-
(f.isEffectivelyPrivate() or f.isEffectivelyInternal())
39+
not f.isEffectivelyPublic()
4040
select f, "Field '" + f.getName() + "' can be 'readonly'."

csharp/ql/src/Likely Bugs/Collections/WriteOnlyContainer.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ where
1818
v.getType() instanceof CollectionType and
1919
(
2020
v instanceof LocalVariable or
21-
v = any(Field f | f.isEffectivelyPrivate() or f.isEffectivelyInternal())
21+
v = any(Field f | not f.isEffectivelyPublic())
2222
) and
2323
forex(Access a | a = v.getAnAccess() |
2424
a = any(ModifierMethodCall m).getQualifier() or

csharp/ql/src/Useless code/DefaultToString.ql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ predicate alwaysDefaultToString(ValueOrRefType t) {
5454
not exists(RefType overriding |
5555
overriding.getAMethod() instanceof ToStringMethod and
5656
overriding.getABaseType+() = t
57+
) and
58+
(
59+
(t.isAbstract() or t instanceof Interface)
60+
implies
61+
not t.isEffectivelyPublic()
5762
)
5863
}
5964

csharp/ql/src/semmle/code/csharp/Member.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@ class Modifiable extends Declaration, @modifiable {
107107
this.isInternal() or
108108
this.getDeclaringType+().isInternal()
109109
}
110+
111+
/**
112+
* Holds if this declaration is effectively `public`, because it
113+
* and all enclosing types are `public`.
114+
*/
115+
predicate isEffectivelyPublic() {
116+
not isEffectivelyPrivate() and not isEffectivelyInternal()
117+
}
110118
}
111119

112120
/** A declaration that is a member of a type. */

csharp/ql/src/semmle/code/csharp/dataflow/internal/Steps.qll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ module Steps {
4848
* or because one of `m`'s enclosing types is).
4949
*/
5050
private predicate isEffectivelyInternalOrPrivate(Modifiable m) {
51-
m.isEffectivelyInternal() or
52-
m.isEffectivelyPrivate()
51+
not m.isEffectivelyPublic()
5352
}
5453

5554
private predicate flowIn(Parameter p, Expr pred, AssignableRead succ) {

csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ private module Internal {
294294
|
295295
succ.(AssignableRead) = a.getAnAccess() and
296296
pred = a.getAnAssignedValue() and
297-
a = any(Modifiable m | m.isEffectivelyInternal() or m.isEffectivelyPrivate())
297+
a = any(Modifiable m | not m.isEffectivelyPublic())
298298
)
299299
}
300300

csharp/ql/test/library-tests/modifiers/Effectively.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@
1515
| Modifiers.cs:41:20:41:21 | F1 | internal |
1616
| Modifiers.cs:43:26:43:27 | F2 | internal |
1717
| Modifiers.cs:47:30:47:31 | F4 | internal |
18+
| Modifiers.cs:52:19:52:19 | S | public |
19+
| Modifiers.cs:54:20:54:21 | P1 | public |
20+
| Modifiers.cs:54:36:54:38 | get_P1 | public |
21+
| Modifiers.cs:54:52:54:54 | set_P1 | public |
22+
| Modifiers.cs:55:20:55:21 | P2 | public |
23+
| Modifiers.cs:55:36:55:38 | get_P2 | public |

csharp/ql/test/library-tests/modifiers/Effectively.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,7 @@ where
77
m.isEffectivelyInternal() and not m.isInternal() and s = "internal"
88
or
99
m.isEffectivelyPrivate() and not m.isPrivate() and s = "private"
10+
or
11+
m.isEffectivelyPublic() and s = "public"
1012
)
1113
select m, s

csharp/ql/test/query-tests/Useless Code/DefaultToString/DefaultToString.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Text;
33

4-
class DefaultToString
4+
public class DefaultToString
55
{
66
void M()
77
{
@@ -29,6 +29,12 @@ void M()
2929

3030
var sb = new StringBuilder();
3131
sb.Append(new char[] { 'a', 'b', 'c' }, 0, 3); // GOOD
32+
33+
IPrivate f = null;
34+
Console.WriteLine(f); // BAD
35+
36+
IPublic g = null;
37+
Console.WriteLine(g); // GOOD
3238
}
3339

3440
class A
@@ -48,6 +54,14 @@ class D : C
4854
{
4955
override public string ToString() { return "D"; }
5056
}
57+
58+
public interface IPublic
59+
{
60+
}
61+
62+
private interface IPrivate
63+
{
64+
}
5165
}
5266

5367
// semmle-extractor-options: /r:System.Runtime.Extensions.dll

0 commit comments

Comments
 (0)