1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 01:15:29 +02:00

Bug 501616 - ArrayIndexOutOfBoundsException in CPPField.getFieldPosition

Use 16 bits to store field position.

Change-Id: I2856bbc06e1df91ca209508ad3258bad1869087f
This commit is contained in:
Sergey Prigogin 2016-09-16 16:33:11 -07:00
parent fb533553c8
commit 6b2530050f
19 changed files with 103 additions and 63 deletions

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Doug Schaefer (IBM) - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -20,8 +21,10 @@ public interface ICPPField extends IField, ICPPMember, ICPPVariable {
public static final ICPPField[] EMPTY_CPPFIELD_ARRAY = {};
/**
* Returns the position of this field within its class owner's declared fields.
* @since 6.0
* Returns the position of this field within its class owner's declared fields, or -1 if the position
* cannot be determined.
*
* @since 6.1
*/
byte getFieldPosition();
int getFieldPosition();
}

View file

@ -93,7 +93,7 @@ public class CPPClassSpecialization extends CPPSpecialization
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return -1;
}
}

View file

@ -8,6 +8,7 @@
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -50,7 +51,7 @@ public class CPPField extends CPPVariable implements ICPPField {
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return -1;
}
}
@ -99,13 +100,13 @@ public class CPPField extends CPPVariable implements ICPPField {
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return getFieldPosition(getName(), getClassOwner());
}
public static byte getFieldPosition(String fieldName, ICPPClassType classOwner) {
public static int getFieldPosition(String fieldName, ICPPClassType classOwner) {
IField[] fields = ClassTypeHelper.getDeclaredFields(classOwner, null);
for (byte fieldPos = 0; fieldPos < fields.length; fieldPos++) {
for (int fieldPos = 0; fieldPos < fields.length; fieldPos++) {
if (fields[fieldPos].getName().equals(fieldName)) {
return fieldPos;
}

View file

@ -8,6 +8,7 @@
*
* Contributors:
* Lukas Wegmann (IFS) - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -54,7 +55,7 @@ public class CPPFieldInstance extends CPPVariableInstance implements ICPPField {
}
@Override
public byte getFieldPosition() {
return ((ICPPFieldTemplate)getSpecializedBinding()).getFieldPosition();
public int getFieldPosition() {
return ((ICPPFieldTemplate) getSpecializedBinding()).getFieldPosition();
}
}

View file

@ -8,6 +8,7 @@
* Contributors:
* Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -48,7 +49,7 @@ public class CPPFieldSpecialization extends CPPVariableSpecialization implements
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return getField().getFieldPosition();
}
}

View file

@ -8,6 +8,7 @@
*
* Contributors:
* Lukas Wegmann (IFS) - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -53,7 +54,7 @@ public class CPPFieldTemplate extends CPPVariableTemplate implements ICPPFieldTe
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return CPPField.getFieldPosition(getName(), getClassOwner());
}
}

View file

@ -8,6 +8,7 @@
*
* Contributors:
* Lukas Wegmann (IFS) - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -45,7 +46,7 @@ public class CPPFieldTemplatePartialSpecialization extends CPPVariableTemplatePa
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return ((ICPPFieldTemplate) getPrimaryTemplate()).getFieldPosition();
}
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -87,7 +88,7 @@ public class CPPUnknownField extends CPPUnknownMember implements ICPPField {
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return -1;
}
}

View file

@ -41,7 +41,7 @@ class CompositeCPPField extends CompositeCPPVariable implements ICPPField {
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return ((ICPPField)rbinding).getFieldPosition();
}
}

View file

@ -41,7 +41,7 @@ public class CompositeCPPFieldInstance extends CompositeCPPVariableInstance impl
}
@Override
public byte getFieldPosition() {
return ((ICPPField)rbinding).getFieldPosition();
public int getFieldPosition() {
return ((ICPPField) rbinding).getFieldPosition();
}
}

View file

@ -41,7 +41,7 @@ public class CompositeCPPFieldTemplate extends CompositeCPPVariableTemplate impl
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return ((ICPPField) rbinding).getFieldPosition();
}
}

View file

@ -43,7 +43,7 @@ public class CompositeCPPFieldTemplatePartialSpecialization
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return ((ICPPField) rbinding).getFieldPosition();
}
}

View file

