Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1h2KU7-0005C0-EF for pgsql-hackers@arkaria.postgresql.org; Fri, 08 Mar 2019 18:44:43 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1h2KU5-0007Qb-Lx for pgsql-hackers@arkaria.postgresql.org; Fri, 08 Mar 2019 18:44:41 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1h2KU5-0007QU-BY for pgsql-hackers@lists.postgresql.org; Fri, 08 Mar 2019 18:44:41 +0000 Received: from mail-qt1-x843.google.com ([2607:f8b0:4864:20::843]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1h2KTx-0001rD-O7 for pgsql-hackers@lists.postgresql.org; Fri, 08 Mar 2019 18:44:39 +0000 Received: by mail-qt1-x843.google.com with SMTP id u7so22345652qtg.9 for ; Fri, 08 Mar 2019 10:44:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=TZQdWRRGzBKxnt2a3UuuESCLIBZRZ8kZBNdM+mYT+Hg=; b=1NPyQQkm+q72I1TQP+8C8OTEyeHmS7OUN29TOe2qzxwp9utBPveeUTxdsBRs5s+pGM JpNrqKxvk1gajx8ri12uZPdRCeo/+NJpqqB2hjPxnBW2tXbN8Uh2OPdlJggtr1NNt/Mc MYqxZYlaHNWfLOvuOUZn5FDa3kzJouJqLvm9beZ2si4XachpZ58OwoDNd/t5ApHskxrf 6lifdlloAqIvIjoW7TOxBTMNfj/NzyY56trohoF4bAmlUBA76dK9lSLBKie7pnlBdZo2 Cqzlip37zOxrWgXFcAi+3VdkYIZvyDXS65iRFlwpFiLW3xSo9oL3LEsjOHb75jwjhSX1 lQog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=TZQdWRRGzBKxnt2a3UuuESCLIBZRZ8kZBNdM+mYT+Hg=; b=Egk0hkki0tqBSp/idLn/W48KWVdwiEcgIcKgM22QiIR24QQQKGMk1p7ZlJu4WQk+IB Uz1jieyG0vWOnb4vWqJ3xgw1BdacCdU+HA9FG7NgRRIm/aaYvNfwmswdL0cU3GqyW174 B9FjdLXqyY+dgrWrT5EN7NYHz/Xdg8OgSDZn/eKSoF92lc9PftqhE77zxOVXpYiiVgki LEG1BDRWLlNNH1NakvFQAx3owZDzd36pVr7AuCm495U5qp8BvP8dKsD2G2G/llEqMzaS OykT/HuWTQf0JHC6qPEVNtJG7nCZYOegZlzqa/tZs8pXwDD70CPD7vpIUdZC7hJDzEAX eqLA== X-Gm-Message-State: APjAAAVyAb78mBbrGERi11ETCHTR+kqxgIu2+k32MyeddPnVnLu92j4C M8suasJ2NYpsb5Nzr9GU9dl46Z4ycSsdfg== X-Google-Smtp-Source: APXvYqwuNB1Uyf7KVVs0ZRii0iF8tR2pt1QaPbtZayZ2j1DnltmqlY9ES2HpJIiEw7zAtONp/URdiw== X-Received: by 2002:a0c:8924:: with SMTP id 33mr16312094qvp.83.1552070672845; Fri, 08 Mar 2019 10:44:32 -0800 (PST) Received: from nimloth.alvh.no-ip.org ([201.186.80.67]) by smtp.gmail.com with ESMTPSA id 50sm5250881qtr.96.2019.03.08.10.44.31 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 08 Mar 2019 10:44:32 -0800 (PST) Received: by nimloth.alvh.no-ip.org (Postfix, from userid 1000) id 243BE121E60; Fri, 8 Mar 2019 15:44:30 -0300 (-03) Date: Fri, 8 Mar 2019 15:44:30 -0300 From: Alvaro Herrera To: Pavel Stehule Cc: Chapman Flack , Markus Winand , PostgreSQL Hackers Subject: Re: PostgreSQL vs SQL/XML Standards Message-ID: <20190308184430.GA14852@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="LQksG6bCIzRHxTLp" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20190308183417.GA4442@alvherre.pgsql> User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --LQksG6bCIzRHxTLp Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2019-Mar-08, Alvaro Herrera wrote: > > Maybe we can call explicitly xmlFreeDoc instead xmlFreeNode > > > > some like > > > > if (cur_copy->type == XML_DOCUMENT_NODE) > > xmlFreeDoc((xmlDocPtr) cur_copy); > > else > > xmlFreeNode(cur_copy); > > > > This looks most correct fix for me. What do you think? > > Seems like that should work, yeah ... Something like this perhaps? Less repetitive ... -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services --LQksG6bCIzRHxTLp Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="xml-more-robust-handling-3.patch" diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 28b3eaaa201..9204d6e9cf6 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -3720,35 +3720,57 @@ xml_xmlnodetoxmltype(xmlNodePtr cur, PgXmlErrorContext *xmlerrcxt) if (cur->type != XML_ATTRIBUTE_NODE && cur->type != XML_TEXT_NODE) { - xmlBufferPtr buf; - xmlNodePtr cur_copy; - - buf = xmlBufferCreate(); - - /* - * The result of xmlNodeDump() won't contain namespace definitions - * from parent nodes, but xmlCopyNode() duplicates a node along with - * its required namespace definitions. - */ - cur_copy = xmlCopyNode(cur, 1); - - if (cur_copy == NULL) - xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, - "could not copy node"); + volatile void (*nodefree) (xmlNodePtr) = NULL; + volatile xmlBufferPtr buf = NULL; + volatile xmlNodePtr cur_copy = NULL; PG_TRY(); { - xmlNodeDump(buf, NULL, cur_copy, 0, 1); + int bytes; + + buf = xmlBufferCreate(); + if (buf == NULL || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not allocate xmlBuffer"); + + /* + * Produce a dump of the node that we can serialize. xmlNodeDump + * does that, but the result of that function won't contain + * namespace definitions from ancestor nodes, so we first do a + * xmlCopyNode() which duplicates the node along with its required + * namespace definitions. + * + * Some old libxml2 versions such as 2.7.6 produce partially + * broken XML_DOCUMENT_NODE nodes (unset content field) when + * copying them. xmlNodeDump of such a node works fine, but + * xmlFreeNode crashes; set us up to call xmlFreeDoc instead. + */ + cur_copy = xmlCopyNode(cur, 1); + if (cur_copy == NULL || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not copy node"); + nodefree = cur_copy->type == XML_DOCUMENT_NODE ? + (void (*) (xmlNodePtr)) xmlFreeDoc : xmlFreeNode; + + bytes = xmlNodeDump(buf, NULL, cur_copy, 0, 1); + if (bytes == -1 || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not dump node"); + result = xmlBuffer_to_xmltype(buf); } PG_CATCH(); { - xmlFreeNode(cur_copy); - xmlBufferFree(buf); + if (nodefree) + nodefree(cur_copy); + if (buf) + xmlBufferFree(buf); PG_RE_THROW(); } PG_END_TRY(); - xmlFreeNode(cur_copy); + + if (nodefree) + nodefree(cur_copy); xmlBufferFree(buf); } else --LQksG6bCIzRHxTLp--