summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorlukasza <lukasza@chromium.org>2016-01-08 11:35:04 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-08 19:36:02 +0000
commitc644f37125ab27311d697af61e56c64d0e29027e (patch)
treef9f73168acee7cfe259bcaaf5425deeab99071f8 /net
parent5efcee9378877176a9ccf173e3bcfa4a902b55d9 (diff)
downloadchromium_src-c644f37125ab27311d697af61e56c64d0e29027e.zip
chromium_src-c644f37125ab27311d697af61e56c64d0e29027e.tar.gz
chromium_src-c644f37125ab27311d697af61e56c64d0e29027e.tar.bz2
Introducing a net::GenerateMimeMultipartBoundary helper.
... and using the helper in places that had introduced separate functions for generating a random Mime boundary (sometimes with bugs - i.e. using '*' characters is disallowed by RFC 1341). TBR=bartfab@chromium.org, stevet@chromium.org BUG=575733 Review URL: https://codereview.chromium.org/1547593002 Cr-Commit-Position: refs/heads/master@{#368404}
Diffstat (limited to 'net')
-rw-r--r--net/base/mime_util.cc49
-rw-r--r--net/base/mime_util.h4
-rw-r--r--net/base/mime_util_unittest.cc28
3 files changed, 81 insertions, 0 deletions
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index d1e202b..3e8d615 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -7,9 +7,11 @@
#include <map>
#include <string>
+#include "base/base64.h"
#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -511,6 +513,17 @@ void HashSetToVector(base::hash_set<T>* source, std::vector<T>* target) {
(*target)[old_target_size + i] = *iter;
}
+// Characters to be used for mime multipart boundary.
+// The RFC 2046 spec says the alphanumeric characters plus the
+// following characters are legal for boundaries: '()+_,-./:=?
+// However the following characters, though legal, cause some sites
+// to fail: (),./:=+
+const char kMimeBoundaryCharacters[] =
+ "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+// Size of mime multipart boundary.
+const size_t kMimeBoundarySize = 69;
+
} // namespace
void GetExtensionsForMimeType(
@@ -557,6 +570,42 @@ void GetExtensionsForMimeType(
HashSetToVector(&unique_extensions, extensions);
}
+NET_EXPORT std::string GenerateMimeMultipartBoundary() {
+ // Based on RFC 1341, section "7.2.1 Multipart: The common syntax":
+ // Because encapsulation boundaries must not appear in the body parts being
+ // encapsulated, a user agent must exercise care to choose a unique
+ // boundary. The boundary in the example above could have been the result of
+ // an algorithm designed to produce boundaries with a very low probability
+ // of already existing in the data to be encapsulated without having to
+ // prescan the data.
+ // [...]
+ // the boundary parameter [...] consists of 1 to 70 characters from a set of
+ // characters known to be very robust through email gateways, and NOT ending
+ // with white space.
+ // [...]
+ // boundary := 0*69<bchars> bcharsnospace
+ // bchars := bcharsnospace / " "
+ // bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" / "+" /
+ // "_" / "," / "-" / "." / "/" / ":" / "=" / "?"
+
+ std::string result;
+ result.reserve(kMimeBoundarySize);
+ result.append("----MultipartBoundary--");
+ while (result.size() < (kMimeBoundarySize - 4)) {
+ // Subtract 2 from the array size to 1) exclude '\0', and 2) turn the size
+ // into the last index.
+ const int last_char_index = sizeof(kMimeBoundaryCharacters) - 2;
+ char c = kMimeBoundaryCharacters[base::RandInt(0, last_char_index)];
+ result.push_back(c);
+ }
+ result.append("----");
+
+ // Not a strict requirement - documentation only.
+ DCHECK_EQ(kMimeBoundarySize, result.size());
+
+ return result;
+}
+
void AddMultipartValueForUpload(const std::string& value_name,
const std::string& value,
const std::string& mime_boundary,
diff --git a/net/base/mime_util.h b/net/base/mime_util.h
index d58ddb0..48b9a64 100644
--- a/net/base/mime_util.h
+++ b/net/base/mime_util.h
@@ -100,6 +100,10 @@ enum CertificateMimeType {
CERTIFICATE_MIME_TYPE_PKCS12_ARCHIVE,
};
+// Generates a random MIME multipart boundary.
+// The returned string is guaranteed to be at most 70 characters long.
+NET_EXPORT std::string GenerateMimeMultipartBoundary();
+
// Prepares one value as part of a multi-part upload request.
NET_EXPORT void AddMultipartValueForUpload(const std::string& value_name,
const std::string& value,
diff --git a/net/base/mime_util_unittest.cc b/net/base/mime_util_unittest.cc
index 8bc61bc..0787d8c 100644
--- a/net/base/mime_util_unittest.cc
+++ b/net/base/mime_util_unittest.cc
@@ -273,6 +273,34 @@ TEST(MimeUtilTest, TestGetExtensionsForMimeType) {
}
}
+TEST(MimeUtilTest, TestGenerateMimeMultipartBoundary) {
+ std::string boundary1 = GenerateMimeMultipartBoundary();
+ std::string boundary2 = GenerateMimeMultipartBoundary();
+
+ // RFC 1341 says: the boundary parameter [...] consists of 1 to 70 characters.
+ EXPECT_GE(70u, boundary1.size());
+ EXPECT_GE(70u, boundary2.size());
+
+ // RFC 1341 asks to: exercise care to choose a unique boundary.
+ EXPECT_NE(boundary1, boundary2);
+ ASSERT_LE(16u, boundary1.size());
+ ASSERT_LE(16u, boundary2.size());
+
+ // Expect that we don't pick '\0' character from the array/string
+ // where we take the characters from.
+ EXPECT_EQ(std::string::npos, boundary1.find('\0'));
+ EXPECT_EQ(std::string::npos, boundary2.find('\0'));
+
+ // Asserts below are not RFC 1341 requirements, but are here
+ // to improve readability of generated MIME documents and to
+ // try to preserve some aspects of the old boundary generation code.
+ EXPECT_EQ("--", boundary1.substr(0, 2));
+ EXPECT_EQ("--", boundary2.substr(0, 2));
+ EXPECT_NE(std::string::npos, boundary1.find("MultipartBoundary"));
+ EXPECT_NE(std::string::npos, boundary2.find("MultipartBoundary"));
+ EXPECT_EQ("--", boundary1.substr(boundary1.size() - 2, 2));
+ EXPECT_EQ("--", boundary2.substr(boundary2.size() - 2, 2));
+}
TEST(MimeUtilTest, TestAddMultipartValueForUpload) {
const char ref_output[] =