InspectionGadgets plugin: feature request for "Hardcoded file separator" inspection

The "Hardcoded file separator" inspection is picking up date formats. It
already tries to recognise and ignore '/' characters in XML strings; is
there any chance of it trying to do the same for common date format strings
as well?

Cheers,
Vil.
--
Vilya Harvey
vilya.harvey@digitalsteps.com / digital steps /
(W) +44 (0)1483 469 480
(M) +44 (0)7816 678 457 http://www.digitalsteps.com/

Disclaimer

This e-mail and any attachments may be confidential and/or legally
privileged. If you have received this email and you are not a named
addressee, please inform the sender at Digital Steps Ltd by phone on
+44 (0)1483 469 480 or by reply email and then delete the email from
your system. If you are not a named addressee you must not use,
disclose, distribute, copy, print or rely on this email. Although
Digital Steps Ltd routinely screens for viruses, addressees should
check this email and any attachments for viruses. Digital Steps Ltd
makes no representation or warranty as to the absence of viruses in this
email or any attachments.

2 comments
Comment actions Permalink


Describe the algorithm you'd like, and I'll put it on the TODO list. Code up the algorithm, and I'll incorporate it and give you a mention.

--Dave Griffith

0
Comment actions Permalink

Dave Griffith wrote:

Describe the algorithm you'd like, and I'll put it on the TODO list. Code up the algorithm, and I'll incorporate it and give you a mention.


Sounds fair. :)

I've attached a class which does some simple checks (mostly regex-based) on
the string content to see whether it's likely to be a date format, a URL or
a fragment of XML before declaring it to be a filename. Use it as you will;
I'm placing that code into the public domain. I've also attached the JUnit
test case for it.

One possible improvement would be to do some checks on the usages of the
string. If it's being used as a parameter to a URL constructor, for example,
then it's probably not a filename that needs to be checked. That might start
costing a few too many processor cycles though. Just a thought, anyway.

Cheerio,
Vil.
--
__
o| . / \|o. _ _ ._ _ ._ _ |
\/ ||\/(_|| (|/||| |(/_(_)| |(/_o| |(/_ |_
/ \__
http://website.lineone.net/~vilya
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**

  • Provides a static method for checking whether a string is likely to be a filename containing hardcoded file

  • separators.

*

  • @author Vilya Harvey

  • @version 1.0

*/
public class HardcodedFilenameRecogniser
{
//
// CONSTANTS
//

/**

  • The regular expression pattern that matches strings which are likely to be date formats. <code>Pattern</code>

  • instances are immutable, so caching the pattern like this is still thread-safe.

*/
private static final Pattern DATE_FORMAT_PATTERN = Pattern.compile("
b[dM]/(/y+)?");

/**

  • A regular expression pattern that matches strings which start with a URL protocol, as they're likely to actually

  • be URLs.

*/
private static final Pattern URL_PATTERN = Pattern.compile("^[a-z][a-z0-9+
-.]+://.*$");


//
// STATIC METHODS
//

/**

  • Check whether a string is likely to be a filename containing one or more hard-coded file separator characters. The

  • method does some simple analysis of the string to determine whether it's likely to be some other type of data -

  • a URL, a date format, or an XML fragment - before deciding that the string is a filename.

*

  • @param str The string to examine.

  • @return <code>true</code> if the string is likely to be a filename with hardcoded file separators,

  • <code>false</code> otherwise.

*/
public static boolean isHardcodedFilenameString(String str)
{
if (str.indexOf('/') == -1 && str.indexOf('
') == -1) {
return false;
}

if (Character.isLetter(str.charAt(0)) && str.charAt(1) == ':') {
return true;
}

if (isXMLString(str)) {
return false;
}

if (isDateFormatString(str)) {
return false;
}

if (isURLString(str)) {
return false;
}

return true;
}


//
// PRIVATE METHODS
//

/**

  • Check whether a string containing at least one '/' or '\' character is likely to be a fragment of XML.

*

  • @param str The string to examine.

  • @return <code>true</code> if the string is likely to be an XML fragment, or <code>false</code> if not.

*/
private static boolean isXMLString(String str)
{
if (str.indexOf("</") != -1) {
return true;
}

if (str.indexOf("/>") != -1) {
return true;
}

return false;
}


/**

  • Check whether a string containing at least one '/' or '\' character is likely to be a date format string.

*

  • @param str The string to check.

  • @return <code>true</code> if the string is likely to be a date string, <code>false</code> if not.

*/
private static boolean isDateFormatString(String str)
{
if (str.length() < 3) {
// A string this short is very unlikely to be a date format.
return false;
}
if (str.startsWith("/") || str.endsWith("/")) {
// Most likely it's a filename if the string starts or ends with a slash.
return false;
} else if (Character.isLetter(str.charAt(0)) && str.charAt(1) == ':') {
// Most likely this is a Windows-style full file name.
return false;
}

Matcher dateFormatMatcher = DATE_FORMAT_PATTERN.matcher(str);
return dateFormatMatcher.find();
}


/**

  • Checks whether a string containing at least one '/' or '\' character is likely to be a URL.

*

  • @param str The string to check.

  • @return <code>true</code> if the string is likely to be a URL, <code>false</code> if not.

*/
private static boolean isURLString(String str)
{
Matcher urlMatcher = URL_PATTERN.matcher(str);
return urlMatcher.find();
}
}
import junit.framework.TestCase;

/**

  • JUnit test case for the {@link HardcodedFilenameRecogniser} class.

*

  • @author Vilya Harvey

  • @version 1.0

*/
public class JUnitHardcodedFilenameRecogniser
extends TestCase
{
//
// CONSTRUCTORS
//

public JUnitHardcodedFilenameRecogniser(String name)
{
super(name);
}


//
// TEST METHODS
//

public void testIsHardcodedFilenameString()
{
// Make sure it recognises absolute file names correctly.
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("/home/data/info.txt"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("
home
data
info.txt"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("c:/home/data/info.txt"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("c:
home
data
info.txt"));

// Make sure it recognises absolute directories correctly, with and without a trailing file separator.
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("/home/data/"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("
home
data
"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("c:/home/data/"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("c:
home
data
"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("/home/data"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("
home
data"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("c:/home/data"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("c:
home
data"));

// Make sure it recognises relative file names correctly.
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("home/data/info.txt"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("home
data
info.txt"));

// Make sure it recognises relative directories correctly, with and without a trailing file separator.
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("home/data/"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("home
data
"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("home/data"));
assertTrue(HardcodedFilenameRecogniser.isHardcodedFilenameString("home
data"));

// Make sure it doesn't recognise XML strings.
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("")); assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("")); assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("")); assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("")); assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("]]>"));

// Make sure it doesn't recognise common date format strings.
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("d/M"));
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("dd/MMMM"));
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("d/M/y"));
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("dd/MMMM/yyyy"));
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("M/d"));
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("MMMM/dd"));
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("M/d/y"));
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("MMMM/dd/yyyy"));

// Make sure it doesn't recognise URLs.
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("http://dd/MMMM/yyyy"));
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("ftp://dd/MMMM/yyyy"));
assertFalse(HardcodedFilenameRecogniser.isHardcodedFilenameString("file://dd/MMMM/yyyy"));
}
}

0

Please sign in to leave a comment.