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

org.owasp.fileio.codecs.PushbackString Maven / Gradle / Ivy

Go to download

The OWASP Java File I/O Security Project provides an easy to use library for validating and sanitizing filenames, directory paths, and uploaded files.

The newest version!
/**
 * This file is part of the Open Web Application Security Project (OWASP) Java File IO Security project. For details, please see
 * https://www.owasp.org/index.php/OWASP_Java_File_I_O_Security_Project.
 *
 * Copyright (c) 2014 - The OWASP Foundation
 *
 * This API is published by OWASP under the Apache 2.0 license. You should read and accept the LICENSE before you use, modify, and/or redistribute this software.
 *
 * @author Jeff Williams Aspect Security - Original ESAPI author
 * @author August Detlefsen CodeMagi - Java File IO Security Project lead
 * @created 2014
 */
package org.owasp.fileio.codecs;

/**
 * The pushback string is used by Codecs to allow them to push decoded characters back onto a string for further decoding. This is necessary to detect double-encoding.
 */
public class PushbackString {

    private String input;
    private Character pushback;
    private Character temp;
    private int index = 0;
    private int mark = 0;

    /**
     * Constructs a new instance of PushbackString
     * @param input the String to decode
     */
    public PushbackString(String input) {
	this.input = input;
    }

    /**
     *
     * @param c The character to set as the pushback
     */
    public void pushback(Character c) {
	pushback = c;
    }

    /**
     * Get the current index of the PushbackString. Typically used in error messages.
     *
     * @return The current index of the PushbackString.
     */
    public int index() {
	return index;
    }

    /**
     *
     * @return true if there are more characters to process
     */
    public boolean hasNext() {
	if (pushback != null) {
	    return true;
	}
	if (input == null) {
	    return false;
	}
	if (input.length() == 0) {
	    return false;
	}
	if (index >= input.length()) {
	    return false;
	}
	return true;
    }

    /**
     *
     * @return the next character
     */
    public Character next() {
	if (pushback != null) {
	    Character save = pushback;
	    pushback = null;
	    return save;
	}
	if (input == null) {
	    return null;
	}
	if (input.length() == 0) {
	    return null;
	}
	if (index >= input.length()) {
	    return null;
	}
	return Character.valueOf(input.charAt(index++));
    }

    /**
     *
     * @return the next hex digit in the input, or null if the next character is not hex
     */
    public Character nextHex() {
	Character c = next();
	if (c == null) {
	    return null;
	}
	if (isHexDigit(c)) {
	    return c;
	}
	return null;
    }

    /**
     *
     * @return the next octal digit in the input, or null if the next character is not octal
     */
    public Character nextOctal() {
	Character c = next();
	if (c == null) {
	    return null;
	}
	if (isOctalDigit(c)) {
	    return c;
	}
	return null;
    }

    /**
     * Returns true if the parameter character is a hexidecimal digit 0 through 9, a through f, or A through F.
     *
     * @param c The Character to test
     * @return true if the input character is a hex digit (0-F)
     */
    public static boolean isHexDigit(Character c) {
	if (c == null) {
	    return false;
	}
	char ch = c.charValue();
	return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
    }

    /**
     * Returns true if the parameter character is an octal digit 0 through 7.
     *
     * @param c The Character to test
     * @return true if the input character is an octal digit (0-7)
     */
    public static boolean isOctalDigit(Character c) {
	if (c == null) {
	    return false;
	}
	char ch = c.charValue();
	return ch >= '0' && ch <= '7';
    }

    /**
     * Return the next character without affecting the current index.
     *
     * @return the next Character in the input
     */
    public Character peek() {
	if (pushback != null) {
	    return pushback;
	}
	if (input == null) {
	    return null;
	}
	if (input.length() == 0) {
	    return null;
	}
	if (index >= input.length()) {
	    return null;
	}
	return Character.valueOf(input.charAt(index));
    }

    /**
     * Test to see if the next character is a particular value without affecting the current index.
     *
     * @param c The character to test for
     * @return true if the next character matches the input character
     */
    public boolean peek(char c) {
	if (pushback != null && pushback.charValue() == c) {
	    return true;
	}
	if (input == null) {
	    return false;
	}
	if (input.length() == 0) {
	    return false;
	}
	if (index >= input.length()) {
	    return false;
	}
	return input.charAt(index) == c;
    }

    /**
     *
     */
    public void mark() {
	temp = pushback;
	mark = index;
    }

    /**
     *
     */
    public void reset() {
	pushback = temp;
	index = mark;
    }

    /**
     *
     * @return the remainder of the input String, prepended with any pushback, if necessary
     */
    protected String remainder() {
	String output = input.substring(index);
	if (pushback != null) {
	    output = pushback + output;
	}
	return output;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy