EdB <edb+m...@sigluy.net> writes:

> otherwise c_str() is not safe
> ---
>  src/gallium/state_trackers/clover/util/compat.hpp | 54 
> ++++++++++++++++++++---
>  1 file changed, 48 insertions(+), 6 deletions(-)
>
> diff --git a/src/gallium/state_trackers/clover/util/compat.hpp 
> b/src/gallium/state_trackers/clover/util/compat.hpp
> index 6f0f7cc..7ca1f85 100644
> --- a/src/gallium/state_trackers/clover/util/compat.hpp
> +++ b/src/gallium/state_trackers/clover/util/compat.hpp
> @@ -197,7 +197,7 @@ namespace clover {
>              return _p[i];
>           }
>  
> -      private:
> +      protected:
>           iterator _p;  //memory array
>           size_type _s; //size
>           size_type _c; //capacity
> @@ -306,18 +306,56 @@ namespace clover {
>  
>        class string : public vector<char> {
>        public:
> -         string() : vector() {
> +         string() : vector(0, 1) {
> +            _p[_s - 1] = '\0';
>           }
>  
> -         string(const char *p) : vector(p, std::strlen(p)) {
> +         string(const char *p) : vector(p, std::strlen(p) + 1) {
> +            _p[_s - 1] = '\0';
>           }
>  
>           template<typename C>
> -         string(const C &v) : vector(v) {
> +         string(const C &v) : vector(&*v.begin(), v.size() + 1) {
> +            _p[_s - 1] = '\0';
>           }
>  
> -         operator std::string() const {
> -            return std::string(begin(), end());
> +         void
> +         reserve(size_type m) {
> +            vector::reserve(m + 1);
> +         }
> +
> +         void
> +         resize(size_type m, char x = '\0') {
> +            vector::resize(m + 1, x);
> +            _p[_s - 1] = '\0';
> +         }
> +
> +         void
> +         push_back(char &x) {
> +            reserve(_s + 1);
> +            _p[_s - 1] = x;
> +            _p[_s] = '\0';
> +            ++_s;
> +         }
> +
> +         size_type
> +         size() const {
> +            return _s - 1;
> +         }
> +
> +         size_type
> +         capacity() const {
> +            return _c - 1;
> +         }
> +
> +         iterator
> +         end() {
> +            return _p + size();
> +         }
> +
> +         const_iterator
> +         end() const {
> +            return _p + size();
>           }
>  

At this point where all methods from the base class need to be redefined
it probably stops making sense to use inheritance instead of
aggregation.  Once we've done that fixing c_str() gets a lot easier (two
lines of code) because we can just declare the container as mutable and
fix up the NULL terminator when c_str() is called.  Both changes
attached.

>           const char *
> @@ -325,6 +363,10 @@ namespace clover {
>              return begin();
>           }
>  
> +         operator std::string() const {
> +            return std::string(begin(), end());
> +         }
> +
>           const char *
>           find(const string &s) const {
>              for (size_t i = 0; i + s.size() < size(); ++i) {
> -- 
> 2.0.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev

From e1e97e017f25f4ed1c75bae71095ffa116374654 Mon Sep 17 00:00:00 2001
From: Francisco Jerez <curroje...@riseup.net>
Date: Mon, 18 Aug 2014 15:21:52 +0300
Subject: [PATCH 1/2] clover/util: Implement compat::string using aggregation
 instead of inheritance.

---
 src/gallium/state_trackers/clover/util/compat.hpp | 76 +++++++++++++++++++++--
 1 file changed, 71 insertions(+), 5 deletions(-)

diff --git a/src/gallium/state_trackers/clover/util/compat.hpp b/src/gallium/state_trackers/clover/util/compat.hpp
index a4e3938..e0ab965 100644
--- a/src/gallium/state_trackers/clover/util/compat.hpp
+++ b/src/gallium/state_trackers/clover/util/compat.hpp
@@ -280,20 +280,83 @@ namespace clover {
          size_t offset;
       };
 
-      class string : public vector<char> {
+      class string {
       public:
-         string() : vector() {
+         typedef char *iterator;
+         typedef const char *const_iterator;
+         typedef char value_type;
+         typedef char &reference;
+         typedef const char &const_reference;
+         typedef std::ptrdiff_t difference_type;
+         typedef std::size_t size_type;
+
+         string() : v() {
          }
 
-         string(const char *p) : vector(p, std::strlen(p)) {
+         string(const char *p) : v(p, std::strlen(p)) {
          }
 
          template<typename C>
-         string(const C &v) : vector(v) {
+         string(const C &v) : v(v) {
          }
 
          operator std::string() const {
-            return std::string(begin(), end());
+            return std::string(v.begin(), v.end());
+         }
+
+         void
+         reserve(size_type n) {
+            v.reserve(n);
+         }
+
+         void
+         resize(size_type n, char x = char()) {
+            v.resize(n, x);
+         }
+
+         void
+         push_back(char x) {
+            v.push_back(x);
+         }
+
+         size_type
+         size() const {
+            return v.size();
+         }
+
+         size_type
+         capacity() const {
+            return v.capacity();
+         }
+
+         iterator
+         begin() {
+            return v.begin();
+         }
+
+         const_iterator
+         begin() const {
+            return v.begin();
+         }
+
+         iterator
+         end() {
+            return v.end();
+         }
+
+         const_iterator
+         end() const {
+            return v.end();
+         }
+
+         reference
+         operator[](size_type i) {
+            return v[i];
+         }
+
+         const_reference
+         operator[](size_type i) const {
+            return v[i];
          }
 
          const char *
@@ -310,6 +373,9 @@ namespace clover {
 
             return end();
          }
+
+      private:
+         mutable vector<char> v;
       };
 
       template<typename T>
-- 
2.0.4

From 07e990c54df270e8dc632eb95338beb5b0aeebf3 Mon Sep 17 00:00:00 2001
From: Francisco Jerez <curroje...@riseup.net>
Date: Mon, 18 Aug 2014 15:25:35 +0300
Subject: [PATCH 2/2] clover/util: Null-terminate the result of
 compat::string::c_str().

Reported-by: EdB <edb+m...@sigluy.net>
---
 src/gallium/state_trackers/clover/util/compat.hpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/clover/util/compat.hpp b/src/gallium/state_trackers/clover/util/compat.hpp
index e0ab965..7305577 100644
--- a/src/gallium/state_trackers/clover/util/compat.hpp
+++ b/src/gallium/state_trackers/clover/util/compat.hpp
@@ -361,7 +361,9 @@ namespace clover {
 
          const char *
          c_str() const {
-            return begin();
+            v.reserve(size() + 1);
+            *v.end() = 0;
+            return v.begin();
          }
 
          const char *
-- 
2.0.4

Attachment: pgp7apTYGBBwq.pgp
Description: PGP signature

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to