CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-net-sourceforge-pmd--pmd-visualforce

PMD language module that provides static code analysis capabilities for Salesforce Visualforce pages and components

Pending
Overview
Eval results
Files

type-analysis.mddocs/

Type Analysis and Salesforce Integration

Type system integration with Salesforce metadata for context-aware analysis of Visualforce expressions and data binding. This capability enables sophisticated analysis of data flow and security risks in Visualforce applications.

Capabilities

DataType Enum

Comprehensive enumeration of all data types that can be referenced from Visualforce pages, consolidating CustomField types and Apex types.

/**
 * Represents all data types available in Visualforce expressions
 * Consolidates Salesforce CustomField types and Apex primitive types
 * Uses CustomField naming conventions for consistency
 */
public enum DataType {
    // Standard Salesforce field types
    AutoNumber(false),
    Checkbox(false, "Boolean"),
    Currency(false, "Currency"), 
    Date(false, "Date"),
    DateTime(false, "Datetime"),
    Email(false),
    EncryptedText(true),
    ExternalLookup(true),
    File(false),
    Hierarchy(false),
    Html(false),
    IndirectLookup(false),
    Location(false),
    LongTextArea(true),
    Lookup(false, "Id"),
    MasterDetail(false),
    MetadataRelationship(false),
    MultiselectPicklist(true),
    Note(true),
    Number(false, "Decimal", "Double", "Integer", "Long"),
    Percent(false),
    Phone(false),
    Picklist(true),
    Summary(false),
    Text(true, "String"),
    TextArea(true),
    Time(false, "Time"),
    Url(false),
    
    /** Fallback for unmappable or ambiguous types */
    Unknown(true);
    
    /**
     * Indicates if this data type requires escaping to prevent XSS attacks
     * Critical for security analysis of Visualforce expressions
     */
    public final boolean requiresEscaping;
    
    /**
     * Map string representation to DataType instance
     * Returns Unknown if mapping fails
     * @param value String representation of data type
     * @return DataType instance, or Unknown if unmappable
     */
    public static DataType fromString(String value);
    
    /**
     * Map primitive type name to DataType instance
     * Returns Unknown if mapping fails  
     * @param value Primitive type name (e.g., "String", "Integer")
     * @return DataType instance, or Unknown if unmappable
     */
    public static DataType fromTypeName(String value);
}

Usage Example:

import net.sourceforge.pmd.lang.visualforce.DataType;

// Map field type to DataType
DataType stringType = DataType.fromString("Text");
DataType numberType = DataType.fromTypeName("Integer");

// Check if type requires escaping for XSS prevention
if (stringType.requiresEscaping) {
    System.out.println("Text fields require output escaping");
}

// Handle unknown types
DataType unknownType = DataType.fromString("CustomType");
if (unknownType == DataType.Unknown) {
    System.out.println("Type could not be determined from metadata");
}

VfExpressionTypeVisitor

Internal visitor that enhances AST nodes with type information from Salesforce metadata analysis.

/**
 * Visitor that adds type information to Visualforce AST nodes
 * Analyzes expressions against Apex classes and Salesforce objects
 * Called automatically by VfParser during AST construction
 */
public class VfExpressionTypeVisitor {
    /**
     * Create type visitor with parser task and language properties
     * @param task Parser task containing source information
     * @param vfProperties Configuration with Apex and Object directories
     */
    public VfExpressionTypeVisitor(ParserTask task, VfLanguageProperties vfProperties);
    
    /**
     * Visit AST root and enhance nodes with type information
     * @param root Root compilation unit
     * @param data Context data (typically null)
     */
    public void visit(ASTCompilationUnit root, Object data);
}

VfTypedNode Interface

Interface for AST nodes that have been enhanced with type information.

/**
 * Interface for AST nodes that contain type information
 * Represents a node that displays a piece of data
 */
public interface VfTypedNode extends VfNode {
    /**
     * Get the resolved data type for this node's value
     * A null value indicates that no matching metadata was found for this node
     * null differs from DataType.Unknown which indicates metadata was found but wasn't mappable
     * @return DataType representing the node's type, or null if no metadata found
     */
    DataType getDataType();
}

Salesforce Metadata Integration

Components for analyzing and integrating with Salesforce metadata to resolve types in Visualforce expressions.

/**
 * Manages property types for Apex classes referenced in Visualforce
 * Analyzes Apex class files to resolve property and method types
 */
public class ApexClassPropertyTypes {
    /**
     * Load and analyze Apex classes from configured directories
     * @param apexDirectories List of directories containing Apex classes
     */
    public ApexClassPropertyTypes(List<String> apexDirectories);
    
    /**
     * Get property type for specified class and property name
     * @param className Fully qualified Apex class name
     * @param propertyName Property or method name
     * @return DataType of the property, or Unknown if not found
     */
    public DataType getPropertyType(String className, String propertyName);
    
