|
18 | 18 | #include "../logunit.h"
|
19 | 19 | #include <log4cxx/logger.h>
|
20 | 20 | #include <log4cxx/xml/xmllayout.h>
|
| 21 | +#include <log4cxx/htmllayout.h> |
21 | 22 | #include <log4cxx/fileappender.h>
|
22 | 23 | #include <log4cxx/mdc.h>
|
23 | 24 |
|
|
37 | 38 | #include "../xml/xlevel.h"
|
38 | 39 | #include <log4cxx/helpers/bytebuffer.h>
|
39 | 40 | #include <log4cxx/helpers/transcoder.h>
|
| 41 | +#include <log4cxx/helpers/loglog.h> |
40 | 42 |
|
41 | 43 |
|
42 | 44 | using namespace log4cxx;
|
@@ -67,6 +69,7 @@ LOGUNIT_CLASS(XMLLayoutTest)
|
67 | 69 | LOGUNIT_TEST(testActivateOptions);
|
68 | 70 | LOGUNIT_TEST(testProblemCharacters);
|
69 | 71 | LOGUNIT_TEST(testNDCWithCDATA);
|
| 72 | + LOGUNIT_TEST(testHTMLLayout); |
70 | 73 | LOGUNIT_TEST_SUITE_END();
|
71 | 74 |
|
72 | 75 |
|
@@ -385,6 +388,7 @@ LOGUNIT_CLASS(XMLLayoutTest)
|
385 | 388 | layout.format(result, event, p);
|
386 | 389 | MDC::clear();
|
387 | 390 |
|
| 391 | + |
388 | 392 | apr_xml_elem* parsedResult = parse(result, p);
|
389 | 393 | checkEventElement(parsedResult, event);
|
390 | 394 |
|
@@ -453,6 +457,60 @@ LOGUNIT_CLASS(XMLLayoutTest)
|
453 | 457 | LOGUNIT_ASSERT_EQUAL(1, ndcCount);
|
454 | 458 | }
|
455 | 459 |
|
| 460 | + /** |
| 461 | + * Tests problematic characters in multiple fields. |
| 462 | + * @throws Exception if parser can not be constructed or source is not a valid XML document. |
| 463 | + */ |
| 464 | + void testHTMLLayout() |
| 465 | + { |
| 466 | + std::string problemName = "com.example.bar<>&\"'"; |
| 467 | + LogString problemNameLS = LOG4CXX_STR("com.example.bar<>&\"'"); |
| 468 | + LevelPtr level = LevelPtr(new XLevel(6000, problemNameLS, 7)); |
| 469 | + NDC::push(problemName); |
| 470 | + auto event = std::make_shared<LoggingEvent>(problemNameLS, level, problemNameLS, LOG4CXX_LOCATION); |
| 471 | + HTMLLayout layout; |
| 472 | + Pool p; |
| 473 | + LogString html(LOG4CXX_STR("<body>")); |
| 474 | + layout.format(html, event, p); |
| 475 | + html += LOG4CXX_STR("</body>"); |
| 476 | + |
| 477 | + LogLog::debug(html); |
| 478 | + char backing[3000]; |
| 479 | + ByteBuffer buf(backing, sizeof(backing)); |
| 480 | + CharsetEncoderPtr encoder(CharsetEncoder::getUTF8Encoder()); |
| 481 | + auto iter = html.begin(); |
| 482 | + encoder->encode(html, iter, buf); |
| 483 | + LOGUNIT_ASSERT(iter == html.end()); |
| 484 | + buf.flip(); |
| 485 | + apr_xml_parser* parser = apr_xml_parser_create(p.getAPRPool()); |
| 486 | + LOGUNIT_ASSERT(parser != 0); |
| 487 | + apr_status_t stat = apr_xml_parser_feed(parser, buf.data(), buf.remaining()); |
| 488 | + LOGUNIT_ASSERT(stat == APR_SUCCESS); |
| 489 | + apr_xml_doc* doc = 0; |
| 490 | + stat = apr_xml_parser_done(parser, &doc); |
| 491 | + LOGUNIT_ASSERT(doc != 0); |
| 492 | + auto parsedResult = doc->root; |
| 493 | + LOGUNIT_ASSERT(parsedResult != 0); |
| 494 | + |
| 495 | + int childElementCount = 0; |
| 496 | + for ( auto node = parsedResult->first_child |
| 497 | + ; node != NULL |
| 498 | + ; node = node->next) |
| 499 | + { |
| 500 | + childElementCount++; |
| 501 | + |
| 502 | + switch (childElementCount) |
| 503 | + { |
| 504 | + case 1: |
| 505 | + LOGUNIT_ASSERT_EQUAL(std::string("tr"), std::string(node->name)); |
| 506 | + break; |
| 507 | + default: |
| 508 | + break; |
| 509 | + } |
| 510 | + } |
| 511 | + LOGUNIT_ASSERT(1 < childElementCount); |
| 512 | + } |
| 513 | + |
456 | 514 | };
|
457 | 515 |
|
458 | 516 |
|
|
0 commit comments