avm1: Correct BitmapData constructor
* Extract is_size_valid, which respects 3 different limits: SWF<=9, SWF10 and SWF>=11. * Delay is_size_valid check after all arguments coercing. * Swap the transparency and fill_color parameters of init_pixels.
This commit is contained in:
parent
f0bea5d241
commit
2d3a4910fc
|
@ -10,6 +10,31 @@ use crate::character::Character;
|
||||||
use crate::display_object::TDisplayObject;
|
use crate::display_object::TDisplayObject;
|
||||||
use gc_arena::{GcCell, MutationContext};
|
use gc_arena::{GcCell, MutationContext};
|
||||||
|
|
||||||
|
fn is_size_valid(swf_version: u8, width: u32, height: u32) -> bool {
|
||||||
|
// From https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html:
|
||||||
|
// "In AIR 1.5 and Flash Player 10, the maximum size for a BitmapData object is 8,191 pixels in
|
||||||
|
// width or height, and the total number of pixels cannot exceed 16,777,215 pixels. (So, if a
|
||||||
|
// BitmapData object is 8,191 pixels wide, it can only be 2,048 pixels high.) In Flash Player 9
|
||||||
|
// and earlier and AIR 1.1 and earlier, the limitation is 2,880 pixels in height and 2,880 in width.
|
||||||
|
// Starting with AIR 3 and Flash player 11, the size limits for a BitmapData object have been removed.
|
||||||
|
// The maximum size of a bitmap is now dependent on the operating system."
|
||||||
|
//
|
||||||
|
// In addition, width and height of 0 are invalid in all versions.
|
||||||
|
if width == 0 || height == 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if swf_version <= 9 {
|
||||||
|
if width > 2880 || height > 2880 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if swf_version == 10 {
|
||||||
|
if width >= 0x2000 || height >= 0x2000 || width * height >= 0x1000000 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
pub fn constructor<'gc>(
|
pub fn constructor<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
|
@ -18,17 +43,12 @@ pub fn constructor<'gc>(
|
||||||
let width = args
|
let width = args
|
||||||
.get(0)
|
.get(0)
|
||||||
.unwrap_or(&Value::Number(0.0))
|
.unwrap_or(&Value::Number(0.0))
|
||||||
.coerce_to_i32(activation)?;
|
.coerce_to_i32(activation)? as u32;
|
||||||
|
|
||||||
let height = args
|
let height = args
|
||||||
.get(1)
|
.get(1)
|
||||||
.unwrap_or(&Value::Number(0.0))
|
.unwrap_or(&Value::Number(0.0))
|
||||||
.coerce_to_i32(activation)?;
|
.coerce_to_i32(activation)? as u32;
|
||||||
|
|
||||||
if width > 2880 || height > 2880 || width <= 0 || height <= 0 {
|
|
||||||
log::warn!("Invalid BitmapData size {}x{}", width, height);
|
|
||||||
return Ok(Value::Undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
let transparency = args
|
let transparency = args
|
||||||
.get(2)
|
.get(2)
|
||||||
|
@ -37,16 +57,19 @@ pub fn constructor<'gc>(
|
||||||
|
|
||||||
let fill_color = args
|
let fill_color = args
|
||||||
.get(3)
|
.get(3)
|
||||||
// can't write this in hex
|
.unwrap_or(&Value::Number(4294967295f64)) // 0xFFFFFFFF
|
||||||
// 0xFFFFFFFF as f64;
|
|
||||||
.unwrap_or(&Value::Number(4294967295_f64))
|
|
||||||
.coerce_to_i32(activation)?;
|
.coerce_to_i32(activation)?;
|
||||||
|
|
||||||
|
if !is_size_valid(activation.swf_version(), width, height) {
|
||||||
|
log::warn!("Invalid BitmapData size: {}x{}", width, height);
|
||||||
|
return Ok(Value::Undefined);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(bitmap_data) = this.as_bitmap_data_object() {
|
if let Some(bitmap_data) = this.as_bitmap_data_object() {
|
||||||
bitmap_data
|
bitmap_data
|
||||||
.bitmap_data()
|
.bitmap_data()
|
||||||
.write(activation.context.gc_context)
|
.write(activation.context.gc_context)
|
||||||
.init_pixels(width as u32, height as u32, fill_color, transparency);
|
.init_pixels(width, height, transparency, fill_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(this.into())
|
Ok(this.into())
|
||||||
|
|
|
@ -164,7 +164,7 @@ pub struct BitmapData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitmapData {
|
impl BitmapData {
|
||||||
pub fn init_pixels(&mut self, width: u32, height: u32, fill_color: i32, transparency: bool) {
|
pub fn init_pixels(&mut self, width: u32, height: u32, transparency: bool, fill_color: i32) {
|
||||||
self.width = width;
|
self.width = width;
|
||||||
self.height = height;
|
self.height = height;
|
||||||
self.transparency = transparency;
|
self.transparency = transparency;
|
||||||
|
|
Loading…
Reference in New Issue