【问题标题】:XQuery concat not outputting document XML in expected wayXQuery concat 未按预期方式输出文档 XML
【发布时间】:2013-07-25 10:39:21
【问题描述】:
let $d := doc('foo.xml')

return concat('let $d := 

', $d)

返回

let $d :=

bar

我需要它返回:

let $d :=

<foo>bar</foo>

【问题讨论】:

  • mblakele 已经“警告”过您生成代码可能存在的危险,您打算评估或以其他方式在没有中间控制的情况下执行。我对更大的图景很好奇。我们也许可以建议替代路线,以防止使用有风险的方法..
  • 这是一段一次性代码,用于生成一些 xquery 以加载一些数据。然而,我对减轻 XQuery 注入很感兴趣。目前,我正在使用封装 xquery 并使用直接字符串替换变量的“查询对象”。有没有更好的办法? (我确定有 - 也许是一个支持安全替换查询中的值的库?)
  • 好吧,如果你确保注入的值只代表字符串,并且不允许过早关闭这些字符串,通过转义特殊字符,首先在 XML 中插入东西,你可以防止很多问题, 要不然。有一些特定于供应商的扩展也可能有所帮助。大多数 XQuery 解析器,包括 MarkLogic 的解析器,都允许使用 eval 类型的函数,这些函数通常也允许参数替换。除此之外,MarkLogic 还支持 xdmp:value(一种轻量级的 eval)和 xdmp:unpath,以解析持有 XPath 类表达式的变量。

标签: xquery marklogic


【解决方案1】:

读取fn:concat 的函数签名,没有理由期望它输出XML。来自http://www.w3.org/TR/xpath-functions/#func-concat

fn:concat(
  $arg1 as xs:anyAtomicType?,
  $arg2 as xs:anyAtomicType?,
  ...)
as xs:string

也就是说,它接受可变数量的原子项目并返回一个字符串。因此,如果您向它传递一个 XML 节点,它会尝试将其原子化并返回一个字符串结果。如果您还没有遇到雾化,请尝试string(doc($uri)) 看看会发生什么。

忽略这一点,您似乎正在尝试使用字符串操作构建 XQuery 表达式 - 可能与 xdmp:eval 一起使用?这很好,但不要使用xdmp:quote 传递XML。出于正确性、性能和安全性的原因,适合这项工作的工具是外部变量。

xdmp:eval('
  declare variable $INPUT external ;
  let $d := $INPUT
  return xdmp:describe($d)',
  (xs:QName('INPUT'), $d))

更好的是,将字符串部分编写为一个单独的 XQuery 模块,并使用相同的外部变量参数 xdmp:invoke

为什么要这样?正确性、效率和安全性。如果你养成了盲目评估字符串的习惯,那么你就是在为问题做准备。传递节点引用比引用大节点更有效。当您将 XML 作为字符串引用时,您可能会以 XQuery 有效字符结束,例如 {。然后你必须转义它们(或切换到使用xdmp:unquote,但这会降低效率)。任何转义都容易出错。在 SQL 中,处理此问题的经典方法是使用绑定变量,而对于 XQuery,它是一个外部变量。与 SQL 中的绑定变量一样,外部变量处理转义。这也使得注入攻击更加困难。

【讨论】:

    【解决方案2】:

    使用管道连接。 例如:$a||$b 如果您的变量是原子类型,那么您可以使用字符串连接。 例如:, $a||fn:string-join(($b),",")

    【讨论】:

      【解决方案3】:
      let $d := xdmp:quote(doc('foo.xml'))
      
      return concat('let $d := &#xD;&#xD;', $d)
      

      【讨论】:

      • 回答你自己的问题似乎有点不公平:)
      • stackoverflow.com/help/self-answer 说“Stack Exchange 一直明确鼓励用户回答他们自己的问题。”不过,这可能不是最好的答案。
      • 如果您打算xdmp:eval 得到那个concat 的结果,并且它包含任何花括号或其他XQuery 语法,它可能会抛出错误或做意想不到的事情。如果攻击者可以控制该 XML,这将成为注入攻击。它可能导致数据被盗或破坏。考虑一下如果 foo.xml 包含 &lt;test&gt;{xdmp:restart(xdmp:hosts(), 'ha!ha!')}&lt;/test&gt; 会发生什么。
      • 我不知道那个自我回答的帖子!很有趣。
      猜你喜欢
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-27
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      相关资源
      最近更新 更多