Commit 15e2e8f5 authored by Dongheun Kang's avatar Dongheun Kang Committed by Commit Bot

Modify ContentType::Parameter() for various cases

The existing code had problems when parsing parameter's attribute
that included multi-parameters or parameter names.
Improved to handle all parameters.

Bug: 1041986
Change-Id: I8ddd97e1d53be84b095d9dcdd487cef24000d86c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1989298
Commit-Queue: Matthew Wolenetz <wolenetz@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarMatthew Wolenetz <wolenetz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#740783}
parent 9e090981
......@@ -32,35 +32,29 @@ namespace blink {
ContentType::ContentType(const String& content_type) : type_(content_type) {}
static bool IsASCIIQuote(UChar c) {
return c == '"';
}
String ContentType::Parameter(const String& parameter_name) const {
String parameter_value;
String stripped_type = type_.StripWhiteSpace();
Vector<String> parameters;
ParseParameters(parameters);
// a MIME type can have one or more "param=value" after a semi-colon, and
// separated from each other by semi-colons
wtf_size_t semi = stripped_type.find(';');
if (semi != kNotFound) {
wtf_size_t start =
stripped_type.FindIgnoringASCIICase(parameter_name, semi + 1);
if (start != kNotFound) {
start = stripped_type.find('=', start + parameter_name.length());
if (start != kNotFound) {
wtf_size_t quote = stripped_type.find('\"', start + 1);
wtf_size_t end = stripped_type.find('\"', start + 2);
if (quote != kNotFound && end != kNotFound) {
start = quote;
} else {
end = stripped_type.find(';', start + 1);
if (end == kNotFound)
end = stripped_type.length();
}
parameter_value = stripped_type.Substring(start + 1, end - (start + 1))
.StripWhiteSpace();
for (auto& parameter : parameters) {
String stripped_parameter = parameter.StripWhiteSpace();
wtf_size_t separator_pos = stripped_parameter.find('=');
if (separator_pos != kNotFound) {
String attribute =
stripped_parameter.Left(separator_pos).StripWhiteSpace();
if (EqualIgnoringASCIICase(attribute, parameter_name)) {
return stripped_parameter.Substring(separator_pos + 1)
.StripWhiteSpace()
.RemoveCharacters(IsASCIIQuote);
}
}
}
return parameter_value;
return String();
}
String ContentType::GetType() const {
......@@ -74,4 +68,29 @@ String ContentType::GetType() const {
return stripped_type;
}
void ContentType::ParseParameters(Vector<String>& result) const {
String stripped_type = type_.StripWhiteSpace();
unsigned cur_pos = 0;
unsigned end_pos = stripped_type.length();
unsigned start_pos = 0;
bool is_quote = false;
while (cur_pos < end_pos) {
if (!is_quote && stripped_type[cur_pos] == ';') {
if (cur_pos != start_pos) {
result.push_back(
stripped_type.Substring(start_pos, cur_pos - start_pos));
}
start_pos = cur_pos + 1;
} else if (stripped_type[cur_pos] == '"') {
is_quote = !is_quote;
}
cur_pos++;
}
if (start_pos != end_pos)
result.push_back(stripped_type.Substring(start_pos));
}
} // namespace blink
......@@ -44,6 +44,8 @@ class PLATFORM_EXPORT ContentType {
const String& Raw() const { return type_; }
private:
void ParseParameters(Vector<String>& result) const;
String type_;
};
......
......@@ -31,6 +31,7 @@
'video/webm;codecs="',
'video/webm;codecs=""',
'video/webm;codecs=","',
'audio/webm;aaacodecsbbb=opus',
'unsupported_mediatype',
'',
null
......@@ -66,6 +67,7 @@
'video/webm;codecs="vorbis, vp8"',
'audio/webm;codecs="vorbis"',
'AUDIO/WEBM;CODECS="vorbis"',
'audio/webm;codecs=vorbis;test="6"',
'audio/webm;codecs="opus"',
'video/webm;codecs="opus"'
], true, 'Test valid WebM type');
......@@ -83,6 +85,7 @@
'audio/mp4;codecs="opus"',
'video/mp4;codecs="opus"'
], true, 'Test valid MP4 type');
</script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment