[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r9499: Add a group of tests for dept
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r9499: Add a group of tests for depth limits. Do depth checking on |
Date: |
Fri, 18 Jul 2008 15:41:31 +0200 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 9499
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Fri 2008-07-18 15:41:31 +0200
message:
Add a group of tests for depth limits. Do depth checking on
MovieClip.attachMovie, duplicateMovieClip and MovieClip.duplicateMovieClip.
This conveniently also prevents UB when converting to int.
Allow attachMovie to accept all legal depths, not just 0-65535. Don't use
depth as ID.
Add static constants to character class for upper and lower bounds.
added:
testsuite/misc-ming.all/DepthLimitsTest.c
modified:
server/character.cpp
server/character.h
server/sprite_instance.cpp
server/vm/ASHandlers.cpp
testsuite/actionscript.all/MovieClip.as
testsuite/misc-ming.all/Makefile.am
------------------------------------------------------------
revno: 9498.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: workingcopy
timestamp: Fri 2008-07-18 08:45:39 +0200
message:
Test that depth of createEmptyMovieClip corresponds to to_int(). Gnash
passes these already.
modified:
testsuite/actionscript.all/MovieClip.as
------------------------------------------------------------
revno: 9498.1.2
committer: Benjamin Wolsey <address@hidden>
branch nick: workingcopy
timestamp: Fri 2008-07-18 13:02:56 +0200
message:
Tests for createEmptyMovieClip() depths. Gnash passes them all except in
version 5.
modified:
testsuite/actionscript.all/MovieClip.as
------------------------------------------------------------
revno: 9498.1.3
committer: Benjamin Wolsey <address@hidden>
branch nick: workingcopy
timestamp: Fri 2008-07-18 13:41:07 +0200
message:
Add test to group depth limit tests together.
added:
testsuite/misc-ming.all/DepthLimitsTest.c
modified:
testsuite/misc-ming.all/Makefile.am
------------------------------------------------------------
revno: 9498.1.4
committer: Benjamin Wolsey <address@hidden>
branch nick: workingcopy
timestamp: Fri 2008-07-18 13:45:21 +0200
message:
Add constants for upper and lower accessible bounds (for MovieClip
methods). Yes, lowerAccessibleBound is the same as staticDepthOffset.
modified:
server/character.cpp
server/character.h
------------------------------------------------------------
revno: 9498.1.5
committer: Benjamin Wolsey <address@hidden>
branch nick: workingcopy
timestamp: Fri 2008-07-18 13:45:30 +0200
message:
Use character::lowerAccessibleBound where that's semantically appropriate.
(attachMovie): accept the full range of valid depths (-16384 to
2130690044).
Do not use depth as character ID, as this will fail for negative depths.
Use
0 instead. Check depth argument for validity, which also prevents UB when
casting to int. Add references to online documentation.
modified:
server/sprite_instance.cpp
------------------------------------------------------------
revno: 9498.1.6
committer: Benjamin Wolsey <address@hidden>
branch nick: workingcopy
timestamp: Fri 2008-07-18 14:30:08 +0200
message:
Add tests for duplicateMovieClip showing depth bounds are the same as for
attachMovie. xcheck -> check for attachMovie.
modified:
testsuite/misc-ming.all/DepthLimitsTest.c
------------------------------------------------------------
revno: 9498.1.7
committer: Benjamin Wolsey <address@hidden>
branch nick: workingcopy
timestamp: Fri 2008-07-18 15:17:47 +0200
message:
Test MovieClip.duplicateMovieClip.
modified:
testsuite/misc-ming.all/DepthLimitsTest.c
------------------------------------------------------------
revno: 9498.1.8
committer: Benjamin Wolsey <address@hidden>
branch nick: workingcopy
timestamp: Fri 2008-07-18 15:18:25 +0200
message:
Add maximum and mininum depths for duplicateMovieClip and
MovieClip.duplicateMovieClip. This also prevents undefined behaviour
when casting from float to int.
modified:
server/sprite_instance.cpp
server/vm/ASHandlers.cpp
------------------------------------------------------------
revno: 9498.1.9
committer: Benjamin Wolsey <address@hidden>
branch nick: workingcopy
timestamp: Fri 2008-07-18 15:39:18 +0200
message:
Depth should be kept as a double until it's checked.
modified:
server/vm/ASHandlers.cpp
=== modified file 'server/character.cpp'
--- a/server/character.cpp 2008-07-16 05:12:53 +0000
+++ b/server/character.cpp 2008-07-18 11:45:21 +0000
@@ -45,6 +45,8 @@
{
// Define static const members or there will be linkage problems.
+const int character::lowerAccessibleBound;
+const int character::upperAccessibleBound;
const int character::staticDepthOffset;
const int character::removedDepthOffset;
const int character::noClipDepthValue;
=== modified file 'server/character.h'
--- a/server/character.h 2008-07-09 07:33:34 +0000
+++ b/server/character.h 2008-07-18 11:45:21 +0000
@@ -317,15 +317,27 @@
public:
+ /// The lowest placeable and accessible depth for a character.
+ /// Macromedia Flash help says: depth starts at -16383 (0x3FFF)
+ ///
+ /// See: http://www.senocular.com/flash/tutorials/depths/?page=2
+ //
+ /// See also http://www.kirupa.com/developer/actionscript/depths2.htm
+ //
+ /// The only way to exceed these bounds is with createEmptyMoveClip(),
+ /// which can be placed at any depth within +/- 2**31.
+ static const int lowerAccessibleBound = -16384;
+
+
+ /// This is the maximum depth a MovieClip character can be placed
+ /// at (attachMovie). Kirupa (see above) says 2130690045, but this
+ /// seems not to be included in the range.
+ static const int upperAccessibleBound = 2130690044;
+
/// This is the amount added to displaylist tag defined depths.
/// Character placed by tags (vs. characters instantiated by ActionScript)
/// always have negative depths by effect of this offset.
- //
- /// Macromedia Flash help says: depth starts at -16383 (0x3FFF)
- ///
- /// See: http://www.senocular.com/flash/tutorials/depths/?page=2
- ///
- static const int staticDepthOffset = -16384;
+ static const int staticDepthOffset = lowerAccessibleBound;
/// This is the offset at which character's depth is
/// shifted when a character is removed from stage but
=== modified file 'server/sprite_instance.cpp'
--- a/server/sprite_instance.cpp 2008-07-14 19:23:43 +0000
+++ b/server/sprite_instance.cpp 2008-07-18 13:18:25 +0000
@@ -195,7 +195,8 @@
// attachMovie(idName:String, newName:String,
// depth:Number [, initObject:Object]) : MovieClip
-static as_value sprite_attach_movie(const fn_call& fn)
+static as_value
+sprite_attach_movie(const fn_call& fn)
{
boost::intrusive_ptr<sprite_instance> sprite =
ensureType<sprite_instance>(fn.this_ptr);
as_value rv;
@@ -236,13 +237,23 @@
const std::string& newname = fn.arg(1).to_string();
- // should we support negative depths ? YES !
- // TODO: What happens when the argument exceeds the max / min depth?
- // Casting a number to an int that cannot represent that value is
- // undefined behaviour.
- int depth_val = boost::uint16_t(fn.arg(2).to_number());
+ // Movies should be attachable from -16384 to 2130690045, according to
+ // kirupa (http://www.kirupa.com/developer/actionscript/depths2.htm)
+ // Tests in misc-ming.all/DepthLimitsTest.c show that 2130690044 is the
+ // maximum valid depth.
+ const double depth = fn.arg(2).to_number();
+
+ // This also checks for overflow, as both numbers are expressible as
+ // boost::int32_t.
+ if (depth < character::lowerAccessibleBound ||
+ depth > character::upperAccessibleBound)
+ {
+ return as_value();
+ }
+
+ boost::int32_t depthValue = static_cast<boost::int32_t>(depth);
- boost::intrusive_ptr<character> newch =
exported_movie->create_character_instance(sprite.get(), depth_val);
+ boost::intrusive_ptr<character> newch =
exported_movie->create_character_instance(sprite.get(), 0);
assert( newch.get() > (void*)0xFFFF );
#ifndef GNASH_USE_GC
assert(newch->get_ref_count() > 0);
@@ -252,9 +263,9 @@
newch->setDynamic();
// place_character() will set depth on newch
- if ( ! sprite->attachCharacter(*newch, depth_val) )
+ if ( ! sprite->attachCharacter(*newch, depthValue) )
{
- log_error(_("Could not attach character at depth %d"), depth_val);
+ log_error(_("Could not attach character at depth %d"), depthValue);
return rv;
}
@@ -356,6 +367,9 @@
}
}
+ // Unlike other MovieClip methods, the depth argument of an empty movie clip
+ // can be any number. All numbers are converted to an int32_t, and are valid
+ // depths even when outside the usual bounds.
character* ch = sprite->add_empty_movieclip(fn.arg(0).to_string().c_str(),
fn.arg(1).to_int());
return as_value(ch);
@@ -391,12 +405,12 @@
}
// Lower bound of source depth below which swapDepth has no effect (below
Timeline/static zone)
- if ( this_depth < character::staticDepthOffset )
+ if ( this_depth < character::lowerAccessibleBound )
{
IF_VERBOSE_ASCODING_ERRORS(
std::stringstream ss; fn.dump_args(ss);
log_aserror(_("%s.swapDepths(%s): won't swap a clip below depth %d (%d)"),
- sprite->getTarget(), ss.str(), character::staticDepthOffset, this_depth);
+ sprite->getTarget(), ss.str(), character::lowerAccessibleBound,
this_depth);
);
return rv;
}
@@ -504,7 +518,8 @@
// and invoke it from here, this should only be a wrapper
//
//duplicateMovieClip(name:String, depth:Number, [initObject:Object]) :
MovieClip
-static as_value sprite_duplicate_movieclip(const fn_call& fn)
+static as_value
+sprite_duplicate_movieclip(const fn_call& fn)
{
boost::intrusive_ptr<sprite_instance> sprite =
ensureType<sprite_instance>(fn.this_ptr);
@@ -517,7 +532,19 @@
}
const std::string& newname = fn.arg(0).to_string();
- int depth = int(fn.arg(1).to_number());
+
+ // Depth as in attachMovie
+ const double depth = fn.arg(1).to_number();
+
+ // This also checks for overflow, as both numbers are expressible as
+ // boost::int32_t.
+ if (depth < character::lowerAccessibleBound ||
+ depth > character::upperAccessibleBound)
+ {
+ return as_value();
+ }
+
+ boost::int32_t depthValue = static_cast<boost::int32_t>(depth);
boost::intrusive_ptr<sprite_instance> ch;
@@ -525,11 +552,11 @@
if (fn.nargs == 3)
{
boost::intrusive_ptr<as_object> initObject = fn.arg(2).to_object();
- ch = sprite->duplicateMovieClip(newname, depth, initObject.get());
+ ch = sprite->duplicateMovieClip(newname, depthValue, initObject.get());
}
else
{
- ch = sprite->duplicateMovieClip(newname, depth);
+ ch = sprite->duplicateMovieClip(newname, depthValue);
}
return as_value(ch.get());
@@ -2428,7 +2455,7 @@
//if ( ! ch->get_accept_anim_moves() )
//if ( ch->isDynamic() )
int depth = ch->get_depth();
- if ( depth < -16384 || depth >= 0 )
+ if ( depth < character::lowerAccessibleBound || depth >= 0 )
{
_dynamicChars.push_back(ch);
}
=== modified file 'server/vm/ASHandlers.cpp'
--- a/server/vm/ASHandlers.cpp 2008-07-02 05:35:00 +0000
+++ b/server/vm/ASHandlers.cpp 2008-07-18 13:39:18 +0000
@@ -1154,7 +1154,21 @@
thread.ensureStack(3);
- const int depth = env.top(0).to_int() + character::staticDepthOffset;
+ // Movies should be attachable from -16384 to 2130690044. See
+ // Tests in misc-ming.all/DepthLimitsTest.c.
+ const double depth = env.top(0).to_number() + character::staticDepthOffset;
+
+ // This also checks for overflow, as both numbers are expressible as
+ // boost::int32_t.
+ if (depth < character::lowerAccessibleBound ||
+ depth > character::upperAccessibleBound)
+ {
+ env.drop(3);
+ return;
+ }
+
+ boost::int32_t depthValue = static_cast<boost::int32_t>(depth);
+
const std::string& newname = env.top(1).to_string();
const std::string& path = env.top(2).to_string();
@@ -1180,7 +1194,7 @@
return;
}
- sprite->duplicateMovieClip(newname, depth);
+ sprite->duplicateMovieClip(newname, depthValue);
env.drop(3);
}
=== modified file 'testsuite/actionscript.all/MovieClip.as'
--- a/testsuite/actionscript.all/MovieClip.as 2008-07-15 20:05:07 +0000
+++ b/testsuite/actionscript.all/MovieClip.as 2008-07-18 11:02:56 +0000
@@ -27,19 +27,19 @@
endOfTest = function()
{
#if OUTPUT_VERSION <= 5
- check_totals(231); // SWF5
+ check_totals(236); // SWF5
#endif
#if OUTPUT_VERSION == 6
- check_totals(650); // SWF6
+ check_totals(655); // SWF6
#endif
#if OUTPUT_VERSION == 7
- check_totals(667); // SWF7
+ check_totals(672); // SWF7
#endif
#if OUTPUT_VERSION >= 8
- check_totals(668); // SWF8+
+ check_totals(673); // SWF8+
#endif
play();
@@ -1594,6 +1594,42 @@
dataLoadInterval = setInterval(onDataCheck, 1000);
#endif
+/// Depth tests.
+
+createEmptyMovieClip("d1", -200000000);
+#if OUTPUT_VERSION > 5
+check_equals(d1.getDepth(), -200000000);
+#else
+xcheck_equals(d1.getDepth(), -200000000);
+#endif
+
+createEmptyMovieClip("d2", -0xffffffff);
+#if OUTPUT_VERSION > 5
+check_equals(d2.getDepth(), 1);
+#else
+xcheck_equals(d2.getDepth(), 1);
+#endif
+
+createEmptyMovieClip("d3", 0xffffffff);
+#if OUTPUT_VERSION > 5
+check_equals(d3.getDepth(), -1);
+#else
+xcheck_equals(d3.getDepth(), -1);
+#endif
+
+createEmptyMovieClip("d4", 0x80000000);
+#if OUTPUT_VERSION > 5
+check_equals(d4.getDepth(), -2147483648);
+#else
+xcheck_equals(d4.getDepth(), -2147483648);
+#endif
+
+createEmptyMovieClip("d5", 0x79999999);
+#if OUTPUT_VERSION > 5
+check_equals(d5.getDepth(), 2040109465);
+#else
+xcheck_equals(d5.getDepth(), 2040109465);
+#endif
//_root.loadVariables(MEDIA(vars.txt), "GET");
=== added file 'testsuite/misc-ming.all/DepthLimitsTest.c'
--- a/testsuite/misc-ming.all/DepthLimitsTest.c 1970-01-01 00:00:00 +0000
+++ b/testsuite/misc-ming.all/DepthLimitsTest.c 2008-07-18 13:17:47 +0000
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *
+ */
+
+/*
+ * Test MovieClip.attachMovie().
+ *
+ * Exports a 'redsquare' symbol and then attach it to main timeline 4 times
+ * at depths 70+[0..3] and with xoffset 70*[0..3]
+ *
+ * run as ./attachMovieTest
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ming.h>
+
+#include "ming_utils.h"
+
+#define OUTPUT_VERSION 6
+#define OUTPUT_FILENAME "DepthLimitsTest.swf"
+
+void
+addRedSquareExport(SWFMovie mo)
+{
+ SWFShape sh;
+ SWFMovieClip mc;
+
+ sh = make_fill_square (0, 0, 60, 60, 255, 0, 0, 255, 0, 0);
+ mc = newSWFMovieClip();
+
+ SWFMovieClip_add(mc, (SWFBlock)sh);
+ /* This is here just to turn the clip into an active one */
+ add_clip_actions(mc, "onRollOver = function() {};");
+ add_clip_actions(mc, "onMouseDown = function() { _root.mouseDown++;
_root.note(_name+' mouseDown '+_root.mouseDown); };");
+ add_clip_actions(mc, "onMouseUp = function() { _root.mouseUp++;
_root.note(_name+' mouseUp '+_root.mouseUp); };");
+ SWFMovieClip_nextFrame(mc);
+
+ SWFMovie_addExport(mo, (SWFBlock)mc, "redsquare");
+
+ SWFMovie_writeExports(mo);
+}
+
+int
+main(int argc, char** argv)
+{
+ SWFMovie mo;
+ const char *srcdir=".";
+ SWFMovieClip dejagnuclip;
+
+
+ /*********************************************
+ *
+ * Initialization
+ *
+ *********************************************/
+
+ if ( argc>1 ) srcdir=argv[1];
+ else
+ {
+ fprintf(stderr, "Usage: %s\n", argv[0]);
+ return 1;
+ }
+
+ puts("Setting things up");
+
+ Ming_init();
+ Ming_useSWFVersion (OUTPUT_VERSION);
+ Ming_setScale(20.0); /* let's talk pixels */
+
+ mo = newSWFMovie();
+ SWFMovie_setRate(mo, 12);
+ //SWFMovie_setDimension(mo, 6400, 4000);
+ SWFMovie_setDimension(mo, 640, 400);
+
+ /*********************************************
+ *
+ * Body
+ *
+ *********************************************/
+
+ dejagnuclip = get_dejagnu_clip((SWFBlock)get_default_font(srcdir), 10,
0, 80, 800, 600);
+ SWFMovie_add(mo, (SWFBlock)dejagnuclip);
+
+ addRedSquareExport(mo);
+ /* it seems we need a SHOWFRAME for this to be effective */
+ /* (maybe it's related to loop-back handling ?) */
+ SWFMovie_nextFrame(mo);
+
+ /* A load of tests for depth */
+
+ add_actions(mo, "attachMovie('redsquare', 'depthtest', -16, initObj);"
+ "d = depthtest.getDepth();");
+ check_equals(mo, "d", "-16");
+
+
+ add_actions(mo, "attachMovie('redsquare', 'depthtest', -16384,
initObj);"
+ "d = depthtest.getDepth();");
+ check_equals(mo, "d", "-16384");
+
+ /* Less than -16384 fails */
+ add_actions(mo, "attachMovie('redsquare', 'depthtest2', -20000,
initObj);"
+ "d = depthtest2.getDepth();");
+ check_equals(mo, "d", "undefined");
+
+ /* It really does */
+ add_actions(mo, "attachMovie('redsquare', 'depthtest2', -16385,
initObj);"
+ "d = depthtest2.getDepth();");
+ check_equals(mo, "d", "undefined");
+
+ /* Up to 2130690044 works */
+ add_actions(mo, "attachMovie('redsquare', 'depthtest2', 1147483648,
initObj);"
+ "d = depthtest2.getDepth();");
+ check_equals(mo, "d", "1147483648");
+
+ /* Up to 2130690044 works */
+ add_actions(mo, "attachMovie('redsquare', 'depthtest3', 2130690044,
initObj);"
+ "d = depthtest3.getDepth();");
+ check_equals(mo, "d", "2130690044");
+
+ /* 2130690045 doesn't work */
+ add_actions(mo, "attachMovie('redsquare', 'depthtest4', 2130690045,
initObj);"
+ "d = depthtest4.getDepth();");
+ check_equals(mo, "d", "undefined");
+
+ /* duplicateMovieClip */
+ /* Same limits... */
+
+ add_actions(mo, "createEmptyMovieClip('original', 10);");
+
+ add_actions(mo, "duplicateMovieClip('original', 'dup1', -1);"
+ "d = dup1.getDepth();");
+ check_equals(mo, "d", "-1");
+
+ add_actions(mo, "original.duplicateMovieClip('odup1', -1);"
+ "d = odup1.getDepth();");
+ check_equals(mo, "d", "-1");
+
+ add_actions(mo, "duplicateMovieClip('original', 'dup2', -16384);"
+ "d = dup2.getDepth();");
+ check_equals(mo, "d", "-16384");
+
+ add_actions(mo, "original.duplicateMovieClip('odup2', -16384);"
+ "d = odup2.getDepth();");
+ check_equals(mo, "d", "-16384");
+
+ add_actions(mo, "duplicateMovieClip('original', 'dup3', -16385);"
+ "d = dup3.getDepth();");
+ check_equals(mo, "d", "undefined");
+
+ add_actions(mo, "original.duplicateMovieClip('odup3', -16385);"
+ "d = odup3.getDepth();");
+ check_equals(mo, "d", "undefined");
+
+ add_actions(mo, "duplicateMovieClip('original', 'dup4', 2130690044);"
+ "d = dup4.getDepth();");
+ check_equals(mo, "d", "2130690044");
+
+ add_actions(mo, "original.duplicateMovieClip('odup4', 2130690044);"
+ "d = odup4.getDepth();");
+ check_equals(mo, "d", "2130690044");
+
+ add_actions(mo, "duplicateMovieClip('original', 'dup5', 2130690045);"
+ "d = dup5.getDepth();");
+ check_equals(mo, "d", "undefined");
+
+ add_actions(mo, "original.duplicateMovieClip('odup5', 2130690045);"
+ "d = odup5.getDepth();");
+ check_equals(mo, "d", "undefined");
+
+ add_actions(mo, "totals(); stop();");
+
+ SWFMovie_nextFrame(mo); /* showFrame */
+
+ /*****************************************************
+ *
+ * Output movie
+ *
+ *****************************************************/
+
+ puts("Saving " OUTPUT_FILENAME );
+
+ SWFMovie_save(mo, OUTPUT_FILENAME);
+
+ return 0;
+}
=== modified file 'testsuite/misc-ming.all/Makefile.am'
--- a/testsuite/misc-ming.all/Makefile.am 2008-07-03 07:07:49 +0000
+++ b/testsuite/misc-ming.all/Makefile.am 2008-07-18 11:41:07 +0000
@@ -112,6 +112,7 @@
displaylist_depths_test9 \
displaylist_depths_test10 \
displaylist_depths_test11 \
+ DepthLimitsTest \
masks_test \
masks_test2 \
masks_test2runner \
@@ -905,6 +906,18 @@
sh $< -f20 $(top_builddir) displaylist_depths_test11.swf > $@
chmod 755 $@
+
+DepthLimitsTest_SOURCES = DepthLimitsTest.c
+DepthLimitsTest_LDADD = libgnashmingutils.la
+
+DepthLimitsTest.swf: DepthLimitsTest
+ ./DepthLimitsTest $(top_srcdir)/testsuite/media
+
+DepthLimitsTestrunner: $(srcdir)/../generic-testrunner.sh DepthLimitsTest.swf
+ sh $< -r5 $(top_builddir) DepthLimitsTest.swf > $@
+ chmod 755 $@
+
+
replace_shapes1test_SOURCES = replace_shapes1test.c
replace_shapes1test_LDADD = libgnashmingutils.la
@@ -1803,6 +1816,7 @@
displaylist_depths_test9runner \
displaylist_depths_test10runner \
displaylist_depths_test11runner \
+ DepthLimitsTestrunner \
matrix_testrunner \
frame_label_testrunner \
path_format_testrunner \
- [Gnash-commit] /srv/bzr/gnash/trunk r9499: Add a group of tests for depth limits. Do depth checking on,
Benjamin Wolsey <=