1 | /******************************************************************************* | |
2 | * Copyhacked (H) 2012-2020. | |
3 | * This program and the accompanying materials | |
4 | * are made available under no term at all, use it like | |
5 | * you want, but share and discuss about it | |
6 | * every time possible with every body. | |
7 | * | |
8 | * Contributors: | |
9 | * ron190 at ymail dot com - initial implementation | |
10 | ******************************************************************************/ | |
11 | package com.jsql.model.injection.strategy.blind.patch; | |
12 | ||
13 | /** | |
14 | * Diff Match and Patch | |
15 | * | |
16 | * Copyright 2006 Google Inc. | |
17 | * http://code.google.com/p/google-diff-match-patch/ | |
18 | * | |
19 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
20 | * you may not use this file except in compliance with the License. | |
21 | * You may obtain a copy of the License at | |
22 | * | |
23 | * http://www.apache.org/licenses/LICENSE-2.0 | |
24 | * | |
25 | * Unless required by applicable law or agreed to in writing, software | |
26 | * distributed under the License is distributed on an "AS IS" BASIS, | |
27 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
28 | * See the License for the specific language governing permissions and | |
29 | * limitations under the License. | |
30 | */ | |
31 | ||
32 | import com.jsql.util.LogLevelUtil; | |
33 | import org.apache.logging.log4j.LogManager; | |
34 | import org.apache.logging.log4j.Logger; | |
35 | ||
36 | import java.io.UnsupportedEncodingException; | |
37 | import java.net.URLDecoder; | |
38 | import java.net.URLEncoder; | |
39 | import java.nio.charset.StandardCharsets; | |
40 | import java.util.*; | |
41 | import java.util.regex.Matcher; | |
42 | import java.util.regex.Pattern; | |
43 | ||
44 | /* | |
45 | * Functions for diff, match and patch. | |
46 | * Computes the difference between two texts to create a patch. | |
47 | * Applies the patch onto another text, allowing for errors. | |
48 | * | |
49 | * @author fraser@google.com (Neil Fraser) | |
50 | */ | |
51 | ||
52 | /** | |
53 | * Class containing the diff, match and patch methods. | |
54 | * Also contains the behaviour settings. | |
55 | */ | |
56 | public class DiffMatchPatch { | |
57 | | |
58 | /** | |
59 | * Log4j logger sent to view. | |
60 | */ | |
61 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
62 | ||
63 | // Defaults. | |
64 | // Set these on your diff_match_patch instance to override the defaults. | |
65 | ||
66 | /** | |
67 | * Number of seconds to map a diff before giving up (0 for infinity). | |
68 | */ | |
69 | public static final float DIFF_TIMEOUT = 1.0f; | |
70 | | |
71 | /** | |
72 | * Cost of an empty edit operation in terms of edit characters. | |
73 | */ | |
74 | public static final short DIFF_EDIT_COST = 4; | |
75 | | |
76 | /** | |
77 | * At what point is no match declared (0.0 = perfection, 1.0 = very loose). | |
78 | */ | |
79 | public static final float MATCH_THRESHOLD = 0.5f; | |
80 | | |
81 | /** | |
82 | * How far to search for a match (0 = exact location, 1000+ = broad match). | |
83 | * A match this many characters away from the expected location will add | |
84 | * 1.0 to the score (0.0 is a perfect match). | |
85 | */ | |
86 | public static final int MATCH_DISTANCE = 1000; | |
87 | | |
88 | /** | |
89 | * When deleting a large block of text (over ~64 characters), how close do | |
90 | * the contents have to be to match the expected contents. (0.0 = perfection, | |
91 | * 1.0 = very loose). Note that Match_Threshold controls how closely the | |
92 | * end points of a delete need to match. | |
93 | */ | |
94 | public static final float PATCH_DELETE_THRESHOLD = 0.5f; | |
95 | | |
96 | /** | |
97 | * Chunk size for context length. | |
98 | */ | |
99 | public static final short PATCH_MARGIN = 4; | |
100 | ||
101 | /** | |
102 | * The number of bits in an int. | |
103 | */ | |
104 | private static final short MATCH_MAX_BITS = 32; | |
105 | ||
106 | // Define some regex patterns for matching boundaries. | |
107 | private static final Pattern BLANK_LINE_END = Pattern.compile("\\n\\r?\\n\\Z", Pattern.DOTALL); | |
108 | private static final Pattern BLANK_LINE_START = Pattern.compile("\\A\\r?\\n\\r?\\n", Pattern.DOTALL); | |
109 | ||
110 | /** | |
111 | * Internal class for returning results from diff_linesToChars(). | |
112 | * Other less paranoid languages just use a three-element array. | |
113 | */ | |
114 | protected static class LinesToCharsResult { | |
115 | protected final String chars1; | |
116 | protected final String chars2; | |
117 | protected final List<String> lineArray; | |
118 | ||
119 | protected LinesToCharsResult(String chars1, String chars2, | |
120 | List<String> lineArray) { | |
121 | this.chars1 = chars1; | |
122 | this.chars2 = chars2; | |
123 | this.lineArray = lineArray; | |
124 | } | |
125 | } | |
126 | ||
127 | // DIFF FUNCTIONS | |
128 | ||
129 | /** | |
130 | * The data structure representing a diff is a Linked list of Diff objects: | |
131 | * {Diff(Operation.DELETE, "Hello"), Diff(Operation.INSERT, "Goodbye"), | |
132 | * Diff(Operation.EQUAL, " world.")} | |
133 | * which means: delete "Hello", add "Goodbye" and keep " world." | |
134 | */ | |
135 | public enum Operation { | |
136 | DELETE, INSERT, EQUAL | |
137 | } | |
138 | ||
139 | /** | |
140 | * Find the differences between two texts. | |
141 | * Run a faster, slightly less optimal diff. | |
142 | * This method allows the 'checklines' of diff_main() to be optional. | |
143 | * Most of the time checklines is wanted, so default to true. | |
144 | * @param text1 Old string to be diffed. | |
145 | * @param text2 New string to be diffed. | |
146 | * @return Linked List of Diff objects. | |
147 | */ | |
148 | public List<Diff> diffMain(String text1, String text2) { | |
149 |
1
1. diffMain : replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffMain → NO_COVERAGE |
return this.diffMain(text1, text2, true); |
150 | } | |
151 | ||
152 | /** | |
153 | * Find the differences between two texts. | |
154 | * @param text1 Old string to be diffed. | |
155 | * @param text2 New string to be diffed. | |
156 | * @param checklines Speedup flag. If false, then don't run a | |
157 | * line-level diff first to identify the changed areas. | |
158 | * If true, then run a faster slightly less optimal diff. | |
159 | * @return Linked List of Diff objects. | |
160 | */ | |
161 | public LinkedList<Diff> diffMain(String text1, String text2, boolean checklines) { | |
162 | ||
163 | // Set a deadline by which time the diff must be complete. | |
164 |
1
1. diffMain : Replaced long addition with subtraction → NO_COVERAGE |
long deadline = System.currentTimeMillis() + (long) (DIFF_TIMEOUT * 1000); |
165 |
1
1. diffMain : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffMain → NO_COVERAGE |
return this.diffMain(text1, text2, checklines, deadline); |
166 | } | |
167 | ||
168 | /** | |
169 | * Find the differences between two texts. Simplifies the problem by | |
170 | * stripping any common prefix or suffix off the texts before diffing. | |
171 | * @param valueText1 Old string to be diffed. | |
172 | * @param valueText2 New string to be diffed. | |
173 | * @param checklines Speedup flag. If false, then don't run a | |
174 | * line-level diff first to identify the changed areas. | |
175 | * If true, then run a faster slightly less optimal diff. | |
176 | * @param deadline Time when the diff should be complete by. Used | |
177 | * internally for recursive calls. Users should set DiffTimeout instead. | |
178 | * @return Linked List of Diff objects. | |
179 | */ | |
180 | private LinkedList<Diff> diffMain(String valueText1, String valueText2, boolean checklines, long deadline) { | |
181 | ||
182 | String text1 = valueText1; | |
183 | String text2 = valueText2; | |
184 | | |
185 | // Check for null inputs. | |
186 |
2
1. diffMain : negated conditional → NO_COVERAGE 2. diffMain : negated conditional → NO_COVERAGE |
if (text1 == null || text2 == null) { |
187 | throw new IllegalArgumentException("Null inputs. (diff_main)"); | |
188 | } | |
189 | ||
190 | // Check for equality (speedup). | |
191 | LinkedList<Diff> diffs; | |
192 |
1
1. diffMain : negated conditional → NO_COVERAGE |
if (text1.equals(text2)) { |
193 | diffs = new LinkedList<>(); | |
194 |
1
1. diffMain : negated conditional → NO_COVERAGE |
if (!text1.isEmpty()) { |
195 | diffs.add(new Diff(Operation.EQUAL, text1)); | |
196 | } | |
197 |
1
1. diffMain : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffMain → NO_COVERAGE |
return diffs; |
198 | } | |
199 | ||
200 | // Trim off common prefix (speedup). | |
201 | int commonlength = this.diffCommonPrefix(text1, text2); | |
202 | String commonprefix = text1.substring(0, commonlength); | |
203 | text1 = text1.substring(commonlength); | |
204 | text2 = text2.substring(commonlength); | |
205 | ||
206 | // Trim off common suffix (speedup). | |
207 | commonlength = this.diffCommonSuffix(text1, text2); | |
208 |
1
1. diffMain : Replaced integer subtraction with addition → NO_COVERAGE |
String commonsuffix = text1.substring(text1.length() - commonlength); |
209 |
1
1. diffMain : Replaced integer subtraction with addition → NO_COVERAGE |
text1 = text1.substring(0, text1.length() - commonlength); |
210 |
1
1. diffMain : Replaced integer subtraction with addition → NO_COVERAGE |
text2 = text2.substring(0, text2.length() - commonlength); |
211 | ||
212 | // Compute the diff on the middle block. | |
213 | diffs = this.diffCompute(text1, text2, checklines, deadline); | |
214 | ||
215 | // Restore the prefix and suffix. | |
216 |
1
1. diffMain : negated conditional → NO_COVERAGE |
if (!commonprefix.isEmpty()) { |
217 |
1
1. diffMain : removed call to java/util/LinkedList::addFirst → NO_COVERAGE |
diffs.addFirst(new Diff(Operation.EQUAL, commonprefix)); |
218 | } | |
219 |
1
1. diffMain : negated conditional → NO_COVERAGE |
if (!commonsuffix.isEmpty()) { |
220 |
1
1. diffMain : removed call to java/util/LinkedList::addLast → NO_COVERAGE |
diffs.addLast(new Diff(Operation.EQUAL, commonsuffix)); |
221 | } | |
222 | ||
223 |
1
1. diffMain : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupMerge → NO_COVERAGE |
this.diffCleanupMerge(diffs); |
224 |
1
1. diffMain : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffMain → NO_COVERAGE |
return diffs; |
225 | } | |
226 | ||
227 | /** | |
228 | * Find the differences between two texts. Assumes that the texts do not | |
229 | * have any common prefix or suffix. | |
230 | * @param text1 Old string to be diffed. | |
231 | * @param text2 New string to be diffed. | |
232 | * @param checklines Speedup flag. If false, then don't run a | |
233 | * line-level diff first to identify the changed areas. | |
234 | * If true, then run a faster slightly less optimal diff. | |
235 | * @param deadline Time when the diff should be complete by. | |
236 | * @return Linked List of Diff objects. | |
237 | */ | |
238 | private LinkedList<Diff> diffCompute(String text1, String text2, boolean checklines, long deadline) { | |
239 | ||
240 | LinkedList<Diff> diffs = new LinkedList<>(); | |
241 | ||
242 |
1
1. diffCompute : negated conditional → NO_COVERAGE |
if (text1.isEmpty()) { |
243 | // Just add some text (speedup). | |
244 | diffs.add(new Diff(Operation.INSERT, text2)); | |
245 |
1
1. diffCompute : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCompute → NO_COVERAGE |
return diffs; |
246 | } | |
247 | ||
248 |
1
1. diffCompute : negated conditional → NO_COVERAGE |
if (text2.isEmpty()) { |
249 | // Just delete some text (speedup). | |
250 | diffs.add(new Diff(Operation.DELETE, text1)); | |
251 |
1
1. diffCompute : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCompute → NO_COVERAGE |
return diffs; |
252 | } | |
253 | ||
254 | { | |
255 | // New scope so as to garbage collect longtext and shorttext. | |
256 |
2
1. diffCompute : changed conditional boundary → NO_COVERAGE 2. diffCompute : negated conditional → NO_COVERAGE |
String longtext = text1.length() > text2.length() ? text1 : text2; |
257 |
2
1. diffCompute : changed conditional boundary → NO_COVERAGE 2. diffCompute : negated conditional → NO_COVERAGE |
String shorttext = text1.length() > text2.length() ? text2 : text1; |
258 | int i = longtext.indexOf(shorttext); | |
259 |
1
1. diffCompute : negated conditional → NO_COVERAGE |
if (i != -1) { |
260 | // Shorter text is inside the longer text (speedup). | |
261 |
2
1. diffCompute : negated conditional → NO_COVERAGE 2. diffCompute : changed conditional boundary → NO_COVERAGE |
Operation op = (text1.length() > text2.length()) ? |
262 | Operation.DELETE : Operation.INSERT; | |
263 | diffs.add(new Diff(op, longtext.substring(0, i))); | |
264 | diffs.add(new Diff(Operation.EQUAL, shorttext)); | |
265 |
1
1. diffCompute : Replaced integer addition with subtraction → NO_COVERAGE |
diffs.add(new Diff(op, longtext.substring(i + shorttext.length()))); |
266 |
1
1. diffCompute : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCompute → NO_COVERAGE |
return diffs; |
267 | } | |
268 | ||
269 |
1
1. diffCompute : negated conditional → NO_COVERAGE |
if (shorttext.length() == 1) { |
270 | // Single character string. | |
271 | // After the previous speedup, the character can't be an equality. | |
272 | diffs.add(new Diff(Operation.DELETE, text1)); | |
273 | diffs.add(new Diff(Operation.INSERT, text2)); | |
274 |
1
1. diffCompute : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCompute → NO_COVERAGE |
return diffs; |
275 | } | |
276 | } | |
277 | ||
278 | // Check to see if the problem can be split in two. | |
279 | String[] hm = this.diffHalfMatch(text1, text2); | |
280 |
1
1. diffCompute : negated conditional → NO_COVERAGE |
if (hm != null) { |
281 | // A half-match was found, sort out the return data. | |
282 | String text1A = hm[0]; | |
283 | String text1B = hm[1]; | |
284 | String text2A = hm[2]; | |
285 | String text2B = hm[3]; | |
286 | String midCommon = hm[4]; | |
287 | // Send both pairs off for separate processing. | |
288 | LinkedList<Diff> diffsA = this.diffMain(text1A, text2A, checklines, deadline); | |
289 | List<Diff> diffsB = this.diffMain(text1B, text2B, checklines, deadline); | |
290 | // Merge the results. | |
291 | diffs = diffsA; | |
292 | diffs.add(new Diff(Operation.EQUAL, midCommon)); | |
293 | diffs.addAll(diffsB); | |
294 |
1
1. diffCompute : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCompute → NO_COVERAGE |
return diffs; |
295 | } | |
296 | ||
297 |
5
1. diffCompute : negated conditional → NO_COVERAGE 2. diffCompute : negated conditional → NO_COVERAGE 3. diffCompute : negated conditional → NO_COVERAGE 4. diffCompute : changed conditional boundary → NO_COVERAGE 5. diffCompute : changed conditional boundary → NO_COVERAGE |
if (checklines && text1.length() > 100 && text2.length() > 100) { |
298 |
1
1. diffCompute : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCompute → NO_COVERAGE |
return this.diffLineMode(text1, text2, deadline); |
299 | } | |
300 | ||
301 |
1
1. diffCompute : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCompute → NO_COVERAGE |
return this.diffBisect(text1, text2, deadline); |
302 | } | |
303 | ||
304 | /** | |
305 | * Do a quick line-level diff on both strings, then rediff the parts for | |
306 | * greater accuracy. | |
307 | * This speedup can produce non-minimal diffs. | |
308 | * @param valueText1 Old string to be diffed. | |
309 | * @param valueText2 New string to be diffed. | |
310 | * @param deadline Time when the diff should be complete by. | |
311 | * @return Linked List of Diff objects. | |
312 | */ | |
313 | private LinkedList<Diff> diffLineMode(String valueText1, String valueText2, long deadline) { | |
314 | ||
315 | // Scan the text on a line-by-line basis first. | |
316 | LinesToCharsResult b = this.diffLinesToChars(valueText1, valueText2); | |
317 | String text1 = b.chars1; | |
318 | String text2 = b.chars2; | |
319 | List<String> linearray = b.lineArray; | |
320 | ||
321 | LinkedList<Diff> diffs = this.diffMain(text1, text2, false, deadline); | |
322 | ||
323 | // Convert the diff back to original text. | |
324 |
1
1. diffLineMode : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCharsToLines → NO_COVERAGE |
this.diffCharsToLines(diffs, linearray); |
325 | // Eliminate freak matches (e.g. blank lines) | |
326 |
1
1. diffLineMode : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemantic → NO_COVERAGE |
this.diffCleanupSemantic(diffs); |
327 | ||
328 | // Rediff any replacement blocks, this time character-by-character. | |
329 | // Add a dummy entry at the end. | |
330 | diffs.add(new Diff(Operation.EQUAL, "")); | |
331 | int countDelete = 0; | |
332 | int countInsert = 0; | |
333 | StringBuilder textDelete = new StringBuilder(); | |
334 | StringBuilder textInsert = new StringBuilder(); | |
335 | ListIterator<Diff> pointer = diffs.listIterator(); | |
336 | Diff thisDiff = pointer.next(); | |
337 | ||
338 |
1
1. diffLineMode : negated conditional → NO_COVERAGE |
while (thisDiff != null) { |
339 | switch (thisDiff.getOperation()) { | |
340 | case INSERT: | |
341 |
1
1. diffLineMode : Changed increment from 1 to -1 → NO_COVERAGE |
countInsert++; |
342 | textInsert.append(thisDiff.getText()); | |
343 | break; | |
344 | case DELETE: | |
345 |
1
1. diffLineMode : Changed increment from 1 to -1 → NO_COVERAGE |
countDelete++; |
346 | textDelete.append(thisDiff.getText()); | |
347 | break; | |
348 | case EQUAL: | |
349 | // Upon reaching an equality, check for prior redundancies. | |
350 |
4
1. diffLineMode : changed conditional boundary → NO_COVERAGE 2. diffLineMode : changed conditional boundary → NO_COVERAGE 3. diffLineMode : negated conditional → NO_COVERAGE 4. diffLineMode : negated conditional → NO_COVERAGE |
if (countDelete >= 1 && countInsert >= 1) { |
351 | // Delete the offending records and add the merged ones. | |
352 | pointer.previous(); | |
353 |
3
1. diffLineMode : negated conditional → NO_COVERAGE 2. diffLineMode : Replaced integer addition with subtraction → NO_COVERAGE 3. diffLineMode : changed conditional boundary → NO_COVERAGE |
for (int j = 0; j < countDelete + countInsert; j++) { |
354 | pointer.previous(); | |
355 |
1
1. diffLineMode : removed call to java/util/ListIterator::remove → NO_COVERAGE |
pointer.remove(); |
356 | } | |
357 | for (Diff newDiff : this.diffMain(textDelete.toString(), textInsert.toString(), false, deadline)) { | |
358 |
1
1. diffLineMode : removed call to java/util/ListIterator::add → NO_COVERAGE |
pointer.add(newDiff); |
359 | } | |
360 | } | |
361 | countInsert = 0; | |
362 | countDelete = 0; | |
363 |
1
1. diffLineMode : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
textDelete.setLength(0); |
364 |
1
1. diffLineMode : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
textInsert.setLength(0); |
365 | break; | |
366 | } | |
367 |
1
1. diffLineMode : negated conditional → NO_COVERAGE |
thisDiff = pointer.hasNext() ? pointer.next() : null; |
368 | } | |
369 | diffs.removeLast(); // Remove the dummy entry at the end. | |
370 | ||
371 |
1
1. diffLineMode : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffLineMode → NO_COVERAGE |
return diffs; |
372 | } | |
373 | ||
374 | /** | |
375 | * Find the 'middle snake' of a diff, split the problem in two | |
376 | * and return the recursively constructed diff. | |
377 | * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations. | |
378 | * @param text1 Old string to be diffed. | |
379 | * @param text2 New string to be diffed. | |
380 | * @param deadline Time at which to bail if not yet complete. | |
381 | * @return LinkedList of Diff objects. | |
382 | */ | |
383 | protected LinkedList<Diff> diffBisect(String text1, String text2, long deadline) { | |
384 | ||
385 | // Cache the text lengths to prevent multiple calls. | |
386 | int text1Length = text1.length(); | |
387 | int text2Length = text2.length(); | |
388 |
3
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE 2. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE 3. diffBisect : Replaced integer division with multiplication → NO_COVERAGE |
int maxD = (text1Length + text2Length + 1) / 2; |
389 | int vOffset = maxD; | |
390 |
1
1. diffBisect : Replaced integer multiplication with division → NO_COVERAGE |
int vLength = 2 * maxD; |
391 | int[] v1 = new int[vLength]; | |
392 | int[] v2 = new int[vLength]; | |
393 |
2
1. diffBisect : changed conditional boundary → NO_COVERAGE 2. diffBisect : negated conditional → NO_COVERAGE |
for (int x = 0; x < vLength; x++) { |
394 | v1[x] = -1; | |
395 | v2[x] = -1; | |
396 | } | |
397 |
1
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
v1[vOffset + 1] = 0; |
398 |
1
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
v2[vOffset + 1] = 0; |
399 |
1
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE |
int delta = text1Length - text2Length; |
400 | // If the total number of characters is odd, then the front path will | |
401 | // collide with the reverse path. | |
402 |
2
1. diffBisect : negated conditional → NO_COVERAGE 2. diffBisect : Replaced integer modulus with multiplication → NO_COVERAGE |
boolean front = delta % 2 != 0; |
403 | // Offsets for start and end of k loop. | |
404 | // Prevents mapping of space beyond the grid. | |
405 | int k1start = 0; | |
406 | int k1end = 0; | |
407 | int k2start = 0; | |
408 | int k2end = 0; | |
409 | ||
410 |
2
1. diffBisect : negated conditional → NO_COVERAGE 2. diffBisect : changed conditional boundary → NO_COVERAGE |
for (int d = 0; d < maxD; d++) { |
411 | // Bail out if deadline is reached. | |
412 |
2
1. diffBisect : changed conditional boundary → NO_COVERAGE 2. diffBisect : negated conditional → NO_COVERAGE |
if (System.currentTimeMillis() > deadline) { |
413 | break; | |
414 | } | |
415 | ||
416 | // Walk the front path one step. | |
417 |
5
1. diffBisect : removed negation → NO_COVERAGE 2. diffBisect : changed conditional boundary → NO_COVERAGE 3. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE 4. diffBisect : negated conditional → NO_COVERAGE 5. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
for (int k1 = -d + k1start; k1 <= d - k1end; k1 += 2) { |
418 |
1
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
int k1Offset = vOffset + k1; |
419 | int x1; | |
420 |
7
1. diffBisect : negated conditional → NO_COVERAGE 2. diffBisect : changed conditional boundary → NO_COVERAGE 3. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE 4. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE 5. diffBisect : negated conditional → NO_COVERAGE 6. diffBisect : negated conditional → NO_COVERAGE 7. diffBisect : removed negation → NO_COVERAGE |
if (k1 == -d || (k1 != d && v1[k1Offset - 1] < v1[k1Offset + 1])) { |
421 |
1
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
x1 = v1[k1Offset + 1]; |
422 | } else { | |
423 |
2
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE 2. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
x1 = v1[k1Offset - 1] + 1; |
424 | } | |
425 |
1
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE |
int y1 = x1 - k1; |
426 |
4
1. diffBisect : changed conditional boundary → NO_COVERAGE 2. diffBisect : changed conditional boundary → NO_COVERAGE 3. diffBisect : negated conditional → NO_COVERAGE 4. diffBisect : negated conditional → NO_COVERAGE |
while (x1 < text1Length && y1 < text2Length |
427 |
1
1. diffBisect : negated conditional → NO_COVERAGE |
&& text1.charAt(x1) == text2.charAt(y1)) { |
428 |
1
1. diffBisect : Changed increment from 1 to -1 → NO_COVERAGE |
x1++; |
429 |
1
1. diffBisect : Changed increment from 1 to -1 → NO_COVERAGE |
y1++; |
430 | } | |
431 | v1[k1Offset] = x1; | |
432 |
2
1. diffBisect : negated conditional → NO_COVERAGE 2. diffBisect : changed conditional boundary → NO_COVERAGE |
if (x1 > text1Length) { |
433 | // Ran off the right of the graph. | |
434 |
1
1. diffBisect : Changed increment from 2 to -2 → NO_COVERAGE |
k1end += 2; |
435 |
2
1. diffBisect : negated conditional → NO_COVERAGE 2. diffBisect : changed conditional boundary → NO_COVERAGE |
} else if (y1 > text2Length) { |
436 | // Ran off the bottom of the graph. | |
437 |
1
1. diffBisect : Changed increment from 2 to -2 → NO_COVERAGE |
k1start += 2; |
438 |
1
1. diffBisect : negated conditional → NO_COVERAGE |
} else if (front) { |
439 |
2
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE 2. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
int k2Offset = vOffset + delta - k1; |
440 |
5
1. diffBisect : negated conditional → NO_COVERAGE 2. diffBisect : changed conditional boundary → NO_COVERAGE 3. diffBisect : changed conditional boundary → NO_COVERAGE 4. diffBisect : negated conditional → NO_COVERAGE 5. diffBisect : negated conditional → NO_COVERAGE |
if (k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] != -1) { |
441 | // Mirror x2 onto top-left coordinate system. | |
442 |
1
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE |
int x2 = text1Length - v2[k2Offset]; |
443 |
2
1. diffBisect : changed conditional boundary → NO_COVERAGE 2. diffBisect : negated conditional → NO_COVERAGE |
if (x1 >= x2) { |
444 | // Overlap detected. | |
445 |
1
1. diffBisect : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffBisect → NO_COVERAGE |
return this.diffBisectSplit(text1, text2, x1, y1, deadline); |
446 | } | |
447 | } | |
448 | } | |
449 | } | |
450 | ||
451 | // Walk the reverse path one step. | |
452 |
5
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE 2. diffBisect : removed negation → NO_COVERAGE 3. diffBisect : negated conditional → NO_COVERAGE 4. diffBisect : changed conditional boundary → NO_COVERAGE 5. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE |
for (int k2 = -d + k2start; k2 <= d - k2end; k2 += 2) { |
453 |
1
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
int k2Offset = vOffset + k2; |
454 | int x2; | |
455 |
7
1. diffBisect : removed negation → NO_COVERAGE 2. diffBisect : negated conditional → NO_COVERAGE 3. diffBisect : changed conditional boundary → NO_COVERAGE 4. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE 5. diffBisect : negated conditional → NO_COVERAGE 6. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE 7. diffBisect : negated conditional → NO_COVERAGE |
if (k2 == -d || (k2 != d && v2[k2Offset - 1] < v2[k2Offset + 1])) { |
456 |
1
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
x2 = v2[k2Offset + 1]; |
457 | } else { | |
458 |
2
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE 2. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE |
x2 = v2[k2Offset - 1] + 1; |
459 | } | |
460 |
1
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE |
int y2 = x2 - k2; |
461 |
6
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE 2. diffBisect : negated conditional → NO_COVERAGE 3. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE 4. diffBisect : negated conditional → NO_COVERAGE 5. diffBisect : changed conditional boundary → NO_COVERAGE 6. diffBisect : changed conditional boundary → NO_COVERAGE |
while (x2 < text1Length && y2 < text2Length |
462 |
2
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE 2. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE |
&& text1.charAt(text1Length - x2 - 1) |
463 |
1
1. diffBisect : negated conditional → NO_COVERAGE |
== text2.charAt(text2Length - y2 - 1)) { |
464 |
1
1. diffBisect : Changed increment from 1 to -1 → NO_COVERAGE |
x2++; |
465 |
1
1. diffBisect : Changed increment from 1 to -1 → NO_COVERAGE |
y2++; |
466 | } | |
467 | v2[k2Offset] = x2; | |
468 |
2
1. diffBisect : changed conditional boundary → NO_COVERAGE 2. diffBisect : negated conditional → NO_COVERAGE |
if (x2 > text1Length) { |
469 | // Ran off the left of the graph. | |
470 |
1
1. diffBisect : Changed increment from 2 to -2 → NO_COVERAGE |
k2end += 2; |
471 |
2
1. diffBisect : negated conditional → NO_COVERAGE 2. diffBisect : changed conditional boundary → NO_COVERAGE |
} else if (y2 > text2Length) { |
472 | // Ran off the top of the graph. | |
473 |
1
1. diffBisect : Changed increment from 2 to -2 → NO_COVERAGE |
k2start += 2; |
474 |
1
1. diffBisect : negated conditional → NO_COVERAGE |
} else if (!front) { |
475 |
2
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE 2. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE |
int k1Offset = vOffset + delta - k2; |
476 |
5
1. diffBisect : changed conditional boundary → NO_COVERAGE 2. diffBisect : changed conditional boundary → NO_COVERAGE 3. diffBisect : negated conditional → NO_COVERAGE 4. diffBisect : negated conditional → NO_COVERAGE 5. diffBisect : negated conditional → NO_COVERAGE |
if (k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] != -1) { |
477 | int x1 = v1[k1Offset]; | |
478 |
2
1. diffBisect : Replaced integer addition with subtraction → NO_COVERAGE 2. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE |
int y1 = vOffset + x1 - k1Offset; |
479 | // Mirror x2 onto top-left coordinate system. | |
480 |
1
1. diffBisect : Replaced integer subtraction with addition → NO_COVERAGE |
x2 = text1Length - x2; |
481 |
2
1. diffBisect : changed conditional boundary → NO_COVERAGE 2. diffBisect : negated conditional → NO_COVERAGE |
if (x1 >= x2) { |
482 | // Overlap detected. | |
483 |
1
1. diffBisect : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffBisect → NO_COVERAGE |
return this.diffBisectSplit(text1, text2, x1, y1, deadline); |
484 | } | |
485 | } | |
486 | } | |
487 | } | |
488 | } | |
489 | // Diff took too long and hit the deadline or | |
490 | // number of diffs equals number of characters, no commonality at all. | |
491 | LinkedList<Diff> diffs = new LinkedList<>(); | |
492 | diffs.add(new Diff(Operation.DELETE, text1)); | |
493 | diffs.add(new Diff(Operation.INSERT, text2)); | |
494 |
1
1. diffBisect : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffBisect → NO_COVERAGE |
return diffs; |
495 | } | |
496 | ||
497 | /** | |
498 | * Given the location of the 'middle snake', split the diff in two parts | |
499 | * and recurse. | |
500 | * @param text1 Old string to be diffed. | |
501 | * @param text2 New string to be diffed. | |
502 | * @param x Index of split point in text1. | |
503 | * @param y Index of split point in text2. | |
504 | * @param deadline Time at which to bail if not yet complete. | |
505 | * @return LinkedList of Diff objects. | |
506 | */ | |
507 | private LinkedList<Diff> diffBisectSplit(String text1, String text2, int x, int y, long deadline) { | |
508 | ||
509 | String text1a = text1.substring(0, x); | |
510 | String text2a = text2.substring(0, y); | |
511 | String text1b = text1.substring(x); | |
512 | String text2b = text2.substring(y); | |
513 | ||
514 | // Compute both diffs serially. | |
515 | LinkedList<Diff> diffs = this.diffMain(text1a, text2a, false, deadline); | |
516 | List<Diff> diffsb = this.diffMain(text1b, text2b, false, deadline); | |
517 | ||
518 | diffs.addAll(diffsb); | |
519 |
1
1. diffBisectSplit : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffBisectSplit → NO_COVERAGE |
return diffs; |
520 | } | |
521 | ||
522 | /** | |
523 | * Split two texts into a list of strings. Reduce the texts to a string of | |
524 | * hashes where each Unicode character represents one line. | |
525 | * @param text1 First string. | |
526 | * @param text2 Second string. | |
527 | * @return An object containing the encoded text1, the encoded text2 and | |
528 | * the List of unique strings. The zeroth element of the List of | |
529 | * unique strings is intentionally blank. | |
530 | */ | |
531 | protected LinesToCharsResult diffLinesToChars(String text1, String text2) { | |
532 | ||
533 | List<String> lineArray = new ArrayList<>(); | |
534 | Map<String, Integer> lineHash = new HashMap<>(); | |
535 | // e.g. linearray[4] == "Hello\n" | |
536 | // e.g. linehash.get("Hello\n") == 4 | |
537 | ||
538 | // "\x00" is a valid character, but various debuggers don't like it. | |
539 | // So we'll insert a junk entry to avoid generating a null character. | |
540 | lineArray.add(""); | |
541 | ||
542 | String chars1 = this.diffLinesToCharsMunge(text1, lineArray, lineHash); | |
543 | String chars2 = this.diffLinesToCharsMunge(text2, lineArray, lineHash); | |
544 |
1
1. diffLinesToChars : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffLinesToChars → NO_COVERAGE |
return new LinesToCharsResult(chars1, chars2, lineArray); |
545 | } | |
546 | ||
547 | /** | |
548 | * Split a text into a list of strings. Reduce the texts to a string of | |
549 | * hashes where each Unicode character represents one line. | |
550 | * @param text String to encode. | |
551 | * @param lineArray List of unique strings. | |
552 | * @param lineHash Map of strings to indices. | |
553 | * @return Encoded string. | |
554 | */ | |
555 | private String diffLinesToCharsMunge(String text, List<String> lineArray, | |
556 | Map<String, Integer> lineHash) { | |
557 | ||
558 | int lineStart = 0; | |
559 | int lineEnd = -1; | |
560 | String line; | |
561 | StringBuilder chars = new StringBuilder(); | |
562 | // Walk the text, pulling out a substring for each line. | |
563 | // text.split('\n') would would temporarily double our memory footprint. | |
564 | // Modifying text would create many large strings to garbage collect. | |
565 |
3
1. diffLinesToCharsMunge : Replaced integer subtraction with addition → NO_COVERAGE 2. diffLinesToCharsMunge : negated conditional → NO_COVERAGE 3. diffLinesToCharsMunge : changed conditional boundary → NO_COVERAGE |
while (lineEnd < text.length() - 1) { |
566 | lineEnd = text.indexOf('\n', lineStart); | |
567 |
1
1. diffLinesToCharsMunge : negated conditional → NO_COVERAGE |
if (lineEnd == -1) { |
568 |
1
1. diffLinesToCharsMunge : Replaced integer subtraction with addition → NO_COVERAGE |
lineEnd = text.length() - 1; |
569 | } | |
570 |
1
1. diffLinesToCharsMunge : Replaced integer addition with subtraction → NO_COVERAGE |
line = text.substring(lineStart, lineEnd + 1); |
571 |
1
1. diffLinesToCharsMunge : Replaced integer addition with subtraction → NO_COVERAGE |
lineStart = lineEnd + 1; |
572 | ||
573 |
1
1. diffLinesToCharsMunge : negated conditional → NO_COVERAGE |
if (lineHash.containsKey(line)) { |
574 | chars.append(String.valueOf((char) (int) lineHash.get(line))); | |
575 | } else { | |
576 | lineArray.add(line); | |
577 |
1
1. diffLinesToCharsMunge : Replaced integer subtraction with addition → NO_COVERAGE |
lineHash.put(line, lineArray.size() - 1); |
578 |
1
1. diffLinesToCharsMunge : Replaced integer subtraction with addition → NO_COVERAGE |
chars.append(String.valueOf((char) (lineArray.size() - 1))); |
579 | } | |
580 | } | |
581 |
1
1. diffLinesToCharsMunge : replaced return value with "" for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffLinesToCharsMunge → NO_COVERAGE |
return chars.toString(); |
582 | } | |
583 | ||
584 | /** | |
585 | * Rehydrate the text in a diff from a string of line hashes to real lines of | |
586 | * text. | |
587 | * @param diffs LinkedList of Diff objects. | |
588 | * @param lineArray List of unique strings. | |
589 | */ | |
590 | protected void diffCharsToLines(List<Diff> diffs, List<String> lineArray) { | |
591 | ||
592 | StringBuilder text; | |
593 | for (Diff diff : diffs) { | |
594 | text = new StringBuilder(); | |
595 |
2
1. diffCharsToLines : changed conditional boundary → NO_COVERAGE 2. diffCharsToLines : negated conditional → NO_COVERAGE |
for (int y = 0; y < diff.getText().length(); y++) { |
596 | text.append(lineArray.get(diff.getText().charAt(y))); | |
597 | } | |
598 |
1
1. diffCharsToLines : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
diff.setText(text.toString()); |
599 | } | |
600 | } | |
601 | ||
602 | /** | |
603 | * Determine the common prefix of two strings | |
604 | * @param text1 First string. | |
605 | * @param text2 Second string. | |
606 | * @return The number of characters common to the start of each string. | |
607 | */ | |
608 | public int diffCommonPrefix(String text1, String text2) { | |
609 | ||
610 | // Performance analysis: http://neil.fraser.name/news/2007/10/09/ | |
611 | int n = Math.min(text1.length(), text2.length()); | |
612 |
2
1. diffCommonPrefix : changed conditional boundary → NO_COVERAGE 2. diffCommonPrefix : negated conditional → NO_COVERAGE |
for (int i = 0; i < n; i++) { |
613 |
1
1. diffCommonPrefix : negated conditional → NO_COVERAGE |
if (text1.charAt(i) != text2.charAt(i)) { |
614 |
1
1. diffCommonPrefix : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCommonPrefix → NO_COVERAGE |
return i; |
615 | } | |
616 | } | |
617 |
1
1. diffCommonPrefix : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCommonPrefix → NO_COVERAGE |
return n; |
618 | } | |
619 | ||
620 | /** | |
621 | * Determine the common suffix of two strings | |
622 | * @param text1 First string. | |
623 | * @param text2 Second string. | |
624 | * @return The number of characters common to the end of each string. | |
625 | */ | |
626 | public int diffCommonSuffix(String text1, String text2) { | |
627 | ||
628 | // Performance analysis: http://neil.fraser.name/news/2007/10/09/ | |
629 | int text1Length = text1.length(); | |
630 | int text2Length = text2.length(); | |
631 | int n = Math.min(text1Length, text2Length); | |
632 |
2
1. diffCommonSuffix : changed conditional boundary → NO_COVERAGE 2. diffCommonSuffix : negated conditional → NO_COVERAGE |
for (int i = 1; i <= n; i++) { |
633 |
3
1. diffCommonSuffix : negated conditional → NO_COVERAGE 2. diffCommonSuffix : Replaced integer subtraction with addition → NO_COVERAGE 3. diffCommonSuffix : Replaced integer subtraction with addition → NO_COVERAGE |
if (text1.charAt(text1Length - i) != text2.charAt(text2Length - i)) { |
634 |
2
1. diffCommonSuffix : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCommonSuffix → NO_COVERAGE 2. diffCommonSuffix : Replaced integer subtraction with addition → NO_COVERAGE |
return i - 1; |
635 | } | |
636 | } | |
637 |
1
1. diffCommonSuffix : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCommonSuffix → NO_COVERAGE |
return n; |
638 | } | |
639 | ||
640 | /** | |
641 | * Determine if the suffix of one string is the prefix of another. | |
642 | * @param valueText1 First string. | |
643 | * @param valueText2 Second string. | |
644 | * @return The number of characters common to the end of the first | |
645 | * string and the start of the second string. | |
646 | */ | |
647 | protected int diffCommonOverlap(String valueText1, String valueText2) { | |
648 | ||
649 | String text1 = valueText1; | |
650 | String text2 = valueText2; | |
651 | | |
652 | // Cache the text lengths to prevent multiple calls. | |
653 | int text1Length = text1.length(); | |
654 | int text2Length = text2.length(); | |
655 | // Eliminate the null case. | |
656 |
2
1. diffCommonOverlap : negated conditional → NO_COVERAGE 2. diffCommonOverlap : negated conditional → NO_COVERAGE |
if (text1Length == 0 || text2Length == 0) { |
657 | return 0; | |
658 | } | |
659 | // Truncate the longer string. | |
660 |
2
1. diffCommonOverlap : changed conditional boundary → NO_COVERAGE 2. diffCommonOverlap : negated conditional → NO_COVERAGE |
if (text1Length > text2Length) { |
661 |
1
1. diffCommonOverlap : Replaced integer subtraction with addition → NO_COVERAGE |
text1 = text1.substring(text1Length - text2Length); |
662 |
2
1. diffCommonOverlap : negated conditional → NO_COVERAGE 2. diffCommonOverlap : changed conditional boundary → NO_COVERAGE |
} else if (text1Length < text2Length) { |
663 | text2 = text2.substring(0, text1Length); | |
664 | } | |
665 | int textLength = Math.min(text1Length, text2Length); | |
666 | // Quick check for the worst case. | |
667 |
1
1. diffCommonOverlap : negated conditional → NO_COVERAGE |
if (text1.equals(text2)) { |
668 |
1
1. diffCommonOverlap : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCommonOverlap → NO_COVERAGE |
return textLength; |
669 | } | |
670 | ||
671 | // Start by looking for a single character match | |
672 | // and increase length until no match is found. | |
673 | // Performance analysis: http://neil.fraser.name/news/2010/11/04/ | |
674 | int best = 0; | |
675 | int length = 1; | |
676 | while (true) { | |
677 |
1
1. diffCommonOverlap : Replaced integer subtraction with addition → NO_COVERAGE |
String pattern = text1.substring(textLength - length); |
678 | int found = text2.indexOf(pattern); | |
679 |
1
1. diffCommonOverlap : negated conditional → NO_COVERAGE |
if (found == -1) { |
680 |
1
1. diffCommonOverlap : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCommonOverlap → NO_COVERAGE |
return best; |
681 | } | |
682 |
1
1. diffCommonOverlap : Replaced integer addition with subtraction → NO_COVERAGE |
length += found; |
683 |
3
1. diffCommonOverlap : negated conditional → NO_COVERAGE 2. diffCommonOverlap : negated conditional → NO_COVERAGE 3. diffCommonOverlap : Replaced integer subtraction with addition → NO_COVERAGE |
if (found == 0 || text1.substring(textLength - length).equals( |
684 | text2.substring(0, length))) { | |
685 | best = length; | |
686 |
1
1. diffCommonOverlap : Changed increment from 1 to -1 → NO_COVERAGE |
length++; |
687 | } | |
688 | } | |
689 | } | |
690 | ||
691 | /** | |
692 | * Do the two texts share a substring which is at least half the length of | |
693 | * the longer text? | |
694 | * This speedup can produce non-minimal diffs. | |
695 | * @param text1 First string. | |
696 | * @param text2 Second string. | |
697 | * @return Five element String array, containing the prefix of text1, the | |
698 | * suffix of text1, the prefix of text2, the suffix of text2 and the | |
699 | * common middle. Or null if there was no match. | |
700 | */ | |
701 | protected String[] diffHalfMatch(String text1, String text2) { | |
702 | ||
703 |
2
1. diffHalfMatch : changed conditional boundary → NO_COVERAGE 2. diffHalfMatch : negated conditional → NO_COVERAGE |
String longtext = text1.length() > text2.length() ? text1 : text2; |
704 |
2
1. diffHalfMatch : changed conditional boundary → NO_COVERAGE 2. diffHalfMatch : negated conditional → NO_COVERAGE |
String shorttext = text1.length() > text2.length() ? text2 : text1; |
705 |
5
1. diffHalfMatch : negated conditional → NO_COVERAGE 2. diffHalfMatch : negated conditional → NO_COVERAGE 3. diffHalfMatch : changed conditional boundary → NO_COVERAGE 4. diffHalfMatch : Replaced integer multiplication with division → NO_COVERAGE 5. diffHalfMatch : changed conditional boundary → NO_COVERAGE |
if (longtext.length() < 4 || shorttext.length() * 2 < longtext.length()) { |
706 | return null; // Pointless. | |
707 | } | |
708 | ||
709 | // First check if the second quarter is the seed for a half-match. | |
710 |
2
1. diffHalfMatch : Replaced integer addition with subtraction → NO_COVERAGE 2. diffHalfMatch : Replaced integer division with multiplication → NO_COVERAGE |
String[] hm1 = this.diffHalfMatchI(longtext, shorttext, (longtext.length() + 3) / 4); |
711 | // Check again based on the third quarter. | |
712 |
2
1. diffHalfMatch : Replaced integer addition with subtraction → NO_COVERAGE 2. diffHalfMatch : Replaced integer division with multiplication → NO_COVERAGE |
String[] hm2 = this.diffHalfMatchI(longtext, shorttext, (longtext.length() + 1) / 2); |
713 | String[] hm; | |
714 |
2
1. diffHalfMatch : negated conditional → NO_COVERAGE 2. diffHalfMatch : negated conditional → NO_COVERAGE |
if (hm1 == null && hm2 == null) { |
715 | return null; | |
716 |
1
1. diffHalfMatch : negated conditional → NO_COVERAGE |
} else if (hm2 == null) { |
717 | hm = hm1; | |
718 |
1
1. diffHalfMatch : negated conditional → NO_COVERAGE |
} else if (hm1 == null) { |
719 | hm = hm2; | |
720 | } else { | |
721 | // Both matched. Select the longest. | |
722 |
2
1. diffHalfMatch : negated conditional → NO_COVERAGE 2. diffHalfMatch : changed conditional boundary → NO_COVERAGE |
hm = hm1[4].length() > hm2[4].length() ? hm1 : hm2; |
723 | } | |
724 | ||
725 | // A half-match was found, sort out the return data. | |
726 |
2
1. diffHalfMatch : changed conditional boundary → NO_COVERAGE 2. diffHalfMatch : negated conditional → NO_COVERAGE |
if (text1.length() > text2.length()) { |
727 |
1
1. diffHalfMatch : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffHalfMatch → NO_COVERAGE |
return hm; |
728 | } else { | |
729 |
1
1. diffHalfMatch : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffHalfMatch → NO_COVERAGE |
return new String[]{hm[2], hm[3], hm[0], hm[1], hm[4]}; |
730 | } | |
731 | } | |
732 | ||
733 | /** | |
734 | * Does a substring of shorttext exist within longtext such that the | |
735 | * substring is at least half the length of longtext? | |
736 | * @param longtext Longer string. | |
737 | * @param shorttext Shorter string. | |
738 | * @param i Start index of quarter length substring within longtext. | |
739 | * @return Five element String array, containing the prefix of longtext, the | |
740 | * suffix of longtext, the prefix of shorttext, the suffix of shorttext | |
741 | * and the common middle. Or null if there was no match. | |
742 | */ | |
743 | private String[] diffHalfMatchI(String longtext, String shorttext, int i) { | |
744 | ||
745 | // Start with a 1/4 length substring at position i as a seed. | |
746 |
2
1. diffHalfMatchI : Replaced integer division with multiplication → NO_COVERAGE 2. diffHalfMatchI : Replaced integer addition with subtraction → NO_COVERAGE |
String seed = longtext.substring(i, i + longtext.length() / 4); |
747 | int j = -1; | |
748 | String bestCommon = ""; | |
749 | String bestLongtextA = ""; | |
750 | String bestLongtextB = ""; | |
751 | String bestShorttextA = ""; | |
752 | String bestShorttextB = ""; | |
753 |
2
1. diffHalfMatchI : Replaced integer addition with subtraction → NO_COVERAGE 2. diffHalfMatchI : negated conditional → NO_COVERAGE |
while ((j = shorttext.indexOf(seed, j + 1)) != -1) { |
754 | int prefixLength = this.diffCommonPrefix(longtext.substring(i), | |
755 | shorttext.substring(j)); | |
756 | int suffixLength = this.diffCommonSuffix(longtext.substring(0, i), | |
757 | shorttext.substring(0, j)); | |
758 |
3
1. diffHalfMatchI : negated conditional → NO_COVERAGE 2. diffHalfMatchI : Replaced integer addition with subtraction → NO_COVERAGE 3. diffHalfMatchI : changed conditional boundary → NO_COVERAGE |
if (bestCommon.length() < suffixLength + prefixLength) { |
759 |
2
1. diffHalfMatchI : Replaced integer subtraction with addition → NO_COVERAGE 2. diffHalfMatchI : Replaced integer addition with subtraction → NO_COVERAGE |
bestCommon = shorttext.substring(j - suffixLength, j) |
760 | + shorttext.substring(j, j + prefixLength); | |
761 |
1
1. diffHalfMatchI : Replaced integer subtraction with addition → NO_COVERAGE |
bestLongtextA = longtext.substring(0, i - suffixLength); |
762 |
1
1. diffHalfMatchI : Replaced integer addition with subtraction → NO_COVERAGE |
bestLongtextB = longtext.substring(i + prefixLength); |
763 |
1
1. diffHalfMatchI : Replaced integer subtraction with addition → NO_COVERAGE |
bestShorttextA = shorttext.substring(0, j - suffixLength); |
764 |
1
1. diffHalfMatchI : Replaced integer addition with subtraction → NO_COVERAGE |
bestShorttextB = shorttext.substring(j + prefixLength); |
765 | } | |
766 | } | |
767 |
3
1. diffHalfMatchI : negated conditional → NO_COVERAGE 2. diffHalfMatchI : changed conditional boundary → NO_COVERAGE 3. diffHalfMatchI : Replaced integer multiplication with division → NO_COVERAGE |
if (bestCommon.length() * 2 >= longtext.length()) { |
768 |
1
1. diffHalfMatchI : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffHalfMatchI → NO_COVERAGE |
return new String[]{bestLongtextA, bestLongtextB, |
769 | bestShorttextA, bestShorttextB, bestCommon}; | |
770 | } else { | |
771 | return null; | |
772 | } | |
773 | } | |
774 | ||
775 | /** | |
776 | * Reduce the number of edits by eliminating semantically trivial equalities. | |
777 | * @param diffs LinkedList of Diff objects. | |
778 | */ | |
779 | public void diffCleanupSemantic(LinkedList<Diff> diffs) { | |
780 | ||
781 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (diffs.isEmpty()) { |
782 | return; | |
783 | } | |
784 | boolean changes = false; | |
785 | // Synchronized Stack to avoid Exception | |
786 | Stack<Diff> equalities = new Stack<>(); // Stack of qualities. | |
787 | String lastequality = null; // Always equal to equalities.lastElement().text | |
788 | ListIterator<Diff> pointer = diffs.listIterator(); | |
789 | // Number of characters that changed prior to the equality. | |
790 | int lengthInsertions1 = 0; | |
791 | int lengthDeletions1 = 0; | |
792 | // Number of characters that changed after the equality. | |
793 | int lengthInsertions2 = 0; | |
794 | int lengthDeletions2 = 0; | |
795 | Diff thisDiff = pointer.next(); | |
796 | ||
797 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
while (thisDiff != null) { |
798 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (thisDiff.getOperation() == Operation.EQUAL) { |
799 | // Equality found. | |
800 | equalities.push(thisDiff); | |
801 | lengthInsertions1 = lengthInsertions2; | |
802 | lengthDeletions1 = lengthDeletions2; | |
803 | lengthInsertions2 = 0; | |
804 | lengthDeletions2 = 0; | |
805 | lastequality = thisDiff.getText(); | |
806 | } else { | |
807 | // An insertion or deletion. | |
808 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (thisDiff.getOperation() == Operation.INSERT) { |
809 |
1
1. diffCleanupSemantic : Replaced integer addition with subtraction → NO_COVERAGE |
lengthInsertions2 += thisDiff.getText().length(); |
810 | } else { | |
811 |
1
1. diffCleanupSemantic : Replaced integer addition with subtraction → NO_COVERAGE |
lengthDeletions2 += thisDiff.getText().length(); |
812 | } | |
813 | // Eliminate an equality that is smaller or equal to the edits on both | |
814 | // sides of it. | |
815 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if ( |
816 | lastequality != null | |
817 |
2
1. diffCleanupSemantic : negated conditional → NO_COVERAGE 2. diffCleanupSemantic : changed conditional boundary → NO_COVERAGE |
&& lastequality.length() <= Math.max(lengthInsertions1, lengthDeletions1) |
818 |
2
1. diffCleanupSemantic : changed conditional boundary → NO_COVERAGE 2. diffCleanupSemantic : negated conditional → NO_COVERAGE |
&& lastequality.length() <= Math.max(lengthInsertions2, lengthDeletions2) |
819 | ) { | |
820 | // Walk back to offending equality. | |
821 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
while (thisDiff != equalities.lastElement()) { |
822 | thisDiff = pointer.previous(); | |
823 | } | |
824 | pointer.next(); | |
825 | ||
826 | // Replace equality with a delete. | |
827 |
1
1. diffCleanupSemantic : removed call to java/util/ListIterator::set → NO_COVERAGE |
pointer.set(new Diff(Operation.DELETE, lastequality)); |
828 | // Insert a corresponding an insert. | |
829 |
1
1. diffCleanupSemantic : removed call to java/util/ListIterator::add → NO_COVERAGE |
pointer.add(new Diff(Operation.INSERT, lastequality)); |
830 | ||
831 | equalities.pop(); // Throw away the equality we just deleted. | |
832 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (!equalities.empty()) { |
833 | // Throw away the previous equality (it needs to be reevaluated). | |
834 | equalities.pop(); | |
835 | } | |
836 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (equalities.empty()) { |
837 | // There are no previous equalities, walk back to the start. | |
838 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
while (pointer.hasPrevious()) { |
839 | pointer.previous(); | |
840 | } | |
841 | } else { | |
842 | // There is a safe equality we can fall back to. | |
843 | thisDiff = equalities.lastElement(); | |
844 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
while (thisDiff != pointer.previous()) { |
845 | // Intentionally empty loop. | |
846 | } | |
847 | } | |
848 | ||
849 | lengthInsertions1 = 0; // Reset the counters. | |
850 | lengthInsertions2 = 0; | |
851 | lengthDeletions1 = 0; | |
852 | lengthDeletions2 = 0; | |
853 | lastequality = null; | |
854 | changes = true; | |
855 | } | |
856 | } | |
857 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
thisDiff = pointer.hasNext() ? pointer.next() : null; |
858 | } | |
859 | ||
860 | // Normalize the diff. | |
861 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (changes) { |
862 |
1
1. diffCleanupSemantic : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupMerge → NO_COVERAGE |
this.diffCleanupMerge(diffs); |
863 | } | |
864 |
1
1. diffCleanupSemantic : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemanticLossless → NO_COVERAGE |
this.diffCleanupSemanticLossless(diffs); |
865 | ||
866 | // Find any overlaps between deletions and insertions. | |
867 | // e.g: <del>abcxxx</del><ins>xxxdef</ins> | |
868 | // -> <del>abc</del>xxx<ins>def</ins> | |
869 | // e.g: <del>xxxabc</del><ins>defxxx</ins> | |
870 | // -> <ins>def</ins>xxx<del>abc</del> | |
871 | // Only extract an overlap if it is as big as the edit ahead or behind it. | |
872 | pointer = diffs.listIterator(); | |
873 | Diff prevDiff = null; | |
874 | thisDiff = null; | |
875 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (pointer.hasNext()) { |
876 | prevDiff = pointer.next(); | |
877 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (pointer.hasNext()) { |
878 | thisDiff = pointer.next(); | |
879 | } | |
880 | } | |
881 | ||
882 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
while (thisDiff != null) { |
883 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (prevDiff.getOperation() == Operation.DELETE && |
884 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
thisDiff.getOperation() == Operation.INSERT) { |
885 | String deletion = prevDiff.getText(); | |
886 | String insertion = thisDiff.getText(); | |
887 | int overlapLength1 = this.diffCommonOverlap(deletion, insertion); | |
888 | int overlapLength2 = this.diffCommonOverlap(insertion, deletion); | |
889 |
2
1. diffCleanupSemantic : negated conditional → NO_COVERAGE 2. diffCleanupSemantic : changed conditional boundary → NO_COVERAGE |
if (overlapLength1 >= overlapLength2) { |
890 |
3
1. diffCleanupSemantic : changed conditional boundary → NO_COVERAGE 2. diffCleanupSemantic : Replaced double division with multiplication → NO_COVERAGE 3. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (overlapLength1 >= deletion.length() / 2.0 || |
891 |
3
1. diffCleanupSemantic : changed conditional boundary → NO_COVERAGE 2. diffCleanupSemantic : Replaced double division with multiplication → NO_COVERAGE 3. diffCleanupSemantic : negated conditional → NO_COVERAGE |
overlapLength1 >= insertion.length() / 2.0) { |
892 | // Overlap found. Insert an equality and trim the surrounding edits. | |
893 | pointer.previous(); | |
894 |
1
1. diffCleanupSemantic : removed call to java/util/ListIterator::add → NO_COVERAGE |
pointer.add(new Diff(Operation.EQUAL, |
895 | insertion.substring(0, overlapLength1))); | |
896 |
2
1. diffCleanupSemantic : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE 2. diffCleanupSemantic : Replaced integer subtraction with addition → NO_COVERAGE |
prevDiff.setText(deletion.substring(0, deletion.length() - overlapLength1)); |
897 |
1
1. diffCleanupSemantic : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
thisDiff.setText(insertion.substring(overlapLength1)); |
898 | // pointer.add inserts the element before the cursor, so there is | |
899 | // no need to step past the new element. | |
900 | } | |
901 | } else { | |
902 |
3
1. diffCleanupSemantic : changed conditional boundary → NO_COVERAGE 2. diffCleanupSemantic : Replaced double division with multiplication → NO_COVERAGE 3. diffCleanupSemantic : negated conditional → NO_COVERAGE |
if (overlapLength2 >= deletion.length() / 2.0 || |
903 |
3
1. diffCleanupSemantic : Replaced double division with multiplication → NO_COVERAGE 2. diffCleanupSemantic : negated conditional → NO_COVERAGE 3. diffCleanupSemantic : changed conditional boundary → NO_COVERAGE |
overlapLength2 >= insertion.length() / 2.0) { |
904 | // Reverse overlap found. | |
905 | // Insert an equality and swap and trim the surrounding edits. | |
906 | pointer.previous(); | |
907 |
1
1. diffCleanupSemantic : removed call to java/util/ListIterator::add → NO_COVERAGE |
pointer.add(new Diff(Operation.EQUAL, |
908 | deletion.substring(0, overlapLength2))); | |
909 |
1
1. diffCleanupSemantic : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setOperation → NO_COVERAGE |
prevDiff.setOperation(Operation.INSERT); |
910 |
2
1. diffCleanupSemantic : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE 2. diffCleanupSemantic : Replaced integer subtraction with addition → NO_COVERAGE |
prevDiff.setText(insertion.substring(0, insertion.length() - overlapLength2)); |
911 |
1
1. diffCleanupSemantic : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setOperation → NO_COVERAGE |
thisDiff.setOperation(Operation.DELETE); |
912 |
1
1. diffCleanupSemantic : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
thisDiff.setText(deletion.substring(overlapLength2)); |
913 | // pointer.add inserts the element before the cursor, so there is | |
914 | // no need to step past the new element. | |
915 | } | |
916 | } | |
917 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
thisDiff = pointer.hasNext() ? pointer.next() : null; |
918 | } | |
919 | prevDiff = thisDiff; | |
920 |
1
1. diffCleanupSemantic : negated conditional → NO_COVERAGE |
thisDiff = pointer.hasNext() ? pointer.next() : null; |
921 | } | |
922 | } | |
923 | ||
924 | /** | |
925 | * Look for single edits surrounded on both sides by equalities | |
926 | * which can be shifted sideways to align the edit to a word boundary. | |
927 | * e.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came. | |
928 | * @param diffs LinkedList of Diff objects. | |
929 | */ | |
930 | public void diffCleanupSemanticLossless(List<Diff> diffs) { | |
931 | ||
932 | StringBuilder equality1 = new StringBuilder(); | |
933 | String edit; | |
934 | StringBuilder equality2 = new StringBuilder(); | |
935 | String commonString; | |
936 | int commonOffset; | |
937 | int score; | |
938 | int bestScore; | |
939 | String bestEquality1; | |
940 | String bestEdit; | |
941 | String bestEquality2; | |
942 | // Create a new iterator at the start. | |
943 | ListIterator<Diff> pointer = diffs.listIterator(); | |
944 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
Diff prevDiff = pointer.hasNext() ? pointer.next() : null; |
945 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
Diff thisDiff = pointer.hasNext() ? pointer.next() : null; |
946 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
Diff nextDiff = pointer.hasNext() ? pointer.next() : null; |
947 | ||
948 | // Intentionally ignore the first and last element (don't need checking). | |
949 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
while (nextDiff != null) { |
950 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
if (prevDiff.getOperation() == Operation.EQUAL && |
951 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
nextDiff.getOperation() == Operation.EQUAL) { |
952 | // This is a single edit surrounded by equalities. | |
953 |
1
1. diffCleanupSemanticLossless : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
equality1.setLength(0); |
954 | equality1.append(prevDiff.getText()); | |
955 | edit = thisDiff.getText(); | |
956 |
1
1. diffCleanupSemanticLossless : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
equality2.setLength(0); |
957 | equality2.append(nextDiff.getText()); | |
958 | ||
959 | // First, shift the edit as far left as possible. | |
960 | commonOffset = this.diffCommonSuffix(equality1.toString(), edit); | |
961 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
if (commonOffset != 0) { |
962 |
1
1. diffCleanupSemanticLossless : Replaced integer subtraction with addition → NO_COVERAGE |
commonString = edit.substring(edit.length() - commonOffset); |
963 |
1
1. diffCleanupSemanticLossless : Replaced integer subtraction with addition → NO_COVERAGE |
String substring = equality1.substring(0, equality1.length() - commonOffset); |
964 |
1
1. diffCleanupSemanticLossless : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
equality1.setLength(0); |
965 | equality1.append(substring); | |
966 |
1
1. diffCleanupSemanticLossless : Replaced integer subtraction with addition → NO_COVERAGE |
edit = commonString + edit.substring(0, edit.length() - commonOffset); |
967 | equality2.insert(0, commonString); | |
968 | } | |
969 | ||
970 | // Second, step character by character right, looking for the best fit. | |
971 | bestEquality1 = equality1.toString(); | |
972 | bestEdit = edit; | |
973 | bestEquality2 = equality2.toString(); | |
974 | bestScore = this.diffCleanupSemanticScore(equality1.toString(), edit) | |
975 |
1
1. diffCleanupSemanticLossless : Replaced integer addition with subtraction → NO_COVERAGE |
+ this.diffCleanupSemanticScore(edit, equality2.toString()); |
976 |
2
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE 2. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
while (!edit.isEmpty() && equality2.length() != 0 |
977 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
&& edit.charAt(0) == equality2.charAt(0)) { |
978 | equality1.append(Character.toString(edit.charAt(0))); | |
979 | edit = edit.substring(1) + equality2.charAt(0); | |
980 | String substring = equality2.substring(1); | |
981 |
1
1. diffCleanupSemanticLossless : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
equality2.setLength(0); |
982 | equality2.append(substring); | |
983 | score = this.diffCleanupSemanticScore(equality1.toString(), edit) | |
984 |
1
1. diffCleanupSemanticLossless : Replaced integer addition with subtraction → NO_COVERAGE |
+ this.diffCleanupSemanticScore(edit, equality2.toString()); |
985 | // The >= encourages trailing rather than leading whitespace on edits. | |
986 |
2
1. diffCleanupSemanticLossless : changed conditional boundary → NO_COVERAGE 2. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
if (score >= bestScore) { |
987 | bestScore = score; | |
988 | bestEquality1 = equality1.toString(); | |
989 | bestEdit = edit; | |
990 | bestEquality2 = equality2.toString(); | |
991 | } | |
992 | } | |
993 | ||
994 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
if (!prevDiff.getText().equals(bestEquality1)) { |
995 | // We have an improvement, save it back to the diff. | |
996 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
if (!bestEquality1.isEmpty()) { |
997 |
1
1. diffCleanupSemanticLossless : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
prevDiff.setText(bestEquality1); |
998 | } else { | |
999 | pointer.previous(); // Walk past nextDiff. | |
1000 | pointer.previous(); // Walk past thisDiff. | |
1001 | pointer.previous(); // Walk past prevDiff. | |
1002 |
1
1. diffCleanupSemanticLossless : removed call to java/util/ListIterator::remove → NO_COVERAGE |
pointer.remove(); // Delete prevDiff. |
1003 | pointer.next(); // Walk past thisDiff. | |
1004 | pointer.next(); // Walk past nextDiff. | |
1005 | } | |
1006 |
1
1. diffCleanupSemanticLossless : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
thisDiff.setText(bestEdit); |
1007 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
if (!bestEquality2.isEmpty()) { |
1008 |
1
1. diffCleanupSemanticLossless : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
nextDiff.setText(bestEquality2); |
1009 | } else { | |
1010 |
1
1. diffCleanupSemanticLossless : removed call to java/util/ListIterator::remove → NO_COVERAGE |
pointer.remove(); // Delete nextDiff. |
1011 | nextDiff = thisDiff; | |
1012 | thisDiff = prevDiff; | |
1013 | } | |
1014 | } | |
1015 | } | |
1016 | prevDiff = thisDiff; | |
1017 | thisDiff = nextDiff; | |
1018 |
1
1. diffCleanupSemanticLossless : negated conditional → NO_COVERAGE |
nextDiff = pointer.hasNext() ? pointer.next() : null; |
1019 | } | |
1020 | } | |
1021 | ||
1022 | /** | |
1023 | * Given two strings, compute a score representing whether the internal | |
1024 | * boundary falls on logical boundaries. | |
1025 | * Scores range from 6 (best) to 0 (worst). | |
1026 | * @param one First string. | |
1027 | * @param two Second string. | |
1028 | * @return The score. | |
1029 | */ | |
1030 | private int diffCleanupSemanticScore(String one, String two) { | |
1031 | ||
1032 |
2
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
if (one.isEmpty() || two.isEmpty()) { |
1033 | // Edges are the best. | |
1034 |
1
1. diffCleanupSemanticScore : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemanticScore → NO_COVERAGE |
return 6; |
1035 | } | |
1036 | ||
1037 | // Each port of this function behaves slightly differently due to | |
1038 | // subtle differences in each language's definition of things like | |
1039 | // 'whitespace'. Since this function's purpose is largely cosmetic, | |
1040 | // the choice has been made to use each language's native features | |
1041 | // rather than force total conformity. | |
1042 |
1
1. diffCleanupSemanticScore : Replaced integer subtraction with addition → NO_COVERAGE |
char char1 = one.charAt(one.length() - 1); |
1043 | char char2 = two.charAt(0); | |
1044 |
1
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
boolean nonAlphaNumeric1 = !Character.isLetterOrDigit(char1); |
1045 |
1
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
boolean nonAlphaNumeric2 = !Character.isLetterOrDigit(char2); |
1046 |
2
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
boolean whitespace1 = nonAlphaNumeric1 && Character.isWhitespace(char1); |
1047 |
2
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
boolean whitespace2 = nonAlphaNumeric2 && Character.isWhitespace(char2); |
1048 |
1
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
boolean lineBreak1 = whitespace1 |
1049 |
1
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
&& Character.getType(char1) == Character.CONTROL; |
1050 |
1
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
boolean lineBreak2 = whitespace2 |
1051 |
1
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
&& Character.getType(char2) == Character.CONTROL; |
1052 |
2
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
boolean blankLine1 = lineBreak1 && BLANK_LINE_END.matcher(one).find(); |
1053 |
2
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
boolean blankLine2 = lineBreak2 && BLANK_LINE_START.matcher(two).find(); |
1054 | ||
1055 |
2
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
if (blankLine1 || blankLine2) { |
1056 | // Five points for blank lines. | |
1057 |
1
1. diffCleanupSemanticScore : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemanticScore → NO_COVERAGE |
return 5; |
1058 |
2
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
} else if (lineBreak1 || lineBreak2) { |
1059 | // Four points for line breaks. | |
1060 |
1
1. diffCleanupSemanticScore : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemanticScore → NO_COVERAGE |
return 4; |
1061 |
3
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 3. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
} else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) { |
1062 | // Three points for end of sentences. | |
1063 |
1
1. diffCleanupSemanticScore : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemanticScore → NO_COVERAGE |
return 3; |
1064 |
2
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
} else if (whitespace1 || whitespace2) { |
1065 | // Two points for whitespace. | |
1066 |
1
1. diffCleanupSemanticScore : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemanticScore → NO_COVERAGE |
return 2; |
1067 |
2
1. diffCleanupSemanticScore : negated conditional → NO_COVERAGE 2. diffCleanupSemanticScore : negated conditional → NO_COVERAGE |
} else if (nonAlphaNumeric1 || nonAlphaNumeric2) { |
1068 | // One point for non-alphanumeric. | |
1069 |
1
1. diffCleanupSemanticScore : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemanticScore → NO_COVERAGE |
return 1; |
1070 | } | |
1071 | return 0; | |
1072 | } | |
1073 | ||
1074 | /** | |
1075 | * Reduce the number of edits by eliminating operationally trivial equalities. | |
1076 | * @param diffs LinkedList of Diff objects. | |
1077 | */ | |
1078 | public void diffCleanupEfficiency(LinkedList<Diff> diffs) { | |
1079 | ||
1080 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
if (diffs.isEmpty()) { |
1081 | return; | |
1082 | } | |
1083 | boolean changes = false; | |
1084 | // Synchronized Stack to avoid Exception | |
1085 | Stack<Diff> equalities = new Stack<>(); // Stack of equalities. | |
1086 | String lastequality = null; // Always equal to equalities.lastElement().text | |
1087 | ListIterator<Diff> pointer = diffs.listIterator(); | |
1088 | // Is there an insertion operation before the last equality. | |
1089 | boolean preIns = false; | |
1090 | // Is there a deletion operation before the last equality. | |
1091 | boolean preDel = false; | |
1092 | // Is there an insertion operation after the last equality. | |
1093 | boolean postIns = false; | |
1094 | // Is there a deletion operation after the last equality. | |
1095 | boolean postDel = false; | |
1096 | Diff thisDiff = pointer.next(); | |
1097 | Diff safeDiff = thisDiff; // The last Diff that is known to be unsplitable. | |
1098 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
while (thisDiff != null) { |
1099 | ||
1100 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
if (thisDiff.getOperation() == Operation.EQUAL) { |
1101 | ||
1102 | // Equality found. | |
1103 |
4
1. diffCleanupEfficiency : changed conditional boundary → NO_COVERAGE 2. diffCleanupEfficiency : negated conditional → NO_COVERAGE 3. diffCleanupEfficiency : negated conditional → NO_COVERAGE 4. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
if (thisDiff.getText().length() < DIFF_EDIT_COST && (postIns || postDel)) { |
1104 | // Candidate found. | |
1105 | equalities.push(thisDiff); | |
1106 | preIns = postIns; | |
1107 | preDel = postDel; | |
1108 | lastequality = thisDiff.getText(); | |
1109 | } else { | |
1110 | // Not a candidate, and can never become one. | |
1111 |
1
1. diffCleanupEfficiency : removed call to java/util/Stack::clear → NO_COVERAGE |
equalities.clear(); |
1112 | lastequality = null; | |
1113 | safeDiff = thisDiff; | |
1114 | } | |
1115 | postIns = postDel = false; | |
1116 | } else { | |
1117 | // An insertion or deletion. | |
1118 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
if (thisDiff.getOperation() == Operation.DELETE) { |
1119 | postDel = true; | |
1120 | } else { | |
1121 | postIns = true; | |
1122 | } | |
1123 | ||
1124 | /* | |
1125 | * Five types to be split: | |
1126 | * <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del> | |
1127 | * <ins>A</ins>X<ins>C</ins><del>D</del> | |
1128 | * <ins>A</ins><del>B</del>X<ins>C</ins> | |
1129 | * <ins>A</del>X<ins>C</ins><del>D</del> | |
1130 | * <ins>A</ins><del>B</del>X<del>C</del> | |
1131 | */ | |
1132 |
5
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE 2. diffCleanupEfficiency : negated conditional → NO_COVERAGE 3. diffCleanupEfficiency : negated conditional → NO_COVERAGE 4. diffCleanupEfficiency : negated conditional → NO_COVERAGE 5. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
if ( |
1133 | lastequality != null | |
1134 | && ( | |
1135 | (preIns && preDel && postIns && postDel) | |
1136 | || ( | |
1137 |
2
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE 2. diffCleanupEfficiency : changed conditional boundary → NO_COVERAGE |
(lastequality.length() < DIFF_EDIT_COST / 2) |
1138 |
8
1. diffCleanupEfficiency : Replaced integer addition with subtraction → NO_COVERAGE 2. diffCleanupEfficiency : negated conditional → NO_COVERAGE 3. diffCleanupEfficiency : negated conditional → NO_COVERAGE 4. diffCleanupEfficiency : negated conditional → NO_COVERAGE 5. diffCleanupEfficiency : negated conditional → NO_COVERAGE 6. diffCleanupEfficiency : Replaced integer addition with subtraction → NO_COVERAGE 7. diffCleanupEfficiency : Replaced integer addition with subtraction → NO_COVERAGE 8. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
&& ((preIns ? 1 : 0) + (preDel ? 1 : 0) + (postIns ? 1 : 0) + (postDel ? 1 : 0)) == 3 |
1139 | ) | |
1140 | ) | |
1141 | ) { | |
1142 | // Walk back to offending equality. | |
1143 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
while (thisDiff != equalities.lastElement()) { |
1144 | thisDiff = pointer.previous(); | |
1145 | } | |
1146 | pointer.next(); | |
1147 | ||
1148 | // Replace equality with a delete. | |
1149 |
1
1. diffCleanupEfficiency : removed call to java/util/ListIterator::set → NO_COVERAGE |
pointer.set(new Diff(Operation.DELETE, lastequality)); |
1150 | // Insert a corresponding an insert. | |
1151 | thisDiff = new Diff(Operation.INSERT, lastequality); | |
1152 |
1
1. diffCleanupEfficiency : removed call to java/util/ListIterator::add → NO_COVERAGE |
pointer.add(thisDiff); |
1153 | ||
1154 | equalities.pop(); // Throw away the equality we just deleted. | |
1155 | lastequality = null; | |
1156 |
2
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE 2. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
if (preIns && preDel) { |
1157 | // No changes made which could affect previous entry, keep going. | |
1158 | postIns = postDel = true; | |
1159 |
1
1. diffCleanupEfficiency : removed call to java/util/Stack::clear → NO_COVERAGE |
equalities.clear(); |
1160 | safeDiff = thisDiff; | |
1161 | } else { | |
1162 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
if (!equalities.empty()) { |
1163 | // Throw away the previous equality (it needs to be reevaluated). | |
1164 | equalities.pop(); | |
1165 | } | |
1166 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
if (equalities.empty()) { |
1167 | // There are no previous questionable equalities, | |
1168 | // walk back to the last known safe diff. | |
1169 | thisDiff = safeDiff; | |
1170 | } else { | |
1171 | // There is an equality we can fall back to. | |
1172 | thisDiff = equalities.lastElement(); | |
1173 | } | |
1174 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
while (thisDiff != pointer.previous()) { |
1175 | // Intentionally empty loop. | |
1176 | } | |
1177 | postIns = postDel = false; | |
1178 | } | |
1179 | ||
1180 | changes = true; | |
1181 | } | |
1182 | } | |
1183 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
thisDiff = pointer.hasNext() ? pointer.next() : null; |
1184 | } | |
1185 | ||
1186 |
1
1. diffCleanupEfficiency : negated conditional → NO_COVERAGE |
if (changes) { |
1187 |
1
1. diffCleanupEfficiency : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupMerge → NO_COVERAGE |
this.diffCleanupMerge(diffs); |
1188 | } | |
1189 | } | |
1190 | ||
1191 | /** | |
1192 | * Reorder and merge like edit sections. Merge equalities. | |
1193 | * Any edit section can move as long as it doesn't cross an equality. | |
1194 | * @param diffs LinkedList of Diff objects. | |
1195 | */ | |
1196 | public void diffCleanupMerge(LinkedList<Diff> diffs) { | |
1197 | ||
1198 | diffs.add(new Diff(Operation.EQUAL, "")); // Add a dummy entry at the end. | |
1199 | ListIterator<Diff> pointer = diffs.listIterator(); | |
1200 | int countDelete = 0; | |
1201 | int countInsert = 0; | |
1202 | StringBuilder textDelete = new StringBuilder(); | |
1203 | StringBuilder textInsert = new StringBuilder(); | |
1204 | Diff thisDiff = pointer.next(); | |
1205 | Diff prevEqual = null; | |
1206 | int commonlength; | |
1207 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
while (thisDiff != null) { |
1208 | switch (thisDiff.getOperation()) { | |
1209 | case INSERT: | |
1210 |
1
1. diffCleanupMerge : Changed increment from 1 to -1 → NO_COVERAGE |
countInsert++; |
1211 | textInsert.append(thisDiff.getText()); | |
1212 | prevEqual = null; | |
1213 | break; | |
1214 | case DELETE: | |
1215 |
1
1. diffCleanupMerge : Changed increment from 1 to -1 → NO_COVERAGE |
countDelete++; |
1216 | textDelete.append(thisDiff.getText()); | |
1217 | prevEqual = null; | |
1218 | break; | |
1219 | case EQUAL: | |
1220 |
3
1. diffCleanupMerge : negated conditional → NO_COVERAGE 2. diffCleanupMerge : changed conditional boundary → NO_COVERAGE 3. diffCleanupMerge : Replaced integer addition with subtraction → NO_COVERAGE |
if (countDelete + countInsert > 1) { |
1221 | ||
1222 |
2
1. diffCleanupMerge : negated conditional → NO_COVERAGE 2. diffCleanupMerge : negated conditional → NO_COVERAGE |
boolean bothTypes = countDelete != 0 && countInsert != 0; |
1223 | // Delete the offending records. | |
1224 | pointer.previous(); // Reverse direction. | |
1225 |
3
1. diffCleanupMerge : Changed increment from -1 to 1 → NO_COVERAGE 2. diffCleanupMerge : negated conditional → NO_COVERAGE 3. diffCleanupMerge : changed conditional boundary → NO_COVERAGE |
while (countDelete-- > 0) { |
1226 | pointer.previous(); | |
1227 |
1
1. diffCleanupMerge : removed call to java/util/ListIterator::remove → NO_COVERAGE |
pointer.remove(); |
1228 | } | |
1229 |
3
1. diffCleanupMerge : Changed increment from -1 to 1 → NO_COVERAGE 2. diffCleanupMerge : changed conditional boundary → NO_COVERAGE 3. diffCleanupMerge : negated conditional → NO_COVERAGE |
while (countInsert-- > 0) { |
1230 | pointer.previous(); | |
1231 |
1
1. diffCleanupMerge : removed call to java/util/ListIterator::remove → NO_COVERAGE |
pointer.remove(); |
1232 | } | |
1233 | ||
1234 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (bothTypes) { |
1235 | // Factor out any common prefixies. | |
1236 | commonlength = this.diffCommonPrefix(textInsert.toString(), textDelete.toString()); | |
1237 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (commonlength != 0) { |
1238 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (pointer.hasPrevious()) { |
1239 | thisDiff = pointer.previous(); | |
1240 | // Previous diff should have been an equality: thisDiff.getOperation() == Operation.EQUAL") | |
1241 |
1
1. diffCleanupMerge : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
thisDiff.setText(thisDiff.getText() + textInsert.substring(0, commonlength)); |
1242 | pointer.next(); | |
1243 | } else { | |
1244 |
1
1. diffCleanupMerge : removed call to java/util/ListIterator::add → NO_COVERAGE |
pointer.add(new Diff(Operation.EQUAL, |
1245 | textInsert.substring(0, commonlength))); | |
1246 | } | |
1247 | String substringIns = textInsert.substring(commonlength); | |
1248 |
1
1. diffCleanupMerge : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
textInsert.setLength(0); |
1249 | textInsert.append(substringIns); | |
1250 | String substringDel = textDelete.substring(commonlength); | |
1251 |
1
1. diffCleanupMerge : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
textDelete.setLength(0); |
1252 | textDelete.append(substringDel); | |
1253 | } | |
1254 | // Factor out any common suffixies. | |
1255 | commonlength = this.diffCommonSuffix(textInsert.toString(), textDelete.toString()); | |
1256 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (commonlength != 0) { |
1257 | thisDiff = pointer.next(); | |
1258 |
2
1. diffCleanupMerge : Replaced integer subtraction with addition → NO_COVERAGE 2. diffCleanupMerge : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
thisDiff.setText(textInsert.substring(textInsert.length() - commonlength) + thisDiff.getText()); |
1259 |
1
1. diffCleanupMerge : Replaced integer subtraction with addition → NO_COVERAGE |
String substringIns = textInsert.substring(0, textInsert.length() - commonlength); |
1260 |
1
1. diffCleanupMerge : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
textInsert.setLength(0); |
1261 | textInsert.append(substringIns); | |
1262 |
1
1. diffCleanupMerge : Replaced integer subtraction with addition → NO_COVERAGE |
String substringDel = textDelete.substring(0, textDelete.length() - commonlength); |
1263 |
1
1. diffCleanupMerge : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
textDelete.setLength(0); |
1264 | textDelete.append(substringDel); | |
1265 | pointer.previous(); | |
1266 | } | |
1267 | } | |
1268 | // Insert the merged records. | |
1269 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (textDelete.length() != 0) { |
1270 |
1
1. diffCleanupMerge : removed call to java/util/ListIterator::add → NO_COVERAGE |
pointer.add(new Diff(Operation.DELETE, textDelete.toString())); |
1271 | } | |
1272 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (textInsert.length() != 0) { |
1273 |
1
1. diffCleanupMerge : removed call to java/util/ListIterator::add → NO_COVERAGE |
pointer.add(new Diff(Operation.INSERT, textInsert.toString())); |
1274 | } | |
1275 | // Step forward to the equality. | |
1276 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
thisDiff = pointer.hasNext() ? pointer.next() : null; |
1277 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
} else if (prevEqual != null) { |
1278 | // Merge this equality with the previous one. | |
1279 |
1
1. diffCleanupMerge : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
prevEqual.setText(prevEqual.getText() + thisDiff.getText()); |
1280 |
1
1. diffCleanupMerge : removed call to java/util/ListIterator::remove → NO_COVERAGE |
pointer.remove(); |
1281 | thisDiff = pointer.previous(); | |
1282 | pointer.next(); // Forward direction | |
1283 | } | |
1284 | countInsert = 0; | |
1285 | countDelete = 0; | |
1286 |
1
1. diffCleanupMerge : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
textDelete.setLength(0); |
1287 |
1
1. diffCleanupMerge : removed call to java/lang/StringBuilder::setLength → NO_COVERAGE |
textInsert.setLength(0); |
1288 | prevEqual = thisDiff; | |
1289 | break; | |
1290 | } | |
1291 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
thisDiff = pointer.hasNext() ? pointer.next() : null; |
1292 | } | |
1293 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (diffs.getLast().getText().isEmpty()) { |
1294 | diffs.removeLast(); // Remove the dummy entry at the end. | |
1295 | } | |
1296 | ||
1297 | /* | |
1298 | * Second pass: look for single edits surrounded on both sides by equalities | |
1299 | * which can be shifted sideways to eliminate an equality. | |
1300 | * e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC | |
1301 | */ | |
1302 | boolean changes = false; | |
1303 | // Create a new iterator at the start. | |
1304 | // (As opposed to walking the current one back.) | |
1305 | pointer = diffs.listIterator(); | |
1306 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
Diff prevDiff = pointer.hasNext() ? pointer.next() : null; |
1307 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
thisDiff = pointer.hasNext() ? pointer.next() : null; |
1308 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
Diff nextDiff = pointer.hasNext() ? pointer.next() : null; |
1309 | ||
1310 | // Intentionally ignore the first and last element (don't need checking). | |
1311 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
while (nextDiff != null) { |
1312 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (prevDiff.getOperation() == Operation.EQUAL && |
1313 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
nextDiff.getOperation() == Operation.EQUAL) { |
1314 | // This is a single edit surrounded by equalities. | |
1315 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (thisDiff.getText().endsWith(prevDiff.getText())) { |
1316 | // Shift the edit over the previous equality. | |
1317 |
1
1. diffCleanupMerge : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
thisDiff.setText(prevDiff.getText() |
1318 | + thisDiff.getText().substring(0, thisDiff.getText().length() | |
1319 |
1
1. diffCleanupMerge : Replaced integer subtraction with addition → NO_COVERAGE |
- prevDiff.getText().length())); |
1320 |
1
1. diffCleanupMerge : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
nextDiff.setText(prevDiff.getText() + nextDiff.getText()); |
1321 | pointer.previous(); // Walk past nextDiff. | |
1322 | pointer.previous(); // Walk past thisDiff. | |
1323 | pointer.previous(); // Walk past prevDiff. | |
1324 |
1
1. diffCleanupMerge : removed call to java/util/ListIterator::remove → NO_COVERAGE |
pointer.remove(); // Delete prevDiff. |
1325 | pointer.next(); // Walk past thisDiff. | |
1326 | thisDiff = pointer.next(); // Walk past nextDiff. | |
1327 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
nextDiff = pointer.hasNext() ? pointer.next() : null; |
1328 | changes = true; | |
1329 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
} else if (thisDiff.getText().startsWith(nextDiff.getText())) { |
1330 | // Shift the edit over the next equality. | |
1331 |
1
1. diffCleanupMerge : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
prevDiff.setText(prevDiff.getText() + nextDiff.getText()); |
1332 |
1
1. diffCleanupMerge : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
thisDiff.setText(thisDiff.getText().substring(nextDiff.getText().length()) |
1333 | + nextDiff.getText()); | |
1334 |
1
1. diffCleanupMerge : removed call to java/util/ListIterator::remove → NO_COVERAGE |
pointer.remove(); // Delete nextDiff. |
1335 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
nextDiff = pointer.hasNext() ? pointer.next() : null; |
1336 | changes = true; | |
1337 | } | |
1338 | } | |
1339 | prevDiff = thisDiff; | |
1340 | thisDiff = nextDiff; | |
1341 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
nextDiff = pointer.hasNext() ? pointer.next() : null; |
1342 | } | |
1343 | // If shifts were made, the diff needs reordering and another shift sweep. | |
1344 |
1
1. diffCleanupMerge : negated conditional → NO_COVERAGE |
if (changes) { |
1345 |
1
1. diffCleanupMerge : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupMerge → NO_COVERAGE |
this.diffCleanupMerge(diffs); |
1346 | } | |
1347 | } | |
1348 | ||
1349 | /** | |
1350 | * loc is a location in text1, compute and return the equivalent location in | |
1351 | * text2. | |
1352 | * e.g. "The cat" vs "The big cat", 1->1, 5->8 | |
1353 | * @param diffs List of Diff objects. | |
1354 | * @param loc Location within text1. | |
1355 | * @return Location within text2. | |
1356 | */ | |
1357 | public int diffXIndex(List<Diff> diffs, int loc) { | |
1358 | ||
1359 | int chars1 = 0; | |
1360 | int chars2 = 0; | |
1361 | int lastChars1 = 0; | |
1362 | int lastChars2 = 0; | |
1363 | Diff lastDiff = null; | |
1364 | for (Diff aDiff : diffs) { | |
1365 |
1
1. diffXIndex : negated conditional → NO_COVERAGE |
if (aDiff.getOperation() != Operation.INSERT) { |
1366 | // Equality or deletion. | |
1367 |
1
1. diffXIndex : Replaced integer addition with subtraction → NO_COVERAGE |
chars1 += aDiff.getText().length(); |
1368 | } | |
1369 |
1
1. diffXIndex : negated conditional → NO_COVERAGE |
if (aDiff.getOperation() != Operation.DELETE) { |
1370 | // Equality or insertion. | |
1371 |
1
1. diffXIndex : Replaced integer addition with subtraction → NO_COVERAGE |
chars2 += aDiff.getText().length(); |
1372 | } | |
1373 |
2
1. diffXIndex : negated conditional → NO_COVERAGE 2. diffXIndex : changed conditional boundary → NO_COVERAGE |
if (chars1 > loc) { |
1374 | // Overshot the location. | |
1375 | lastDiff = aDiff; | |
1376 | break; | |
1377 | } | |
1378 | lastChars1 = chars1; | |
1379 | lastChars2 = chars2; | |
1380 | } | |
1381 |
2
1. diffXIndex : negated conditional → NO_COVERAGE 2. diffXIndex : negated conditional → NO_COVERAGE |
if (lastDiff != null && lastDiff.getOperation() == Operation.DELETE) { |
1382 | // The location was deleted. | |
1383 |
1
1. diffXIndex : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffXIndex → NO_COVERAGE |
return lastChars2; |
1384 | } | |
1385 | // Add the remaining character length. | |
1386 |
3
1. diffXIndex : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffXIndex → NO_COVERAGE 2. diffXIndex : Replaced integer subtraction with addition → NO_COVERAGE 3. diffXIndex : Replaced integer addition with subtraction → NO_COVERAGE |
return lastChars2 + (loc - lastChars1); |
1387 | } | |
1388 | ||
1389 | /** | |
1390 | * Convert a Diff list into a pretty HTML report. | |
1391 | * @param diffs List of Diff objects. | |
1392 | * @return HTML representation. | |
1393 | */ | |
1394 | public String diffPrettyHtml(List<Diff> diffs) { | |
1395 | ||
1396 | StringBuilder html = new StringBuilder(); | |
1397 | for (Diff aDiff : diffs) { | |
1398 | String text = aDiff.getText().replace("&", "&").replace("<", "<") | |
1399 | .replace(">", ">").replace("\n", "¶<br>"); | |
1400 | switch (aDiff.getOperation()) { | |
1401 | case INSERT: | |
1402 | html.append("<ins style=\"background:#e6ffe6;\">").append(text) | |
1403 | .append("</ins>"); | |
1404 | break; | |
1405 | case DELETE: | |
1406 | html.append("<del style=\"background:#ffe6e6;\">").append(text) | |
1407 | .append("</del>"); | |
1408 | break; | |
1409 | case EQUAL: | |
1410 | html.append("<span>").append(text).append("</span>"); | |
1411 | break; | |
1412 | } | |
1413 | } | |
1414 |
1
1. diffPrettyHtml : replaced return value with "" for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffPrettyHtml → NO_COVERAGE |
return html.toString(); |
1415 | } | |
1416 | ||
1417 | /** | |
1418 | * Compute and return the source text (all equalities and deletions). | |
1419 | * @param diffs List of Diff objects. | |
1420 | * @return Source text. | |
1421 | */ | |
1422 | public String diffText1(List<Diff> diffs) { | |
1423 | ||
1424 | StringBuilder text = new StringBuilder(); | |
1425 | for (Diff aDiff : diffs) { | |
1426 |
1
1. diffText1 : negated conditional → NO_COVERAGE |
if (aDiff.getOperation() != Operation.INSERT) { |
1427 | text.append(aDiff.getText()); | |
1428 | } | |
1429 | } | |
1430 |
1
1. diffText1 : replaced return value with "" for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffText1 → NO_COVERAGE |
return text.toString(); |
1431 | } | |
1432 | ||
1433 | /** | |
1434 | * Compute and return the destination text (all equalities and insertions). | |
1435 | * @param diffs List of Diff objects. | |
1436 | * @return Destination text. | |
1437 | */ | |
1438 | public String diffText2(List<Diff> diffs) { | |
1439 | ||
1440 | StringBuilder text = new StringBuilder(); | |
1441 | for (Diff aDiff : diffs) { | |
1442 |
1
1. diffText2 : negated conditional → NO_COVERAGE |
if (aDiff.getOperation() != Operation.DELETE) { |
1443 | text.append(aDiff.getText()); | |
1444 | } | |
1445 | } | |
1446 |
1
1. diffText2 : replaced return value with "" for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffText2 → NO_COVERAGE |
return text.toString(); |
1447 | } | |
1448 | ||
1449 | /** | |
1450 | * Compute the Levenshtein distance; the number of inserted, deleted or | |
1451 | * substituted characters. | |
1452 | * @param diffs List of Diff objects. | |
1453 | * @return Number of changes. | |
1454 | */ | |
1455 | public int diffLevenshtein(List<Diff> diffs) { | |
1456 | ||
1457 | int levenshtein = 0; | |
1458 | int insertions = 0; | |
1459 | int deletions = 0; | |
1460 | for (Diff aDiff : diffs) { | |
1461 | switch (aDiff.getOperation()) { | |
1462 | case INSERT: | |
1463 |
1
1. diffLevenshtein : Replaced integer addition with subtraction → NO_COVERAGE |
insertions += aDiff.getText().length(); |
1464 | break; | |
1465 | case DELETE: | |
1466 |
1
1. diffLevenshtein : Replaced integer addition with subtraction → NO_COVERAGE |
deletions += aDiff.getText().length(); |
1467 | break; | |
1468 | case EQUAL: | |
1469 | // A deletion and an insertion is one substitution. | |
1470 |
1
1. diffLevenshtein : Replaced integer addition with subtraction → NO_COVERAGE |
levenshtein += Math.max(insertions, deletions); |
1471 | insertions = 0; | |
1472 | deletions = 0; | |
1473 | break; | |
1474 | } | |
1475 | } | |
1476 |
1
1. diffLevenshtein : Replaced integer addition with subtraction → NO_COVERAGE |
levenshtein += Math.max(insertions, deletions); |
1477 |
1
1. diffLevenshtein : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffLevenshtein → NO_COVERAGE |
return levenshtein; |
1478 | } | |
1479 | ||
1480 | /** | |
1481 | * Crush the diff into an encoded string which describes the operations | |
1482 | * required to transform text1 into text2. | |
1483 | * E.g. =3\t-2\t+ing -> Keep 3 chars, delete 2 chars, insert 'ing'. | |
1484 | * Operations are tab-separated. Inserted text is escaped using %xx notation. | |
1485 | * @param diffs Array of Diff objects. | |
1486 | * @return Delta text. | |
1487 | */ | |
1488 | public String diffToDelta(List<Diff> diffs) { | |
1489 | ||
1490 | StringBuilder text = new StringBuilder(); | |
1491 | for (Diff aDiff : diffs) { | |
1492 | switch (aDiff.getOperation()) { | |
1493 | case INSERT: | |
1494 | text.append("+").append(URLEncoder.encode(aDiff.getText(), StandardCharsets.UTF_8) | |
1495 | .replace('+', ' ')).append("\t"); | |
1496 | break; | |
1497 | case DELETE: | |
1498 | text.append("-").append(aDiff.getText().length()).append("\t"); | |
1499 | break; | |
1500 | case EQUAL: | |
1501 | text.append("=").append(aDiff.getText().length()).append("\t"); | |
1502 | break; | |
1503 | } | |
1504 | } | |
1505 | String delta = text.toString(); | |
1506 |
1
1. diffToDelta : negated conditional → NO_COVERAGE |
if (!delta.isEmpty()) { |
1507 | // Strip off trailing tab character. | |
1508 |
1
1. diffToDelta : Replaced integer subtraction with addition → NO_COVERAGE |
delta = delta.substring(0, delta.length() - 1); |
1509 | delta = Patch.unescapeForEncodeUriCompatability(delta); | |
1510 | } | |
1511 |
1
1. diffToDelta : replaced return value with "" for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffToDelta → NO_COVERAGE |
return delta; |
1512 | } | |
1513 | ||
1514 | /** | |
1515 | * Given the original text1, and an encoded string which describes the | |
1516 | * operations required to transform text1 into text2, compute the full diff. | |
1517 | * @param text1 Source string for the diff. | |
1518 | * @param delta Delta text. | |
1519 | * @return Array of Diff objects or null if invalid. | |
1520 | */ | |
1521 | public List<Diff> diffFromDelta(String text1, String delta) { | |
1522 | ||
1523 | List<Diff> diffs = new LinkedList<>(); | |
1524 | int pointer = 0; // Cursor in text1 | |
1525 | String[] tokens = delta.split("\t"); | |
1526 | ||
1527 | for (String token : tokens) { | |
1528 |
1
1. diffFromDelta : negated conditional → NO_COVERAGE |
if (token.isEmpty()) { |
1529 | // Blank tokens are ok (from a trailing \t). | |
1530 | continue; | |
1531 | } | |
1532 | // Each token begins with a one character parameter which specifies the | |
1533 | // operation of this token (delete, insert, equality). | |
1534 | String param = token.substring(1); | |
1535 | switch (token.charAt(0)) { | |
1536 | case '+': | |
1537 | // decode would change all "+" to " " | |
1538 | param = param.replace("+", "%2B"); | |
1539 | try { | |
1540 | param = URLDecoder.decode(param, StandardCharsets.UTF_8); | |
1541 | } catch (IllegalArgumentException e) { | |
1542 | // Malformed URI sequence. | |
1543 | throw new IllegalArgumentException( | |
1544 | "Illegal escape in diff_fromDelta: " + param, e); | |
1545 | } | |
1546 | diffs.add(new Diff(Operation.INSERT, param)); | |
1547 | break; | |
1548 | case '-': | |
1549 | // Fall through. | |
1550 | case '=': | |
1551 | int n; | |
1552 | try { | |
1553 | n = Integer.parseInt(param); | |
1554 | } catch (NumberFormatException e) { | |
1555 | throw new IllegalArgumentException( | |
1556 | "Invalid number in diff_fromDelta: " + param, e); | |
1557 | } | |
1558 |
2
1. diffFromDelta : changed conditional boundary → NO_COVERAGE 2. diffFromDelta : negated conditional → NO_COVERAGE |
if (n < 0) { |
1559 | throw new IllegalArgumentException( | |
1560 | "Negative number in diff_fromDelta: " + param); | |
1561 | } | |
1562 | String text; | |
1563 | try { | |
1564 | int p1 = pointer; | |
1565 |
1
1. diffFromDelta : Replaced integer addition with subtraction → NO_COVERAGE |
pointer += n; |
1566 | int p2 = pointer; | |
1567 | text = text1.substring(p1, p2); | |
1568 | } catch (StringIndexOutOfBoundsException e) { | |
1569 | throw new IllegalArgumentException("Delta length (" + pointer | |
1570 | + ") larger than source text length (" + text1.length() | |
1571 | + ").", e); | |
1572 | } | |
1573 |
1
1. diffFromDelta : negated conditional → NO_COVERAGE |
if (token.charAt(0) == '=') { |
1574 | diffs.add(new Diff(Operation.EQUAL, text)); | |
1575 | } else { | |
1576 | diffs.add(new Diff(Operation.DELETE, text)); | |
1577 | } | |
1578 | break; | |
1579 | default: | |
1580 | // Anything else is an error. | |
1581 | throw new IllegalArgumentException( | |
1582 | "Invalid diff operation in diff_fromDelta: " + token.charAt(0)); | |
1583 | } | |
1584 | } | |
1585 |
1
1. diffFromDelta : negated conditional → NO_COVERAGE |
if (pointer != text1.length()) { |
1586 | throw new IllegalArgumentException("Delta length (" + pointer | |
1587 | + ") smaller than source text length (" + text1.length() + ")."); | |
1588 | } | |
1589 |
1
1. diffFromDelta : replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffFromDelta → NO_COVERAGE |
return diffs; |
1590 | } | |
1591 | ||
1592 | ||
1593 | // MATCH FUNCTIONS | |
1594 | ||
1595 | /** | |
1596 | * Locate the best instance of 'pattern' in 'text' near 'loc'. | |
1597 | * Returns -1 if no match found. | |
1598 | * @param text The text to search. | |
1599 | * @param pattern The pattern to search for. | |
1600 | * @param valueLoc The location to search around. | |
1601 | * @return Best match index or -1. | |
1602 | */ | |
1603 | public int matchMain(String text, String pattern, int valueLoc) { | |
1604 | ||
1605 | // Check for null inputs. | |
1606 |
2
1. matchMain : negated conditional → NO_COVERAGE 2. matchMain : negated conditional → NO_COVERAGE |
if (text == null || pattern == null) { |
1607 | throw new IllegalArgumentException("Null inputs. (match_main)"); | |
1608 | } | |
1609 | ||
1610 | int loc = Math.max(0, Math.min(valueLoc, text.length())); | |
1611 |
1
1. matchMain : negated conditional → NO_COVERAGE |
if (text.equals(pattern)) { |
1612 | // Shortcut (potentially not guaranteed by the algorithm) | |
1613 | return 0; | |
1614 |
1
1. matchMain : negated conditional → NO_COVERAGE |
} else if (text.isEmpty()) { |
1615 | // Nothing to match. | |
1616 |
1
1. matchMain : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::matchMain → NO_COVERAGE |
return -1; |
1617 |
3
1. matchMain : negated conditional → NO_COVERAGE 2. matchMain : changed conditional boundary → NO_COVERAGE 3. matchMain : Replaced integer addition with subtraction → NO_COVERAGE |
} else if (loc + pattern.length() <= text.length() |
1618 |
2
1. matchMain : negated conditional → NO_COVERAGE 2. matchMain : Replaced integer addition with subtraction → NO_COVERAGE |
&& text.substring(loc, loc + pattern.length()).equals(pattern)) { |
1619 | // Perfect match at the perfect spot! (Includes case of null pattern) | |
1620 |
1
1. matchMain : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::matchMain → NO_COVERAGE |
return loc; |
1621 | } else { | |
1622 | // Do a fuzzy compare. | |
1623 |
1
1. matchMain : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::matchMain → NO_COVERAGE |
return this.matchBitap(text, pattern, loc); |
1624 | } | |
1625 | } | |
1626 | ||
1627 | /** | |
1628 | * Locate the best instance of 'pattern' in 'text' near 'loc' using the | |
1629 | * Bitap algorithm. Returns -1 if no match found. | |
1630 | * @param text The text to search. | |
1631 | * @param pattern The pattern to search for. | |
1632 | * @param loc The location to search around. | |
1633 | * @return Best match index or -1. | |
1634 | */ | |
1635 | protected int matchBitap(String text, String pattern, int loc) { | |
1636 | ||
1637 | // Initialise the alphabet. | |
1638 | Map<Character, Integer> s = this.matchAlphabet(pattern); | |
1639 | ||
1640 | // Highest score beyond which we give up. | |
1641 | double scoreThreshold = MATCH_THRESHOLD; | |
1642 | // Is there a nearby exact match? (speedup) | |
1643 | int bestLoc = text.indexOf(pattern, loc); | |
1644 |
1
1. matchBitap : negated conditional → NO_COVERAGE |
if (bestLoc != -1) { |
1645 | scoreThreshold = Math.min(this.matchBitapScore(0, bestLoc, loc, pattern), | |
1646 | scoreThreshold); | |
1647 | // What about in the other direction? (speedup) | |
1648 |
1
1. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE |
bestLoc = text.lastIndexOf(pattern, loc + pattern.length()); |
1649 |
1
1. matchBitap : negated conditional → NO_COVERAGE |
if (bestLoc != -1) { |
1650 | scoreThreshold = Math.min(this.matchBitapScore(0, bestLoc, loc, pattern), | |
1651 | scoreThreshold); | |
1652 | } | |
1653 | } | |
1654 | ||
1655 | // Initialise the bit arrays. | |
1656 |
2
1. matchBitap : Replaced Shift Left with Shift Right → NO_COVERAGE 2. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE |
int matchmask = 1 << (pattern.length() - 1); |
1657 | bestLoc = -1; | |
1658 | ||
1659 | int binMin; | |
1660 | int binMid; | |
1661 |
1
1. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE |
int binMax = pattern.length() + text.length(); |
1662 | // Empty initialization added to appease Java compiler. | |
1663 | int[] lastRd = new int[0]; | |
1664 |
2
1. matchBitap : changed conditional boundary → NO_COVERAGE 2. matchBitap : negated conditional → NO_COVERAGE |
for (int d = 0; d < pattern.length(); d++) { |
1665 | ||
1666 | // Scan for the best match; each iteration allows for one more error. | |
1667 | // Run a binary search to determine how far from 'loc' we can stray at | |
1668 | // this error level. | |
1669 | binMin = 0; | |
1670 | binMid = binMax; | |
1671 |
2
1. matchBitap : negated conditional → NO_COVERAGE 2. matchBitap : changed conditional boundary → NO_COVERAGE |
while (binMin < binMid) { |
1672 |
3
1. matchBitap : negated conditional → NO_COVERAGE 2. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE 3. matchBitap : changed conditional boundary → NO_COVERAGE |
if (this.matchBitapScore(d, loc + binMid, loc, pattern) |
1673 | <= scoreThreshold) { | |
1674 | binMin = binMid; | |
1675 | } else { | |
1676 | binMax = binMid; | |
1677 | } | |
1678 |
3
1. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE 2. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE 3. matchBitap : Replaced integer division with multiplication → NO_COVERAGE |
binMid = (binMax - binMin) / 2 + binMin; |
1679 | } | |
1680 | // Use the result from this iteration as the maximum for the next. | |
1681 | binMax = binMid; | |
1682 |
2
1. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE 2. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE |
int start = Math.max(1, loc - binMid + 1); |
1683 |
2
1. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE 2. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE |
int finish = Math.min(loc + binMid, text.length()) + pattern.length(); |
1684 | ||
1685 |
1
1. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE |
int[] rd = new int[finish + 2]; |
1686 |
3
1. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE 2. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE 3. matchBitap : Replaced Shift Left with Shift Right → NO_COVERAGE |
rd[finish + 1] = (1 << d) - 1; |
1687 |
2
1. matchBitap : negated conditional → NO_COVERAGE 2. matchBitap : changed conditional boundary → NO_COVERAGE |
for (int j = finish; j >= start; j--) { |
1688 | ||
1689 | int charMatch; | |
1690 |
5
1. matchBitap : changed conditional boundary → NO_COVERAGE 2. matchBitap : negated conditional → NO_COVERAGE 3. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE 4. matchBitap : negated conditional → NO_COVERAGE 5. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE |
if (text.length() <= j - 1 || !s.containsKey(text.charAt(j - 1))) { |
1691 | // Out of range. | |
1692 | charMatch = 0; | |
1693 | } else { | |
1694 |
1
1. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE |
charMatch = s.get(text.charAt(j - 1)); |
1695 | } | |
1696 |
1
1. matchBitap : negated conditional → NO_COVERAGE |
if (d == 0) { |
1697 | // First pass: exact match. | |
1698 |
4
1. matchBitap : Replaced bitwise AND with OR → NO_COVERAGE 2. matchBitap : Replaced bitwise OR with AND → NO_COVERAGE 3. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE 4. matchBitap : Replaced Shift Left with Shift Right → NO_COVERAGE |
rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; |
1699 | } else { | |
1700 | // Subsequent passes: fuzzy match. | |
1701 |
11
1. matchBitap : Replaced Shift Left with Shift Right → NO_COVERAGE 2. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE 3. matchBitap : Replaced bitwise OR with AND → NO_COVERAGE 4. matchBitap : Replaced bitwise OR with AND → NO_COVERAGE 5. matchBitap : Replaced bitwise OR with AND → NO_COVERAGE 6. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE 7. matchBitap : Replaced Shift Left with Shift Right → NO_COVERAGE 8. matchBitap : Replaced bitwise OR with AND → NO_COVERAGE 9. matchBitap : Replaced bitwise AND with OR → NO_COVERAGE 10. matchBitap : Replaced bitwise OR with AND → NO_COVERAGE 11. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE |
rd[j] = (((rd[j + 1] << 1) | 1) & charMatch) |
1702 | | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1]; | |
1703 | } | |
1704 | ||
1705 |
2
1. matchBitap : negated conditional → NO_COVERAGE 2. matchBitap : Replaced bitwise AND with OR → NO_COVERAGE |
if ((rd[j] & matchmask) != 0) { |
1706 |
1
1. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE |
double score = this.matchBitapScore(d, j - 1, loc, pattern); |
1707 | // This match will almost certainly be better than any existing | |
1708 | // match. But check anyway. | |
1709 |
2
1. matchBitap : negated conditional → NO_COVERAGE 2. matchBitap : changed conditional boundary → NO_COVERAGE |
if (score <= scoreThreshold) { |
1710 | // Told you so. | |
1711 | scoreThreshold = score; | |
1712 |
1
1. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE |
bestLoc = j - 1; |
1713 |
2
1. matchBitap : changed conditional boundary → NO_COVERAGE 2. matchBitap : negated conditional → NO_COVERAGE |
if (bestLoc > loc) { |
1714 | // When passing loc, don't exceed our current distance from loc. | |
1715 |
2
1. matchBitap : Replaced integer subtraction with addition → NO_COVERAGE 2. matchBitap : Replaced integer multiplication with division → NO_COVERAGE |
start = Math.max(1, 2 * loc - bestLoc); |
1716 | } else { | |
1717 | // Already passed loc, downhill from here on in. | |
1718 | break; | |
1719 | } | |
1720 | } | |
1721 | } | |
1722 | } | |
1723 |
3
1. matchBitap : changed conditional boundary → NO_COVERAGE 2. matchBitap : negated conditional → NO_COVERAGE 3. matchBitap : Replaced integer addition with subtraction → NO_COVERAGE |
if (this.matchBitapScore(d + 1, loc, loc, pattern) > scoreThreshold) { |
1724 | // No hope for a (better) match at greater error levels. | |
1725 | break; | |
1726 | } | |
1727 | lastRd = rd; | |
1728 | } | |
1729 |
1
1. matchBitap : replaced int return with 0 for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::matchBitap → NO_COVERAGE |
return bestLoc; |
1730 | } | |
1731 | ||
1732 | /** | |
1733 | * Compute and return the score for a match with e errors and x location. | |
1734 | * @param e Number of errors in match. | |
1735 | * @param x Location of match. | |
1736 | * @param loc Expected location of match. | |
1737 | * @param pattern Pattern being sought. | |
1738 | * @return Overall score for match (0.0 = good, 1.0 = bad). | |
1739 | */ | |
1740 | private double matchBitapScore(int e, int x, int loc, String pattern) { | |
1741 | ||
1742 |
1
1. matchBitapScore : Replaced float division with multiplication → NO_COVERAGE |
float accuracy = (float) e / pattern.length(); |
1743 |
1
1. matchBitapScore : Replaced integer subtraction with addition → NO_COVERAGE |
int proximity = Math.abs(loc - x); |
1744 |
3
1. matchBitapScore : Replaced float addition with subtraction → NO_COVERAGE 2. matchBitapScore : Replaced float division with multiplication → NO_COVERAGE 3. matchBitapScore : replaced double return with 0.0d for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::matchBitapScore → NO_COVERAGE |
return accuracy + (proximity / (float) MATCH_DISTANCE); |
1745 | } | |
1746 | ||
1747 | /** | |
1748 | * Initialise the alphabet for the Bitap algorithm. | |
1749 | * @param pattern The text to encode. | |
1750 | * @return Hash of character locations. | |
1751 | */ | |
1752 | protected Map<Character, Integer> matchAlphabet(String pattern) { | |
1753 | ||
1754 | Map<Character, Integer> s = new HashMap<>(); | |
1755 | char[] charPattern = pattern.toCharArray(); | |
1756 | for (char c : charPattern) { | |
1757 | s.put(c, 0); | |
1758 | } | |
1759 | int i = 0; | |
1760 | for (char c : charPattern) { | |
1761 |
4
1. matchAlphabet : Replaced bitwise OR with AND → NO_COVERAGE 2. matchAlphabet : Replaced Shift Left with Shift Right → NO_COVERAGE 3. matchAlphabet : Replaced integer subtraction with addition → NO_COVERAGE 4. matchAlphabet : Replaced integer subtraction with addition → NO_COVERAGE |
s.put(c, s.get(c) | (1 << (pattern.length() - i - 1))); |
1762 |
1
1. matchAlphabet : Changed increment from 1 to -1 → NO_COVERAGE |
i++; |
1763 | } | |
1764 |
1
1. matchAlphabet : replaced return value with Collections.emptyMap for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::matchAlphabet → NO_COVERAGE |
return s; |
1765 | } | |
1766 | ||
1767 | ||
1768 | // PATCH FUNCTIONS | |
1769 | ||
1770 | /** | |
1771 | * Increase the context until it is unique, | |
1772 | * but don't let the pattern expand beyond Match_MaxBits. | |
1773 | * @param patch The patch to grow. | |
1774 | * @param text Source text. | |
1775 | */ | |
1776 | protected void patchAddContext(Patch patch, String text) { | |
1777 | ||
1778 |
1
1. patchAddContext : negated conditional → NO_COVERAGE |
if (text.isEmpty()) { |
1779 | return; | |
1780 | } | |
1781 |
1
1. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE |
String pattern = text.substring(patch.getStart2(), patch.getStart2() + patch.getLength1()); |
1782 | int padding = 0; | |
1783 | ||
1784 | // Look for the first and last matches of pattern in text. If two different | |
1785 | // matches are found, increase the pattern length. | |
1786 |
1
1. patchAddContext : negated conditional → NO_COVERAGE |
while (text.indexOf(pattern) != text.lastIndexOf(pattern) |
1787 |
2
1. patchAddContext : negated conditional → NO_COVERAGE 2. patchAddContext : changed conditional boundary → NO_COVERAGE |
&& pattern.length() < DiffMatchPatch.MATCH_MAX_BITS - PATCH_MARGIN - PATCH_MARGIN) { |
1788 |
1
1. patchAddContext : Changed increment from 4 to -4 → NO_COVERAGE |
padding += PATCH_MARGIN; |
1789 |
1
1. patchAddContext : Replaced integer subtraction with addition → NO_COVERAGE |
pattern = text.substring(Math.max(0, patch.getStart2() - padding), |
1790 |
2
1. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE 2. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE |
Math.min(text.length(), patch.getStart2() + patch.getLength1() + padding)); |
1791 | } | |
1792 | // Add one chunk for good luck. | |
1793 |
1
1. patchAddContext : Changed increment from 4 to -4 → NO_COVERAGE |
padding += PATCH_MARGIN; |
1794 | ||
1795 | // Add the prefix. | |
1796 |
1
1. patchAddContext : Replaced integer subtraction with addition → NO_COVERAGE |
String prefix = text.substring(Math.max(0, patch.getStart2() - padding), |
1797 | patch.getStart2()); | |
1798 |
1
1. patchAddContext : negated conditional → NO_COVERAGE |
if (!prefix.isEmpty()) { |
1799 |
1
1. patchAddContext : removed call to java/util/LinkedList::addFirst → NO_COVERAGE |
patch.getDiffs().addFirst(new Diff(Operation.EQUAL, prefix)); |
1800 | } | |
1801 | // Add the suffix. | |
1802 |
1
1. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE |
String suffix = text.substring(patch.getStart2() + patch.getLength1(), |
1803 |
2
1. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE 2. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE |
Math.min(text.length(), patch.getStart2() + patch.getLength1() + padding)); |
1804 |
1
1. patchAddContext : negated conditional → NO_COVERAGE |
if (!suffix.isEmpty()) { |
1805 |
1
1. patchAddContext : removed call to java/util/LinkedList::addLast → NO_COVERAGE |
patch.getDiffs().addLast(new Diff(Operation.EQUAL, suffix)); |
1806 | } | |
1807 | ||
1808 | // Roll back the start points. | |
1809 |
2
1. patchAddContext : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE 2. patchAddContext : Replaced integer subtraction with addition → NO_COVERAGE |
patch.setStart1(patch.getStart1() - prefix.length()); |
1810 |
2
1. patchAddContext : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE 2. patchAddContext : Replaced integer subtraction with addition → NO_COVERAGE |
patch.setStart2(patch.getStart2() - prefix.length()); |
1811 | // Extend the lengths. | |
1812 |
3
1. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE 2. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE 3. patchAddContext : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(patch.getLength1() + prefix.length() + suffix.length()); |
1813 |
2
1. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE 2. patchAddContext : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + prefix.length() + suffix.length()); |
1814 | } | |
1815 | ||
1816 | /** | |
1817 | * Compute a list of patches to turn text1 into text2. | |
1818 | * A set of diffs will be computed. | |
1819 | * @param text1 Old text. | |
1820 | * @param text2 New text. | |
1821 | * @return LinkedList of Patch objects. | |
1822 | */ | |
1823 | public List<Patch> patchMake(String text1, String text2) { | |
1824 | ||
1825 |
2
1. patchMake : negated conditional → NO_COVERAGE 2. patchMake : negated conditional → NO_COVERAGE |
if (text1 == null || text2 == null) { |
1826 | throw new IllegalArgumentException("Null inputs. (patch_make)"); | |
1827 | } | |
1828 | // No diffs provided, compute our own. | |
1829 | LinkedList<Diff> diffs = this.diffMain(text1, text2, true); | |
1830 |
2
1. patchMake : changed conditional boundary → NO_COVERAGE 2. patchMake : negated conditional → NO_COVERAGE |
if (diffs.size() > 2) { |
1831 |
1
1. patchMake : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemantic → NO_COVERAGE |
this.diffCleanupSemantic(diffs); |
1832 |
1
1. patchMake : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupEfficiency → NO_COVERAGE |
this.diffCleanupEfficiency(diffs); |
1833 | } | |
1834 |
1
1. patchMake : replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchMake → NO_COVERAGE |
return this.patchMake(text1, diffs); |
1835 | } | |
1836 | ||
1837 | /** | |
1838 | * Compute a list of patches to turn text1 into text2. | |
1839 | * text1 will be derived from the provided diffs. | |
1840 | * @param diffs Array of Diff objects for text1 to text2. | |
1841 | * @return LinkedList of Patch objects. | |
1842 | */ | |
1843 | public List<Patch> patchMake(LinkedList<Diff> diffs) { | |
1844 | ||
1845 |
1
1. patchMake : negated conditional → NO_COVERAGE |
if (diffs == null) { |
1846 | throw new IllegalArgumentException("Null inputs. (patch_make)"); | |
1847 | } | |
1848 | // No origin string provided, compute our own. | |
1849 | String text1 = this.diffText1(diffs); | |
1850 |
1
1. patchMake : replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchMake → NO_COVERAGE |
return this.patchMake(text1, diffs); |
1851 | } | |
1852 | ||
1853 | /** | |
1854 | * Compute a list of patches to turn text1 into text2. | |
1855 | * text2 is not provided, diffs are the delta between text1 and text2. | |
1856 | * @param text1 Old text. | |
1857 | * @param diffs Array of Diff objects for text1 to text2. | |
1858 | * @return Deque of Patch objects. | |
1859 | */ | |
1860 | public List<Patch> patchMake(String text1, Deque<Diff> diffs) { | |
1861 | ||
1862 |
2
1. patchMake : negated conditional → NO_COVERAGE 2. patchMake : negated conditional → NO_COVERAGE |
if (text1 == null || diffs == null) { |
1863 | throw new IllegalArgumentException("Null inputs. (patch_make)"); | |
1864 | } | |
1865 | ||
1866 | List<Patch> patches = new LinkedList<>(); | |
1867 |
1
1. patchMake : negated conditional → NO_COVERAGE |
if (diffs.isEmpty()) { |
1868 |
1
1. patchMake : replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchMake → NO_COVERAGE |
return patches; // Get rid of the null case. |
1869 | } | |
1870 | Patch patch = new Patch(); | |
1871 | int charCount1 = 0; // Number of characters into the text1 string. | |
1872 | int charCount2 = 0; // Number of characters into the text2 string. | |
1873 | // Start with text1 (prepatch_text) and apply the diffs until we arrive at | |
1874 | // text2 (postpatch_text). We recreate the patches one by one to determine | |
1875 | // context info. | |
1876 | String prepatchText = text1; | |
1877 | String postpatchText = text1; | |
1878 | ||
1879 | for (Diff aDiff : diffs) { | |
1880 |
2
1. patchMake : negated conditional → NO_COVERAGE 2. patchMake : negated conditional → NO_COVERAGE |
if (patch.getDiffs().isEmpty() && aDiff.getOperation() != Operation.EQUAL) { |
1881 | // A new patch starts here. | |
1882 |
1
1. patchMake : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE |
patch.setStart1(charCount1); |
1883 |
1
1. patchMake : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE |
patch.setStart2(charCount2); |
1884 | } | |
1885 | ||
1886 | switch (aDiff.getOperation()) { | |
1887 | case INSERT: | |
1888 | patch.getDiffs().add(aDiff); | |
1889 |
1
1. patchMake : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + aDiff.getText().length()); |
1890 | postpatchText = postpatchText.substring(0, charCount2) | |
1891 | + aDiff.getText() + postpatchText.substring(charCount2); | |
1892 | break; | |
1893 | case DELETE: | |
1894 |
2
1. patchMake : Replaced integer addition with subtraction → NO_COVERAGE 2. patchMake : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(patch.getLength1() + aDiff.getText().length()); |
1895 | patch.getDiffs().add(aDiff); | |
1896 | postpatchText = postpatchText.substring(0, charCount2) | |
1897 |
1
1. patchMake : Replaced integer addition with subtraction → NO_COVERAGE |
+ postpatchText.substring(charCount2 + aDiff.getText().length()); |
1898 | break; | |
1899 | case EQUAL: | |
1900 | if ( | |
1901 |
2
1. patchMake : negated conditional → NO_COVERAGE 2. patchMake : changed conditional boundary → NO_COVERAGE |
aDiff.getText().length() <= 2 * PATCH_MARGIN |
1902 |
2
1. patchMake : negated conditional → NO_COVERAGE 2. patchMake : negated conditional → NO_COVERAGE |
&& !patch.getDiffs().isEmpty() && aDiff != diffs.getLast() |
1903 | ) { | |
1904 | // Small equality inside a patch. | |
1905 | patch.getDiffs().add(aDiff); | |
1906 |
2
1. patchMake : Replaced integer addition with subtraction → NO_COVERAGE 2. patchMake : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(patch.getLength1() + aDiff.getText().length()); |
1907 |
1
1. patchMake : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + aDiff.getText().length()); |
1908 | } | |
1909 | ||
1910 | if ( | |
1911 |
2
1. patchMake : negated conditional → NO_COVERAGE 2. patchMake : changed conditional boundary → NO_COVERAGE |
aDiff.getText().length() >= 2 * PATCH_MARGIN |
1912 |
1
1. patchMake : negated conditional → NO_COVERAGE |
&& !patch.getDiffs().isEmpty() |
1913 | ) { | |
1914 | // Time for a new patch. | |
1915 |
1
1. patchMake : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchAddContext → NO_COVERAGE |
this.patchAddContext(patch, prepatchText); |
1916 | patches.add(patch); | |
1917 | patch = new Patch(); | |
1918 | // Unlike Unidiff, our patch lists have a rolling context. | |
1919 | // http://code.google.com/p/google-diff-match-patch/wiki/Unidiff | |
1920 | // Update prepatch text & pos to reflect the application of the | |
1921 | // just completed patch. | |
1922 | prepatchText = postpatchText; | |
1923 | charCount1 = charCount2; | |
1924 | } | |
1925 | break; | |
1926 | } | |
1927 | ||
1928 | // Update the current character count. | |
1929 |
1
1. patchMake : negated conditional → NO_COVERAGE |
if (aDiff.getOperation() != Operation.INSERT) { |
1930 |
1
1. patchMake : Replaced integer addition with subtraction → NO_COVERAGE |
charCount1 += aDiff.getText().length(); |
1931 | } | |
1932 |
1
1. patchMake : negated conditional → NO_COVERAGE |
if (aDiff.getOperation() != Operation.DELETE) { |
1933 |
1
1. patchMake : Replaced integer addition with subtraction → NO_COVERAGE |
charCount2 += aDiff.getText().length(); |
1934 | } | |
1935 | } | |
1936 | // Pick up the leftover patch if not empty. | |
1937 |
1
1. patchMake : negated conditional → NO_COVERAGE |
if (!patch.getDiffs().isEmpty()) { |
1938 |
1
1. patchMake : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchAddContext → NO_COVERAGE |
this.patchAddContext(patch, prepatchText); |
1939 | patches.add(patch); | |
1940 | } | |
1941 | ||
1942 |
1
1. patchMake : replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchMake → NO_COVERAGE |
return patches; |
1943 | } | |
1944 | ||
1945 | /** | |
1946 | * Given an array of patches, return another array that is identical. | |
1947 | * @param patches Array of Patch objects. | |
1948 | * @return Array of Patch objects. | |
1949 | */ | |
1950 | public LinkedList<Patch> patchDeepCopy(List<Patch> patches) { | |
1951 | ||
1952 | LinkedList<Patch> patchesCopy = new LinkedList<>(); | |
1953 | for (Patch aPatch : patches) { | |
1954 | Patch patchCopy = new Patch(); | |
1955 | for (Diff aDiff : aPatch.getDiffs()) { | |
1956 | Diff diffCopy = new Diff(aDiff.getOperation(), aDiff.getText()); | |
1957 | patchCopy.getDiffs().add(diffCopy); | |
1958 | } | |
1959 |
1
1. patchDeepCopy : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE |
patchCopy.setStart1(aPatch.getStart1()); |
1960 |
1
1. patchDeepCopy : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE |
patchCopy.setStart2(aPatch.getStart2()); |
1961 |
1
1. patchDeepCopy : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patchCopy.setLength1(aPatch.getLength1()); |
1962 | patchCopy.setLength2(aPatch.getLength2()); | |
1963 | patchesCopy.add(patchCopy); | |
1964 | } | |
1965 |
1
1. patchDeepCopy : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchDeepCopy → NO_COVERAGE |
return patchesCopy; |
1966 | } | |
1967 | ||
1968 | /** | |
1969 | * Merge a set of patches onto the text. Return a patched text, as well | |
1970 | * as an array of true/false values indicating which patches were applied. | |
1971 | * @param valuePatches Array of Patch objects | |
1972 | * @param valueText Old text. | |
1973 | * @return Two element Object array, containing the new text and an array of | |
1974 | * boolean values. | |
1975 | */ | |
1976 | public Object[] patchApply(LinkedList<Patch> valuePatches, String valueText) { | |
1977 | ||
1978 |
1
1. patchApply : negated conditional → NO_COVERAGE |
if (valuePatches.isEmpty()) { |
1979 |
1
1. patchApply : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchApply → NO_COVERAGE |
return new Object[]{valueText, new boolean[0]}; |
1980 | } | |
1981 | | |
1982 | // Deep copy the patches so that no changes are made to originals. | |
1983 | LinkedList<Patch> patches = this.patchDeepCopy(valuePatches); | |
1984 | ||
1985 | String nullPadding = this.patchAddPadding(patches); | |
1986 | String text = nullPadding + valueText + nullPadding; | |
1987 |
1
1. patchApply : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchSplitMax → NO_COVERAGE |
this.patchSplitMax(patches); |
1988 | ||
1989 | int x = 0; | |
1990 | // delta keeps track of the offset between the expected and actual location | |
1991 | // of the previous patch. If there are patches expected at positions 10 and | |
1992 | // 20, but the first patch was found at 12, delta is 2 and the second patch | |
1993 | // has an effective expected position of 22. | |
1994 | int delta = 0; | |
1995 | boolean[] results = new boolean[patches.size()]; | |
1996 | for (Patch aPatch : patches) { | |
1997 | ||
1998 |
1
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE |
int expectedLoc = aPatch.getStart2() + delta; |
1999 | String text1 = this.diffText1(aPatch.getDiffs()); | |
2000 | int startLoc; | |
2001 | int endLoc = -1; | |
2002 | ||
2003 |
2
1. patchApply : changed conditional boundary → NO_COVERAGE 2. patchApply : negated conditional → NO_COVERAGE |
if (text1.length() > DiffMatchPatch.MATCH_MAX_BITS) { |
2004 | // patch_splitMax will only provide an oversized pattern in the case of | |
2005 | // a monster delete. | |
2006 | startLoc = this.matchMain(text, | |
2007 | text1.substring(0, DiffMatchPatch.MATCH_MAX_BITS), expectedLoc); | |
2008 |
1
1. patchApply : negated conditional → NO_COVERAGE |
if (startLoc != -1) { |
2009 | endLoc = this.matchMain(text, | |
2010 |
1
1. patchApply : Replaced integer subtraction with addition → NO_COVERAGE |
text1.substring(text1.length() - DiffMatchPatch.MATCH_MAX_BITS), |
2011 |
2
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE 2. patchApply : Replaced integer subtraction with addition → NO_COVERAGE |
expectedLoc + text1.length() - DiffMatchPatch.MATCH_MAX_BITS); |
2012 |
3
1. patchApply : changed conditional boundary → NO_COVERAGE 2. patchApply : negated conditional → NO_COVERAGE 3. patchApply : negated conditional → NO_COVERAGE |
if (endLoc == -1 || startLoc >= endLoc) { |
2013 | // Can't find valid trailing context. Drop this patch. | |
2014 | startLoc = -1; | |
2015 | } | |
2016 | } | |
2017 | } else { | |
2018 | startLoc = this.matchMain(text, text1, expectedLoc); | |
2019 | } | |
2020 | ||
2021 |
1
1. patchApply : negated conditional → NO_COVERAGE |
if (startLoc == -1) { |
2022 | // No match found. :( | |
2023 | results[x] = false; | |
2024 | // Subtract the delta for this failed patch from subsequent patches. | |
2025 |
2
1. patchApply : Replaced integer subtraction with addition → NO_COVERAGE 2. patchApply : Replaced integer subtraction with addition → NO_COVERAGE |
delta -= aPatch.getLength2() - aPatch.getLength1(); |
2026 | } else { | |
2027 | // Found a match. :) | |
2028 | results[x] = true; | |
2029 |
1
1. patchApply : Replaced integer subtraction with addition → NO_COVERAGE |
delta = startLoc - expectedLoc; |
2030 | String text2; | |
2031 |
1
1. patchApply : negated conditional → NO_COVERAGE |
if (endLoc == -1) { |
2032 | text2 = text.substring(startLoc, | |
2033 |
1
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE |
Math.min(startLoc + text1.length(), text.length())); |
2034 | } else { | |
2035 |
1
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE |
text2 = text.substring(startLoc, |
2036 | Math.min(endLoc + DiffMatchPatch.MATCH_MAX_BITS, text.length())); | |
2037 | } | |
2038 | ||
2039 |
1
1. patchApply : negated conditional → NO_COVERAGE |
if (text1.equals(text2)) { |
2040 | // Perfect match, just shove the replacement text in. | |
2041 | text = text.substring(0, startLoc) + this.diffText2(aPatch.getDiffs()) | |
2042 |
1
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE |
+ text.substring(startLoc + text1.length()); |
2043 | } else { | |
2044 | // Imperfect match. Run a diff to get a framework of equivalent | |
2045 | // indices. | |
2046 | List<Diff> diffs = this.diffMain(text1, text2, false); | |
2047 |
2
1. patchApply : changed conditional boundary → NO_COVERAGE 2. patchApply : negated conditional → NO_COVERAGE |
if (text1.length() > DiffMatchPatch.MATCH_MAX_BITS |
2048 |
3
1. patchApply : Replaced float division with multiplication → NO_COVERAGE 2. patchApply : changed conditional boundary → NO_COVERAGE 3. patchApply : negated conditional → NO_COVERAGE |
&& this.diffLevenshtein(diffs) / (float) text1.length() |
2049 | > DiffMatchPatch.PATCH_DELETE_THRESHOLD) { | |
2050 | // The end points match, but the content is unacceptably bad. | |
2051 | results[x] = false; | |
2052 | } else { | |
2053 |
1
1. patchApply : removed call to com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::diffCleanupSemanticLossless → NO_COVERAGE |
this.diffCleanupSemanticLossless(diffs); |
2054 | int index1 = 0; | |
2055 | for (Diff aDiff : aPatch.getDiffs()) { | |
2056 |
1
1. patchApply : negated conditional → NO_COVERAGE |
if (aDiff.getOperation() != Operation.EQUAL) { |
2057 | int index2 = this.diffXIndex(diffs, index1); | |
2058 |
1
1. patchApply : negated conditional → NO_COVERAGE |
if (aDiff.getOperation() == Operation.INSERT) { |
2059 | // Insertion | |
2060 |
2
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE 2. patchApply : Replaced integer addition with subtraction → NO_COVERAGE |
text = text.substring(0, startLoc + index2) + aDiff.getText() |
2061 | + text.substring(startLoc + index2); | |
2062 |
1
1. patchApply : negated conditional → NO_COVERAGE |
} else if (aDiff.getOperation() == Operation.DELETE) { |
2063 | // Deletion | |
2064 |
1
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE |
text = text.substring(0, startLoc + index2) |
2065 |
1
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE |
+ text.substring(startLoc + this.diffXIndex(diffs, |
2066 |
1
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE |
index1 + aDiff.getText().length())); |
2067 | } | |
2068 | } | |
2069 |
1
1. patchApply : negated conditional → NO_COVERAGE |
if (aDiff.getOperation() != Operation.DELETE) { |
2070 |
1
1. patchApply : Replaced integer addition with subtraction → NO_COVERAGE |
index1 += aDiff.getText().length(); |
2071 | } | |
2072 | } | |
2073 | } | |
2074 | } | |
2075 | } | |
2076 |
1
1. patchApply : Changed increment from 1 to -1 → NO_COVERAGE |
x++; |
2077 | } | |
2078 | // Strip the padding off. | |
2079 | text = text.substring(nullPadding.length(), text.length() | |
2080 |
1
1. patchApply : Replaced integer subtraction with addition → NO_COVERAGE |
- nullPadding.length()); |
2081 |
1
1. patchApply : replaced return value with null for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchApply → NO_COVERAGE |
return new Object[]{text, results}; |
2082 | } | |
2083 | ||
2084 | /** | |
2085 | * Add some padding on text start and end so that edges can match something. | |
2086 | * Intended to be called only from within patch_apply. | |
2087 | * @param patches Array of Patch objects. | |
2088 | * @return The padding string added to each side. | |
2089 | */ | |
2090 | public String patchAddPadding(Deque<Patch> patches) { | |
2091 | ||
2092 | short paddingLength = DiffMatchPatch.PATCH_MARGIN; | |
2093 | StringBuilder nullPadding = new StringBuilder(); | |
2094 |
3
1. patchAddPadding : changed conditional boundary → NO_COVERAGE 2. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE 3. patchAddPadding : negated conditional → NO_COVERAGE |
for (short x = 1; x <= paddingLength; x++) { |
2095 | nullPadding.append(String.valueOf((char) x)); | |
2096 | } | |
2097 | ||
2098 | // Bump all the patches forward. | |
2099 | for (Patch aPatch : patches) { | |
2100 |
2
1. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE 2. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE |
aPatch.setStart1(aPatch.getStart1() + paddingLength); |
2101 |
2
1. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE 2. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE |
aPatch.setStart2(aPatch.getStart2() + paddingLength); |
2102 | } | |
2103 | ||
2104 | // Add some padding on start of first diff. | |
2105 | Patch patch = patches.getFirst(); | |
2106 | Deque<Diff> diffs = patch.getDiffs(); | |
2107 |
2
1. patchAddPadding : negated conditional → NO_COVERAGE 2. patchAddPadding : negated conditional → NO_COVERAGE |
if (diffs.isEmpty() || diffs.getFirst().getOperation() != Operation.EQUAL) { |
2108 | // Add nullPadding equality. | |
2109 |
1
1. patchAddPadding : removed call to java/util/Deque::addFirst → NO_COVERAGE |
diffs.addFirst(new Diff(Operation.EQUAL, nullPadding.toString())); |
2110 |
2
1. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE 2. patchAddPadding : Replaced integer subtraction with addition → NO_COVERAGE |
patch.setStart1(patch.getStart1() - paddingLength); // Should be 0. |
2111 |
2
1. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE 2. patchAddPadding : Replaced integer subtraction with addition → NO_COVERAGE |
patch.setStart2(patch.getStart2() - paddingLength); // Should be 0. |
2112 |
2
1. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE 2. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(patch.getLength1() + paddingLength); |
2113 |
1
1. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + paddingLength); |
2114 |
2
1. patchAddPadding : negated conditional → NO_COVERAGE 2. patchAddPadding : changed conditional boundary → NO_COVERAGE |
} else if (paddingLength > diffs.getFirst().getText().length()) { |
2115 | // Grow first equality. | |
2116 | Diff firstDiff = diffs.getFirst(); | |
2117 |
1
1. patchAddPadding : Replaced integer subtraction with addition → NO_COVERAGE |
int extraLength = paddingLength - firstDiff.getText().length(); |
2118 |
1
1. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
firstDiff.setText(nullPadding.substring(firstDiff.getText().length()) |
2119 | + firstDiff.getText()); | |
2120 |
2
1. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE 2. patchAddPadding : Replaced integer subtraction with addition → NO_COVERAGE |
patch.setStart1(patch.getStart1() - extraLength); |
2121 |
2
1. patchAddPadding : Replaced integer subtraction with addition → NO_COVERAGE 2. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE |
patch.setStart2(patch.getStart2() - extraLength); |
2122 |
2
1. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE 2. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength1(patch.getLength1() + extraLength); |
2123 |
1
1. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + extraLength); |
2124 | } | |
2125 | ||
2126 | // Add some padding on end of last diff. | |
2127 | patch = patches.getLast(); | |
2128 | diffs = patch.getDiffs(); | |
2129 |
2
1. patchAddPadding : negated conditional → NO_COVERAGE 2. patchAddPadding : negated conditional → NO_COVERAGE |
if (diffs.isEmpty() || diffs.getLast().getOperation() != Operation.EQUAL) { |
2130 | // Add nullPadding equality. | |
2131 |
1
1. patchAddPadding : removed call to java/util/Deque::addLast → NO_COVERAGE |
diffs.addLast(new Diff(Operation.EQUAL, nullPadding.toString())); |
2132 |
2
1. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE 2. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(patch.getLength1() + paddingLength); |
2133 |
1
1. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + paddingLength); |
2134 |
2
1. patchAddPadding : negated conditional → NO_COVERAGE 2. patchAddPadding : changed conditional boundary → NO_COVERAGE |
} else if (paddingLength > diffs.getLast().getText().length()) { |
2135 | // Grow last equality. | |
2136 | Diff lastDiff = diffs.getLast(); | |
2137 |
1
1. patchAddPadding : Replaced integer subtraction with addition → NO_COVERAGE |
int extraLength = paddingLength - lastDiff.getText().length(); |
2138 |
1
1. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
lastDiff.setText(lastDiff.getText() + nullPadding.substring(0, extraLength)); |
2139 |
2
1. patchAddPadding : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE 2. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength1(patch.getLength1() + extraLength); |
2140 |
1
1. patchAddPadding : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + extraLength); |
2141 | } | |
2142 | ||
2143 |
1
1. patchAddPadding : replaced return value with "" for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchAddPadding → NO_COVERAGE |
return nullPadding.toString(); |
2144 | } | |
2145 | ||
2146 | /** | |
2147 | * Look through the patches and break up any which are longer than the | |
2148 | * maximum limit of the match algorithm. | |
2149 | * Intended to be called only from within patch_apply. | |
2150 | * @param patches List of Patch objects. | |
2151 | */ | |
2152 | public void patchSplitMax(List<Patch> patches) { | |
2153 | ||
2154 | short patchSize = DiffMatchPatch.MATCH_MAX_BITS; | |
2155 | String precontext; | |
2156 | String postcontext; | |
2157 | Patch patch; | |
2158 | int start1; | |
2159 | int start2; | |
2160 | boolean empty; | |
2161 | Operation diffType; | |
2162 | String diffText; | |
2163 | ListIterator<Patch> pointer = patches.listIterator(); | |
2164 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
Patch bigpatch = pointer.hasNext() ? pointer.next() : null; |
2165 | ||
2166 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
while (bigpatch != null) { |
2167 |
2
1. patchSplitMax : changed conditional boundary → NO_COVERAGE 2. patchSplitMax : negated conditional → NO_COVERAGE |
if (bigpatch.getLength1() <= DiffMatchPatch.MATCH_MAX_BITS) { |
2168 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
bigpatch = pointer.hasNext() ? pointer.next() : null; |
2169 | continue; | |
2170 | } | |
2171 | // Remove the big old patch. | |
2172 |
1
1. patchSplitMax : removed call to java/util/ListIterator::remove → NO_COVERAGE |
pointer.remove(); |
2173 | start1 = bigpatch.getStart1(); | |
2174 | start2 = bigpatch.getStart2(); | |
2175 | precontext = ""; | |
2176 | ||
2177 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
while (!bigpatch.getDiffs().isEmpty()) { |
2178 | // Create one of several smaller patches. | |
2179 | patch = new Patch(); | |
2180 | empty = true; | |
2181 |
2
1. patchSplitMax : Replaced integer subtraction with addition → NO_COVERAGE 2. patchSplitMax : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE |
patch.setStart1(start1 - precontext.length()); |
2182 |
2
1. patchSplitMax : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE 2. patchSplitMax : Replaced integer subtraction with addition → NO_COVERAGE |
patch.setStart2(start2 - precontext.length()); |
2183 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
if (!precontext.isEmpty()) { |
2184 |
1
1. patchSplitMax : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(patch.setLength2(precontext.length())); |
2185 | patch.getDiffs().add(new Diff(Operation.EQUAL, precontext)); | |
2186 | } | |
2187 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
while (!bigpatch.getDiffs().isEmpty() |
2188 |
3
1. patchSplitMax : negated conditional → NO_COVERAGE 2. patchSplitMax : changed conditional boundary → NO_COVERAGE 3. patchSplitMax : Replaced integer subtraction with addition → NO_COVERAGE |
&& patch.getLength1() < patchSize - PATCH_MARGIN) { |
2189 | diffType = bigpatch.getDiffs().getFirst().getOperation(); | |
2190 | diffText = bigpatch.getDiffs().getFirst().getText(); | |
2191 | ||
2192 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
if (diffType == Operation.INSERT) { |
2193 | // Insertions are harmless. | |
2194 |
1
1. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + diffText.length()); |
2195 |
1
1. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE |
start2 += diffText.length(); |
2196 |
1
1. patchSplitMax : removed call to java/util/LinkedList::addLast → NO_COVERAGE |
patch.getDiffs().addLast(bigpatch.getDiffs().removeFirst()); |
2197 | empty = false; | |
2198 |
2
1. patchSplitMax : negated conditional → NO_COVERAGE 2. patchSplitMax : negated conditional → NO_COVERAGE |
} else if (diffType == Operation.DELETE && patch.getDiffs().size() == 1 |
2199 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
&& patch.getDiffs().getFirst().getOperation() == Operation.EQUAL |
2200 |
3
1. patchSplitMax : Replaced integer multiplication with division → NO_COVERAGE 2. patchSplitMax : changed conditional boundary → NO_COVERAGE 3. patchSplitMax : negated conditional → NO_COVERAGE |
&& diffText.length() > 2 * patchSize) { |
2201 | // This is a large deletion. Let it pass in one chunk. | |
2202 |
2
1. patchSplitMax : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE 2. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength1(patch.getLength1() + diffText.length()); |
2203 |
1
1. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE |
start1 += diffText.length(); |
2204 | empty = false; | |
2205 | patch.getDiffs().add(new Diff(diffType, diffText)); | |
2206 | bigpatch.getDiffs().removeFirst(); | |
2207 | } else { | |
2208 | // Deletion or equality. Only take as much as we can stomach. | |
2209 | diffText = diffText.substring(0, Math.min(diffText.length(), | |
2210 |
2
1. patchSplitMax : Replaced integer subtraction with addition → NO_COVERAGE 2. patchSplitMax : Replaced integer subtraction with addition → NO_COVERAGE |
patchSize - patch.getLength1() - PATCH_MARGIN)); |
2211 |
2
1. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE 2. patchSplitMax : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(patch.getLength1() + diffText.length()); |
2212 |
1
1. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE |
start1 += diffText.length(); |
2213 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
if (diffType == Operation.EQUAL) { |
2214 |
1
1. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + diffText.length()); |
2215 |
1
1. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE |
start2 += diffText.length(); |
2216 | } else { | |
2217 | empty = false; | |
2218 | } | |
2219 | patch.getDiffs().add(new Diff(diffType, diffText)); | |
2220 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
if (diffText.equals(bigpatch.getDiffs().getFirst().getText())) { |
2221 | bigpatch.getDiffs().removeFirst(); | |
2222 | } else { | |
2223 |
1
1. patchSplitMax : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
bigpatch.getDiffs().getFirst().setText(bigpatch.getDiffs().getFirst().getText() |
2224 | .substring(diffText.length())); | |
2225 | } | |
2226 | } | |
2227 | } | |
2228 | // Compute the head context for the next patch. | |
2229 | precontext = this.diffText2(patch.getDiffs()); | |
2230 |
1
1. patchSplitMax : Replaced integer subtraction with addition → NO_COVERAGE |
precontext = precontext.substring(Math.max(0, precontext.length() |
2231 | - PATCH_MARGIN)); | |
2232 | // Append the end context for this patch. | |
2233 |
2
1. patchSplitMax : negated conditional → NO_COVERAGE 2. patchSplitMax : changed conditional boundary → NO_COVERAGE |
if (this.diffText1(bigpatch.getDiffs()).length() > PATCH_MARGIN) { |
2234 | postcontext = this.diffText1(bigpatch.getDiffs()).substring(0, PATCH_MARGIN); | |
2235 | } else { | |
2236 | postcontext = this.diffText1(bigpatch.getDiffs()); | |
2237 | } | |
2238 | ||
2239 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
if (!postcontext.isEmpty()) { |
2240 |
2
1. patchSplitMax : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE 2. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength1(patch.getLength1() + postcontext.length()); |
2241 |
1
1. patchSplitMax : Replaced integer addition with subtraction → NO_COVERAGE |
patch.setLength2(patch.getLength2() + postcontext.length()); |
2242 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
if (!patch.getDiffs().isEmpty() |
2243 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
&& patch.getDiffs().getLast().getOperation() == Operation.EQUAL) { |
2244 |
1
1. patchSplitMax : removed call to com/jsql/model/injection/strategy/blind/patch/Diff::setText → NO_COVERAGE |
patch.getDiffs().getLast().setText(patch.getDiffs().getLast().getText() + postcontext); |
2245 | } else { | |
2246 | patch.getDiffs().add(new Diff(Operation.EQUAL, postcontext)); | |
2247 | } | |
2248 | } | |
2249 | ||
2250 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
if (!empty) { |
2251 |
1
1. patchSplitMax : removed call to java/util/ListIterator::add → NO_COVERAGE |
pointer.add(patch); |
2252 | } | |
2253 | } | |
2254 |
1
1. patchSplitMax : negated conditional → NO_COVERAGE |
bigpatch = pointer.hasNext() ? pointer.next() : null; |
2255 | } | |
2256 | } | |
2257 | ||
2258 | /** | |
2259 | * Take a list of patches and return a textual representation. | |
2260 | * @param patches List of Patch objects. | |
2261 | * @return Text representation of patches. | |
2262 | */ | |
2263 | public String patchToText(List<Patch> patches) { | |
2264 | ||
2265 | StringBuilder text = new StringBuilder(); | |
2266 | for (Patch aPatch : patches) { | |
2267 | text.append(aPatch); | |
2268 | } | |
2269 |
1
1. patchToText : replaced return value with "" for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchToText → NO_COVERAGE |
return text.toString(); |
2270 | } | |
2271 | ||
2272 | /** | |
2273 | * Parse a textual representation of patches and return a List of Patch | |
2274 | * objects. | |
2275 | * @param textline Text representation of patches. | |
2276 | * @return List of Patch objects. | |
2277 | */ | |
2278 | public List<Patch> patchFromText(String textline) { | |
2279 | ||
2280 | List<Patch> patches = new LinkedList<>(); | |
2281 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
if (textline.isEmpty()) { |
2282 |
1
1. patchFromText : replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchFromText → NO_COVERAGE |
return patches; |
2283 | } | |
2284 | List<String> textList = Arrays.asList(textline.split("\n")); | |
2285 | Deque<String> text = new LinkedList<>(textList); | |
2286 | Patch patch; | |
2287 | Pattern patchHeader = Pattern.compile("^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$"); | |
2288 | Matcher m; | |
2289 | char sign; | |
2290 | String line; | |
2291 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
while (!text.isEmpty()) { |
2292 | ||
2293 | m = patchHeader.matcher(text.getFirst()); | |
2294 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
if (!m.matches()) { |
2295 | throw new IllegalArgumentException( | |
2296 | "Invalid patch string: " + text.getFirst()); | |
2297 | } | |
2298 | patch = new Patch(); | |
2299 | patches.add(patch); | |
2300 |
1
1. patchFromText : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE |
patch.setStart1(Integer.parseInt(m.group(1))); |
2301 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
if (m.group(2).isEmpty()) { |
2302 |
2
1. patchFromText : Replaced integer subtraction with addition → NO_COVERAGE 2. patchFromText : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE |
patch.setStart1(patch.getStart1() - 1); |
2303 |
1
1. patchFromText : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(1); |
2304 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
} else if ("0".equals(m.group(2))) { |
2305 |
1
1. patchFromText : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(0); |
2306 | } else { | |
2307 |
2
1. patchFromText : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart1 → NO_COVERAGE 2. patchFromText : Replaced integer subtraction with addition → NO_COVERAGE |
patch.setStart1(patch.getStart1() - 1); |
2308 |
1
1. patchFromText : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setLength1 → NO_COVERAGE |
patch.setLength1(Integer.parseInt(m.group(2))); |
2309 | } | |
2310 | ||
2311 |
1
1. patchFromText : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE |
patch.setStart2(Integer.parseInt(m.group(3))); |
2312 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
if (m.group(4).isEmpty()) { |
2313 |
2
1. patchFromText : Replaced integer subtraction with addition → NO_COVERAGE 2. patchFromText : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE |
patch.setStart2(patch.getStart2() - 1); |
2314 | patch.setLength2(1); | |
2315 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
} else if ("0".equals(m.group(4))) { |
2316 | patch.setLength2(0); | |
2317 | } else { | |
2318 |
2
1. patchFromText : removed call to com/jsql/model/injection/strategy/blind/patch/Patch::setStart2 → NO_COVERAGE 2. patchFromText : Replaced integer subtraction with addition → NO_COVERAGE |
patch.setStart2(patch.getStart2() - 1); |
2319 | patch.setLength2(Integer.parseInt(m.group(4))); | |
2320 | } | |
2321 | text.removeFirst(); | |
2322 | ||
2323 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
while (!text.isEmpty()) { |
2324 | ||
2325 | try { | |
2326 | sign = text.getFirst().charAt(0); | |
2327 | } catch (IndexOutOfBoundsException e) { | |
2328 | | |
2329 | LOGGER.log(LogLevelUtil.IGNORE, e); | |
2330 | | |
2331 | // Blank line? Whatever. | |
2332 | text.removeFirst(); | |
2333 | continue; | |
2334 | } | |
2335 | ||
2336 | line = text.getFirst().substring(1); | |
2337 | line = line.replace("+", "%2B"); // decode would change all "+" to " " | |
2338 | try { | |
2339 | line = URLDecoder.decode(line, StandardCharsets.UTF_8); | |
2340 | } catch (IllegalArgumentException e) { | |
2341 | // Malformed URI sequence. | |
2342 | throw new IllegalArgumentException( | |
2343 | "Illegal escape in patch_fromText: " + line, e); | |
2344 | } | |
2345 | ||
2346 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
if (sign == '-') { |
2347 | // Deletion. | |
2348 | patch.getDiffs().add(new Diff(Operation.DELETE, line)); | |
2349 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
} else if (sign == '+') { |
2350 | // Insertion. | |
2351 | patch.getDiffs().add(new Diff(Operation.INSERT, line)); | |
2352 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
} else if (sign == ' ') { |
2353 | // Minor equality. | |
2354 | patch.getDiffs().add(new Diff(Operation.EQUAL, line)); | |
2355 |
1
1. patchFromText : negated conditional → NO_COVERAGE |
} else if (sign == '@') { |
2356 | // Start of next patch. | |
2357 | break; | |
2358 | } else { | |
2359 | // WTF? | |
2360 | throw new IllegalArgumentException( | |
2361 | "Invalid patch mode '" + sign + "' in: " + line); | |
2362 | } | |
2363 | text.removeFirst(); | |
2364 | } | |
2365 | } | |
2366 |
1
1. patchFromText : replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/patch/DiffMatchPatch::patchFromText → NO_COVERAGE |
return patches; |
2367 | } | |
2368 | } | |
Mutations | ||
149 |
1.1 |
|
164 |
1.1 |
|
165 |
1.1 |
|
186 |
1.1 2.2 |
|
192 |
1.1 |
|
194 |
1.1 |
|
197 |
1.1 |
|
208 |
1.1 |
|
209 |
1.1 |
|
210 |
1.1 |
|
216 |
1.1 |
|
217 |
1.1 |
|
219 |
1.1 |
|
220 |
1.1 |
|
223 |
1.1 |
|
224 |
1.1 |
|
242 |
1.1 |
|
245 |
1.1 |
|
248 |
1.1 |
|
251 |
1.1 |
|
256 |
1.1 2.2 |
|
257 |
1.1 2.2 |
|
259 |
1.1 |
|
261 |
1.1 2.2 |
|
265 |
1.1 |
|
266 |
1.1 |
|
269 |
1.1 |
|
274 |
1.1 |
|
280 |
1.1 |
|
294 |
1.1 |
|
297 |
1.1 2.2 3.3 4.4 5.5 |
|
298 |
1.1 |
|
301 |
1.1 |
|
324 |
1.1 |
|
326 |
1.1 |
|
338 |
1.1 |
|
341 |
1.1 |
|
345 |
1.1 |
|
350 |
1.1 2.2 3.3 4.4 |
|
353 |
1.1 2.2 3.3 |
|
355 |
1.1 |
|
358 |
1.1 |
|
363 |
1.1 |
|
364 |
1.1 |
|
367 |
1.1 |
|
371 |
1.1 |
|
388 |
1.1 2.2 3.3 |
|
390 |
1.1 |
|
393 |
1.1 2.2 |
|
397 |
1.1 |
|
398 |
1.1 |
|
399 |
1.1 |
|
402 |
1.1 2.2 |
|
410 |
1.1 2.2 |
|
412 |
1.1 2.2 |
|
417 |
1.1 2.2 3.3 4.4 5.5 |
|
418 |
1.1 |
|
420 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
421 |
1.1 |
|
423 |
1.1 2.2 |
|
425 |
1.1 |
|
426 |
1.1 2.2 3.3 4.4 |
|
427 |
1.1 |
|
428 |
1.1 |
|
429 |
1.1 |
|
432 |
1.1 2.2 |
|
434 |
1.1 |
|
435 |
1.1 2.2 |
|
437 |
1.1 |
|
438 |
1.1 |
|
439 |
1.1 2.2 |
|
440 |
1.1 2.2 3.3 4.4 5.5 |
|
442 |
1.1 |
|
443 |
1.1 2.2 |
|
445 |
1.1 |
|
452 |
1.1 2.2 3.3 4.4 5.5 |
|
453 |
1.1 |
|
455 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
456 |
1.1 |
|
458 |
1.1 2.2 |
|
460 |
1.1 |
|
461 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
462 |
1.1 2.2 |
|
463 |
1.1 |
|
464 |
1.1 |
|
465 |
1.1 |
|
468 |
1.1 2.2 |
|
470 |
1.1 |
|
471 |
1.1 2.2 |
|
473 |
1.1 |
|
474 |
1.1 |
|
475 |
1.1 2.2 |
|
476 |
1.1 2.2 3.3 4.4 5.5 |
|
478 |
1.1 2.2 |
|
480 |
1.1 |
|
481 |
1.1 2.2 |
|
483 |
1.1 |
|
494 |
1.1 |
|
519 |
1.1 |
|
544 |
1.1 |
|
565 |
1.1 2.2 3.3 |
|
567 |
1.1 |
|
568 |
1.1 |
|
570 |
1.1 |
|
571 |
1.1 |
|
573 |
1.1 |
|
577 |
1.1 |
|
578 |
1.1 |
|
581 |
1.1 |
|
595 |
1.1 2.2 |
|
598 |
1.1 |
|
612 |
1.1 2.2 |
|
613 |
1.1 |
|
614 |
1.1 |
|
617 |
1.1 |
|
632 |
1.1 2.2 |
|
633 |
1.1 2.2 3.3 |
|
634 |
1.1 2.2 |
|
637 |
1.1 |
|
656 |
1.1 2.2 |
|
660 |
1.1 2.2 |
|
661 |
1.1 |
|
662 |
1.1 2.2 |
|
667 |
1.1 |
|
668 |
1.1 |
|
677 |
1.1 |
|
679 |
1.1 |
|
680 |
1.1 |
|
682 |
1.1 |
|
683 |
1.1 2.2 3.3 |
|
686 |
1.1 |
|
703 |
1.1 2.2 |
|
704 |
1.1 2.2 |
|
705 |
1.1 2.2 3.3 4.4 5.5 |
|
710 |
1.1 2.2 |
|
712 |
1.1 2.2 |
|
714 |
1.1 2.2 |
|
716 |
1.1 |
|
718 |
1.1 |
|
722 |
1.1 2.2 |
|
726 |
1.1 2.2 |
|
727 |
1.1 |
|
729 |
1.1 |
|
746 |
1.1 2.2 |
|
753 |
1.1 2.2 |
|
758 |
1.1 2.2 3.3 |
|
759 |
1.1 2.2 |
|
761 |
1.1 |
|
762 |
1.1 |
|
763 |
1.1 |
|
764 |
1.1 |
|
767 |
1.1 2.2 3.3 |
|
768 |
1.1 |
|
781 |
1.1 |
|
797 |
1.1 |
|
798 |
1.1 |
|
808 |
1.1 |
|
809 |
1.1 |
|
811 |
1.1 |
|
815 |
1.1 |
|
817 |
1.1 2.2 |
|
818 |
1.1 2.2 |
|
821 |
1.1 |
|
827 |
1.1 |
|
829 |
1.1 |
|
832 |
1.1 |
|
836 |
1.1 |
|
838 |
1.1 |
|
844 |
1.1 |
|
857 |
1.1 |
|
861 |
1.1 |
|
862 |
1.1 |
|
864 |
1.1 |
|
875 |
1.1 |
|
877 |
1.1 |
|
882 |
1.1 |
|
883 |
1.1 |
|
884 |
1.1 |
|
889 |
1.1 2.2 |
|
890 |
1.1 2.2 3.3 |
|
891 |
1.1 2.2 3.3 |
|
894 |
1.1 |
|
896 |
1.1 2.2 |
|
897 |
1.1 |
|
902 |
1.1 2.2 3.3 |
|
903 |
1.1 2.2 3.3 |
|
907 |
1.1 |
|
909 |
1.1 |
|
910 |
1.1 2.2 |
|
911 |
1.1 |
|
912 |
1.1 |
|
917 |
1.1 |
|
920 |
1.1 |
|
944 |
1.1 |
|
945 |
1.1 |
|
946 |
1.1 |
|
949 |
1.1 |
|
950 |
1.1 |
|
951 |
1.1 |
|
953 |
1.1 |
|
956 |
1.1 |
|
961 |
1.1 |
|
962 |
1.1 |
|
963 |
1.1 |
|
964 |
1.1 |
|
966 |
1.1 |
|
975 |
1.1 |
|
976 |
1.1 2.2 |
|
977 |
1.1 |
|
981 |
1.1 |
|
984 |
1.1 |
|
986 |
1.1 2.2 |
|
994 |
1.1 |
|
996 |
1.1 |
|
997 |
1.1 |
|
1002 |
1.1 |
|
1006 |
1.1 |
|
1007 |
1.1 |
|
1008 |
1.1 |
|
1010 |
1.1 |
|
1018 |
1.1 |
|
1032 |
1.1 2.2 |
|
1034 |
1.1 |
|
1042 |
1.1 |
|
1044 |
1.1 |
|
1045 |
1.1 |
|
1046 |
1.1 2.2 |
|
1047 |
1.1 2.2 |
|
1048 |
1.1 |
|
1049 |
1.1 |
|
1050 |
1.1 |
|
1051 |
1.1 |
|
1052 |
1.1 2.2 |
|
1053 |
1.1 2.2 |
|
1055 |
1.1 2.2 |
|
1057 |
1.1 |
|
1058 |
1.1 2.2 |
|
1060 |
1.1 |
|
1061 |
1.1 2.2 3.3 |
|
1063 |
1.1 |
|
1064 |
1.1 2.2 |
|
1066 |
1.1 |
|
1067 |
1.1 2.2 |
|
1069 |
1.1 |
|
1080 |
1.1 |
|
1098 |
1.1 |
|
1100 |
1.1 |
|
1103 |
1.1 2.2 3.3 4.4 |
|
1111 |
1.1 |
|
1118 |
1.1 |
|
1132 |
1.1 2.2 3.3 4.4 5.5 |
|
1137 |
1.1 2.2 |
|
1138 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
1143 |
1.1 |
|
1149 |
1.1 |
|
1152 |
1.1 |
|
1156 |
1.1 2.2 |
|
1159 |
1.1 |
|
1162 |
1.1 |
|
1166 |
1.1 |
|
1174 |
1.1 |
|
1183 |
1.1 |
|
1186 |
1.1 |
|
1187 |
1.1 |
|
1207 |
1.1 |
|
1210 |
1.1 |
|
1215 |
1.1 |
|
1220 |
1.1 2.2 3.3 |
|
1222 |
1.1 2.2 |
|
1225 |
1.1 2.2 3.3 |
|
1227 |
1.1 |
|
1229 |
1.1 2.2 3.3 |
|
1231 |
1.1 |
|
1234 |
1.1 |
|
1237 |
1.1 |
|
1238 |
1.1 |
|
1241 |
1.1 |
|
1244 |
1.1 |
|
1248 |
1.1 |
|
1251 |
1.1 |
|
1256 |
1.1 |
|
1258 |
1.1 2.2 |
|
1259 |
1.1 |
|
1260 |
1.1 |
|
1262 |
1.1 |
|
1263 |
1.1 |
|
1269 |
1.1 |
|
1270 |
1.1 |
|
1272 |
1.1 |
|
1273 |
1.1 |
|
1276 |
1.1 |
|
1277 |
1.1 |
|
1279 |
1.1 |
|
1280 |
1.1 |
|
1286 |
1.1 |
|
1287 |
1.1 |
|
1291 |
1.1 |
|
1293 |
1.1 |
|
1306 |
1.1 |
|
1307 |
1.1 |
|
1308 |
1.1 |
|
1311 |
1.1 |
|
1312 |
1.1 |
|
1313 |
1.1 |
|
1315 |
1.1 |
|
1317 |
1.1 |
|
1319 |
1.1 |
|
1320 |
1.1 |
|
1324 |
1.1 |
|
1327 |
1.1 |
|
1329 |
1.1 |
|
1331 |
1.1 |
|
1332 |
1.1 |
|
1334 |
1.1 |
|
1335 |
1.1 |
|
1341 |
1.1 |
|
1344 |
1.1 |
|
1345 |
1.1 |
|
1365 |
1.1 |
|
1367 |
1.1 |
|
1369 |
1.1 |
|
1371 |
1.1 |
|
1373 |
1.1 2.2 |
|
1381 |
1.1 2.2 |
|
1383 |
1.1 |
|
1386 |
1.1 2.2 3.3 |
|
1414 |
1.1 |
|
1426 |
1.1 |
|
1430 |
1.1 |
|
1442 |
1.1 |
|
1446 |
1.1 |
|
1463 |
1.1 |
|
1466 |
1.1 |
|
1470 |
1.1 |
|
1476 |
1.1 |
|
1477 |
1.1 |
|
1506 |
1.1 |
|
1508 |
1.1 |
|
1511 |
1.1 |
|
1528 |
1.1 |
|
1558 |
1.1 2.2 |
|
1565 |
1.1 |
|
1573 |
1.1 |
|
1585 |
1.1 |
|
1589 |
1.1 |
|
1606 |
1.1 2.2 |
|
1611 |
1.1 |
|
1614 |
1.1 |
|
1616 |
1.1 |
|
1617 |
1.1 2.2 3.3 |
|
1618 |
1.1 2.2 |
|
1620 |
1.1 |
|
1623 |
1.1 |
|
1644 |
1.1 |
|
1648 |
1.1 |
|
1649 |
1.1 |
|
1656 |
1.1 2.2 |
|
1661 |
1.1 |
|
1664 |
1.1 2.2 |
|
1671 |
1.1 2.2 |
|
1672 |
1.1 2.2 3.3 |
|
1678 |
1.1 2.2 3.3 |
|
1682 |
1.1 2.2 |
|
1683 |
1.1 2.2 |
|
1685 |
1.1 |
|
1686 |
1.1 2.2 3.3 |
|
1687 |
1.1 2.2 |
|
1690 |
1.1 2.2 3.3 4.4 5.5 |
|
1694 |
1.1 |
|
1696 |
1.1 |
|
1698 |
1.1 2.2 3.3 4.4 |
|
1701 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.10 11.11 |
|
1705 |
1.1 2.2 |
|
1706 |
1.1 |
|
1709 |
1.1 2.2 |
|
1712 |
1.1 |
|
1713 |
1.1 2.2 |
|
1715 |
1.1 2.2 |
|
1723 |
1.1 2.2 3.3 |
|
1729 |
1.1 |
|
1742 |
1.1 |
|
1743 |
1.1 |
|
1744 |
1.1 2.2 3.3 |
|
1761 |
1.1 2.2 3.3 4.4 |
|
1762 |
1.1 |
|
1764 |
1.1 |
|
1778 |
1.1 |
|
1781 |
1.1 |
|
1786 |
1.1 |
|
1787 |
1.1 2.2 |
|
1788 |
1.1 |
|
1789 |
1.1 |
|
1790 |
1.1 2.2 |
|
1793 |
1.1 |
|
1796 |
1.1 |
|
1798 |
1.1 |
|
1799 |
1.1 |
|
1802 |
1.1 |
|
1803 |
1.1 2.2 |
|
1804 |
1.1 |
|
1805 |
1.1 |
|
1809 |
1.1 2.2 |
|
1810 |
1.1 2.2 |
|
1812 |
1.1 2.2 3.3 |
|
1813 |
1.1 2.2 |
|
1825 |
1.1 2.2 |
|
1830 |
1.1 2.2 |
|
1831 |
1.1 |
|
1832 |
1.1 |
|
1834 |
1.1 |
|
1845 |
1.1 |
|
1850 |
1.1 |
|
1862 |
1.1 2.2 |
|
1867 |
1.1 |
|
1868 |
1.1 |
|
1880 |
1.1 2.2 |
|
1882 |
1.1 |
|
1883 |
1.1 |
|
1889 |
1.1 |
|
1894 |
1.1 2.2 |
|
1897 |
1.1 |
|
1901 |
1.1 2.2 |
|
1902 |
1.1 2.2 |
|
1906 |
1.1 2.2 |
|
1907 |
1.1 |
|
1911 |
1.1 2.2 |
|
1912 |
1.1 |
|
1915 |
1.1 |
|
1929 |
1.1 |
|
1930 |
1.1 |
|
1932 |
1.1 |
|
1933 |
1.1 |
|
1937 |
1.1 |
|
1938 |
1.1 |
|
1942 |
1.1 |
|
1959 |
1.1 |
|
1960 |
1.1 |
|
1961 |
1.1 |
|
1965 |
1.1 |
|
1978 |
1.1 |
|
1979 |
1.1 |
|
1987 |
1.1 |
|
1998 |
1.1 |
|
2003 |
1.1 2.2 |
|
2008 |
1.1 |
|
2010 |
1.1 |
|
2011 |
1.1 2.2 |
|
2012 |
1.1 2.2 3.3 |
|
2021 |
1.1 |
|
2025 |
1.1 2.2 |
|
2029 |
1.1 |
|
2031 |
1.1 |
|
2033 |
1.1 |
|
2035 |
1.1 |
|
2039 |
1.1 |
|
2042 |
1.1 |
|
2047 |
1.1 2.2 |
|
2048 |
1.1 2.2 3.3 |
|
2053 |
1.1 |
|
2056 |
1.1 |
|
2058 |
1.1 |
|
2060 |
1.1 2.2 |
|
2062 |
1.1 |
|
2064 |
1.1 |
|
2065 |
1.1 |
|
2066 |
1.1 |
|
2069 |
1.1 |
|
2070 |
1.1 |
|
2076 |
1.1 |
|
2080 |
1.1 |
|
2081 |
1.1 |
|
2094 |
1.1 2.2 3.3 |
|
2100 |
1.1 2.2 |
|
2101 |
1.1 2.2 |
|
2107 |
1.1 2.2 |
|
2109 |
1.1 |
|
2110 |
1.1 2.2 |
|
2111 |
1.1 2.2 |
|
2112 |
1.1 2.2 |
|
2113 |
1.1 |
|
2114 |
1.1 2.2 |
|
2117 |
1.1 |
|
2118 |
1.1 |
|
2120 |
1.1 2.2 |
|
2121 |
1.1 2.2 |
|
2122 |
1.1 2.2 |
|
2123 |
1.1 |
|
2129 |
1.1 2.2 |
|
2131 |
1.1 |
|
2132 |
1.1 2.2 |
|
2133 |
1.1 |
|
2134 |
1.1 2.2 |
|
2137 |
1.1 |
|
2138 |
1.1 |
|
2139 |
1.1 2.2 |
|
2140 |
1.1 |
|
2143 |
1.1 |
|
2164 |
1.1 |
|
2166 |
1.1 |
|
2167 |
1.1 2.2 |
|
2168 |
1.1 |
|
2172 |
1.1 |
|
2177 |
1.1 |
|
2181 |
1.1 2.2 |
|
2182 |
1.1 2.2 |
|
2183 |
1.1 |
|
2184 |
1.1 |
|
2187 |
1.1 |
|
2188 |
1.1 2.2 3.3 |
|
2192 |
1.1 |
|
2194 |
1.1 |
|
2195 |
1.1 |
|
2196 |
1.1 |
|
2198 |
1.1 2.2 |
|
2199 |
1.1 |
|
2200 |
1.1 2.2 3.3 |
|
2202 |
1.1 2.2 |
|
2203 |
1.1 |
|
2210 |
1.1 2.2 |
|
2211 |
1.1 2.2 |
|
2212 |
1.1 |
|
2213 |
1.1 |
|
2214 |
1.1 |
|
2215 |
1.1 |
|
2220 |
1.1 |
|
2223 |
1.1 |
|
2230 |
1.1 |
|
2233 |
1.1 2.2 |
|
2239 |
1.1 |
|
2240 |
1.1 2.2 |
|
2241 |
1.1 |
|
2242 |
1.1 |
|
2243 |
1.1 |
|
2244 |
1.1 |
|
2250 |
1.1 |
|
2251 |
1.1 |
|
2254 |
1.1 |
|
2269 |
1.1 |
|
2281 |
1.1 |
|
2282 |
1.1 |
|
2291 |
1.1 |
|
2294 |
1.1 |
|
2300 |
1.1 |
|
2301 |
1.1 |
|
2302 |
1.1 2.2 |
|
2303 |
1.1 |
|
2304 |
1.1 |
|
2305 |
1.1 |
|
2307 |
1.1 2.2 |
|
2308 |
1.1 |
|
2311 |
1.1 |
|
2312 |
1.1 |
|
2313 |
1.1 2.2 |
|
2315 |
1.1 |
|
2318 |
1.1 2.2 |
|
2323 |
1.1 |
|
2346 |
1.1 |
|
2349 |
1.1 |
|
2352 |
1.1 |
|
2355 |
1.1 |
|
2366 |
1.1 |