Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.6:Update
pacemaker
pacemaker#3361-0002-Fix-libcrmcommon-pcmk__xml_...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pacemaker#3361-0002-Fix-libcrmcommon-pcmk__xml_read-recovery-works-for-s.patch of Package pacemaker
From 0c8ad521a48561ebbb81967552eaa74c65a1aa5a Mon Sep 17 00:00:00 2001 From: Reid Wahl <nrwahl@protonmail.com> Date: Fri, 9 Feb 2024 12:43:28 -0800 Subject: [PATCH 2/2] Fix: libcrmcommon: pcmk__xml_read() recovery works for stdin Regression introduced in 2.1.7 by 596297a. Previously, if pcmk__xml_read() was called with an argument of NULL or "-", we told libxml2 to read from stdin's file descriptor and parse XML from it. If this failed, we tried the same thing again. The problem is that the data from stdin has already been read and discarded on the first attempt. So the second attempt with XML_PARSE_RECOVER finds an empty document. Signed-off-by: Reid Wahl <nrwahl@protonmail.com> --- lib/common/xml.c | 67 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 22 deletions(-) Index: pacemaker-2.1.7+20231219.0f7f88312/lib/common/xml.c =================================================================== --- pacemaker-2.1.7+20231219.0f7f88312.orig/lib/common/xml.c +++ pacemaker-2.1.7+20231219.0f7f88312/lib/common/xml.c @@ -867,32 +867,44 @@ string2xml(const char *input) return xml; } -xmlNode * -stdin2xml(void) +/*! + * \internal + * \brief Read from \c stdin until EOF or error + * + * \return Newly allocated string containing the bytes read from \c stdin, or + * \c NULL on error + * + * \note The caller is responsible for freeing the return value using \c free(). + */ +static char * +read_stdin(void) { - size_t data_length = 0; - size_t read_chars = 0; - - char *xml_buffer = NULL; - xmlNode *xml_obj = NULL; + char *buf = NULL; + size_t length = 0; do { - xml_buffer = pcmk__realloc(xml_buffer, data_length + PCMK__BUFFER_SIZE); - read_chars = fread(xml_buffer + data_length, 1, PCMK__BUFFER_SIZE, - stdin); - data_length += read_chars; - } while (read_chars == PCMK__BUFFER_SIZE); - - if (data_length == 0) { - crm_warn("No XML supplied on stdin"); - free(xml_buffer); - return NULL; + buf = pcmk__realloc(buf, length + PCMK__BUFFER_SIZE + 1); + length += fread(buf + length, 1, PCMK__BUFFER_SIZE, stdin); + } while ((feof(stdin) == 0) && (ferror(stdin) == 0)); + + if (ferror(stdin) != 0) { + crm_err("Error reading input from stdin"); + free(buf); + buf = NULL; + } else { + buf[length] = '\0'; } + clearerr(stdin); + return buf; +} - xml_buffer[data_length] = '\0'; - xml_obj = string2xml(xml_buffer); - free(xml_buffer); +xmlNode * +stdin2xml(void) +{ + char *xml_buffer = read_stdin(); + xmlNode *xml_obj = string2xml(xml_buffer); + free(xml_buffer); crm_log_xml_trace(xml_obj, "Created fragment"); return xml_obj; } @@ -1008,16 +1020,28 @@ filename2xml(const char *filename) if (pcmk__str_eq(filename, "-", pcmk__str_null_matches)) { /* STDIN_FILENO == fileno(stdin) */ - output = xmlCtxtReadFd(ctxt, STDIN_FILENO, "unknown.xml", NULL, - PCMK__XML_PARSE_OPTS_WITHOUT_RECOVER); - - if (output == NULL) { - output = xmlCtxtReadFd(ctxt, STDIN_FILENO, "unknown.xml", NULL, - PCMK__XML_PARSE_OPTS_WITH_RECOVER); - if (output) { - crm_warn("Successfully recovered from XML errors " - "(note: a future release will treat this as a fatal failure)"); + /* @COMPAT After dropping XML_PARSE_RECOVER, we can avoid capturing + * stdin into a buffer and instead call + * xmlCtxtReadFd(ctxt, STDIN_FILENO, NULL, NULL, XML_PARSE_NOBLANKS); + * + * For now we have to save the input so that we can use it twice. + */ + char *input = read_stdin(); + + if (input != NULL) { + output = xmlCtxtReadDoc(ctxt, (pcmkXmlStr) input, "unknown.xml", NULL, + PCMK__XML_PARSE_OPTS_WITHOUT_RECOVER); + + if (output == NULL) { + output = xmlCtxtReadDoc(ctxt, (pcmkXmlStr) input, "unknown.xml", NULL, + PCMK__XML_PARSE_OPTS_WITH_RECOVER); + if (output) { + crm_warn("Successfully recovered from XML errors " + "(note: a future release will treat this as a fatal failure)"); + } } + + free(input); } } else if (uncompressed) {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor