Author: bago Date: Mon Jan 15 07:11:42 2007 New Revision: 496365 URL: http://svn.apache.org/viewvc?view=rev&rev=496365 Log: Fix macro expansion: now it should be more strict and compliant.
Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/macro/MacroExpand.java james/jspf/trunk/src/main/java/org/apache/james/jspf/util/SPFTermsRegexps.java james/jspf/trunk/src/test/java/org/apache/james/jspf/macro/MacroExpandTest.java Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/macro/MacroExpand.java URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/macro/MacroExpand.java?view=diff&rev=496365&r1=496364&r2=496365 ============================================================================== --- james/jspf/trunk/src/main/java/org/apache/james/jspf/macro/MacroExpand.java (original) +++ james/jspf/trunk/src/main/java/org/apache/james/jspf/macro/MacroExpand.java Mon Jan 15 07:11:42 2007 @@ -28,6 +28,7 @@ import org.apache.james.jspf.core.Logger; import org.apache.james.jspf.exceptions.PermErrorException; +import org.apache.james.jspf.util.SPFTermsRegexps; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -37,13 +38,11 @@ public class MacroExpand { - public static final String MACRO_REGEX = "\\%\\{[lsoditpvhcrLSODITPVHCR]\\d*r?[\\.\\-\\+,/_\\=]*\\}"; - private MacroData macroData; - private Pattern inputPattern; + private Pattern domainSpecPattern; - private Matcher inputMatcher; + private Pattern macroStringPattern; private Pattern cellPattern; @@ -61,7 +60,10 @@ */ public MacroExpand(MacroData macroData, Logger logger) { this.macroData = macroData; - inputPattern = Pattern.compile(MACRO_REGEX); + // This matches 2 groups + domainSpecPattern = Pattern.compile(SPFTermsRegexps.DOMAIN_SPEC_REGEX_R); + // The real pattern replacer + macroStringPattern = Pattern.compile(SPFTermsRegexps.MACRO_STRING_REGEX_TOKEN); log = logger; } @@ -78,8 +80,16 @@ log.debug("Start do expand explanation: " + input); + String[] parts = input.split(" "); isExplanation = true; - return expand(input); + StringBuffer res = new StringBuffer(); + for (int i = 0; i < parts.length; i++) { + if (i > 0) res.append(" "); + res.append(expandMacroString(parts[i])); + } + log.debug("Done expand explanation: " + res); + + return res.toString(); } /** @@ -95,8 +105,26 @@ log.debug("Start expand domain: " + input); + Matcher inputMatcher = domainSpecPattern.matcher(input); + if (!inputMatcher.matches() || inputMatcher.groupCount() != 2) { + throw new PermErrorException("Invalid DomainSpec: "+input); + } + + System.err.println(inputMatcher.group(1)+"|"+inputMatcher.group(2)); + StringBuffer res = new StringBuffer(); + if (inputMatcher.group(1) != null && inputMatcher.group(1).length() > 0) { + res.append(expandMacroString(inputMatcher.group(1))); + } + if (inputMatcher.group(2) != null && inputMatcher.group(2).length() > 0) { + if (inputMatcher.group(2).startsWith(".")) { + res.append(inputMatcher.group(2)); + } else { + res.append(expandMacroString(inputMatcher.group(2))); + } + } + isExplanation = false; - String domainName = expand(input); + String domainName = expandMacroString(input); // reduce to less than 255 characters, deleting subdomains from left int split = 0; while (domainName.length() > 255 && split > -1) { @@ -115,20 +143,37 @@ * @throws PermErrorException * This get thrown if invalid macros are used */ - private String expand(String input) throws PermErrorException { - - input = replaceLiterals(input); + private String expandMacroString(String input) throws PermErrorException { StringBuffer decodedValue = new StringBuffer(); - inputMatcher = inputPattern.matcher(input); + Matcher inputMatcher = macroStringPattern.matcher(input); String macroCell; + int pos = 0; while (inputMatcher.find()) { - macroCell = input.substring(inputMatcher.start() + 2, inputMatcher - .end() - 1); - inputMatcher - .appendReplacement(decodedValue, replaceCell(macroCell)); + String match2 = inputMatcher.group(); + if (pos != inputMatcher.start()) { + throw new PermErrorException("Middle part does not match: "+input.substring(0,pos)+">>"+input.substring(pos, inputMatcher.start())+"<<"+input.substring(inputMatcher.start())); + } + if (match2.length() > 0) { + if (match2.startsWith("%{")) { + macroCell = input.substring(inputMatcher.start() + 2, inputMatcher + .end() - 1); + inputMatcher + .appendReplacement(decodedValue, replaceCell(macroCell)); + } else if (match2.length() == 2 && match2.startsWith("%")) { + // handle the % escaping + inputMatcher.appendReplacement(decodedValue, match2.substring(1)); + } + } + + pos = inputMatcher.end(); + } + + if (input.length() != pos) { + throw new PermErrorException("End part does not match: "+input.substring(pos)); } + inputMatcher.appendTail(decodedValue); return decodedValue.toString(); @@ -346,26 +391,6 @@ } return buildString.toString(); - } - - /** - * Replace all literals in the given String - * - * @param data - * The String we want to replace the literals - * @return given The given String with all literales replaced - */ - private String replaceLiterals(String data) { - - log.debug("Replace literals on String: " + data); - - data = data.replaceAll("%%", "%"); - data = data.replaceAll("%_", " "); - data = data.replaceAll("%-", "%20"); - - log.debug("Replaced String: " + data); - - return data; } /** Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/util/SPFTermsRegexps.java URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/util/SPFTermsRegexps.java?view=diff&rev=496365&r1=496364&r2=496365 ============================================================================== --- james/jspf/trunk/src/main/java/org/apache/james/jspf/util/SPFTermsRegexps.java (original) +++ james/jspf/trunk/src/main/java/org/apache/james/jspf/util/SPFTermsRegexps.java Mon Jan 15 07:11:42 2007 @@ -27,25 +27,31 @@ final String ALPHA_PATTERN = "[a-zA-Z]"; - final String MACRO_LETTER_PATTERN = "[lsodipvhLSODIPVH]"; + final String MACRO_LETTER_PATTERN = "[ctlsodipvhCTLSODIPVH]"; final String TRANSFORMERS_REGEX = "\\d*[r]?"; final String DELEMITER_REGEX = "[\\.\\-\\+,/_\\=]"; + final String MACRO_LETTERS_REGEX = MACRO_LETTER_PATTERN + TRANSFORMERS_REGEX + DELEMITER_REGEX + "*"; + final String MACRO_EXPAND_REGEX = "\\%(?:\\{" - + MACRO_LETTER_PATTERN + TRANSFORMERS_REGEX + DELEMITER_REGEX + "*" - + "\\}|\\%|\\_|\\-)"; + + MACRO_LETTERS_REGEX + "\\}|\\%|\\_|\\-)"; final String MACRO_LITERAL_REGEX = "[\\x21-\\x24\\x26-\\x7e]"; /** - * ABNF: macro-string = *( macro-expand / macro-literal ) + * This is used by the MacroExpander */ - final String MACRO_STRING_REGEX = "(?:" + MACRO_EXPAND_REGEX - + "|" + MACRO_LITERAL_REGEX + "{1})*"; + final String MACRO_STRING_REGEX_TOKEN = MACRO_EXPAND_REGEX + + "|" + MACRO_LITERAL_REGEX + "{1}"; + /** + * ABNF: macro-string = *( macro-expand / macro-literal ) + */ + final String MACRO_STRING_REGEX = "(?:" + MACRO_STRING_REGEX_TOKEN +")*"; + final String ALPHA_DIGIT_PATTERN = "[a-zA-Z0-9]"; /** @@ -71,6 +77,12 @@ */ final String DOMAIN_SPEC_REGEX = "(" + SPFTermsRegexps.MACRO_STRING_REGEX + DOMAIN_END_REGEX + ")"; + + /** + * Spring MACRO_STRING from DOMAIN_END (domain end starts with .) + */ + final String DOMAIN_SPEC_REGEX_R = "(" + + SPFTermsRegexps.MACRO_STRING_REGEX + ")(" + DOMAIN_END_REGEX + ")"; } Modified: james/jspf/trunk/src/test/java/org/apache/james/jspf/macro/MacroExpandTest.java URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/test/java/org/apache/james/jspf/macro/MacroExpandTest.java?view=diff&rev=496365&r1=496364&r2=496365 ============================================================================== --- james/jspf/trunk/src/test/java/org/apache/james/jspf/macro/MacroExpandTest.java (original) +++ james/jspf/trunk/src/test/java/org/apache/james/jspf/macro/MacroExpandTest.java Mon Jan 15 07:11:42 2007 @@ -112,6 +112,26 @@ .expandDomain("%{s}")); } + public void testPercK() throws PermErrorException { + try { + defIp4me.expandDomain("%{k}"); + fail("%{k} is not a valid expansion"); + } catch (PermErrorException e) { + } + } + + public void testPercentAloneIsError() throws PermErrorException { + try { + defIp4me.expandDomain("%{s}%"); + fail("invalid percent at end of line"); + } catch (PermErrorException e) { + } + } + + public void testDoublePercent() throws PermErrorException { + assertEquals("%", defIp4me.expandDomain("%%")); + } + public void testPercO() throws PermErrorException { assertEquals("email.example.com", defIp4me.expandDomain("%{o}")); } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]