summaryrefslogtreecommitdiff
path: root/configmgr/source/access.cxx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2015-07-07 19:09:03 +0200
committerStephan Bergmann <sbergman@redhat.com>2015-07-07 19:09:03 +0200
commit375f9460d99a0e2c366318edcc41d64d6170286e (patch)
treeab887bbcd585b04df528e85056f75288fd540982 /configmgr/source/access.cxx
parentd62253dee17dc25e6e66512870123b321f34c750 (diff)
Validate names of elements added via the API
Change-Id: I052f8ca6a8788665acb1bf87456f7cc67d64c365
Diffstat (limited to 'configmgr/source/access.cxx')
-rw-r--r--configmgr/source/access.cxx37
1 files changed, 37 insertions, 0 deletions
diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx
index 41d86e78228b..b8fadbcc62f8 100644
--- a/configmgr/source/access.cxx
+++ b/configmgr/source/access.cxx
@@ -76,6 +76,7 @@
#include <cppuhelper/weak.hxx>
#include <osl/interlck.h>
#include <osl/mutex.hxx>
+#include <rtl/character.hxx>
#include <rtl/ref.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/ustring.h>
@@ -103,6 +104,26 @@
namespace configmgr {
+namespace {
+
+// Conservatively forbid what is either not an XML Char (including lone
+// surrogates, even though they should not appear in well-formed UNO OUString
+// instances anyway), or is a slash (as it causes problems in path syntax):
+bool isValidName(OUString const & name) {
+ for (sal_Int32 i = 0; i != name.getLength();) {
+ sal_uInt32 c = name.iterateCodePoints(&i);
+ if ((c < 0x20 && !(c == 0x09 || c == 0x0A || c == 0x0D))
+ || rtl::isHighSurrogate(c) || rtl::isLowSurrogate(c) || c == 0xFFFE
+ || c == 0xFFFF || c == '/')
+ {
+ return false;
+ }
+ }
+ return !name.isEmpty();
+}
+
+}
+
oslInterlockedCount Access::acquireCounting() {
return osl_atomic_increment(&m_refCount);
}
@@ -648,6 +669,10 @@ void Access::setName(OUString const & aName)
if (node->getMandatory() == Data::NO_LAYER &&
!(other.is() && other->isFinalized()))
{
+ if (!isValidName(aName)) {
+ throw css::uno::RuntimeException(
+ "invalid element name " + aName);
+ }
rtl::Reference< RootAccess > root(getRootAccess());
rtl::Reference< ChildAccess > childAccess(
static_cast< ChildAccess * >(this));
@@ -1163,10 +1188,18 @@ void Access::insertByName(
Modifications localMods;
switch (getNode()->kind()) {
case Node::KIND_LOCALIZED_PROPERTY:
+ if (!isValidName(aName)) {
+ throw css::lang::IllegalArgumentException(
+ aName, static_cast<cppu::OWeakObject *>(this), 0);
+ }
insertLocalizedValueChild(aName, aElement, &localMods);
break;
case Node::KIND_GROUP:
{
+ if (!isValidName(aName)) {
+ throw css::lang::IllegalArgumentException(
+ aName, static_cast<cppu::OWeakObject *>(this), 0);
+ }
checkValue(aElement, TYPE_ANY, true);
rtl::Reference< ChildAccess > child(
new ChildAccess(
@@ -1179,6 +1212,10 @@ void Access::insertByName(
break;
case Node::KIND_SET:
{
+ if (!isValidName(aName)) {
+ throw css::lang::IllegalArgumentException(
+ aName, static_cast<cppu::OWeakObject *>(this), 0);
+ }
rtl::Reference< ChildAccess > freeAcc(
getFreeSetMember(aElement));
freeAcc->bind(getRootAccess(), this, aName); // must not throw