Bug 123893

Summary: CCE in ResolvedAnnotation
Product: [Eclipse Project] JDT Reporter: Dirk Baeumer <dirk_baeumer>
Component: CoreAssignee: Kent Johnson <kent_johnson>
Status: VERIFIED FIXED QA Contact:
Severity: major    
Priority: P3    
Version: 3.2   
Target Milestone: 3.2 M5   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Dirk Baeumer CLA 2006-01-14 17:58:22 EST
A class cast exception happens in getAllMemberValuePairs due to the fact that the names array is an array of Strings and the comparator cast those elements to char[].

Additionally the insertion loop at the end can produce an AIOBE since the returned value from binarySearch is the negative insertion index and can therefore be less than -1. 

The correct code of the method should be as follows:

		// handle case of more methods than declared members
		char[][] names = new char[declaredLength][];
		for (int i = 0; i < declaredLength; i++)
			names[i] = pairs[i].getName().toCharArray();
		Comparator comparator = new Comparator() {
			public int compare(Object arg0, Object arg1) {
				return CharOperation.compareWith((char[]) arg0, (char[]) arg1);
			}
		};
		Arrays.sort(names, comparator);
		IResolvedMemberValuePair[] allPairs = new  IResolvedMemberValuePair[methodLength];
		for (int i = 0; i < methodLength; i++) {
			int index = Arrays.binarySearch(names, methods[i].selector, comparator);
			allPairs[i] = index < 0 
				? new ResolvedDefaultValuePair(methods[i], this.bindingResolver) 
				: pairs[index];
		}
		return allPairs;

The are some additionally comments here:

- the algorithm sorts the names not the pairs but the index is used at the end 
  to access the pairs not the names. So this only works if all names are found
  since the picked pair might not match the name for which the binary search
  is used.
Comment 1 Kent Johnson CLA 2006-01-16 15:48:49 EST
SO much for inheriting code.

Dirk, do you have a case we can test against?
Comment 2 Dirk Baeumer CLA 2006-01-17 04:19:32 EST
Not a public one. However making a test case is simple:

- create an annotation with two default values and a non default value.
- when sorted the default value should come after the non default value
- reference the annotation only providing the non default value
- resolve an IResolvedAnnotation from it
- call getAllMemberValuePairs

This should produce both exception.
Comment 3 David Audel CLA 2006-02-14 07:37:46 EST
Verified for 3.2 M5 using build I20060214-0010