gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r11850: Check for NaN to fix bug #28


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11850: Check for NaN to fix bug #28773. Prevent other potential bugs if methods
Date: Sat, 30 Jan 2010 14:29:02 +0100
User-agent: Bazaar (2.0.2)

------------------------------------------------------------
revno: 11850 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Sat 2010-01-30 14:29:02 +0100
message:
  Check for NaN to fix bug #28773. Prevent other potential bugs if methods
  of BitmapData are called after disposal.
modified:
  libcore/asobj/flash/display/BitmapData_as.cpp
  libcore/asobj/flash/display/BitmapData_as.h
=== modified file 'libcore/asobj/flash/display/BitmapData_as.cpp'
--- a/libcore/asobj/flash/display/BitmapData_as.cpp     2010-01-25 18:52:20 
+0000
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp     2010-01-30 13:03:35 
+0000
@@ -124,6 +124,7 @@
 boost::int32_t
 BitmapData_as::getPixel(int x, int y, bool transparency) const
 {
+    assert(!_bitmapData.empty());
 
     // A value of 0, 0 is inside the bitmap.
     if (x < 0 || y < 0) return 0;
@@ -153,11 +154,8 @@
 BitmapData_as::fillRect(int x, int y, int w, int h, boost::uint32_t color)
 {
 
-    GNASH_REPORT_FUNCTION;
-
-    // The bitmap has been "disposed".
-    if (_bitmapData.empty()) return;
-    assert (_bitmapData.size() == _width * _height);
+    // This also catches disposed BitmapDatas.
+    assert(_bitmapData.size() == _width * _height);
 
     if (w < 0 || h < 0) return;
 
@@ -168,14 +166,12 @@
 
     // If x or y is less than 0, make a rectangle of the
     // intersection with the bitmap.    
-    if (x < 0)
-    {
+    if (x < 0) {
         w += x;
         x = 0;
     }
 
-    if (y < 0)
-    {
+    if (y < 0) {
         h += y;
         y = 0;
     }
@@ -197,15 +193,11 @@
     // Make colour non-transparent if the image doesn't support it.
     if (!_transparent) color |= 0xff000000;
     
-    while (it != e)
-    {
-
+    while (it != e) {
         // Fill from x for the width of the rectangle.
         std::fill_n(it + x, w, color);
-
         // Move to the next line
         std::advance(it, _width);
-
     }
 
     updateAttachedBitmaps();
@@ -336,10 +328,16 @@
 
     if (fn.nargs < 2) return as_value();
     
+    if (disposed(*ptr)) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("fillRect called on disposed BitmapData!");
+        );
+        return as_value();
+    }
+    
     const as_value& arg = fn.arg(0);
     
-    if ( ! arg.is_object() )
-    {
+    if (!arg.is_object()) {
         /// Isn't an object...
         IF_VERBOSE_ASCODING_ERRORS(
             std::ostringstream ss;
@@ -402,8 +400,14 @@
 {
        BitmapData_as* ptr = ensure<ThisIsNative<BitmapData_as> >(fn);
 
-    if (fn.nargs < 2)
-    {
+    if (fn.nargs < 2) {
+        return as_value();
+    }
+
+    if (disposed(*ptr)) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("getPixel called on disposed BitmapData!");
+        );
         return as_value();
     }
     
@@ -419,8 +423,14 @@
 {
        BitmapData_as* ptr = ensure<ThisIsNative<BitmapData_as> >(fn);
 
-    if (fn.nargs < 2)
-    {
+    if (fn.nargs < 2) {
+        return as_value();
+    }
+
+    if (disposed(*ptr)) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("getPixel32 called on disposed BitmapData!");
+        );
         return as_value();
     }
     
@@ -504,9 +514,16 @@
         return as_value();
     }
 
-    double x = fn.arg(0).to_number();
-    double y = fn.arg(1).to_number();
-    if (x < 0 || y < 0) return as_value();
+    if (disposed(*ptr)) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("setPixel called on disposed BitmapData!");
+        );
+        return as_value();
+    }
+
+    const double x = fn.arg(0).to_number();
+    const double y = fn.arg(1).to_number();
+    if (isNaN(x) || isNaN(y) || x < 0 || y < 0) return as_value();
     if (x >= ptr->getWidth() || y >= ptr->getHeight()) {
         return as_value();
     }
@@ -528,9 +545,16 @@
         return as_value();
     }
 
-    double x = fn.arg(0).to_number();
-    double y = fn.arg(1).to_number();
-    if (x < 0 || y < 0) return as_value();
+    if (disposed(*ptr)) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("setPixel32 called on disposed BitmapData!");
+        );
+        return as_value();
+    }
+
+    const double x = fn.arg(0).to_number();
+    const double y = fn.arg(1).to_number();
+    if (isNaN(x) || isNaN(y) || x < 0 || y < 0) return as_value();
     if (x >= ptr->getWidth() || y >= ptr->getHeight()) {
         return as_value();
     }