@ -16,20 +16,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IPDOMNode;
@ -100,6 +86,20 @@ import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.Status;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Database for storing semantic information for one project.
*/
@ -274,10 +274,11 @@ public class PDOM extends PlatformObject implements IPDOM {
*
* CDT 9.2 development (versions not supported on the 9.0.x branch)
* 202.0 - C++14 constexpr evaluation, bug 490475.
* 202.0 - Use 16 bits to store field position, bug 501616.
*/
private static final int MIN_SUPPORTED_VERSION= version(202, 0);
private static final int MAX_SUPPORTED_VERSION= version(202, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(202, 0);
private static final int MIN_SUPPORTED_VERSION= version(203, 0);
private static final int MAX_SUPPORTED_VERSION= version(203, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(203, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;

View file

@ -9,6 +9,7 @@
* Doug Schaefer (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
@ -207,6 +208,7 @@ public abstract class PDOMNode implements IInternalPDOMNode {
/**
* Convenience method for fetching a byte from the database.
*
* @param offset Location of the byte.
* @return a byte from the database.
*/
@ -219,6 +221,21 @@ public abstract class PDOMNode implements IInternalPDOMNode {
}
}
/**
* Convenience method for fetching a two-byte integer number from the database.
*
* @param offset Location of the number
* @return a number from the database.
*/
protected short getShort(long offset) {
try {
return getDB().getShort(offset);
} catch (CoreException e) {
CCorePlugin.log(e);
return 0;
}
}
/**
* Returns the bit at the specified offset in a bit vector.
* @param bitVector Bits.

View file

@ -9,16 +9,17 @@
* QNX - Initial API and implementation
* IBM Corporation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
@ -27,10 +28,10 @@ import org.eclipse.core.runtime.CoreException;
* @author Doug Schaefer
*/
class PDOMCPPField extends PDOMCPPVariable implements ICPPField {
protected static final int FIELD_POSITION_OFFSET = PDOMCPPVariable.RECORD_SIZE; // byte
protected static final int FIELD_POSITION_OFFSET = PDOMCPPVariable.RECORD_SIZE; // 2 bytes 1-based
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = FIELD_POSITION_OFFSET + 1;
protected static final int RECORD_SIZE = FIELD_POSITION_OFFSET + 2;
public PDOMCPPField(PDOMLinkage linkage, PDOMNode parent, ICPPField field, boolean setTypeAndValue)
throws CoreException {
@ -50,11 +51,6 @@ class PDOMCPPField extends PDOMCPPVariable implements ICPPField {
}
}
private void setFieldPosition(ICPPField field) throws CoreException {
final Database db = getDB();
db.putByte(record + FIELD_POSITION_OFFSET, field.getFieldPosition());
}
@Override
protected int getRecordSize() {
return RECORD_SIZE;
@ -109,7 +105,16 @@ class PDOMCPPField extends PDOMCPPVariable implements ICPPField {
}
@Override
public byte getFieldPosition() {
return getByte(record + FIELD_POSITION_OFFSET);
public int getFieldPosition() {
return Short.toUnsignedInt(getShort(record + FIELD_POSITION_OFFSET)) - 1;
}
private void setFieldPosition(ICPPField field) throws CoreException {
int shiftedPos = field.getFieldPosition() + 1;
if ((shiftedPos & 0xFFFF0000) != 0) {
CCorePlugin.log(new IllegalArgumentException("Invalid field position " + field.getFieldPosition())); //$NON-NLS-1$
shiftedPos = 0;
}
getDB().putShort(record + FIELD_POSITION_OFFSET, (short) shiftedPos);
}
}

View file

@ -8,6 +8,7 @@
*
* Contributors:
* Lukas Wegmann (IFS) - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
@ -53,7 +54,7 @@ public class PDOMCPPFieldInstance extends PDOMCPPVariableInstance implements ICP
}
@Override
public byte getFieldPosition() {
return ((ICPPField)getSpecializedBinding()).getFieldPosition();
public int getFieldPosition() {
return ((ICPPField) getSpecializedBinding()).getFieldPosition();
}
}

View file

@ -6,8 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Bryan Wilkinson (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
@ -131,7 +132,7 @@ class PDOMCPPFieldSpecialization extends PDOMCPPSpecialization implements ICPPFi
}
@Override
public byte getFieldPosition() {
public int getFieldPosition() {
return getField().getFieldPosition();
}
}

View file

@ -8,25 +8,26 @@
*
* Contributors:
* Lukas Wegmann (IFS) - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
public class PDOMCPPFieldTemplate extends PDOMCPPVariableTemplate implements ICPPFieldTemplate {
protected static final int FIELD_POSITION_OFFSET = PDOMCPPVariableTemplate.RECORD_SIZE; // byte
protected static final int FIELD_POSITION_OFFSET = PDOMCPPVariableTemplate.RECORD_SIZE; // 2 bytes 1-based
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = FIELD_POSITION_OFFSET + 1;
protected static final int RECORD_SIZE = FIELD_POSITION_OFFSET + 2;
public PDOMCPPFieldTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPFieldTemplate template)
throws CoreException, DOMException {
@ -38,11 +39,6 @@ public class PDOMCPPFieldTemplate extends PDOMCPPVariableTemplate implements ICP
super(pdomLinkage, record);
}
private void setFieldPosition(ICPPField field) throws CoreException {
final Database db = getDB();
db.putByte(record + FIELD_POSITION_OFFSET, field.getFieldPosition());
}
@Override
public int getNodeType() {
return IIndexCPPBindingConstants.CPP_FIELD_TEMPLATE;
@ -64,7 +60,16 @@ public class PDOMCPPFieldTemplate extends PDOMCPPVariableTemplate implements ICP
}
@Override
public byte getFieldPosition() {
return getByte(record + FIELD_POSITION_OFFSET);
public int getFieldPosition() {
return Short.toUnsignedInt(getShort(record + FIELD_POSITION_OFFSET)) - 1;
}
private void setFieldPosition(ICPPField field) throws CoreException {
int shiftedPos = field.getFieldPosition() + 1;
if ((shiftedPos & 0xFFFF0000) != 0) {
CCorePlugin.log(new IllegalArgumentException("Invalid field position " + field.getFieldPosition())); //$NON-NLS-1$
shiftedPos = 0;
}
getDB().putShort(record + FIELD_POSITION_OFFSET, (short) shiftedPos);
}
}

View file

@ -8,6 +8,7 @@
*
* Contributors:
* Lukas Wegmann (IFS) - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
@ -75,7 +76,7 @@ public class PDOMCPPFieldTemplatePartialSpecialization extends PDOMCPPVariableTe
}
@Override
public byte getFieldPosition() {
return ((ICPPField)getPrimaryTemplate()).getFieldPosition();
public int getFieldPosition() {
return ((ICPPField) getPrimaryTemplate()).getFieldPosition();
}
}