1
0
Fork 0
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:
Sergey Prigogin 2014-04-16 12:10:39 -07:00
parent d7ceaaed42
commit 4381cc5da1
6 changed files with 68 additions and 83 deletions

View file

@ -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.

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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.
*/

View file

@ -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);