pax_global_header00006660000000000000000000000064122512100020014473gustar00rootroot0000000000000052 comment=9565bff72c5f5b7cd1ecefe8eead5dd19e3b7c5e jformatstring-0.10~20131207/000077500000000000000000000000001225121000200153225ustar00rootroot00000000000000jformatstring-0.10~20131207/README000066400000000000000000000000001225121000200161700ustar00rootroot00000000000000jformatstring-0.10~20131207/build.xml000066400000000000000000000040501225121000200171420ustar00rootroot00000000000000 FB home ${findbugs.home} FB ant ${anttask.jar} jformatstring-0.10~20131207/src/000077500000000000000000000000001225121000200161115ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/000077500000000000000000000000001225121000200170325ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/000077500000000000000000000000001225121000200176075ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/umd/000077500000000000000000000000001225121000200203745ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/umd/cs/000077500000000000000000000000001225121000200210015ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/000077500000000000000000000000001225121000200226025ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/000077500000000000000000000000001225121000200265465ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/Conversion.java000066400000000000000000000104211225121000200315340ustar00rootroot00000000000000/* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* This file has been extensively modified from the original Sun implementation * to provide for compile time checking of Format Strings. * * These modifications were performed by Bill Pugh, this code is free software. * */ package edu.umd.cs.findbugs.formatStringChecker; class Conversion { // Byte, Short, Integer, Long, BigInteger // (and associated primitives due to autoboxing) static final char DECIMAL_INTEGER = 'd'; static final char OCTAL_INTEGER = 'o'; static final char HEXADECIMAL_INTEGER = 'x'; static final char HEXADECIMAL_INTEGER_UPPER = 'X'; // Float, Double, BigDecimal // (and associated primitives due to autoboxing) static final char SCIENTIFIC = 'e'; static final char SCIENTIFIC_UPPER = 'E'; static final char GENERAL = 'g'; static final char GENERAL_UPPER = 'G'; static final char DECIMAL_FLOAT = 'f'; static final char HEXADECIMAL_FLOAT = 'a'; static final char HEXADECIMAL_FLOAT_UPPER = 'A'; // Character, Byte, Short, Integer // (and associated primitives due to autoboxing) static final char CHARACTER = 'c'; static final char CHARACTER_UPPER = 'C'; // java.util.Date, java.util.Calendar, long static final char DATE_TIME = 't'; static final char DATE_TIME_UPPER = 'T'; // if (arg.TYPE != boolean) return boolean // if (arg != null) return true; else return false; static final char BOOLEAN = 'b'; static final char BOOLEAN_UPPER = 'B'; // if (arg instanceof Formattable) arg.formatTo() // else arg.toString(); static final char STRING = 's'; static final char STRING_UPPER = 'S'; // arg.hashCode() static final char HASHCODE = 'h'; static final char HASHCODE_UPPER = 'H'; static final char LINE_SEPARATOR = 'n'; static final char PERCENT_SIGN = '%'; static boolean isValid(char c) { return (isGeneral(c) || isInteger(c) || isFloat(c) || isText(c) || c == 't' || isCharacter(c)); } // Returns true iff the Conversion is applicable to all objects. static boolean isGeneral(char c) { switch (c) { case BOOLEAN: case BOOLEAN_UPPER: case STRING: case STRING_UPPER: case HASHCODE: case HASHCODE_UPPER: return true; default: return false; } } // Returns true iff the Conversion is applicable to character. static boolean isCharacter(char c) { switch (c) { case CHARACTER: case CHARACTER_UPPER: return true; default: return false; } } // Returns true iff the Conversion is an integer type. static boolean isInteger(char c) { switch (c) { case DECIMAL_INTEGER: case OCTAL_INTEGER: case HEXADECIMAL_INTEGER: case HEXADECIMAL_INTEGER_UPPER: return true; default: return false; } } // Returns true iff the Conversion is a floating-point type. static boolean isFloat(char c) { switch (c) { case SCIENTIFIC: case SCIENTIFIC_UPPER: case GENERAL: case GENERAL_UPPER: case DECIMAL_FLOAT: case HEXADECIMAL_FLOAT: case HEXADECIMAL_FLOAT_UPPER: return true; default: return false; } } // Returns true iff the Conversion does not require an argument static boolean isText(char c) { switch (c) { case LINE_SEPARATOR: case PERCENT_SIGN: return true; default: return false; } } }jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/DateTime.java000066400000000000000000000113751225121000200311140ustar00rootroot00000000000000/* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* This file has been extensively modified from the original Sun implementation * to provide for compile time checking of Format Strings. * * These modifications were performed by Bill Pugh, this code is free software. * */ package edu.umd.cs.findbugs.formatStringChecker; class DateTime { static final char HOUR_OF_DAY_0 = 'H'; // (00 - 23) static final char HOUR_0 = 'I'; // (01 - 12) static final char HOUR_OF_DAY = 'k'; // (0 - 23) -- like H static final char HOUR = 'l'; // (1 - 12) -- like I static final char MINUTE = 'M'; // (00 - 59) static final char NANOSECOND = 'N'; // (000000000 - 999999999) static final char MILLISECOND = 'L'; // jdk, not in gnu (000 - 999) static final char MILLISECOND_SINCE_EPOCH = 'Q'; // (0 - 99...?) static final char AM_PM = 'p'; // (am or pm) static final char SECONDS_SINCE_EPOCH = 's'; // (0 - 99...?) static final char SECOND = 'S'; // (00 - 60 - leap second) static final char TIME = 'T'; // (24 hour hh:mm:ss) static final char ZONE_NUMERIC = 'z'; // (-1200 - +1200) - ls minus? static final char ZONE = 'Z'; // (symbol) // Date static final char NAME_OF_DAY_ABBREV = 'a'; // 'a' static final char NAME_OF_DAY = 'A'; // 'A' static final char NAME_OF_MONTH_ABBREV = 'b'; // 'b' static final char NAME_OF_MONTH = 'B'; // 'B' static final char CENTURY = 'C'; // (00 - 99) static final char DAY_OF_MONTH_0 = 'd'; // (01 - 31) static final char DAY_OF_MONTH = 'e'; // (1 - 31) -- like d // * static final char ISO_WEEK_OF_YEAR_2 = 'g'; // cross %y %V // * static final char ISO_WEEK_OF_YEAR_4 = 'G'; // cross %Y %V static final char NAME_OF_MONTH_ABBREV_X = 'h'; // -- same b static final char DAY_OF_YEAR = 'j'; // (001 - 366) static final char MONTH = 'm'; // (01 - 12) // * static final char DAY_OF_WEEK_1 = 'u'; // (1 - 7) Monday // * static final char WEEK_OF_YEAR_SUNDAY = 'U'; // (0 - 53) Sunday+ // * static final char WEEK_OF_YEAR_MONDAY_01 = 'V'; // (01 - 53) Monday+ // * static final char DAY_OF_WEEK_0 = 'w'; // (0 - 6) Sunday // * static final char WEEK_OF_YEAR_MONDAY = 'W'; // (00 - 53) Monday static final char YEAR_2 = 'y'; // (00 - 99) static final char YEAR_4 = 'Y'; // (0000 - 9999) // Composites static final char TIME_12_HOUR = 'r'; // (hh:mm:ss [AP]M) static final char TIME_24_HOUR = 'R'; // (hh:mm same as %H:%M) // * static final char LOCALE_TIME = 'X'; // (%H:%M:%S) - parse format? static final char DATE_TIME = 'c'; // (Sat Nov 04 12:02:33 EST 1999) static final char DATE = 'D'; // (mm/dd/yy) static final char ISO_STANDARD_DATE = 'F'; // (%Y-%m-%d) // * static final char LOCALE_DATE = 'x'; // (mm/dd/yy) static boolean isValid(char c) { switch (c) { case HOUR_OF_DAY_0: case HOUR_0: case HOUR_OF_DAY: case HOUR: case MINUTE: case NANOSECOND: case MILLISECOND: case MILLISECOND_SINCE_EPOCH: case AM_PM: case SECONDS_SINCE_EPOCH: case SECOND: case TIME: case ZONE_NUMERIC: case ZONE: // Date case NAME_OF_DAY_ABBREV: case NAME_OF_DAY: case NAME_OF_MONTH_ABBREV: case NAME_OF_MONTH: case CENTURY: case DAY_OF_MONTH_0: case DAY_OF_MONTH: // * case ISO_WEEK_OF_YEAR_2: // * case ISO_WEEK_OF_YEAR_4: case NAME_OF_MONTH_ABBREV_X: case DAY_OF_YEAR: case MONTH: // * case DAY_OF_WEEK_1: // * case WEEK_OF_YEAR_SUNDAY: // * case WEEK_OF_YEAR_MONDAY_01: // * case DAY_OF_WEEK_0: // * case WEEK_OF_YEAR_MONDAY: case YEAR_2: case YEAR_4: // Composites case TIME_12_HOUR: case TIME_24_HOUR: // * case LOCALE_TIME: case DATE_TIME: case DATE: case ISO_STANDARD_DATE: // * case LOCALE_DATE: return true; default: return false; } } }ExtraFormatArgumentsException.java000066400000000000000000000033631225121000200353400ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* This file has been extensively modified from the original Sun implementation * to provide for compile time checking of Format Strings. * * These modifications were performed by Bill Pugh, this code is free software. * */ package edu.umd.cs.findbugs.formatStringChecker; public class ExtraFormatArgumentsException extends FormatterException { private static final long serialVersionUID = 1L; public final int provided; public final int used; public ExtraFormatArgumentsException(int provided, int used) { this.provided = provided; this.used = used; } }jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/Flags.java000066400000000000000000000076401225121000200304540ustar00rootroot00000000000000/* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* This file has been extensively modified from the original Sun implementation * to provide for compile time checking of Format Strings. * * These modifications were performed by Bill Pugh, this code is free software. * */ package edu.umd.cs.findbugs.formatStringChecker; import java.util.DuplicateFormatFlagsException; import java.util.UnknownFormatFlagsException; class Flags { private int flags; static final Flags NONE = new Flags(0); // '' // duplicate declarations from Formattable.java static final Flags LEFT_JUSTIFY = new Flags(1 << 0); // '-' static final Flags UPPERCASE = new Flags(1 << 1); // '^' static final Flags ALTERNATE = new Flags(1 << 2); // '#' // numerics static final Flags PLUS = new Flags(1 << 3); // '+' static final Flags LEADING_SPACE = new Flags(1 << 4); // ' ' static final Flags ZERO_PAD = new Flags(1 << 5); // '0' static final Flags GROUP = new Flags(1 << 6); // ',' static final Flags PARENTHESES = new Flags(1 << 7); // '(' // indexing static final Flags PREVIOUS = new Flags(1 << 8); // '<' private Flags(int f) { flags = f; } public int valueOf() { return flags; } public boolean contains(Flags f) { return (flags & f.valueOf()) == f.valueOf(); } public Flags dup() { return new Flags(flags); } Flags add(Flags f) { flags |= f.valueOf(); return this; } public Flags remove(Flags f) { flags &= ~f.valueOf(); return this; } public static Flags parse(String s) { char[] ca = s.toCharArray(); Flags f = new Flags(0); for (int i = 0; i < ca.length; i++) { Flags v = parse(ca[i]); if (f.contains(v)) throw new DuplicateFormatFlagsException(v.toString()); f.add(v); } return f; } // parse those flags which may be provided by users private static Flags parse(char c) { switch (c) { case '-': return LEFT_JUSTIFY; case '#': return ALTERNATE; case '+': return PLUS; case ' ': return LEADING_SPACE; case '0': return ZERO_PAD; case ',': return GROUP; case '(': return PARENTHESES; case '<': return PREVIOUS; default: throw new UnknownFormatFlagsException(String.valueOf(c)); } } // Returns a string representation of the current Flags. public static String toString(Flags f) { return f.toString(); } public String toString() { StringBuilder sb = new StringBuilder(); if (contains(LEFT_JUSTIFY)) sb.append('-'); if (contains(UPPERCASE)) sb.append('^'); if (contains(ALTERNATE)) sb.append('#'); if (contains(PLUS)) sb.append('+'); if (contains(LEADING_SPACE)) sb.append(' '); if (contains(ZERO_PAD)) sb.append('0'); if (contains(GROUP)) sb.append(','); if (contains(PARENTHESES)) sb.append('('); if (contains(PREVIOUS)) sb.append('<'); return sb.toString(); } }jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/FormatSpecifier.java000066400000000000000000000277711225121000200325110ustar00rootroot00000000000000/* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* This file has been extensively modified from the original Sun implementation * to provide for compile time checking of Format Strings. * * These modifications were performed by Bill Pugh, this code is free software. * */ package edu.umd.cs.findbugs.formatStringChecker; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Calendar; import java.util.Date; import java.util.FormatFlagsConversionMismatchException; import java.util.GregorianCalendar; import java.util.IllegalFormatFlagsException; import java.util.IllegalFormatPrecisionException; import java.util.IllegalFormatWidthException; import java.util.MissingFormatWidthException; import java.util.UnknownFormatConversionException; public class FormatSpecifier { private int index = -1; private Flags f = Flags.NONE; private int width; private int precision; private boolean dt = false; private char c; private final String source; public String toString() { return source; } private int index(String s) throws FormatterNumberFormatException { if (s != null) { try { index = Integer.parseInt(s.substring(0, s.length() - 1)); } catch (NumberFormatException x) { throw new FormatterNumberFormatException(s, "index"); } } else { index = 0; } return index; } public int index() { return index; } private Flags flags(String s) { f = Flags.parse(s); if (f.contains(Flags.PREVIOUS)) index = -1; return f; } Flags flags() { return f; } private int width(String s) throws FormatterNumberFormatException { width = -1; if (s != null) { try { width = Integer.parseInt(s); if (width < 0) throw new IllegalFormatWidthException(width); } catch (NumberFormatException x) { throw new FormatterNumberFormatException(s, "width"); } } return width; } private int precision(String s) throws FormatterNumberFormatException { precision = -1; if (s != null) { try { // remove the '.' precision = Integer.parseInt(s.substring(1)); if (precision < 0) throw new IllegalFormatPrecisionException(precision); } catch (NumberFormatException x) { throw new FormatterNumberFormatException(s, "precision"); } } return precision; } int precision() { return precision; } private char conversion(String s) { c = s.charAt(0); if (!dt) { if (!Conversion.isValid(c)) throw new UnknownFormatConversionException(String.valueOf(c)); if (Character.isUpperCase(c)) f.add(Flags.UPPERCASE); c = Character.toLowerCase(c); if (Conversion.isText(c)) index = -2; } return c; } FormatSpecifier(String source, String[] sa) throws FormatFlagsConversionMismatchException, FormatterNumberFormatException { int idx = 0; this.source = source; index(sa[idx++]); flags(sa[idx++]); width(sa[idx++]); precision(sa[idx++]); if (sa[idx] != null) { dt = true; if (sa[idx].equals("T")) f.add(Flags.UPPERCASE); } conversion(sa[++idx]); if (dt) checkDateTime(); else if (Conversion.isGeneral(c)) checkGeneral(); else if (Conversion.isCharacter(c)) checkCharacter(); else if (Conversion.isInteger(c)) checkInteger(); else if (Conversion.isFloat(c)) checkFloat(); else if (Conversion.isText(c)) checkText(); else throw new UnknownFormatConversionException(String.valueOf(c)); } private void checkGeneral() throws FormatFlagsConversionMismatchException { if ((c == Conversion.BOOLEAN || c == Conversion.HASHCODE) && f.contains(Flags.ALTERNATE)) failMismatch(Flags.ALTERNATE, c); // '-' requires a width if (width == -1 && f.contains(Flags.LEFT_JUSTIFY)) throw new MissingFormatWidthException(toString()); checkBadFlags(Flags.PLUS, Flags.LEADING_SPACE, Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES); } private void checkDateTime() throws FormatFlagsConversionMismatchException { if (precision != -1) throw new IllegalFormatPrecisionException(precision); if (!DateTime.isValid(c)) throw new UnknownFormatConversionException("t" + c); checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE, Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES); // '-' requires a width if (width == -1 && f.contains(Flags.LEFT_JUSTIFY)) throw new MissingFormatWidthException(toString()); } private void checkCharacter() throws FormatFlagsConversionMismatchException { if (precision != -1) throw new IllegalFormatPrecisionException(precision); checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE, Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES); // '-' requires a width if (width == -1 && f.contains(Flags.LEFT_JUSTIFY)) throw new MissingFormatWidthException(toString()); } private void checkInteger() throws FormatFlagsConversionMismatchException { checkNumeric(); if (precision != -1) throw new IllegalFormatPrecisionException(precision); if (c == Conversion.DECIMAL_INTEGER) checkBadFlags(Flags.ALTERNATE); else checkBadFlags(Flags.GROUP); } private void checkBadFlags(Flags... badFlags) throws FormatFlagsConversionMismatchException { for (int i = 0; i < badFlags.length; i++) if (f.contains(badFlags[i])) failMismatch(badFlags[i], c); } private void checkFloat() throws FormatFlagsConversionMismatchException { checkNumeric(); if (c == Conversion.DECIMAL_FLOAT) { } else if (c == Conversion.HEXADECIMAL_FLOAT) { checkBadFlags(Flags.PARENTHESES, Flags.GROUP); } else if (c == Conversion.SCIENTIFIC) { checkBadFlags(Flags.GROUP); } else if (c == Conversion.GENERAL) { checkBadFlags(Flags.ALTERNATE); } } private void checkNumeric() { if (width != -1 && width < 0) throw new IllegalFormatWidthException(width); if (precision != -1 && precision < 0) throw new IllegalFormatPrecisionException(precision); // '-' and '0' require a width if (width == -1 && (f.contains(Flags.LEFT_JUSTIFY) || f .contains(Flags.ZERO_PAD))) throw new MissingFormatWidthException(toString()); // bad combination if ((f.contains(Flags.PLUS) && f.contains(Flags.LEADING_SPACE)) || (f.contains(Flags.LEFT_JUSTIFY) && f .contains(Flags.ZERO_PAD))) throw new IllegalFormatFlagsException(f.toString()); } private void checkText() { if (precision != -1) throw new IllegalFormatPrecisionException(precision); switch (c) { case Conversion.PERCENT_SIGN: if (f.valueOf() != Flags.LEFT_JUSTIFY.valueOf() && f.valueOf() != Flags.NONE.valueOf()) throw new IllegalFormatFlagsException(f.toString()); // '-' requires a width if (width == -1 && f.contains(Flags.LEFT_JUSTIFY)) throw new MissingFormatWidthException(toString()); break; case Conversion.LINE_SEPARATOR: if (width != -1) throw new IllegalFormatWidthException(width); if (f.valueOf() != Flags.NONE.valueOf()) throw new IllegalFormatFlagsException(f.toString()); break; default: throw new UnknownFormatConversionException(String.valueOf(c)); } } public void print(String arg, int argIndex) throws IllegalFormatConversionException, FormatFlagsConversionMismatchException { try { if (arg.charAt(0) == '[') failConversion(arg); if (dt) { printDateTime(arg); return; } switch (c) { case Conversion.DECIMAL_INTEGER: case Conversion.OCTAL_INTEGER: case Conversion.HEXADECIMAL_INTEGER: printInteger(arg); break; case Conversion.SCIENTIFIC: case Conversion.GENERAL: case Conversion.DECIMAL_FLOAT: case Conversion.HEXADECIMAL_FLOAT: printFloat(arg); break; case Conversion.CHARACTER: case Conversion.CHARACTER_UPPER: printCharacter(arg); break; case Conversion.BOOLEAN: printBoolean(arg); break; case Conversion.STRING: case Conversion.HASHCODE: case Conversion.LINE_SEPARATOR: case Conversion.PERCENT_SIGN: break; default: throw new UnknownFormatConversionException(String.valueOf(c)); } } catch (IllegalFormatConversionException e) { e.setArgIndex(argIndex); throw e; } } private boolean matchSig(String signature, Class... classes) { for (Class c : classes) if (matchSig(signature, c)) return true; return false; } private boolean matchSig(String signature, Class c) { return signature.equals("L" + c.getName().replace('.', '/') + ";"); } private boolean mightBeUnknown(String arg) { if (matchSig(arg, Object.class) || matchSig(arg, Number.class) || matchSig(arg, Serializable.class) || matchSig(arg, Comparable.class)) return true; return false; } private void printInteger(String arg) throws IllegalFormatConversionException, FormatFlagsConversionMismatchException { if (mightBeUnknown(arg)) return; if (matchSig(arg, Byte.class, Short.class, Integer.class, Long.class)) printLong(); else if (matchSig(arg, BigInteger.class)) { } else failConversion(arg); } private void printFloat(String arg) throws IllegalFormatConversionException { if (mightBeUnknown(arg)) return; if (matchSig(arg, Float.class, Double.class)) { } else if (matchSig(arg, BigDecimal.class)) { printBigDecimal(arg); } else failConversion(arg); } private void printDateTime(String arg) throws IllegalFormatConversionException { if (mightBeUnknown(arg)) return; if (matchSig(arg, Long.class, Date.class, java.sql.Date.class, java.sql.Time.class, java.sql.Timestamp.class, Calendar.class, GregorianCalendar.class)) { } else { failConversion(arg); } } private void printCharacter(String arg) throws IllegalFormatConversionException { if (mightBeUnknown(arg)) return; if (matchSig(arg, Character.class, Byte.class, Short.class, Integer.class)) { } else { failConversion(arg); } } private void printBoolean(String arg) throws IllegalFormatConversionException { if (mightBeUnknown(arg)) return; if (matchSig(arg, Boolean.class)) return; failConversion(arg); } private void printLong() throws FormatFlagsConversionMismatchException { if (c == Conversion.OCTAL_INTEGER) { checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE, Flags.PLUS); } else if (c == Conversion.HEXADECIMAL_INTEGER) { checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE, Flags.PLUS); } } private void printBigDecimal(String arg) throws IllegalFormatConversionException { if (c == Conversion.HEXADECIMAL_FLOAT) failConversion(arg); } private void failMismatch(Flags f, char c) throws FormatFlagsConversionMismatchException { String fs = f.toString(); throw new FormatFlagsConversionMismatchException(fs, c); } private void failConversion(String arg) throws IllegalFormatConversionException { if (dt) throw new IllegalFormatConversionException(this.toString(), f.contains(Flags.UPPERCASE) ? 'T' : 't', arg); throw new IllegalFormatConversionException(this.toString(), c, arg); } }jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/Formatter.java000066400000000000000000000113461225121000200313610ustar00rootroot00000000000000/* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* This file has been extensively modified from the original Sun implementation * to provide for compile time checking of Format Strings. * * These modifications were performed by Bill Pugh, this code is free software. * */ package edu.umd.cs.findbugs.formatStringChecker; import java.util.ArrayList; import java.util.FormatFlagsConversionMismatchException; import java.util.IllegalFormatException; import java.util.List; import java.util.UnknownFormatConversionException; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class Formatter { public static void check(String format, String... args) throws ExtraFormatArgumentsException, IllegalFormatConversionException, IllegalFormatException, FormatFlagsConversionMismatchException, MissingFormatArgumentException, FormatterNumberFormatException { // index of last argument referenced int last = -1; // last ordinary index int lasto = -1; // last index used int maxIndex = -1; for (FormatSpecifier fs : parse(format)) { int index = fs.index(); switch (index) { case -2: // ignore it break; case -1: // relative index if (last < 0 || last > args.length - 1) throw new MissingFormatArgumentException(last, fs.toString()); fs.print(args[last], last); break; case 0: // ordinary index lasto++; last = lasto; if (lasto > args.length - 1) throw new MissingFormatArgumentException(lasto, fs.toString()); maxIndex = Math.max(maxIndex, lasto); fs.print(args[lasto], lasto); break; default: // explicit index last = index - 1; if (last > args.length - 1) throw new MissingFormatArgumentException(last, fs.toString()); maxIndex = Math.max(maxIndex, last); fs.print(args[last], last); break; } } if (maxIndex < args.length - 1) { throw new ExtraFormatArgumentsException(args.length, maxIndex + 1); } } // %[argument_index$][flags][width][.precision][t]conversion private static final String formatSpecifier = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])"; private static Pattern fsPattern = Pattern.compile(formatSpecifier); // Look for format specifiers in the format string. private static List parse(String s) throws FormatFlagsConversionMismatchException, FormatterNumberFormatException { ArrayList al = new ArrayList(); Matcher m = fsPattern.matcher(s); int i = 0; while (i < s.length()) { if (m.find(i)) { // Anything between the start of the string and the beginning // of the format specifier is either fixed text or contains // an invalid format string. if (m.start() != i) { // Make sure we didn't miss any invalid format specifiers checkText(s.substring(i, m.start())); } // Expect 6 groups in regular expression String[] sa = new String[6]; for (int j = 0; j < m.groupCount(); j++) { sa[j] = m.group(j + 1); } al.add(new FormatSpecifier(m.group(0), sa)); i = m.end(); } else { // No more valid format specifiers. Check for possible invalid // format specifiers. checkText(s.substring(i)); // The rest of the string is fixed text break; } } return al; } private static void checkText(String s) { int idx; // If there are any '%' in the given string, we got a bad format // specifier. if ((idx = s.indexOf('%')) != -1) { char c = (idx > s.length() - 2 ? '%' : s.charAt(idx + 1)); throw new UnknownFormatConversionException(String.valueOf(c)); } } } jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/FormatterException.java000066400000000000000000000031021225121000200332270ustar00rootroot00000000000000/* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* This file has been extensively modified from the original Sun implementation * to provide for compile time checking of Format Strings. * * These modifications were performed by Bill Pugh, this code is free software. * */ package edu.umd.cs.findbugs.formatStringChecker; public abstract class FormatterException extends Exception { private static final long serialVersionUID = 1L; } FormatterNumberFormatException.java000066400000000000000000000024341225121000200355010ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/* * Copyright 2013 by Bill Pugh. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. This * particular file as subject to the "Classpath" exception. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * */ package edu.umd.cs.findbugs.formatStringChecker; public class FormatterNumberFormatException extends FormatterException { private static final long serialVersionUID = 1L; final String txt, kind; /** * @return the txt */ public String getTxt() { return txt; } /** * @return the msg */ public String getKind() { return kind; } public FormatterNumberFormatException(String txt, String kind) { this.txt = txt; this.kind = kind; } } IllegalFormatConversionException.java000066400000000000000000000056131225121000200360060ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* This file has been extensively modified from the original Sun implementation * to provide for compile time checking of Format Strings. * * These modifications were performed by Bill Pugh, this code is free software. * */ package edu.umd.cs.findbugs.formatStringChecker; public class IllegalFormatConversionException extends FormatterException { private static final long serialVersionUID = 1L; final private String formatSpecifier; final private char conversion; final private String signature; int argIndex = -1; /** * Constructs an instance of this class with the mismatched conversion and * the corresponding argument class. * * @param formatSpecifier * Inapplicable format specifier * * @param signature * Signature of the mismatched argument */ public IllegalFormatConversionException(String formatSpecifier, char conversion, String signature) { if (signature == null) throw new NullPointerException(); this.conversion = conversion; this.formatSpecifier = formatSpecifier; this.signature = signature; } public void setArgIndex(int argIndex) { if (argIndex == -1) throw new IllegalStateException("arg index already set"); this.argIndex = argIndex; } public int getArgIndex() { return argIndex; } public String getFormatSpecifier() { return formatSpecifier; } public char getConversion() { return conversion; } /** * Returns the class of the mismatched argument. * * @return The class of the mismatched argument */ public String getArgumentSignature() { return signature; } // javadoc inherited from Throwable.java public String getMessage() { return String.format("%s can't format %s", formatSpecifier, signature); } } MissingFormatArgumentException.java000066400000000000000000000034221225121000200354770ustar00rootroot00000000000000jformatstring-0.10~20131207/src/java/edu/umd/cs/findbugs/formatStringChecker/* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* This file has been extensively modified from the original Sun implementation * to provide for compile time checking of Format Strings. * * These modifications were performed by Bill Pugh, this code is free software. * */ package edu.umd.cs.findbugs.formatStringChecker; public class MissingFormatArgumentException extends FormatterException { private static final long serialVersionUID = 1L; public final int pos; public final String formatSpecifier; public MissingFormatArgumentException(int pos, String formatSpecifier) { this.pos = pos; this.formatSpecifier = formatSpecifier; } }jformatstring-0.10~20131207/src/junit/000077500000000000000000000000001225121000200172425ustar00rootroot00000000000000jformatstring-0.10~20131207/src/junit/edu/000077500000000000000000000000001225121000200200175ustar00rootroot00000000000000jformatstring-0.10~20131207/src/junit/edu/umd/000077500000000000000000000000001225121000200206045ustar00rootroot00000000000000jformatstring-0.10~20131207/src/junit/edu/umd/cs/000077500000000000000000000000001225121000200212115ustar00rootroot00000000000000jformatstring-0.10~20131207/src/junit/edu/umd/cs/findbugs/000077500000000000000000000000001225121000200230125ustar00rootroot00000000000000jformatstring-0.10~20131207/src/junit/edu/umd/cs/findbugs/formatStringChecker/000077500000000000000000000000001225121000200267565ustar00rootroot00000000000000FormatterCompileTimeTest.java000066400000000000000000000071111225121000200344750ustar00rootroot00000000000000jformatstring-0.10~20131207/src/junit/edu/umd/cs/findbugs/formatStringChecker/* * Copyright 2013 by Bill Pugh. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. This * particular file as subject to the "Classpath" exception. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * */ package edu.umd.cs.findbugs.formatStringChecker; import org.junit.Test; public class FormatterCompileTimeTest { @Test public void shouldWork() throws FormatterException { Formatter.check("%d%n%d", "Ljava/lang/Integer;", "Ljava/lang/Short;"); Formatter.check("%d\n", "Ljava/math/BigInteger;"); Formatter.check("%f\n", "Ljava/math/BigDecimal;"); } @Test(expected = IllegalFormatConversionException.class) public void stringWhereIntegerExpected() throws FormatterException { Formatter.check("%d", "Ljava/lang/String;"); } @Test(expected = MissingFormatArgumentException.class) public void notEnoughParameters() throws FormatterException { Formatter.check("%s%s", "Ljava/lang/String;"); } @Test(expected = IllegalFormatConversionException.class) public void passingAnArray() throws FormatterException { Formatter.check("%s", "[I"); } @Test(expected = IllegalFormatConversionException.class) public void passingAnIntToABoolean() throws FormatterException { Formatter.check("%b", "Ljava/lang/Integer;"); } @Test(expected = ExtraFormatArgumentsException.class) public void tooManyParameters() throws FormatterException { Formatter.check("%s%s", "Ljava/lang/String;", "Ljava/lang/String;", "Ljava/lang/String;"); } @Test public void testBug1874856FalsePositive() throws FormatterException { Formatter.check("s1 Duke's Birthday: %1$tm %1$te, %1$tY", "Ljava/util/GregorianCalendar;"); Formatter.check("s2 Duke's Birthday: %1$tm %