O3D: Incorporate latest patches

- Better URL fetching/parsing (227158)
- Better object cleanup (227181)
- Don't return unint'd memory (227197)

BUG=chromium:227158, chromium:227181, chromium:227197
TEST=emerge-lumpy o3d, run Hangouts and 1:1 video chat

Change-Id: I6624932d0080380b1dc034bae797e53b7925e196
Reviewed-on: https://gerrit.chromium.org/gerrit/47782
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Commit-Queue: Josh Horwich <jhorwich@google.com>
Tested-by: Josh Horwich <jhorwich@google.com>
Reviewed-by: Noah Richards <noahric@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/47830
Tested-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
diff --git a/media-plugins/o3d/files/o3d-227158.patch b/media-plugins/o3d/files/o3d-227158.patch
new file mode 100644
index 0000000..6bfbd6c
--- /dev/null
+++ b/media-plugins/o3d/files/o3d-227158.patch
@@ -0,0 +1,112 @@
+--- o3d/ppapi_plugin/cross/whitelist.cc
++++ o3d/ppapi_plugin/cross/whitelist.cc
+@@ -37,6 +37,7 @@
+
+ #include "base/basictypes.h"
+ #include "base/logging.h"
++#include "ppapi/cpp/dev/url_util_dev.h"
+ #include "ppapi/cpp/private/var_private.h"
+
+ // TODO(jhorwich) Unfork this file when PPAPI plugin is merged into
+@@ -56,41 +57,9 @@
+   O3D_PLUGIN_DOMAIN_WHITELIST
+ };
+
+-static const char kHttpsProtocol[] = "https://";
+-
+-static std::string GetURL(pp::InstancePrivate *instance) {
+-  std::string url;
+-  pp::VarPrivate window = instance->GetWindowObject();
+-  pp::VarPrivate location = window.GetProperty("location");
+-  pp::VarPrivate href = location.GetProperty("href");
+-  url = href.AsString();
+-  return url;
+-}
+-
+-static std::string ParseUrlHost(const std::string &in_url) {
+-  size_t host_start;
+-  if (in_url.find(kHttpsProtocol) == 0) {
+-    host_start = sizeof(kHttpsProtocol) - 1;
+-  } else {
+-    // Do not allow usage on non https pages.
+-    return "";
+-  }
+-  size_t path_start = in_url.find("/", host_start);
+-  if (path_start == std::string::npos) {
+-    path_start = in_url.size();
+-  }
+-  const std::string host_and_port(
+-      in_url.substr(host_start, path_start - host_start));
+-  size_t colon_pos = host_and_port.find(":");
+-  if (colon_pos == std::string::npos) {
+-    colon_pos = host_and_port.size();
+-  }
+-  return host_and_port.substr(0, colon_pos);
+-}
+-
+-static bool IsDomainWhitelisted(const std::string &in_url) {
+-  std::string host(ParseUrlHost(in_url));
++static const char kHttpsProtocol[] = "https";
+
++static bool IsHostWhitelisted(std::string host) {
+   // convert the host to a lower-cased version so we
+   // don't have to worry about case mismatches.
+   std::transform(host.begin(), host.end(), host.begin(), ::tolower);
+@@ -105,23 +74,46 @@
+   return false;
+ }
+
++static std::string GetURLComponent(std::string url,
++                                   const struct PP_URLComponent_Dev* comp) {
++  std::string result;
++  if (comp->begin >= 0 &&
++      comp->len > 0 &&
++      (comp->begin < url.size()) &&
++      (comp->len <= url.size() - comp->begin)) {
++    result = url.substr(comp->begin, comp->len);
++  }
++  return result;
++}
++
+ #endif  // O3D_PLUGIN_DOMAIN_WHITELIST
+
+ bool IsDomainAuthorized(pp::InstancePrivate *instance) {
+ #ifdef O3D_PLUGIN_DOMAIN_WHITELIST
+-  std::string url(GetURL(instance));
+-  if (url.empty()) {
+-    // This can happen in Chrome due to a bug with cross-origin security checks,
+-    // including on legitimate pages. Until it's fixed we'll just allow any
+-    // domain when this happens.
+-    // http://code.google.com/p/chromium/issues/detail?id=64229
+-    LOG(WARNING) <<
+-        "Allowing use despite inability to determine the hosting page";
+-    return true;
++  const pp::URLUtil_Dev* utils = pp::URLUtil_Dev::Get();
++  if (utils == NULL) {
++    LOG(ERROR) << "Unable to get URLUtil_Dev interface - unauthorized";
++    return false;
++  }
++  PP_URLComponents_Dev components;
++  pp::Var doc_url = utils->GetDocumentURL(*instance, &components);
++  if (!doc_url.is_string()) {
++    LOG(ERROR) << "Unable to get document URL - unauthorized";
++    return false;
++  }
++  std::string url = doc_url.AsString();
++  std::string scheme = GetURLComponent(url, &components.scheme);
++  std::string host = GetURLComponent(url, &components.host);
++
++  // Require HTTPS
++  if (scheme.compare(kHttpsProtocol) != 0) {
++    LOG(ERROR) << "Non-HTTPS scheme - unauthorized";
++    return false;
+   }
+-  bool authorized = IsDomainWhitelisted(url);
++
++  bool authorized = IsHostWhitelisted(host);
+   if (!authorized) {
+-    LOG(ERROR) << "Unauthorized domain";
++    LOG(ERROR) << "Unauthorized host";
+   }
+   return authorized;
+ #else
diff --git a/media-plugins/o3d/files/o3d-227181.patch b/media-plugins/o3d/files/o3d-227181.patch
new file mode 100644
index 0000000..341fd2e
--- /dev/null
+++ b/media-plugins/o3d/files/o3d-227181.patch
@@ -0,0 +1,42 @@
+--- o3d/core/cross/element.cc	(revision 193397)
++++ o3d/core/cross/element.cc	(working copy)
+@@ -63,6 +63,11 @@
+ }
+ 
+ Element::~Element() {
++  // Unregister any DrawElements that might think they own us.
++  DrawElementRefArray::iterator iter, end = draw_elements_.end();
++  for (iter = draw_elements_.begin(); iter != end; ++iter) {
++    iter->Get()->SetOwner(0);
++  }
+ }
+ 
+ void Element::SetOwner(Shape* new_owner) {
+--- o3d/core/cross/shape.h	(revision 193397)
++++ o3d/core/cross/shape.h	(working copy)
+@@ -55,6 +55,8 @@
+  public:
+   typedef SmartPointer<Shape> Ref;
+ 
++  virtual ~Shape();
++
+   // Gets an Array of Elements in this shape.
+   // Returns:
+   //   ElementArray of elements in this shape.
+--- o3d/core/cross/shape.cc	(revision 193397)
++++ o3d/core/cross/shape.cc	(working copy)
+@@ -44,6 +44,14 @@
+     : ParamObject(service_locator) {
+ }
+ 
++Shape::~Shape() {
++  // Unregister any Elements that might think they own us.
++  ElementRefArray::iterator iter, end = elements_.end();
++  for (iter = elements_.begin(); iter != end; ++iter) {
++    iter->Get()->SetOwner(0);
++  }
++}
++
+ ObjectBase::Ref Shape::Create(ServiceLocator* service_locator) {
+   return ObjectBase::Ref(new Shape(service_locator));
+ }
diff --git a/media-plugins/o3d/files/o3d-227197.patch b/media-plugins/o3d/files/o3d-227197.patch
new file mode 100644
index 0000000..c4385dc
--- /dev/null
+++ b/media-plugins/o3d/files/o3d-227197.patch
@@ -0,0 +1,32 @@
+--- o3d/core/cross/buffer.h	(revision 193397)
++++ o3d/core/cross/buffer.h	(working copy)
+@@ -215,6 +215,10 @@
+ 
+   void AdjustBufferMemoryInfo(bool add);
+ 
++  bool InternalSet(o3d::RawData *raw_data,
++                   size_t offset,
++                   size_t length);
++
+   Features* features_;
+ 
+   // Fields.
+--- o3d/core/cross/buffer.cc	(revision 193397)
++++ o3d/core/cross/buffer.cc	(working copy)
+@@ -389,6 +389,16 @@
+ bool Buffer::Set(o3d::RawData *raw_data,
+                  size_t offset,
+                  size_t length) {
++  bool ret = InternalSet(raw_data, offset, length);
++  if (!ret) {
++    Free();
++  }
++  return ret;
++}
++
++bool Buffer::InternalSet(o3d::RawData *raw_data,
++                         size_t offset,
++                         size_t length) {
+   DCHECK(raw_data);
+ 
+   if (!raw_data->IsOffsetLengthValid(offset, length)) {
diff --git a/media-plugins/o3d/o3d-179976-r2.ebuild b/media-plugins/o3d/o3d-179976-r3.ebuild
similarity index 88%
rename from media-plugins/o3d/o3d-179976-r2.ebuild
rename to media-plugins/o3d/o3d-179976-r3.ebuild
index 04f3c82..94ea591 100644
--- a/media-plugins/o3d/o3d-179976-r2.ebuild
+++ b/media-plugins/o3d/o3d-179976-r3.ebuild
@@ -51,10 +51,16 @@
 	unset GYP_GENERATOR_FLAGS
 	unset BUILD_OUT
 	unset builddir_name
-	epatch "${FILESDIR}"/gcc-4_7.patch
 
+	epatch "${FILESDIR}"/gcc-4_7.patch
 	epatch "${FILESDIR}/o3d-38135.patch" || \
 		die "Could not apply patch o3d-38135.patch"
+	epatch "${FILESDIR}/o3d-227158.patch" || \
+		die "Could not apply patch o3d-227158.patch"
+	epatch "${FILESDIR}/o3d-227181.patch" || \
+		die "Could not apply patch o3d-227181.patch"
+	epatch "${FILESDIR}/o3d-227197.patch" || \
+		die "Could not apply patch o3d-227197.patch"
 
 	${EGCLIENT} runhooks || die
 }