@@ -18,6 +18,7 @@ type FileDiff struct {
18
18
core.NoopMerger
19
19
CleanupDisabled bool
20
20
WhitespaceIgnore bool
21
+ Timeout time.Duration
21
22
22
23
l core.Logger
23
24
}
@@ -34,6 +35,10 @@ const (
34
35
// ConfigFileWhitespaceIgnore is the name of the configuration option (FileDiff.Configure())
35
36
// to suppress whitespace changes which can pollute the core diff of the files
36
37
ConfigFileWhitespaceIgnore = "FileDiff.WhitespaceIgnore"
38
+
39
+ // ConfigFileDiffTimeout is the number of milliseconds a single diff calculation may elapse.
40
+ // We need this timeout to avoid spending too much time comparing big or "bad" files.
41
+ ConfigFileDiffTimeout = "FileDiff.Timeout"
37
42
)
38
43
39
44
// FileDiffData is the type of the dependency provided by FileDiff.
@@ -77,6 +82,12 @@ func (diff *FileDiff) ListConfigurationOptions() []core.ConfigurationOption {
77
82
Flag : "no-diff-whitespace" ,
78
83
Type : core .BoolConfigurationOption ,
79
84
Default : false },
85
+ {
86
+ Name : ConfigFileDiffTimeout ,
87
+ Description : "Maximum time in milliseconds a single diff calculation may elapse." ,
88
+ Flag : "diff-timeout" ,
89
+ Type : core .IntConfigurationOption ,
90
+ Default : 1000 },
80
91
}
81
92
82
93
return options [:]
@@ -93,6 +104,12 @@ func (diff *FileDiff) Configure(facts map[string]interface{}) error {
93
104
if val , exists := facts [ConfigFileWhitespaceIgnore ].(bool ); exists {
94
105
diff .WhitespaceIgnore = val
95
106
}
107
+ if val , exists := facts [ConfigFileDiffTimeout ].(int ); exists {
108
+ if val <= 0 {
109
+ diff .l .Warnf ("invalid timeout value: %d" , val )
110
+ }
111
+ diff .Timeout = time .Duration (val ) * time .Millisecond
112
+ }
96
113
return nil
97
114
}
98
115
@@ -133,10 +150,9 @@ func (diff *FileDiff) Consume(deps map[string]interface{}) (map[string]interface
133
150
// git/git 4f7770c87ce3c302e1639a7737a6d2531fe4b160 fetch-pack.c is invalid UTF-8
134
151
strFrom , strTo := string (blobFrom .Data ), string (blobTo .Data )
135
152
dmp := diffmatchpatch .New ()
136
- dmp .DiffTimeout = time . Hour
153
+ dmp .DiffTimeout = diff . Timeout
137
154
src , dst , _ := dmp .DiffLinesToRunes (stripWhitespace (strFrom , diff .WhitespaceIgnore ), stripWhitespace (strTo , diff .WhitespaceIgnore ))
138
155
diffs := dmp .DiffMainRunes (src , dst , false )
139
-
140
156
if ! diff .CleanupDisabled {
141
157
diffs = dmp .DiffCleanupMerge (dmp .DiffCleanupSemanticLossless (diffs ))
142
158
}
0 commit comments