mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 01:15:29 +02:00
Fixed integer overflow in binary search methods.
This commit is contained in:
parent
d7ceaaed42
commit
4381cc5da1
6 changed files with 68 additions and 83 deletions
|
@ -1,16 +1,15 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2006 IBM Corporation and others.
|
||||
* Copyright (c) 2002, 2014 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Rational Software - Initial API and implementation
|
||||
* Rational Software - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.util;
|
||||
|
||||
|
||||
/**
|
||||
* The SortOperation takes a collection of objects and returns
|
||||
* a sorted collection of these objects. The sorting of these
|
||||
|
@ -22,6 +21,7 @@ package org.eclipse.cdt.internal.core.util;
|
|||
public class ToStringSorter {
|
||||
Object[] sortedObjects;
|
||||
String[] sortedStrings;
|
||||
|
||||
/**
|
||||
* Returns true if stringTwo is 'greater than' stringOne
|
||||
* This is the 'ordering' method of the sort operation.
|
||||
|
@ -29,13 +29,14 @@ public class ToStringSorter {
|
|||
public boolean compare(String stringOne, String stringTwo) {
|
||||
return stringOne.compareTo(stringTwo) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the objects in sorted collection and return that collection.
|
||||
*/
|
||||
private void quickSort(int left, int right) {
|
||||
int originalLeft = left;
|
||||
int originalRight = right;
|
||||
int midIndex = (left + right) / 2;
|
||||
int midIndex = (left + right) >>> 1;
|
||||
String midToString = this.sortedStrings[midIndex];
|
||||
|
||||
do {
|
||||
|
@ -60,6 +61,7 @@ public class ToStringSorter {
|
|||
if (left < originalRight)
|
||||
quickSort(left, originalRight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new sorted collection from this unsorted collection.
|
||||
* Sort using quick sort.
|
||||
|
|
|
@ -36,7 +36,7 @@ public abstract class ArrayUtil {
|
|||
* the given class object.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static public <T> T[] append(Class<T> c, T[] array, T obj) {
|
||||
public static <T> T[] append(Class<T> c, T[] array, T obj) {
|
||||
if (obj == null)
|
||||
return array;
|
||||
if (array == null || array.length == 0) {
|
||||
|
@ -65,7 +65,7 @@ public abstract class ArrayUtil {
|
|||
* Object.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static public <T> T[] append(T[] array, T obj) {
|
||||
public static <T> T[] append(T[] array, T obj) {
|
||||
if (obj == null)
|
||||
return array;
|
||||
if (array == null || array.length == 0) {
|
||||
|
@ -90,22 +90,21 @@ public abstract class ArrayUtil {
|
|||
|
||||
/**
|
||||
* Assumes that array contains {@code null}s at the end, only.
|
||||
* @returns index of first {@code null}, or -1
|
||||
*
|
||||
* @return index of first {@code null}, or -1
|
||||
*/
|
||||
private static int findFirstNull(Object[] array) {
|
||||
boolean haveNull= false;
|
||||
int left= 0;
|
||||
int right= array.length - 1;
|
||||
while (left <= right) {
|
||||
int mid= (left + right) / 2;
|
||||
int low= 0;
|
||||
int high= array.length;
|
||||
while (low < high) {
|
||||
int mid= (low + high) >>> 1;
|
||||
if (array[mid] == null) {
|
||||
haveNull= true;
|
||||
right= mid - 1;
|
||||
high= mid;
|
||||
} else {
|
||||
left= mid + 1;
|
||||
low= mid + 1;
|
||||
}
|
||||
}
|
||||
return haveNull ? right + 1 : -1;
|
||||
return high < array.length ? high : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,7 +113,7 @@ public abstract class ArrayUtil {
|
|||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("unchecked")
|
||||
static public Object[] append(Class<?> c, Object[] array, int currentLength, Object obj) {
|
||||
public static Object[] append(Class<?> c, Object[] array, int currentLength, Object obj) {
|
||||
return appendAt((Class<Object>) c, array, currentLength, obj);
|
||||
}
|
||||
|
||||
|
@ -124,7 +123,7 @@ public abstract class ArrayUtil {
|
|||
* @since 5.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static public <T> T[] appendAt(Class<T> c, T[] array, int currentLength, T obj) {
|
||||
public static <T> T[] appendAt(Class<T> c, T[] array, int currentLength, T obj) {
|
||||
if (obj == null)
|
||||
return array;
|
||||
if (array == null || array.length == 0) {
|
||||
|
@ -155,7 +154,7 @@ public abstract class ArrayUtil {
|
|||
* @return The modified array, which may be the same as the first parameter.
|
||||
* @since 5.4
|
||||
*/
|
||||
static public <T> T[] appendAt(T[] array, int currentLength, T obj) {
|
||||
public static <T> T[] appendAt(T[] array, int currentLength, T obj) {
|
||||
if (obj == null)
|
||||
return array;
|
||||
if (currentLength >= array.length) {
|
||||
|
@ -180,7 +179,7 @@ public abstract class ArrayUtil {
|
|||
* @param forceNew
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static public <T> T[] trim(Class<T> c, T[] array, boolean forceNew) {
|
||||
public static <T> T[] trim(Class<T> c, T[] array, boolean forceNew) {
|
||||
if (array == null)
|
||||
return (T[]) Array.newInstance(c, 0);
|
||||
|
||||
|
@ -214,7 +213,7 @@ public abstract class ArrayUtil {
|
|||
* @param forceNew
|
||||
* @since 5.2
|
||||
*/
|
||||
static public <T> T[] trim(T[] array, boolean forceNew) {
|
||||
public static <T> T[] trim(T[] array, boolean forceNew) {
|
||||
int i = array.length;
|
||||
if (i == 0 || array[i - 1] != null) {
|
||||
if (!forceNew) {
|
||||
|
@ -235,7 +234,7 @@ public abstract class ArrayUtil {
|
|||
* @param array the array to be trimmed
|
||||
* @since 5.2
|
||||
*/
|
||||
static public <T> T[] trim(T[] array) {
|
||||
public static <T> T[] trim(T[] array) {
|
||||
return trim(array, false);
|
||||
}
|
||||
|
||||
|
@ -250,7 +249,7 @@ public abstract class ArrayUtil {
|
|||
* @return the modified array, which may be the same as the first parameter.
|
||||
* @since 5.4
|
||||
*/
|
||||
static public <T> T[] trim(T[] array, int newLength) {
|
||||
public static <T> T[] trim(T[] array, int newLength) {
|
||||
if (newLength == array.length)
|
||||
return array;
|
||||
Assert.isTrue(array[newLength] == null);
|
||||
|
|
|
@ -601,7 +601,7 @@ public class ChangeGenerator extends ASTVisitor {
|
|||
int low = 0;
|
||||
int high = preprocessorStatements.length;
|
||||
while (low < high) {
|
||||
int mid = (low + high) / 2;
|
||||
int mid = (low + high) >>> 1;
|
||||
IASTNode statement = preprocessorStatements[mid];
|
||||
if (statement.isPartOfTranslationUnitFile() && endOffset(statement) > offset) {
|
||||
high = mid;
|
||||
|
|
|
@ -252,7 +252,7 @@ public class LinkedNamesFinder {
|
|||
int low = 0;
|
||||
int high = comments.length;
|
||||
while (low < high) {
|
||||
int mid = (low + high) / 2;
|
||||
int mid = (low + high) >>> 1;
|
||||
int offset = comments[mid].getFileLocation().getNodeOffset();
|
||||
if (offset < startOffset) {
|
||||
low = mid + 1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2006 IBM Corporation and others.
|
||||
* Copyright (c) 2005, 2014 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -13,18 +13,16 @@ package org.eclipse.cdt.internal.ui.util;
|
|||
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Quick sort to sort two arrays in parallel.
|
||||
*/
|
||||
public class TwoArrayQuickSort {
|
||||
|
||||
private static void internalSort(String[] keys, Object[] values, int left, int right, boolean ignoreCase) {
|
||||
|
||||
int original_left= left;
|
||||
int original_right= right;
|
||||
|
||||
String mid= keys[(left + right) / 2];
|
||||
String mid= keys[(left + right) >>> 1];
|
||||
do {
|
||||
while (smaller(keys[left], mid, ignoreCase)) {
|
||||
left++;
|
||||
|
@ -53,11 +51,13 @@ public class TwoArrayQuickSort {
|
|||
internalSort(keys, values, left, original_right, ignoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean smaller(String left, String right, boolean ignoreCase) {
|
||||
if (ignoreCase)
|
||||
return left.compareToIgnoreCase(right) < 0;
|
||||
return left.compareTo(right) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts keys and values in parallel.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2011 Wind River Systems and others.
|
||||
* Copyright (c) 2007, 2014 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -48,7 +48,6 @@ import org.eclipse.swt.widgets.Display;
|
|||
* DisassemblyDocument
|
||||
*/
|
||||
public class DisassemblyDocument extends REDDocument implements IDisassemblyDocument {
|
||||
|
||||
public final static String CATEGORY_MODEL = "category_model"; //$NON-NLS-1$
|
||||
public final static String CATEGORY_DISASSEMBLY = "category_disassembly"; //$NON-NLS-1$
|
||||
public final static String CATEGORY_SOURCE = "category_source"; //$NON-NLS-1$
|
||||
|
@ -222,10 +221,8 @@ public class DisassemblyDocument extends REDDocument implements IDisassemblyDocu
|
|||
* given address would be inserted. The position is supposed to become the
|
||||
* first in this list of all positions with the same offset.
|
||||
*
|
||||
* @param positions
|
||||
* the list in which the index is computed
|
||||
* @param address
|
||||
* the address for which the index is computed
|
||||
* @param positions the list in which the index is computed
|
||||
* @param address the address for which the index is computed
|
||||
* @return the computed index
|
||||
*
|
||||
*/
|
||||
|
@ -234,23 +231,24 @@ public class DisassemblyDocument extends REDDocument implements IDisassemblyDocu
|
|||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
int left = 0;
|
||||
int right = size - 1;
|
||||
int low = 0;
|
||||
int high = size;
|
||||
int mid = 0;
|
||||
while (left <= right) {
|
||||
mid = (left + right) / 2;
|
||||
while (low < high) {
|
||||
mid = (low + high) >>> 1;
|
||||
AddressRangePosition range = positions.get(mid);
|
||||
int compareSign = address.compareTo(range.fAddressOffset);
|
||||
if (compareSign < 0) {
|
||||
right = mid - 1;
|
||||
high = mid;
|
||||
} else if (compareSign == 0) {
|
||||
break;
|
||||
} else if (address.compareTo(range.fAddressOffset.add(range.fAddressLength)) >= 0) {
|
||||
left = mid + 1;
|
||||
low = mid + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int idx = mid;
|
||||
AddressRangePosition p = positions.get(idx);
|
||||
if (address.compareTo(p.fAddressOffset) == 0) {
|
||||
|
@ -273,10 +271,8 @@ public class DisassemblyDocument extends REDDocument implements IDisassemblyDocu
|
|||
* given address would be inserted. The position is supposed to become the
|
||||
* last but one in this list of all positions with the same address.
|
||||
*
|
||||
* @param positions
|
||||
* the list in which the index is computed
|
||||
* @param address
|
||||
* the address for which the index is computed
|
||||
* @param positions the list in which the index is computed
|
||||
* @param address the address for which the index is computed
|
||||
* @return the computed index
|
||||
*
|
||||
*/
|
||||
|
@ -285,22 +281,23 @@ public class DisassemblyDocument extends REDDocument implements IDisassemblyDocu
|
|||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
int left = 0;
|
||||
int right = size - 1;
|
||||
int low = 0;
|
||||
int high = size;
|
||||
int mid = 0;
|
||||
while (left <= right) {
|
||||
mid = (left + right) / 2;
|
||||
while (low < high) {
|
||||
mid = (low + high) >>> 1;
|
||||
AddressRangePosition range = positions.get(mid);
|
||||
if (address.compareTo(range.fAddressOffset) < 0) {
|
||||
right = mid - 1;
|
||||
high = mid;
|
||||
} else if (address.compareTo(range.fAddressOffset) == 0) {
|
||||
break;
|
||||
} else if (address.compareTo(range.fAddressOffset.add(range.fAddressLength)) >= 0) {
|
||||
left = mid + 1;
|
||||
low = mid + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int idx = mid;
|
||||
AddressRangePosition p = positions.get(idx);
|
||||
if (address.compareTo(p.fAddressOffset) > 0) {
|
||||
|
@ -323,46 +320,43 @@ public class DisassemblyDocument extends REDDocument implements IDisassemblyDocu
|
|||
* given offset would be inserted. The position is supposed to become the
|
||||
* last in this list of all positions with the same offset.
|
||||
*
|
||||
* @param positions
|
||||
* the list in which the index is computed
|
||||
* @param offset
|
||||
* the offset for which the index is computed
|
||||
* @param positions the list in which the index is computed
|
||||
* @param offset the offset for which the index is computed
|
||||
* @return the computed index
|
||||
*
|
||||
* @see IDocument#computeIndexInCategory(String, int)
|
||||
*/
|
||||
protected int computeIndexInPositionListLast(List<Position> positions, int offset) {
|
||||
|
||||
if (positions.size() == 0)
|
||||
return 0;
|
||||
|
||||
int left = 0;
|
||||
int right = positions.size() - 1;
|
||||
int low = 0;
|
||||
int high = positions.size() - 1;
|
||||
int mid = 0;
|
||||
Position p = null;
|
||||
|
||||
while (left < right) {
|
||||
|
||||
mid = (left + right) / 2;
|
||||
while (low < high) {
|
||||
mid = (low + high) >>> 1;
|
||||
|
||||
p = positions.get(mid);
|
||||
if (offset < p.getOffset()) {
|
||||
if (left == mid)
|
||||
right = left;
|
||||
else
|
||||
right = mid - 1;
|
||||
if (low == mid) {
|
||||
high = low;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
} else if (offset > p.getOffset()) {
|
||||
if (right == mid)
|
||||
left = right;
|
||||
else
|
||||
left = mid + 1;
|
||||
if (high == mid) {
|
||||
low = high;
|
||||
} else {
|
||||
low = mid + 1;
|
||||
}
|
||||
} else if (offset == p.getOffset()) {
|
||||
left = right = mid;
|
||||
low = high = mid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int pos = left;
|
||||
int pos = low;
|
||||
p = positions.get(pos);
|
||||
while (offset >= p.getOffset()) {
|
||||
// entry will become the last of all entries with the same offset
|
||||
|
@ -374,12 +368,11 @@ public class DisassemblyDocument extends REDDocument implements IDisassemblyDocu
|
|||
}
|
||||
|
||||
assert 0 <= pos && pos <= positions.size();
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position for the supplied category and index.
|
||||
* Returns the position for the supplied category and index.
|
||||
*
|
||||
* @param category
|
||||
* @param index
|
||||
|
@ -399,20 +392,11 @@ public class DisassemblyDocument extends REDDocument implements IDisassemblyDocu
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param address
|
||||
* @return
|
||||
*/
|
||||
public AddressRangePosition getPositionOfAddress(BigInteger address) {
|
||||
AddressRangePosition pos = getPositionOfAddress(CATEGORY_DISASSEMBLY, address);
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param category
|
||||
* @param address
|
||||
* @return
|
||||
*/
|
||||
public AddressRangePosition getPositionOfAddress(String category, BigInteger address) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<AddressRangePosition> positions = (List<AddressRangePosition>) getDocumentManagedPositions().get(category);
|
||||
|
|
Loading…
Add table
Reference in a new issue