From: Brian W. <bwe...@xb...> - 2012-03-20 20:49:31
|
On Mar 20, 2012, at 5:09 AM, Abby Kehat wrote: > Brian – > > Actually, it’s more of a problem that retrieving the regexp field. > > The purpose of the NAPTRRecord is to support regular expression based rewriting. The rewriting is often done using regular expression backreferences to refer to the original phone number in the query. You can see the specification of the regular expression field syntax in section 3.2 of this RFC, including an example of using backreferences. Basically the first part (between the first two ‘!’) is an extended regular expression which is used to capture [part of] the original phone number. The second part (between the second two ‘!’) is a substitution expression which is applied to the text captured by the first part. > > For example, the regular expression field !^(.+)$!0\1! means: capture the entire phone number (^(.+)$). Prefix the phone number with a zero (0\1). > > When written as a Java String, !^(.+)$!0\1! becomes "!^(.+)$!0\\1!" since the backslash has to be escaped in Java strings. If the backslash is not escaped, it has a totally different meaning: replace the original phone number with the string ‘0\001’, where \001 represents the unprintable character with byte value of 1. Right. Java uses backslashes for escaping in Strings. > However, constructing a NAPTRRecord with a regular expression containing backreferences throws an IllegalArgumentException! > > The following code attempts to create a NAPTRRecord with a regular expression mentioned above, !^(.+)$!0\1!. > > NAPTRRecord rec = new NAPTRRecord(name, // Name > DClass.IN, // Class > 0, // TTL > 0, // Order > 0, // Preference > "u", // Flags > "E2U+sip", // Service > "!^(.+)$!0\\1!", // Regular expression. > Name.root); // Replacement > > Exception in thread "main" java.lang.IllegalArgumentException: bad escape > at org.xbill.DNS.NAPTRRecord.<init>(NAPTRRecord.java:55) > > The problem is the backreference in the replacement part of the regular expression; the string ‘0\1’. ThebyteArrayFromString(String) method used by the NAPTRRecord constructor throws the exception when it parses the ‘\1’ as it doesn’t know how to handle a backslash followed by less than 3 digits (see theRecord.byteArrayFromString(String s) method, lines 374-375). That's DNS master file escaping. One could probably argue that since this isn't a master file, master file escaping isn't necessary, but that's how dnsjava has worked for over 10 years, and changing it now would likely break other users. > As backreferences are quite often needed in NAPTR records, it would be great if you could fix this issue. Right now we have a workaround doubling and singling backslashes when accessing the regular expression, but this is causing quite a bit of confusion in our code and our logs. I don't know what the right answer is for this. Adding a new NAPTRRecord constructor that took byte arrays instead of Strings might solve the problem, but it's ugly (since you probably have Strings, and would need to convert them into byte arrays). Adding a new constructor that took Strings, but interpreted them differently, would be weird. Adding some sort of global property for this might work, but may cause other problems. Brian |