    /**
     * Check if class is known from analysis
     * @param className Fully qualified class name
     * @return true if class was found and analyzed
     */
    public boolean hasClass(String className);
}

/**
 * Visitor for analyzing Apex class property types
 * Traverses Apex AST to extract type information
 */
public class ApexClassPropertyTypesVisitor {
    /**
     * Visit Apex class AST to extract property type information
     * @param apexRoot Root of Apex AST
     * @param className Class name being analyzed
     * @return Map of property names to their DataTypes
     */
    public Map<String, DataType> visit(Node apexRoot, String className);
}

/**
 * Manages field types for Salesforce standard and custom objects
 * Analyzes object metadata files to resolve field types
 */
public class ObjectFieldTypes {
    /**
     * Load and analyze object definitions from configured directories
     * @param objectDirectories List of directories containing object metadata
     */
    public ObjectFieldTypes(List<String> objectDirectories);
    
    /**
     * Get field type for specified object and field name
     * @param objectName API name of Salesforce object
     * @param fieldName API name of field
     * @return DataType of the field, or Unknown if not found
     */
    public DataType getFieldType(String objectName, String fieldName);
    
    /**
     * Check if object is known from metadata analysis
     * @param objectName API name of object
     * @return true if object metadata was found and analyzed
     */
    public boolean hasObject(String objectName);
}

/**
 * Utility class for Salesforce standard field types
 * Provides type information for standard objects and fields
 */
public class SalesforceFieldTypes {
    /**
     * Get type for standard object field
     * @param objectName Standard object name (Account, Contact, etc.)
     * @param fieldName Standard field name
     * @return DataType of standard field, or Unknown if not standard
     */
    public static DataType getStandardFieldType(String objectName, String fieldName);
    
    /**
     * Check if field is a standard Salesforce field
     * @param objectName Object name
     * @param fieldName Field name  
     * @return true if this is a known standard field
     */
    public static boolean isStandardField(String objectName, String fieldName);
}

Usage Example:

import net.sourceforge.pmd.lang.visualforce.ast.*;
import net.sourceforge.pmd.lang.visualforce.DataType;

/**
 * Rule that uses type information to detect XSS vulnerabilities
 */
public class TypeAwareXssRule extends AbstractVfRule {
    
    @Override
    public Object visit(ASTElExpression expression, Object data) {
        // Check if this is a typed node with type information
        if (expression instanceof VfTypedNode) {
            VfTypedNode typedNode = (VfTypedNode) expression;
            DataType dataType = typedNode.getDataType();
            
            // Check if type information exists and requires escaping
            if (dataType != null && dataType.requiresEscaping && isInOutputContext(expression)) {
                addViolation(data, expression,
                    "Potentially unsafe output of " + dataType + 
                    " type - consider using HTMLENCODE() or JSENCODE()");
            }
        }
        
        return super.visit(expression, data);
    }
    
    private boolean isInOutputContext(ASTElExpression expression) {
        // Logic to determine if expression is in output context
        // (as opposed to being used in conditional logic, etc.)
        return true; // Simplified for example
    }
}

Integration with Analysis Pipeline

The type analysis system integrates with the overall parsing pipeline:

  1. Parser Integration: VfExpressionTypeVisitor is automatically invoked during parsing
  2. Metadata Loading: Apex and Object metadata is loaded based on VfLanguageProperties configuration
  3. Type Enhancement: AST nodes are enhanced with type information during construction
  4. Rule Access: Rules can access type information through VfTypedNode interface

Configuration Example:

import net.sourceforge.pmd.lang.visualforce.VfLanguageProperties;
import java.util.Arrays;

// Configure type analysis paths
VfLanguageProperties properties = new VfLanguageProperties();

// Set Apex class directories for type resolution
properties.setProperty(VfLanguageProperties.APEX_DIRECTORIES_DESCRIPTOR,
    Arrays.asList("/force-app/main/default/classes"));

// Set Object metadata directories
properties.setProperty(VfLanguageProperties.OBJECTS_DIRECTORIES_DESCRIPTOR,
    Arrays.asList("/force-app/main/default/objects"));

// Parser will automatically use these paths for type analysis
VfParser parser = new VfParser(properties);

Security Analysis Integration

The type system is specifically designed to support security analysis:

  • XSS Detection: requiresEscaping flag identifies types that need output encoding
  • Data Flow Analysis: Type information enables tracking of data from sources to sinks
  • Context Awareness: Different escaping requirements based on output context (HTML, JavaScript, CSS)
  • Metadata Integration: Real-time analysis against actual Salesforce org metadata

This capability enables sophisticated security analysis that goes beyond simple pattern matching to understand the actual data flow and security implications of Visualforce expressions.

Install with Tessl CLI

npx tessl i tessl/maven-net-sourceforge-pmd--pmd-visualforce

docs

ast-parsing.md

index.md

language-module.md

rule-development.md

type-analysis.md

tile.json