@@ -8,29 +8,55 @@ class BashShellScript extends ShellScript {
8
8
)
9
9
}
10
10
11
- private string lineProducer ( int i ) {
12
- result = this .getRawScript ( ) .regexpReplaceAll ( "\\\\\\s*\n" , "" ) .splitAt ( "\n" , i )
11
+ /**
12
+ * Gets the line at 0-based index `lineIndex` within this shell script,
13
+ * assuming newlines as separators.
14
+ */
15
+ private string lineProducer ( int lineIndex ) {
16
+ result = this .getRawScript ( ) .regexpReplaceAll ( "\\\\\\s*\n" , "" ) .splitAt ( "\n" , lineIndex )
13
17
}
14
18
15
- private predicate cmdSubstitutionReplacement ( string cmdSubs , string id , int k ) {
16
- exists ( string line | line = this .lineProducer ( k ) |
17
- exists ( int i , int j |
18
- cmdSubs =
19
- // $() cmd substitution
20
- line .regexpFind ( "\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)" , i , j )
21
- .regexpReplaceAll ( "^\\$\\(" , "" )
22
- .regexpReplaceAll ( "\\)$" , "" ) and
23
- id = "cmdsubs:" + k + ":" + i + ":" + j
24
- )
25
- or
26
- exists ( int i , int j |
27
- // `...` cmd substitution
28
- cmdSubs =
29
- line .regexpFind ( "\\`[^\\`]+\\`" , i , j )
30
- .regexpReplaceAll ( "^\\`" , "" )
31
- .regexpReplaceAll ( "\\`$" , "" ) and
32
- id = "cmd:" + k + ":" + i + ":" + j
33
- )
19
+ private predicate cmdSubstitutionReplacement ( string command , string id , int lineIndex ) {
20
+ this .commandInSubstitution ( lineIndex , command , id )
21
+ or
22
+ this .commandInBackticks ( lineIndex , command , id )
23
+ }
24
+
25
+ /**
26
+ * Holds if there is a command substitution `$(command)` in
27
+ * the line at `lineIndex` in the shell script,
28
+ * and `id` is a unique identifier for this command.
29
+ */
30
+ private predicate commandInSubstitution ( int lineIndex , string command , string id ) {
31
+ exists ( int occurrenceIndex , int occurrenceOffset |
32
+ command =
33
+ // Look for the command inside a $(...) command substitution
34
+ this .lineProducer ( lineIndex )
35
+ .regexpFind ( "\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)" , occurrenceIndex ,
36
+ occurrenceOffset )
37
+ // trim starting $( - TODO do this in first regex
38
+ .regexpReplaceAll ( "^\\$\\(" , "" )
39
+ // trim ending ) - TODO do this in first regex
40
+ .regexpReplaceAll ( "\\)$" , "" ) and
41
+ id = "cmdsubs:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
42
+ )
43
+ }
44
+
45
+ /**
46
+ * Holds if `command` is a command in backticks `` `...` `` in
47
+ * the line at `lineIndex` in the shell script,
48
+ * and `id` is a unique identifier for this command.
49
+ */
50
+ private predicate commandInBackticks ( int lineIndex , string command , string id ) {
51
+ exists ( int occurrenceIndex , int occurrenceOffset |
52
+ command =
53
+ this .lineProducer ( lineIndex )
54
+ .regexpFind ( "\\`[^\\`]+\\`" , occurrenceIndex , occurrenceOffset )
55
+ // trim leading backtick - TODO do this in first regex
56
+ .regexpReplaceAll ( "^\\`" , "" )
57
+ // trim trailing backtick - TODO do this in first regex
58
+ .regexpReplaceAll ( "\\`$" , "" ) and
59
+ id = "cmd:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
34
60
)
35
61
}
36
62
0 commit comments