Bug 1330326 - Add Split() function on String classes. r?froydnj
MozReview-Commit-ID: 8GpqWsfGnWp
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -219,39 +219,16 @@ using namespace mozilla::psm;
using namespace mozilla::widget;
#if defined(MOZ_WIDGET_GONK)
using namespace mozilla::system;
#endif
using namespace mozilla::widget;
namespace mozilla {
-static nsTArray<nsCString> StringSplit(const nsACString& str)
-{
- nsTArray<nsCString> result;
-
- nsACString::const_iterator begin, iter, end;
- str.BeginReading(begin);
- str.EndReading(end);
- while (begin != end) {
- iter = begin;
- FindCharInReadable(',', iter, end);
- nsDependentCSubstring path = Substring(begin, iter);
- if (!path.IsEmpty()) {
- result.AppendElement(Substring(begin, iter));
- }
- begin = iter;
- if (begin != end) {
- begin++;
- }
- }
-
- return result;
-}
-
namespace dom {
class MemoryReportRequestChild : public PMemoryReportRequestChild,
public nsIRunnable
{
public:
NS_DECL_ISUPPORTS
@@ -1524,20 +1501,19 @@ ContentChild::RecvSetProcessSandbox(cons
// didn't intend it.
MOZ_RELEASE_ASSERT(brokerFd >= 0);
}
// Allow user overrides of seccomp-bpf syscall filtering
std::vector<int> syscallWhitelist;
nsAdoptingCString extraSyscalls =
Preferences::GetCString("security.sandbox.content.syscall_whitelist");
if (extraSyscalls) {
- auto callNumbers = StringSplit(extraSyscalls);
- for (const nsCString& callNrString : callNumbers) {
+ for (const nsCSubstring& callNrString : extraSyscalls.Split(',')) {
nsresult rv;
- int callNr = callNrString.ToInteger(&rv);
+ int callNr = PromiseFlatCString(callNrString).ToInteger(&rv);
if (NS_SUCCEEDED(rv)) {
syscallWhitelist.push_back(callNr);
}
}
}
sandboxEnabled = SetContentProcessSandbox(brokerFd, syscallWhitelist);
}
#elif defined(XP_WIN)
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
@@ -49,39 +49,16 @@ static const int wronly = SandboxBroker:
static const int rdwr = rdonly | wronly;
static const int rdwrcr = rdwr | SandboxBroker::MAY_CREATE;
#if defined(MOZ_WIDGET_GONK)
static const int wrlog = wronly | SandboxBroker::MAY_CREATE;
#endif
}
#endif
-static nsTArray<nsCString> StringSplit(const nsACString& str)
-{
- nsTArray<nsCString> result;
-
- nsACString::const_iterator begin, iter, end;
- str.BeginReading(begin);
- str.EndReading(end);
- while (begin != end) {
- iter = begin;
- FindCharInReadable(',', iter, end);
- nsDependentCSubstring path = Substring(begin, iter);
- if (!path.IsEmpty()) {
- result.AppendElement(Substring(begin, iter));
- }
- begin = iter;
- if (begin != end) {
- begin++;
- }
- }
-
- return result;
-}
-
SandboxBrokerPolicyFactory::SandboxBrokerPolicyFactory()
{
// Policy entries that are the same in every process go here, and
// are cached over the lifetime of the factory.
#if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_WIDGET_GONK)
SandboxBroker::Policy* policy = new SandboxBroker::Policy;
// Devices that need write access:
@@ -215,21 +192,21 @@ SandboxBrokerPolicyFactory::GetContentPo
UniquePtr<SandboxBroker::Policy>
policy(new SandboxBroker::Policy(*mCommonContentPolicy));
// Now read any extra paths, this requires accessing user preferences
// so we can only do it now. Our constructor is initialized before
// user preferences are read in.
nsAdoptingCString extraPathString =
Preferences::GetCString("security.sandbox.content.write_path_whitelist");
-
if (extraPathString) {
- auto extraPaths = StringSplit(extraPathString);
- for (const nsCString& path : extraPaths) {
- policy->AddDynamic(rdwr, path.get());
+ for (const nsCSubstring& path : extraPathString.Split(',')) {
+ nsCString stripPath(path);
+ stripPath.StripWhitespace();
+ policy->AddDynamic(rdwr, stripPath.get());
}
}
// Return the common policy.
return policy;
#endif
}
--- a/xpcom/string/nsTSubstring.cpp
+++ b/xpcom/string/nsTSubstring.cpp
@@ -1078,8 +1078,17 @@ nsTSubstring_CharT::SizeOfIncludingThisI
size_t
nsTSubstring_CharT::SizeOfIncludingThisEvenIfShared(
mozilla::MallocSizeOf aMallocSizeOf) const
{
return aMallocSizeOf(this) + SizeOfExcludingThisEvenIfShared(aMallocSizeOf);
}
+nsTSubstringSplitter_CharT nsTSubstring_CharT::Split(const nsTSubstring_CharT::char_type aChar)
+{
+ return nsTSubstringSplitter_CharT(this, aChar);
+}
+
+const nsTSubstring_CharT& nsTSubstringSplitter_CharT::nsTSubstringSplit_Iter::operator* () const
+{
+ return mObj.Get(mPos);
+}
--- a/xpcom/string/nsTSubstring.h
+++ b/xpcom/string/nsTSubstring.h
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// IWYU pragma: private, include "nsString.h"
#include "mozilla/Casting.h"
+#include "mozilla/UniquePtr.h"
#include "mozilla/MemoryReporting.h"
#ifndef MOZILLA_INTERNAL_API
#error Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead.
#endif
/**
* The base for string comparators
@@ -41,16 +42,18 @@ public:
nsTDefaultStringComparator_CharT()
{
}
virtual int operator()(const char_type*, const char_type*,
uint32_t, uint32_t) const override;
};
+class nsTSubstringSplitter_CharT;
+
/**
* nsTSubstring is the most abstract class in the string hierarchy. It
* represents a single contiguous array of characters, which may or may not
* be null-terminated. This type is not instantiated directly. A sub-class
* is instantiated instead. For example, see nsTString.
*
* NAMES:
* nsAString for wide characters
@@ -704,16 +707,17 @@ public:
ReplaceLiteral(aPos, 0, aStr, N - 1);
}
void Cut(index_type aCutStart, size_type aCutLength)
{
Replace(aCutStart, aCutLength, char_traits::sEmptyBuffer, 0);
}
+ nsTSubstringSplitter_CharT Split(const char_type aChar);
/**
* buffer sizing
*/
/**
* Attempts to set the capacity to the given size in number of
* characters, without affecting the length of the string.
@@ -902,18 +906,17 @@ public:
{
::NS_ABORT_OOM(aLength * sizeof(char_type));
}
protected:
friend class nsTObsoleteAStringThunk_CharT;
friend class nsTSubstringTuple_CharT;
-
- // XXX GCC 3.4 needs this :-(
+ friend class nsTSubstringSplitter_CharT;
friend class nsTPromiseFlatString_CharT;
char_type* mData;
size_type mLength;
uint32_t mFlags;
// default initialization
nsTSubstring_CharT()
@@ -1163,8 +1166,94 @@ operator>=(const nsTSubstring_CharT::bas
}
inline bool
operator>(const nsTSubstring_CharT::base_string_type& aLhs,
const nsTSubstring_CharT::base_string_type& aRhs)
{
return Compare(aLhs, aRhs) > 0;
}
+
+class nsTSubstringSplitter_CharT
+{
+ class nsTSubstringSplit_Iter
+ {
+ public:
+ nsTSubstringSplit_Iter(const nsTSubstringSplitter_CharT& aObj,
+ nsTSubstring_CharT::size_type aPos)
+ : mObj(aObj)
+ , mPos(aPos)
+ {
+ }
+
+ bool operator!=(const nsTSubstringSplit_Iter& other) const
+ {
+ return mPos != other.mPos;
+ }
+
+ const nsTSubstring_CharT& operator*() const;
+
+ const nsTSubstringSplit_Iter& operator++()
+ {
+ ++mPos;
+ return *this;
+ }
+
+ private:
+ const nsTSubstringSplitter_CharT& mObj;
+ nsTSubstring_CharT::size_type mPos;
+ };
+
+private:
+ const nsTSubstring_CharT* mStr;
+ mozilla::UniquePtr<nsTSubstring_CharT[]> mArray;
+ nsTSubstring_CharT::size_type mArraySize;
+ const nsTSubstring_CharT::char_type mDelim;
+
+public:
+ nsTSubstringSplitter_CharT(const nsTSubstring_CharT* aStr,
+ nsTSubstring_CharT::char_type aDelim)
+ : mStr(aStr)
+ , mArray(nullptr)
+ , mDelim(aDelim)
+ {
+ if (mStr->IsEmpty()) {
+ mArraySize = 0;
+ return;
+ }
+
+ nsTSubstring_CharT::size_type delimCount = mStr->CountChar(aDelim);
+ mArraySize = delimCount + 1;
+ mArray.reset(new nsTSubstring_CharT[mArraySize]);
+
+ size_t seenParts = 0;
+ // signed int due to return from FindChar
+ int32_t start = 0;
+ do {
+ int32_t offset = mStr->FindChar(aDelim, start);
+ if (offset != -1) {
+ nsTSubstring_CharT::size_type length = offset - start;
+ mArray[seenParts++].Assign(mStr->Data() + start, length);
+ start = offset + 1;
+ } else {
+ // Get the remainder
+ mArray[seenParts++].Assign(mStr->Data() + start, mStr->Length() - start);
+ break;
+ }
+ } while (start < (int32_t)mStr->Length());
+ }
+
+ nsTSubstringSplit_Iter begin() const
+ {
+ return nsTSubstringSplit_Iter(*this, 0);
+ }
+
+ nsTSubstringSplit_Iter end() const
+ {
+ return nsTSubstringSplit_Iter(*this, mArraySize);
+ }
+
+ const nsTSubstring_CharT& Get(const nsTSubstring_CharT::size_type index) const
+ {
+ MOZ_ASSERT(index < mArraySize);
+ return mArray[index];
+ }
+};
--- a/xpcom/string/string-template-def-char.h
+++ b/xpcom/string/string-template-def-char.h
@@ -18,8 +18,9 @@
#define nsTDependentString_CharT nsDependentCString
#define nsTDependentSubstring_CharT nsDependentCSubstring
#define nsTLiteralString_CharT nsLiteralCString
#define nsTXPIDLString_CharT nsXPIDLCString
#define nsTGetterCopies_CharT nsCGetterCopies
#define nsTAdoptingString_CharT nsAdoptingCString
#define nsTPromiseFlatString_CharT nsPromiseFlatCString
#define TPromiseFlatString_CharT PromiseFlatCString
+#define nsTSubstringSplitter_CharT nsCSubstringSplitter
--- a/xpcom/string/string-template-def-unichar.h
+++ b/xpcom/string/string-template-def-unichar.h
@@ -18,8 +18,9 @@
#define nsTDependentString_CharT nsDependentString
#define nsTDependentSubstring_CharT nsDependentSubstring
#define nsTLiteralString_CharT nsLiteralString
#define nsTXPIDLString_CharT nsXPIDLString
#define nsTGetterCopies_CharT nsGetterCopies
#define nsTAdoptingString_CharT nsAdoptingString
#define nsTPromiseFlatString_CharT nsPromiseFlatString
#define TPromiseFlatString_CharT PromiseFlatString
+#define nsTSubstringSpliiter_CharT nsSubstringSplitter
--- a/xpcom/string/string-template-undef.h
+++ b/xpcom/string/string-template-undef.h
@@ -19,8 +19,9 @@
#undef nsTDependentString_CharT
#undef nsTDependentSubstring_CharT
#undef nsTLiteralString_CharT
#undef nsTXPIDLString_CharT
#undef nsTGetterCopies_CharT
#undef nsTAdoptingString_CharT
#undef nsTPromiseFlatString_CharT
#undef TPromiseFlatString_CharT
+#undef nsTSubstringSplitter_CharT
--- a/xpcom/tests/gtest/TestStrings.cpp
+++ b/xpcom/tests/gtest/TestStrings.cpp
@@ -973,9 +973,47 @@ TEST(Strings, todouble)
test_todouble_helper(NS_LITERAL_STRING("123456789.98765432123456"), 123456789.98765432123456, true);
test_todouble_helper(NS_LITERAL_STRING("0"), 0, true);
test_todouble_helper(NS_LITERAL_STRING("1.e5"), 100000, true);
test_todouble_helper(NS_LITERAL_STRING(""), 0, false);
test_todouble_helper(NS_LITERAL_STRING("42foo"), 42, false);
test_todouble_helper(NS_LITERAL_STRING("foo"), 0, false);
}
+TEST(Strings, Split)
+{
+ nsCString one("one"),
+ two("one;two"),
+ three("one--three");
+
+ size_t counter = 0;
+ for (const nsCSubstring& token : one.Split(',')) {
+ EXPECT_TRUE(token.Equals(NS_LITERAL_CSTRING("one")));
+ counter++;
+ }
+ EXPECT_EQ(counter, (size_t)1);
+
+ counter = 0;
+ for (const nsCSubstring& token : two.Split(';')) {
+ if (counter == 0) {
+ EXPECT_TRUE(token.Equals(NS_LITERAL_CSTRING("one")));
+ } else if (counter == 1) {
+ EXPECT_TRUE(token.Equals(NS_LITERAL_CSTRING("two")));
+ }
+ counter++;
+ }
+ EXPECT_EQ(counter, (size_t)2);
+
+ counter = 0;
+ for (const nsCSubstring& token : three.Split('-')) {
+ if (counter == 0) {
+ EXPECT_TRUE(token.Equals(NS_LITERAL_CSTRING("one")));
+ } else if (counter == 1) {
+ EXPECT_TRUE(token.Equals(NS_LITERAL_CSTRING("")));
+ } else if (counter == 2) {
+ EXPECT_TRUE(token.Equals(NS_LITERAL_CSTRING("three")));
+ }
+ counter++;
+ }
+ EXPECT_EQ(counter, (size_t)3);
+}
+
} // namespace TestStrings