Improved handling of XML parser errors
This commit is contained in:
committed by
Andrew Gaul
parent
a9b9631c5c
commit
52b263b99c
@ -3597,9 +3597,16 @@ static int list_bucket(const char* path, S3ObjList& head, const char* delimiter,
|
||||
}
|
||||
|
||||
// xmlDocPtr
|
||||
s3fsXmlBufferParserError parserError;
|
||||
parserError.SetXmlParseError();
|
||||
|
||||
std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> doc(xmlReadMemory(encbody.c_str(), static_cast<int>(encbody.size()), "", nullptr, 0), xmlFreeDoc);
|
||||
if(nullptr == doc){
|
||||
S3FS_PRN_ERR("xmlReadMemory returns with error.");
|
||||
if(parserError.IsXmlParseError()){
|
||||
S3FS_PRN_ERR("xmlReadMemory returns with error: %s", parserError.GetXmlParseError().c_str());
|
||||
}else{
|
||||
S3FS_PRN_ERR("xmlReadMemory returns with error.");
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
if(0 != append_objects_from_xml(path, doc.get(), head)){
|
||||
|
||||
@ -461,8 +461,16 @@ bool simple_parse_xml(const char* data, size_t len, const char* key, std::string
|
||||
// ":1: parser error : Document is empty" to stderr.
|
||||
// Make sure len is not 0 beforehand.
|
||||
//
|
||||
s3fsXmlBufferParserError parserError;
|
||||
parserError.SetXmlParseError();
|
||||
|
||||
std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> doc(xmlReadMemory(data, static_cast<int>(len), "", nullptr, 0), xmlFreeDoc);
|
||||
if(nullptr == doc){
|
||||
if(parserError.IsXmlParseError()){
|
||||
S3FS_PRN_ERR("xmlReadMemory returns with error: %s", parserError.GetXmlParseError().c_str());
|
||||
}else{
|
||||
S3FS_PRN_ERR("xmlReadMemory returns with error.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
#include <libxml/parser.h> // [NOTE] nessetially include this header in some environments
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
#include "mpu_util.h"
|
||||
|
||||
@ -35,6 +37,44 @@ typedef std::unique_ptr<xmlXPathObject, decltype(&xmlXPathFreeObject)> unique_pt
|
||||
typedef std::unique_ptr<xmlXPathContext, decltype(&xmlXPathFreeContext)> unique_ptr_xmlXPathContext;
|
||||
typedef std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> unique_ptr_xmlDoc;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Utility Class
|
||||
//-------------------------------------------------------------------
|
||||
class s3fsXmlBufferParserError
|
||||
{
|
||||
private:
|
||||
static constexpr int ERROR_BUFFER_SIZE = 1024;
|
||||
std::array<char, ERROR_BUFFER_SIZE> error_buffer{};
|
||||
|
||||
static void ParserErrorHandler(void* ctx, const char *msg, ...)
|
||||
{
|
||||
auto* errbuf = static_cast<char*>(ctx);
|
||||
if(errbuf){
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
vsnprintf(errbuf + strlen(errbuf), ERROR_BUFFER_SIZE - strlen(errbuf) - 1, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void SetXmlParseError()
|
||||
{
|
||||
error_buffer.fill(0);
|
||||
xmlSetGenericErrorFunc(error_buffer.data(), s3fsXmlBufferParserError::ParserErrorHandler);
|
||||
}
|
||||
|
||||
std::string GetXmlParseError() const
|
||||
{
|
||||
return strlen(error_buffer.data()) ? error_buffer.data() : "";
|
||||
}
|
||||
|
||||
bool IsXmlParseError() const
|
||||
{
|
||||
return (0 < strlen(error_buffer.data()));
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Functions
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user