如何正确地将字符串参数传递给 Oracle 中的 XPATH?
How to correctly pass a string argument to XPATH in Oracle?
如何将字符串参数传递给 EXTRACTVALUE
?
例如:
EXTRACTVALUE(fooColumn, '/foo/bar[@baz = "arg"]/@value')
如何用实参 :arg
替换 "arg"
?
天真的解决方案:
EXTRACTVALUE(fooColumn, '/foo/bar[@baz = "' || :arg || '"]/@value')
这里如何防止可能的“XPath”注入?
有没有XPath转义函数?
EXTRACTVALUE
已弃用,您应该改用 XMLQUERY
或 XMLTABLE
。
您可以尝试使用 DBMS_ASSERT
包:
CREATE FUNCTION enquote_name (
name IN VARCHAR2
) RETURN VARCHAR2
IS
BEGIN
-- Wrap it in a function call to use the PL/SQL FALSE literal.
RETURN DBMS_ASSERT.ENQUOTE_NAME(name, FALSE);
END;
/
然后:
SELECT XMLQUERY(
('/foo/bar[@baz='||ENQUOTE_NAME(:arg)||']/@value')
PASSING fooColumn
RETURNING CONTENT
) AS value
FROM table_name
或
SELECT EXTRACTVALUE( foocolumn, '/foo/bar[@baz='||ENQUOTE_NAME(:arg)||']/@value')
AS value
FROM table_name
其中 table:
CREATE TABLE table_name ( foocolumn ) AS
SELECT XMLTYPE(
'<foo><bar baz="abc" value="123" /><bar baz="def" value="456" /></foo>'
)
FROM DUAL;
输出,当:arg
为def
时:
VALUE
456
如果您尝试将 :arg
用作 'abc"][@value="123'
,则查询 returns 零行(或为 EXTRACTVALUE
引发异常);但是,如果您尝试传递相同的值而不将其包装在对 ENQUOTE_NAME
的调用中(并包括 ENQUOTE_NAME
将添加的双引号),那么它将执行您试图避免的 XPATH 注入。
db<>fiddle here
如何将字符串参数传递给 EXTRACTVALUE
?
例如:
EXTRACTVALUE(fooColumn, '/foo/bar[@baz = "arg"]/@value')
如何用实参 :arg
替换 "arg"
?
天真的解决方案:
EXTRACTVALUE(fooColumn, '/foo/bar[@baz = "' || :arg || '"]/@value')
这里如何防止可能的“XPath”注入? 有没有XPath转义函数?
EXTRACTVALUE
已弃用,您应该改用 XMLQUERY
或 XMLTABLE
。
您可以尝试使用 DBMS_ASSERT
包:
CREATE FUNCTION enquote_name (
name IN VARCHAR2
) RETURN VARCHAR2
IS
BEGIN
-- Wrap it in a function call to use the PL/SQL FALSE literal.
RETURN DBMS_ASSERT.ENQUOTE_NAME(name, FALSE);
END;
/
然后:
SELECT XMLQUERY(
('/foo/bar[@baz='||ENQUOTE_NAME(:arg)||']/@value')
PASSING fooColumn
RETURNING CONTENT
) AS value
FROM table_name
或
SELECT EXTRACTVALUE( foocolumn, '/foo/bar[@baz='||ENQUOTE_NAME(:arg)||']/@value')
AS value
FROM table_name
其中 table:
CREATE TABLE table_name ( foocolumn ) AS
SELECT XMLTYPE(
'<foo><bar baz="abc" value="123" /><bar baz="def" value="456" /></foo>'
)
FROM DUAL;
输出,当:arg
为def
时:
VALUE 456
如果您尝试将 :arg
用作 'abc"][@value="123'
,则查询 returns 零行(或为 EXTRACTVALUE
引发异常);但是,如果您尝试传递相同的值而不将其包装在对 ENQUOTE_NAME
的调用中(并包括 ENQUOTE_NAME
将添加的双引号),那么它将执行您试图避免的 XPATH 注入。
db<>fiddle here