Index: api/src/java/org/sakaiproject/entitybroker/util/TemplateParseUtil.java =================================================================== --- api/src/java/org/sakaiproject/entitybroker/util/TemplateParseUtil.java (revision 54842) +++ api/src/java/org/sakaiproject/entitybroker/util/TemplateParseUtil.java (working copy) @@ -85,15 +85,15 @@ /** * Defines the valid chars for a replacement variable */ - public static String VALID_VAR_CHARS = "[A-Za-z0-9_\\.\\-=:;]"; + public static String VALID_VAR_CHARS = "[A-Za-z0-9\\\\(\\\\)\\+\\*\\.\\-_=,:;!~@%]"; /** * Defines the valid chars for a parser input (e.g. entity reference) */ - public static String VALID_INPUT_CHARS = "[A-Za-z0-9_\\-\\.=:;"+SEPARATOR+"]"; + public static String VALID_INPUT_CHARS = "[A-Za-z0-9\\\\(\\\\)\\+\\*\\.\\-_=,:;!~@%"+SEPARATOR+"]"; /** * Defines the valid chars for a template */ - public static String VALID_TEMPLATE_CHARS = "[A-Za-z0-9_\\-\\.=:;"+SEPARATOR+"\\{\\}]"; + public static String VALID_TEMPLATE_CHARS = "[A-Za-z0-9\\\\(\\\\)\\+\\*\\.\\-_=,:;&!~@%"+SEPARATOR+"\\{\\}]"; /** * Stores the preloaded default templates @@ -236,11 +236,17 @@ String extension = null; if (input != null) { int extensionLoc = input.lastIndexOf(PERIOD, input.length()); - if (extensionLoc > 0) { - stripped = input.substring(0, extensionLoc); - if ( (input.length() - 1) > extensionLoc) { - extension = input.substring(extensionLoc + 1); - } + if (extensionLoc == 0) { + // starts with a period so no extension, do nothing + } else { + int sepLoc = input.lastIndexOf(SEPARATOR, input.length()); + if (extensionLoc > 0 + && sepLoc < extensionLoc) { + stripped = input.substring(0, extensionLoc); + if ( (input.length() - 1) > extensionLoc) { + extension = input.substring(extensionLoc + 1); + } + } } } return new String[] {input, stripped, extension};