@@ -562,7 +586,7 @@
     
     // Returns the immutable height of the bitmap or -1 if dispose() has
     // been called.
-    if (ptr->getBitmapData().empty()) return -1;
+    if (disposed(*ptr)) return -1;
        return as_value(ptr->getHeight());
 }
 
@@ -573,7 +597,7 @@
 
     // Returns the immutable rectangle of the bitmap or -1 if dispose()
     // has been called.
-    if (ptr->getBitmapData().empty()) return -1;
+    if (disposed(*ptr)) return -1;
 
     // If it's not found construction will fail.
     as_value rectangle(fn.env().find_object("flash.geom.Rectangle"));
@@ -602,7 +626,7 @@
     if (fn.nargs) return as_value();
     
     // Returns whether bitmap is transparent or -1 if dispose() has been 
called.
-    if (ptr->getBitmapData().empty()) return -1;
+    if (disposed(*ptr)) return -1;
        return as_value(ptr->isTransparent());
 }
 
@@ -616,7 +640,7 @@
     
     // Returns the immutable width of the bitmap or -1 if dispose() has
     // been called.
-    if (ptr->getBitmapData().empty()) return -1;
+    if (disposed(*ptr)) return -1;
        return as_value(ptr->getWidth());
 }
 

=== modified file 'libcore/asobj/flash/display/BitmapData_as.h'
--- a/libcore/asobj/flash/display/BitmapData_as.h       2010-01-25 18:52:20 
+0000
+++ b/libcore/asobj/flash/display/BitmapData_as.h       2010-01-30 13:06:07 
+0000
@@ -32,6 +32,12 @@
 class Bitmap;
 
 
+/// Implements the BitmapData native type.
+//
+/// This holds a vector of bitmap data. The vector's size does not change
+/// from construction until disposal. Disposal is signified by the clearing
+/// of the vector. All callers should check whether the BitmapData has been
+/// disposed before attempting to access any stored pixel data.
 class BitmapData_as : public Relay
 {
 
@@ -49,36 +55,43 @@
     size_t getHeight() const { return _height; }
     bool isTransparent() const { return _transparent; }
     
-    const BitmapArray& getBitmapData() const
-    {
+    const BitmapArray& getBitmapData() const {
         return _bitmapData;
     }
  
     /// Set a specified pixel to the specified color.
     //
-    /// Callers must make sure the pixel is in range. Retains transparency
+    /// Callers must make sure the pixel is in range and that the
+    /// BitmapData has not been disposed. Retains transparency
     /// (which is opaque, for non-transparent BitmapData objects).
     void setPixel(int x, int y, boost::uint32_t color) {
+        assert(!_bitmapData.empty());
         const BitmapArray::size_type index = x * _width + y;
         _bitmapData[index] = (_bitmapData[index] & 0xff000000) | color;
     }
 
     /// Set a specified pixel to the specified color.
     //
-    /// Callers must make sure the pixel is in range. Set to opaque for
-    /// non-transparent BitmapData objects
+    /// Callers must make sure the pixel is in range and that the BitmapData
+    /// has not been disposed. Set to opaque for non-transparent BitmapData
+    /// objects
     void setPixel32(int x, int y, boost::uint32_t color) {
+        assert(!_bitmapData.empty());
         _bitmapData[x * _width + y] = _transparent ? color : color | 
0xff000000;
     }
 
-
-    /// Returns an unsigned int representation of the pixel
-    /// at (x, y) either with or without transparency.
+    /// Returns the value of the pixel at (x, y) optionally with transparency.
+    //
+    /// Callers must make that dispose() has not been called.
+    /// Returns 0 if the pixel is out of range.
     boost::int32_t getPixel(int x, int y, bool transparency) const;
 
     void update(const boost::uint8_t* data);
 
-    // Fill the bitmap with a colour starting at x, y
+    /// Fill the bitmap with a colour starting at x, y
+    //
+    /// Callers must check that arguments are within the BitmapData's range
+    /// and that dispose() has not been called.
     void fillRect(int x, int y, int w, int h, boost::uint32_t color);
     
     // Free the bitmap data (clear the array)
@@ -115,6 +128,12 @@
 
 };
 
+inline bool
+disposed(const BitmapData_as& bm)
+{
+    return bm.getBitmapData().empty();
+}
+
 
 /// Initialize the global BitmapData class
 void bitmapdata_class_init(as_object& where, const ObjectURI& uri);


reply via email to

[Prev in Thread] Current Thread [Next in Thread]