All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.jimple.infoflow.sourcesSinks.definitions.FieldSourceSinkDefinition Maven / Gradle / Ivy

There is a newer version: 2.9.0
Show newest version
package soot.jimple.infoflow.sourcesSinks.definitions;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * Class for defining fields as sources or sinks
 * 
 * @author Steven Arzt
 *
 */
public class FieldSourceSinkDefinition extends AbstractSourceSinkDefinition
		implements IAccessPathBasedSourceSinkDefinition {

	protected final String fieldSignature;
	protected Set accessPaths;

	/**
	 * Creates a new instance of the {@link FieldSourceSinkDefinition} class
	 * 
	 * @param fieldSignature The Soot signature of the target field
	 */
	public FieldSourceSinkDefinition(String fieldSignature) {
		this(fieldSignature, null);
	}

	/**
	 * Creates a new instance of the {@link FieldSourceSinkDefinition} class
	 * 
	 * @param fieldSignature The Soot signature of the target field
	 * @param accessPaths    The access paths on the field that have been defined as
	 *                       sources or sinks
	 */
	public FieldSourceSinkDefinition(String fieldSignature, Set accessPaths) {
		this.fieldSignature = fieldSignature;
		this.accessPaths = accessPaths;
	}

	/**
	 * Gets the signature of the referenced Soot field
	 * 
	 * @return The signature of the referenced Soot field
	 */
	public String getFieldSignature() {
		return fieldSignature;
	}

	/**
	 * Gets the access paths on the field that have been defined as sources or sinks
	 * 
	 * @return The access paths on the field that have been defined as sources or
	 *         sinks
	 */
	public Set getAccessPaths() {
		return accessPaths;
	}

	@Override
	public FieldSourceSinkDefinition getSourceOnlyDefinition() {
		Set sources = null;
		if (accessPaths != null) {
			sources = new HashSet<>(accessPaths.size());
			for (AccessPathTuple apt : accessPaths)
				if (apt.getSourceSinkType().isSource())
					sources.add(apt);
		}
		return buildNewDefinition(sources);
	}

	@Override
	public FieldSourceSinkDefinition getSinkOnlyDefinition() {
		Set sinks = null;
		if (accessPaths != null) {
			sinks = new HashSet<>(accessPaths.size());
			for (AccessPathTuple apt : accessPaths)
				if (apt.getSourceSinkType().isSink())
					sinks.add(apt);
		}
		return buildNewDefinition(sinks);
	}

	/**
	 * Factory method for creating a new field-based source/sink definition based on
	 * the current one. This method is used when transforming the current
	 * definition. Derived classes can override this method to create instances of
	 * the correct class.
	 * 
	 * @param accessPaths The of access paths for the new definition
	 * @return The new source/sink definition
	 */
	protected FieldSourceSinkDefinition buildNewDefinition(Set accessPaths) {
		return buildNewDefinition(fieldSignature, accessPaths);
	}

	/**
	 * Factory method for creating a new field-based source/sink definition based on
	 * the current one. This method is used when transforming the current
	 * definition. Derived classes can override this method to create instances of
	 * the correct class.
	 * 
	 * @param fieldSignature The field signature
	 * @param accessPaths    The of access paths for the new definition
	 * @return The new source/sink definition
	 */
	protected FieldSourceSinkDefinition buildNewDefinition(String fieldSignature, Set accessPaths) {
		return new FieldSourceSinkDefinition(fieldSignature, accessPaths);
	}

	@Override
	public void merge(ISourceSinkDefinition other) {
		if (other instanceof FieldSourceSinkDefinition) {
			FieldSourceSinkDefinition otherField = (FieldSourceSinkDefinition) other;

			// Merge the base object definitions
			if (otherField.accessPaths != null && !otherField.accessPaths.isEmpty()) {
				if (this.accessPaths == null)
					this.accessPaths = new HashSet<>();
				for (AccessPathTuple apt : otherField.accessPaths)
					this.accessPaths.add(apt);
			}
		}
	}

	@Override
	public boolean isEmpty() {
		return accessPaths == null || accessPaths.isEmpty();
	}

	@Override
	public Set getAllAccessPaths() {
		return accessPaths;
	}

	@Override
	public IAccessPathBasedSourceSinkDefinition filter(Collection toFilter) {
		// Filter the access paths
		Set filteredAPs = null;
		if (accessPaths != null && !accessPaths.isEmpty()) {
			filteredAPs = new HashSet<>(accessPaths.size());
			for (AccessPathTuple ap : accessPaths)
				if (toFilter.contains(ap))
					filteredAPs.add(ap);
		}
		FieldSourceSinkDefinition def = buildNewDefinition(fieldSignature, filteredAPs);
		def.setCategory(category);
		return def;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((accessPaths == null) ? 0 : accessPaths.hashCode());
		result = prime * result + ((fieldSignature == null) ? 0 : fieldSignature.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		FieldSourceSinkDefinition other = (FieldSourceSinkDefinition) obj;
		if (accessPaths == null) {
			if (other.accessPaths != null)
				return false;
		} else if (!accessPaths.equals(other.accessPaths))
			return false;
		if (fieldSignature == null) {
			if (other.fieldSignature != null)
				return false;
		} else if (!fieldSignature.equals(other.fieldSignature))
			return false;
		return true;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy