<commit_before>/**
 * OWASP Enterprise Security API (ESAPI)
 * 
 * This file is part of the Open Web Application Security Project (OWASP)
 * Enterprise Security API (ESAPI) project. For details, please see
 * http://www.owasp.org/esapi.
 *
 * Copyright (c) 2007 - The OWASP Foundation
 * 
 * The ESAPI is published by OWASP under the LGPL. You should read and accept the
 * LICENSE before you use, modify, and/or redistribute this software.
 * 
 * @author <NAME> <a href="http://www.aspectsecurity.com">Aspect Security</a>
 * @created 2007
 */
package org.owasp.esapi;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.owasp.esapi.errors.EncodingException;
import org.owasp.esapi.errors.IntrusionException;
import org.owasp.esapi.errors.ValidationAvailabilityException;
import org.owasp.esapi.errors.ValidationException;
import org.owasp.validator.html.AntiSamy;
import org.owasp.validator.html.CleanResults;
import org.owasp.validator.html.Policy;
import org.owasp.validator.html.PolicyException;
import org.owasp.validator.html.ScanException;

/**
 * Reference implementation of the IValidator interface. This implementation
 * relies on the ESAPI Encoder, Java Pattern (regex), Date,
 * and several other classes to provide basic validation functions. This library
 * has a heavy emphasis on whitelist validation and canonicalization. All double-encoded
 * characters, even in multiple encoding schemes, such as <PRE>&amp;lt;</PRE> or
 * <PRE>%26lt;<PRE> or even <PRE>%25%26lt;</PRE> are disallowed.
 * 
 * @author <NAME> (jeff.williams .at. aspectsecurity.com) <a href="http://www.aspectsecurity.com">Aspect Security</a>
 * @author <NAME>(jim.manico .at. aspectsecurity.com) <a href="http://www.aspectsecurity.com">Aspect Security</a>
 *
 * @since June 1, 2007
 * @see org.owasp.esapi.interfaces.IValidator
 */
public class Validator implements org.owasp.esapi.interfaces.IValidator {

	/** The logger. */
	private static final Logger logger = Logger.getLogger("ESAPI", "Validator");
	
	/** OWASP AntiSamy markup verification policy */
	private Policy antiSamyPolicy = null;
	
	/** constants */
	private static final int MAX_CREDIT_CARD_LENGTH = 19;
	private static final int MAX_PARAMETER_NAME_LENGTH = 100;
	private static final int MAX_PARAMETER_VALUE_LENGTH = 10000;
	
	public Validator() {
	}
	

	/**
	 * Returns true if data received from browser is valid. Only URL encoding is
	 * supported. Double encoding is treated as an attack.
	 */
	public boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws IntrusionException  {
		try {
			getValidInput(context, input, type, maxLength, allowNull);
			return true;
		} catch( Exception e ) {
			return false;
		}
	}

	/**
	 * Validates data received from the browser and returns a safe version. Only
	 * URL encoding is supported. Double encoding is treated as an attack.
	 */
	public String getValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws ValidationException, IntrusionException {

		try {
			
			//System.out.println("ESAPI Raw Input=" + input);
			
			context = ESAPI.encoder().canonicalize( context );
    		String canonical = ESAPI.encoder().canonicalize( input );
    		
    		//System.out.println("ESAPI Cannonicalizied input=" + canonical);
    		
    		if (isEmpty(canonical)) {
    			if (allowNull) return null;
       			throw new ValidationException( "Input required: context=" + context, "Input required: context=" + context + ", type=" + type + "), input=" + input );
    		}
    		
    		//System.out.println("ESAPI allow null check passed");
    		
    		if (canonical.length() > maxLength) {
    			//FIXME: ENHANCE if the length is exceeded by a wide margin, throw IntrusionException?
    			throw new ValidationException( "Input can not exceed " + maxLength + " characters: context=" + context, "Input exceeds maximum allowed length of " + maxLength + " by " + (canonical.length()-maxLength) + " characters: context=" + context + ", type=" + type + "), input=" + input);
    		}
    		
    		//System.out.println("ESAPI maxLength check passed");
    		
    		if ( type == null || type.length() == 0 ) {
    			throw new ValidationException("Invalid input: context=" + context, "Validation misconfiguration, specified type to validate against was null: context=" + context + ", type=" + type + "), input=" + input );
    		}
    		
    		//System.out.println("ESAPI type null check passed");
    		
    		Pattern p = ((SecurityConfiguration)ESAPI.securityConfiguration()).getValidationPattern( type );
    		if ( p == null ) {
    			try {
    				p = Pattern.compile( type );
    			} catch( PatternSyntaxException e ) {
    				throw new ValidationException("Invalid input: context=" + context, "Validation misconfiguration, type to validate against must be defined in ESAPI.properties or a valid regular expression: context=" + context + ", type=" + type + "), input=" + input );
    			}
    		}
    		
    		//System.out.println("ESAPI pattern compiles check passed for pattern ");
    		
    		if ( !p.matcher(canonical).matches() ) {
    			throw new ValidationException("Invalid input: context=" + context, "Invalid input: context=" + context + ", type=" + type + "(" + p.pattern() + "), input=" + input );
    		}
    		
    		//System.out.println("ESAPI pattern match check passed");
    		
    		// if everything passed, then return the canonical form
    		return canonical;
    		
	    } catch (EncodingException e) {
	        throw new ValidationException("Invalid input: context=" + context, "Error canonicalizing user input", e);
	    }
	}

	/**
	 * Returns true if input is a valid date according to the specified date format.
	 */
	public boolean isValidDate(String context, String input, DateFormat format, boolean allowNull) throws IntrusionException {
		try {
			getValidDate(context, input, format, allowNull);
			return true;<commit_msg>removed my garbage code so Jeff does not smite me<commit_after>/**
 * OWASP Enterprise Security API (ESAPI)
 * 
 * This file is part of the Open Web Application Security Project (OWASP)
 * Enterprise Security API (ESAPI) project. For details, please see
 * http://www.owasp.org/esapi.
 *
 * Copyright (c) 2007 - The OWASP Foundation
 * 
 * The ESAPI is published by OWASP under the LGPL. You should read and accept the
 * LICENSE before you use, modify, and/or redistribute this software.
 * 
 * @author <NAME> <a href="http://www.aspectsecurity.com">Aspect Security</a>
 * @created 2007
 */
package org.owasp.esapi;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.owasp.esapi.errors.EncodingException;
import org.owasp.esapi.errors.IntrusionException;
import org.owasp.esapi.errors.ValidationAvailabilityException;
import org.owasp.esapi.errors.ValidationException;
import org.owasp.validator.html.AntiSamy;
import org.owasp.validator.html.CleanResults;
import org.owasp.validator.html.Policy;
import org.owasp.validator.html.PolicyException;
import org.owasp.validator.html.ScanException;

/**
 * Reference implementation of the IValidator interface. This implementation
 * relies on the ESAPI Encoder, Java Pattern (regex), Date,
 * and several other classes to provide basic validation functions. This library
 * has a heavy emphasis on whitelist validation and canonicalization. All double-encoded
 * characters, even in multiple encoding schemes, such as <PRE>&amp;lt;</PRE> or
 * <PRE>%26lt;<PRE> or even <PRE>%25%26lt;</PRE> are disallowed.
 * 
 * @author <NAME> (jeff.williams .at. aspectsecurity.com) <a href="http://www.aspectsecurity.com">Aspect Security</a>
 * @author <NAME>(jim.manico .at. aspectsecurity.com) <a href="http://www.aspectsecurity.com">Aspect Security</a>
 *
 * @since June 1, 2007
 * @see org.owasp.esapi.interfaces.IValidator
 */
public class Validator implements org.owasp.esapi.interfaces.IValidator {

	/** The logger. */
	private static final Logger logger = Logger.getLogger("ESAPI", "Validator");
	
	/** OWASP AntiSamy markup verification policy */
	private Policy antiSamyPolicy = null;
	
	/** constants */
	private static final int MAX_CREDIT_CARD_LENGTH = 19;
	private static final int MAX_PARAMETER_NAME_LENGTH = 100;
	private static final int MAX_PARAMETER_VALUE_LENGTH = 10000;
	
	public Validator() {
	}
	

	/**
	 * Returns true if data received from browser is valid. Only URL encoding is
	 * supported. Double encoding is treated as an attack.
	 */
	public boolean isValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws IntrusionException  {
		try {
			getValidInput(context, input, type, maxLength, allowNull);
			return true;
		} catch( Exception e ) {
			return false;
		}
	}

	/**
	 * Validates data received from the browser and returns a safe version. Only
	 * URL encoding is supported. Double encoding is treated as an attack.
	 */
	public String getValidInput(String context, String input, String type, int maxLength, boolean allowNull) throws ValidationException, IntrusionException {

		try {
			context = ESAPI.encoder().canonicalize( context );
    		String canonical = ESAPI.encoder().canonicalize( input );

    		if (isEmpty(canonical)) {
    			if (allowNull) return null;
       			throw new ValidationException( "Input required: context=" + context, "Input required: context=" + context + ", type=" + type + "), input=" + input );
    		}

    		if (canonical.length() > maxLength) {
    			//FIXME: ENHANCE if the length is exceeded by a wide margin, throw IntrusionException?
    			throw new ValidationException( "Input can not exceed " + maxLength + " characters: context=" + context, "Input exceeds maximum allowed length of " + maxLength + " by " + (canonical.length()-maxLength) + " characters: context=" + context + ", type=" + type + "), input=" + input);
    		}

    		if ( type == null || type.length() == 0 ) {
    			throw new ValidationException("Invalid input: context=" + context, "Validation misconfiguration, specified type to validate against was null: context=" + context + ", type=" + type + "), input=" + input );
    		}

    		//TODO - let us know when its a ESAPI.properties config problem! This exception does not diffrentiate
    		Pattern p = ((SecurityConfiguration)ESAPI.securityConfiguration()).getValidationPattern( type );
    		if ( p == null ) {
    			try {
    				p = Pattern.compile( type );
    			} catch( PatternSyntaxException e ) {
    				throw new ValidationException("Invalid input: context=" + context, "Validation misconfiguration, type to validate against must be defined in ESAPI.properties or a valid regular expression: context=" + context + ", type=" + type + "), input=" + input );
    			}
    		}

    		if ( !p.matcher(canonical).matches() ) {
    			throw new ValidationException("Invalid input: context=" + context, "Invalid input: context=" + context + ", type=" + type + "(" + p.pattern() + "), input=" + input );
    		}
    		
    		return canonical;
    		
	    } catch (EncodingException e) {
	        throw new ValidationException("Invalid input: context=" + context, "Error canonicalizing user input", e);
	    }
	}

	/**
	 * Returns true if input is a valid date according to the specified date format.
	 */
	public boolean isValidDate(String context, String input, DateFormat format, boolean allowNull) throws IntrusionException {
		try {
			getValidDate(context, input, format, allowNull);
			return true;
{'fraction_non_alphanumeric': 0.1125142577806746, 'fraction_numerical': 0.004888381945576014, 'mean_word_length': 3.781846513439813, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 8, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3379391', 'n_tokens_mistral': 3706, 'n_tokens_neox': 3461, 'n_words': 1123}