carnold 2005/02/11 15:03:41
Modified: include/log4cxx fileappender.h
src fileappender.cpp
tests/src fileappendertestcase.cpp
Log:
LOGCXX-22: Backslashes in filenames in XML, UNC fix
Revision Changes Path
1.22 +8 -1 logging-log4cxx/include/log4cxx/fileappender.h
Index: fileappender.h
===================================================================
RCS file: /home/cvs/logging-log4cxx/include/log4cxx/fileappender.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- fileappender.h 11 Feb 2005 01:04:36 -0000 1.21
+++ fileappender.h 11 Feb 2005 23:03:40 -0000 1.22
@@ -217,11 +217,18 @@
*/
void setBufferSize(int bufferSize) { this->bufferSize = bufferSize; }
+ /**
+ * Replaces double backslashes with single backslashes
+ * for compatibility with paths from earlier XML configurations
files.
+ * @param name file name
+ * @return corrected file name
+ */
+ static LogString stripDuplicateBackslashes(const LogString& name);
+
private:
FileAppender(const FileAppender&);
FileAppender& operator=(const FileAppender&);
- void stripDoubleBackslashes(LogString& name);
}; // class FileAppender
} // namespace log4cxx
1.22 +36 -9 logging-log4cxx/src/fileappender.cpp
Index: fileappender.cpp
===================================================================
RCS file: /home/cvs/logging-log4cxx/src/fileappender.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- fileappender.cpp 11 Feb 2005 01:04:36 -0000 1.21
+++ fileappender.cpp 11 Feb 2005 23:03:41 -0000 1.22
@@ -111,9 +111,7 @@
if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("FILE"),
LOG4CXX_STR("file"))
|| StringHelper::equalsIgnoreCase(option,
LOG4CXX_STR("FILENAME"), LOG4CXX_STR("filename")))
{
- LogString tmpValue(value);
- stripDoubleBackslashes(tmpValue);
- fileName = tmpValue;
+ fileName = stripDuplicateBackslashes(value);
}
else if (StringHelper::equalsIgnoreCase(option,
LOG4CXX_STR("APPEND"), LOG4CXX_STR("append")))
{
@@ -180,13 +178,42 @@
-void FileAppender::stripDoubleBackslashes(LogString& name) {
+/**
+ * Replaces double backslashes (except the leading doubles of UNC's)
+ * with single backslashes for compatibility with existing path
+ * specifications that were working around use of
+ * OptionConverter::convertSpecialChars in XML configuration files.
+ *
+ * @param src source string
+ * @return modified string
+ * @since 0.9.8
+ *
+ */
+LogString FileAppender::stripDuplicateBackslashes(const LogString& src) {
logchar backslash = LOG4CXX_STR('\\');
- for(LogString::size_type i = name.find(backslash);
- i != LogString::npos;
- i = name.find(backslash, i + 1)) {
- if (i + 1 < name.length() && name[i + 1] == backslash) {
- name.erase(i, 1);
+ LogString::size_type i = src.find_last_of(backslash);
+ if (i != LogString::npos) {
+ LogString tmp(src);
+ for(;
+ i != LogString::npos && i > 0;
+ i = tmp.find_last_of(backslash, i - 1)) {
+ //
+ // if the preceding character is a slash then
+ // remove the preceding character
+ // and continue processing
+ if (tmp[i - 1] == backslash) {
+ tmp.erase(i, 1);
+ i--;
+ if (i == 0) break;
+ } else {
+ //
+ // if there an odd number of slashes
+ // the string wasn't trying to work around
+ // OptionConverter::convertSpecialChars
+ return src;
}
+ }
+ return tmp;
}
+ return src;
}
\ No newline at end of file
1.3 +46 -0 logging-log4cxx/tests/src/fileappendertestcase.cpp
Index: fileappendertestcase.cpp
===================================================================
RCS file: /home/cvs/logging-log4cxx/tests/src/fileappendertestcase.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- fileappendertestcase.cpp 11 Feb 2005 01:04:36 -0000 1.2
+++ fileappendertestcase.cpp 11 Feb 2005 23:03:41 -0000 1.3
@@ -42,6 +42,7 @@
// tests defined here
CPPUNIT_TEST(testSetDoubleBackslashes);
+ CPPUNIT_TEST(testStripDuplicateBackslashes);
CPPUNIT_TEST_SUITE_END();
@@ -60,6 +61,51 @@
const File& file = appender.getFile();
CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("output\\temp"),
file.getName());
}
+
+ /**
+ * Tests that double backslashes in filespecs are stripped
+ * on calls to setOption.
+ * @since 0.9.8
+ */
+ void testStripDoubleBackslashes() {
+
+ FileAppender appender;
+ appender.setOption(LOG4CXX_STR("FILE"),
LOG4CXX_STR("output\\\\temp"));
+ const File& file = appender.getFile();
+ CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("output\\temp"),
file.getName());
+ }
+
+ /**
+ * Tests stripDuplicateBackslashes
+ *
+ * @since 0.9.8
+ */
+ void testStripDuplicateBackslashes() {
+ CPPUNIT_ASSERT_EQUAL((LogString)
LOG4CXX_STR("\\foo\\bar\\foo"),
+
FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\foo\\bar\\foo")));
+ CPPUNIT_ASSERT_EQUAL((LogString)
LOG4CXX_STR("\\foo\\bar\\foo\\"),
+
FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\foo\\\\bar\\\\foo\\\\")));
+ CPPUNIT_ASSERT_EQUAL((LogString)
LOG4CXX_STR("\\foo\\bar\\foo\\"),
+
FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\foo\\bar\\foo\\")));
+ //
+ // UNC's should either start with two backslashes and contain
additional singles
+ // or four back slashes and addition doubles
+ CPPUNIT_ASSERT_EQUAL((LogString)
LOG4CXX_STR("\\\\foo\\bar\\foo"),
+
FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\\\\\foo\\\\bar\\\\foo")));
+ CPPUNIT_ASSERT_EQUAL((LogString)
LOG4CXX_STR("\\\\foo\\bar\\foo"),
+
FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\foo\\bar\\foo")));
+ //
+ // it it starts with doubles but has no other path component
+ // then it is a file path
+ CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\foo.log"),
+
FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\foo.log")));
+ //
+ // it it starts with quads but has no other path component
+ // then it is a UNC
+ CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\\\foo.log"),
+
FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\\\\\foo.log")));
+ }
+
};
CPPUNIT_TEST_SUITE_REGISTRATION(FileAppenderTestCase);