[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/parser/button_character_...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/parser/button_character_... |
Date: |
Wed, 12 Dec 2007 23:49:28 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 07/12/12 23:49:28
Modified files:
. : ChangeLog
server/parser : button_character_def.cpp button_character_def.h
Log message:
cleanup parser by splitting DEFINEBUTTON, DEFINEBUTTON2 and
DEFINEBUTTONSOUND
reading functions. Added a boundary arg to button_record parser to
avoid reading
out of bounds (with side-effect of reducing seek-back need)
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5151&r2=1.5152
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/button_character_def.cpp?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/button_character_def.h?cvsroot=gnash&r1=1.20&r2=1.21
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5151
retrieving revision 1.5152
diff -u -b -r1.5151 -r1.5152
--- ChangeLog 12 Dec 2007 22:45:27 -0000 1.5151
+++ ChangeLog 12 Dec 2007 23:49:27 -0000 1.5152
@@ -1,5 +1,13 @@
2007-12-12 Sandro Santilli <address@hidden>
+ * server/parser/button_character_def.{cpp,h}: cleanup parser by
+ splitting DEFINEBUTTON, DEFINEBUTTON2 and DEFINEBUTTONSOUND
+ reading functions. Added a boundary arg to button_record parser
+ to avoid reading out of bounds (with side-effect of reducing
+ seek-back need)
+
+2007-12-12 Sandro Santilli <address@hidden>
+
* testsuite/actionscript.all/System.as: update expected results.
* server/swf/tag_loaders.cpp (define_bits_jpeg3_loader): don't read
rgb data past alpha_position.
Index: server/parser/button_character_def.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/button_character_def.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/parser/button_character_def.cpp 7 Oct 2007 21:15:59 -0000
1.19
+++ server/parser/button_character_def.cpp 12 Dec 2007 23:49:28 -0000
1.20
@@ -17,7 +17,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-/* $Id: button_character_def.cpp,v 1.19 2007/10/07 21:15:59 strk Exp $ */
+/* $Id: button_character_def.cpp,v 1.20 2007/12/12 23:49:28 strk Exp $ */
// Based on the public domain work of Thatcher Ulrich <address@hidden> 2003
@@ -91,18 +91,34 @@
bool
button_record::read(stream* in, int tag_type,
- movie_definition* m)
+ movie_definition* m, unsigned long endPos)
{
+ // caller should check this
+ assert(in->get_position() < endPos);
int flags = in->read_u8();
if (flags == 0)
{
return false;
}
- m_hit_test = flags & 8 ? true : false;
- m_down = flags & 4 ? true : false;
- m_over = flags & 2 ? true : false;
- m_up = flags & 1 ? true : false;
+ // Upper 4 bits are:
+ //
+ // ButtonReserved = readBits (f, 2);
+ // ButtonHasBlendMode = readBits(f, 1);
+ // ButtonHasFilterList = readBits(f, 1);
+ //
+ m_hit_test = flags & (1<<3); // 8 ? true : false;
+ m_down = flags & (1<<2); // 4 ? true : false;
+ m_over = flags & (1<<1); // 2 ? true : false;
+ m_up = flags & (1<<0); // 1 ? true : false;
+
+ if (in->get_position()+2 > endPos)
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_(" premature end of button record input stream,
can't read character id"));
+ );
+ return false;
+ }
m_character_id = in->read_u16();
// Get character definition now (safer)
@@ -122,16 +138,26 @@
{
IF_VERBOSE_PARSE(
log_parse(_(" button record for states %x contain "
- "character %d (%s)"), flags, m_character_id,
+ "character %d (%s)"),
(m_hit_test<<4)+(m_down<<2)+(m_over<<1)+(m_up), m_character_id,
typeName(*m_character_def).c_str());
);
}
+ if (in->get_position()+2 > endPos)
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_(" premature end of button record input stream,
can't read button layer (depth?)"));
+ );
+ return false;
+ }
m_button_layer = in->read_u16();
+
+ // TODO: pass available range to button matrix read
m_button_matrix.read(in);
- if (tag_type == 34)
+ if (tag_type == SWF::DEFINEBUTTON2)
{
+ // TODO: pass available range to button cxform read
m_button_cxform.read_rgba(in);
}
@@ -202,29 +228,20 @@
);
}
-
-
void
-button_character_definition::read(stream* in, int tag_type, movie_definition*
m)
-// Initialize from the given stream.
+button_character_definition::readDefineButton(stream* in, movie_definition* m)
{
// Character ID has been read already
- assert(
- tag_type == SWF::DEFINEBUTTON // 7
- || tag_type == SWF::DEFINEBUTTONSOUND // 17
- || tag_type == SWF::DEFINEBUTTON2 // 34
- );
-
- if (tag_type == SWF::DEFINEBUTTON)
- {
// Old button tag.
+ unsigned long endTagPos = in->get_tag_end_position();
+
// Read button character records.
for (;;)
{
button_record r;
- if (r.read(in, tag_type, m) == false)
+ if (r.read(in, SWF::DEFINEBUTTON, m, endTagPos) == false)
{
// Null record; marks the end of button records.
break;
@@ -238,50 +255,64 @@
}
}
+ if ( in->get_position() >= endTagPos )
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("Premature end of DEFINEBUTTON tag, won't read
actions"));
+ );
+ return;
+ }
+
// Read actions.
button_action actions;
- actions.read(in, tag_type);
+ // TODO: pass valid end position to button_action parser
+ actions.read(in, SWF::DEFINEBUTTON);
m_button_actions.push_back(actions);
- }
- else if (tag_type == SWF::DEFINEBUTTONSOUND)
- {
- assert(m_sound == NULL); // redefinition button sound is
error
- m_sound = new button_sound_def();
- IF_VERBOSE_PARSE(
- log_parse(_("button sound options: "));
- );
- for (int i = 0; i < 4; i++)
- {
- button_sound_info& bs = m_sound->m_button_sounds[i];
- bs.m_sound_id = in->read_u16();
- if (bs.m_sound_id > 0)
- {
- bs.m_sam = m->get_sound_sample(bs.m_sound_id);
- if (bs.m_sam == NULL)
+
+ // detect min/max layer number
+ m_min_layer=0;
+ m_max_layer=0;
+ for (unsigned int i=0; i<m_button_records.size(); i++)
{
-// printf("sound tag not found,
sound_id=%d, button state #=%i", bs.sound_id, i);
- }
- IF_VERBOSE_PARSE(
- log_parse("\n sound_id = %d", bs.m_sound_id);
- );
- bs.m_sound_style.read(in);
- }
- }
+ int this_layer = m_button_records[i].m_button_layer;
+
+ if ((i==0) || (this_layer < m_min_layer)) m_min_layer=this_layer;
+ if ((i==0) || (this_layer > m_max_layer)) m_max_layer=this_layer;
}
- else if (tag_type == SWF::DEFINEBUTTON2)
- {
+}
+
+void
+button_character_definition::readDefineButton2(stream* in, movie_definition* m)
+{
+ // Character ID has been read already
+
// Read the menu flag
// (this is a single bit, the other 7 bits are reserved)
m_menu = in->read_u8() != 0;
unsigned button_2_action_offset = in->read_u16();
+ unsigned long tagEndPosition = in->get_tag_end_position();
unsigned next_action_pos = in->get_position() +
button_2_action_offset - 2;
+ if ( next_action_pos > tagEndPosition )
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("Next Button2 actionOffset (%u) points past the
end of tag (%lu)"),
+ button_2_action_offset, tagEndPosition);
+ );
+ return;
+ }
+
+ unsigned long endOfButtonRecords = tagEndPosition;
+ if ( ! button_2_action_offset ) endOfButtonRecords = tagEndPosition;
+
// Read button records.
- for (;;)
+ // takes at least 1 byte for the end mark button record, so
+ // we don't attempt to parse at all unless we have at least 1 byte left
+ while ( in->get_position() < endOfButtonRecords )
{
button_record r;
- if (r.read(in, tag_type, m) == false)
+ if (r.read(in, SWF::DEFINEBUTTON2, m, endOfButtonRecords) ==
false)
{
// Null record; marks the end of button records.
break;
@@ -295,24 +326,17 @@
}
}
- if ( next_action_pos >= in->get_tag_end_position() )
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Next Button2 actionOffset (%u) points
past the end of tag"), button_2_action_offset);
- );
- return;
- }
-
in->set_position(next_action_pos);
// Read Button2ActionConditions
- for (;;)
+ // Don't read past tag end
+ while ( in->get_position() < tagEndPosition )
{
unsigned next_action_offset = in->read_u16();
next_action_pos = in->get_position() +
next_action_offset - 2;
m_button_actions.resize(m_button_actions.size() + 1);
- m_button_actions.back().read(in, tag_type);
+ m_button_actions.back().read(in, SWF::DEFINEBUTTON2);
if (next_action_offset == 0 )
{
@@ -333,8 +357,6 @@
// seek to next action.
in->set_position(next_action_pos);
}
- }
-
// detect min/max layer number
m_min_layer=0;
@@ -348,6 +370,69 @@
}
}
+void
+button_character_definition::readDefineButtonSound(stream* in,
movie_definition* m)
+{
+ // Character ID has been read already
+
+ if ( m_sound )
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("Attempt to redefine button sound ignored"));
+ );
+ return;
+ }
+
+ m_sound = new button_sound_def();
+
+ IF_VERBOSE_PARSE(
+ log_parse(_("button sound options: "));
+ );
+
+ for (int i = 0; i < 4; i++)
+ {
+ button_sound_info& bs = m_sound->m_button_sounds[i];
+ bs.m_sound_id = in->read_u16();
+ if (bs.m_sound_id)
+ {
+ bs.m_sam = m->get_sound_sample(bs.m_sound_id);
+ if ( ! bs.m_sam )
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror(_("sound tag not found,
sound_id=%d, button state #=%i"), bs.m_sound_id, i);
+ );
+ }
+ IF_VERBOSE_PARSE(
+ log_parse("\n sound_id = %d", bs.m_sound_id);
+ );
+ bs.m_sound_style.read(in);
+ }
+ }
+}
+
+
+void
+button_character_definition::read(stream* in, int tag_type, movie_definition*
m)
+// Initialize from the given stream.
+{
+ // Character ID has been read already
+
+ switch (tag_type)
+ {
+ case SWF::DEFINEBUTTON:
+ readDefineButton(in, m);
+ break;
+ case SWF::DEFINEBUTTONSOUND:
+ readDefineButtonSound(in, m);
+ break;
+ case SWF::DEFINEBUTTON2:
+ readDefineButton2(in, m);
+ break;
+ default:
+ abort();
+ }
+}
+
character*
button_character_definition::create_character_instance(
Index: server/parser/button_character_def.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/button_character_def.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- server/parser/button_character_def.h 4 Dec 2007 11:45:32 -0000
1.20
+++ server/parser/button_character_def.h 12 Dec 2007 23:49:28 -0000
1.21
@@ -56,7 +56,11 @@
/// Read a button record from the SWF stream.
//
/// Return true if we read a record; false if this is a null
- bool read(stream* in, int tag_type, movie_definition* m);
+ ///
+ /// @param endPos
+ /// Last stream offset available for a valid read
+ ///
+ bool read(stream* in, int tag_type, movie_definition* m, unsigned
long endPos);
/// Return true if the button_record is valid
//
@@ -96,6 +100,8 @@
int m_conditions;
typedef std::vector<action_buffer*> ActionList;
+
+ // TODO: define ownership of list elements !!
ActionList m_actions;
~button_action();
@@ -153,7 +159,9 @@
struct button_sound_def
{
- void read(stream* in, movie_definition* m);
+ // TODO: implement ?
+ //void read(stream* in, movie_definition* m);
+
button_sound_info m_button_sounds[4];
#ifdef GNASH_USE_GC
@@ -181,6 +189,7 @@
typedef std::vector<button_action> ButtonActVect;
ButtonActVect m_button_actions;
+ // TODO: define ownership of this sound !
button_sound_def* m_sound;
button_character_definition();
@@ -189,8 +198,18 @@
/// Create a mutable instance of our definition.
character* create_character_instance(character* parent, int id);
+ /// Read a SWF::DEFINEBUTTON, SWF::DEFINEBUTTONSOUND or
SWF::DEFINEBUTTON2
void read(stream* in, int tag_type, movie_definition* m);
+ /// Read a SWF::DEFINEBUTTON tag
+ void readDefineButton(stream* in, movie_definition* m);
+
+ /// Read a SWF::DEFINEBUTTON2 tag
+ void readDefineButton2(stream* in, movie_definition* m);
+
+ /// Read a SWF::DEFINEBUTTONSOUND tag
+ void readDefineButtonSound(stream* in, movie_definition* m);
+
const rect& get_bound() const {
// It is required that get_bound() is implemented in character definition
// classes. However, button character definitions do not have shape
- [Gnash-commit] gnash ChangeLog server/parser/button_character_...,
Sandro Santilli <=