Gnash  0.8.11dev
SWFStream.h
Go to the documentation of this file.
1 // stream.h - SWF stream reading class, for Gnash
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 
20 #ifndef GNASH_STREAM_H
21 #define GNASH_STREAM_H
22 
23 #include "SWF.h"
24 #include "dsodefs.h" // still neded ?
25 #include "GnashException.h"
26 
27 #include <string>
28 #include <sstream>
29 #include <vector> // for composition
30 #include <cstdint> // for boost::?int??_t
31 
32 // Define the following macro if you want to want Gnash parser
33 // to assume the underlying SWF is well-formed. It would make
34 // parsing faster, but might result in horrible behaviour with
35 // malformed SWFs (like taking up all system memory, keeping
36 // CPU busy for a long long time, or simply corrupting memory)
37 //
38 // This might be eventually set by a --disable-swf-checks or similar
39 // configure switch...
40 //
41 //#define GNASH_TRUST_SWF_INPUT
42 
43 namespace gnash {
44  class IOChannel;
45 }
46 
47 namespace gnash {
48 
50 //
59 {
60 public:
61  SWFStream(IOChannel* input);
62  ~SWFStream();
63 
68  //
71  unsigned read_uint(unsigned short bitcount);
72 
76  //
79  bool read_bit();
80 
85  //
88  int read_sint(unsigned short bitcount);
89 
91  //
94  float read_fixed();
95 
97  //
100  float read_ufixed();
101 
103  //
106  float read_short_ufixed();
107 
109  //
112  float read_short_sfixed();
113 
115  //
118  float read_long_float();
119 
121  //
124  double read_d64();
125 
127  //
135  void align()
136  {
137  m_unused_bits=0;
138  // m_current_byte = 0; // this is not needed
139  }
140 
142  //
145  unsigned read(char *buf, unsigned count);
146 
148  //
151  std::uint8_t read_u8();
152 
154  //
157  std::int8_t read_s8();
158 
160  //
163  std::uint16_t read_u16();
164 
166  //
169  std::int16_t read_s16();
170 
172  //
175  std::uint32_t read_u32();
176 
179  //
182  std::int32_t read_s32();
183 
188  //
191  std::uint32_t read_V32()
192  {
193  ensureBytes(1);
194  std::uint32_t res = read_u8();
195  if (!(res & 0x00000080)) return res;
196 
197  ensureBytes(1);
198  res = (res & 0x0000007F) | read_u8() << 7;
199  if (!(res & 0x00004000)) return res;
200 
201  ensureBytes(1);
202  res = (res & 0x00003FFF) | read_u8() << 14;
203  if (!(res & 0x00200000)) return res;
204 
205  ensureBytes(1);
206  res = (res & 0x001FFFFF) | read_u8() << 21;
207  if (!(res & 0x10000000)) return res;
208 
209  ensureBytes(1);
210  res = (res & 0x0FFFFFFF) | read_u8() << 28;
211  return res;
212  }
213 
220  void skip_V32()
221  {
222  ensureBytes(1);
223  if (!(read_u8() & 0x80)) return;
224  ensureBytes(1);
225  if (!(read_u8() & 0x80)) return;
226  ensureBytes(1);
227  if (!(read_u8() & 0x80)) return;
228  ensureBytes(1);
229  if (!(read_u8() & 0x80)) return;
230  ensureBytes(1);
231  static_cast<void> (read_u8());
232  }
233 
236  //
245  {
246  ensureBytes(1);
247  unsigned count = read_u8();
248  if (count == 0xFF)
249  {
250  ensureBytes(2);
251  count = read_u16();
252  }
253  return count;
254  };
255 
265  void read_string(std::string& to);
266 
268  //
278  void read_string_with_length(std::string& to);
279 
281  //
293  void read_string_with_length(unsigned len, std::string& to);
294 
296  //
304  unsigned long tell();
305 
307  //
317  bool seek(unsigned long pos);
318 
320  unsigned long get_tag_end_position();
321 
323  //
326  SWF::TagType open_tag();
327 
329  void close_tag();
330 
332  //
345  bool skip_bytes(unsigned num)
346  {
347  // there's probably a better way, but
348  // it's the interface that counts atm
349  size_t curpos = tell();
350  return seek(curpos+num);
351  }
352 
355  {
356  // seek will call align...
357  seek(get_tag_end_position());
358  }
359 
363  //
370  void ensureBytes(unsigned long needed);
371 
375  //
382  void ensureBits(unsigned long needed)
383  {
384 #ifndef GNASH_TRUST_SWF_INPUT
385  if ( _tagBoundsStack.empty() ) return; // not in a tag (should we check file length ?)
386  unsigned long int bytesLeft = get_tag_end_position() - tell();
387  unsigned long int bitsLeft = (bytesLeft*8)+m_unused_bits;
388  if ( bitsLeft < needed )
389  {
390  std::stringstream ss;
391  ss << "premature end of tag: need to read " << needed << " bytes, but only " << bitsLeft << " left in this tag";
392  throw ParserException(ss.str());
393  }
394 #endif
395  }
396 
398  //
413  void consumeInput();
414 
415 private:
416 
417  IOChannel* m_input;
418  std::uint8_t m_current_byte;
419  std::uint8_t m_unused_bits;
420 
421  typedef std::pair<unsigned long,unsigned long> TagBoundaries;
422  // position of start and end of tag
423  std::vector<TagBoundaries> _tagBoundsStack;
424 };
425 
426 
427 } // namespace gnash
428 
429 
430 #endif // GNASH_STREAM_H
431 
432 
433 // Local Variables:
434 // mode: C++
435 // c-basic-offset: 8
436 // tab-width: 8
437 // indent-tabs-mode: t
438 // End:
gnash::IOChannel::read_le16
std::uint16_t read_le16()
Read a 16-bit word from a little-endian stream.
Definition: IOChannel.cpp:39
action_buffer.h
gnash::SWFStream::ensureBits
void ensureBits(unsigned long needed)
Ensure the requested number of bits are available for a bitwise read in currently opened tag.
Definition: SWFStream.h:382
gnash::SWFStream::read_uint
unsigned read_uint(unsigned short bitcount)
Reads a bit-packed unsigned integer from the stream and returns it. The given bitcount determines the...
Definition: SWFStream.cpp:102
gnash::SWFStream::skip_to_tag_end
void skip_to_tag_end()
Discard all bytes up to end of tag.
Definition: SWFStream.h:354
gnash::SWFStream::read_sint
int read_sint(unsigned short bitcount)
Reads a bit-packed little-endian signed integer from the stream. The given bitcount determines the nu...
Definition: SWFStream.cpp:191
gnash::SWFStream::read_s8
std::int8_t read_s8()
Read a aligned signed 8-bit value from the stream.
Definition: SWFStream.cpp:326
gnash::log_swferror
void log_swferror(StringType msg, Args... args)
Definition: log.h:325
gnash::key::d
@ d
Definition: GnashKey.h:150
gnash::SWF::TagType
TagType
SWF tag types. Symbolic names copied from Ming.
Definition: SWF.h:31
dsodefs.h
gnash::key::i
@ i
Definition: GnashKey.h:155
gnash::SWFStream::consumeInput
void consumeInput()
Consume any pending input.
Definition: SWFStream.cpp:601
_
#define _(String)
Definition: log.h:44
gnash::SWFStream::read_long_float
float read_long_float()
Read a 32bit (1:sign 8:exp 23:mantissa) floating point value.
Definition: SWFStream.cpp:285
gnash::SWFStream::read_string
void read_string(std::string &to)
Reads a null-terminated string from the given file and assigns it to the given std::string,...
Definition: SWFStream.cpp:395
gnash::SWFStream::read_variable_count
unsigned read_variable_count()
Read a length in a byte or three.
Definition: SWFStream.h:244
gnash
Anonymous namespace for callbacks, local functions, event handlers etc.
Definition: dbus_ext.cpp:41
gnash::key::s
@ s
Definition: GnashKey.h:165
gnash::SWFStream::read_d64
double read_d64()
Read a 64-bit double value.
Definition: SWFStream.cpp:300
gnash::SWFStream::read
unsigned read(char *buf, unsigned count)
Read <count> bytes from the source stream and copy that data to <buf>.
Definition: SWFStream.cpp:68
gnash::IOChannel::seek
virtual bool seek(std::streampos p)=0
Seek to the specified position.
gnash::log_error
void log_error(StringType msg, Args... args)
Definition: log.h:283
gnash::SWFStream::read_short_ufixed
float read_short_ufixed()
Read a 8.8 fixed point unsigned value.
Definition: SWFStream.cpp:228
gnash::SWFStream::read_s16
std::int16_t read_s16()
Read a aligned signed 16-bit value from the stream.
Definition: SWFStream.cpp:355
gnash::SWFStream::open_tag
SWF::TagType open_tag()
Open an SWF tag and return it's type.
Definition: SWFStream.cpp:505
gnash::SWFStream::read_fixed
float read_fixed()
Read a 16.16 fixed point signed value.
Definition: SWFStream.cpp:208
gnash::IOChannel
A virtual IO channel.
Definition: IOChannel.h:43
gnash::IOException
Exception signalling an IO error.
Definition: IOChannel.h:35
gnash::IOChannel::read_le32
std::uint32_t read_le32()
Read a 32-bit word from a little-endian stream. returning it as a native-endian word.
Definition: IOChannel.cpp:28
Property.h
gnash::SWFStream::read_short_sfixed
float read_short_sfixed()
Read a 8.8 fixed point signed value.
Definition: SWFStream.cpp:235
gnash::SWFStream::tell
unsigned long tell()
Return our current (byte) position in the input stream.
Definition: SWFStream.cpp:447
gnash::SWFStream::read_s32
std::int32_t read_s32()
Read a aligned signed 32-bit value from the stream.
Definition: SWFStream.cpp:388
gnash::SWFStream::read_u32
std::uint32_t read_u32()
Read a aligned unsigned 32-bit value from the stream.
Definition: SWFStream.cpp:361
gnash::key::p
@ p
Definition: GnashKey.h:162
gnash::SWFStream::SWFStream
SWFStream(IOChannel *input)
Definition: SWFStream.cpp:36
gnash::ParserException
An SWF parsing exception.
Definition: GnashException.h:90
gnash::SWFStream::close_tag
void close_tag()
Seek to the end of the most-recently-opened tag.
Definition: SWFStream.cpp:582
gnash::SWFStream::get_tag_end_position
unsigned long get_tag_end_position()
Return the file position of the end of the current tag.
Definition: SWFStream.cpp:497
IF_VERBOSE_PARSE
#define IF_VERBOSE_PARSE(x)
Definition: log.h:378
gnash::log_parse
void log_parse(StringType msg, Args... args)
Definition: log.h:313
log.h
gnash::SWFStream::read_ufixed
float read_ufixed()
Read a 16.16 fixed point unsigned value.
Definition: SWFStream.cpp:219
gnash::key::f
@ f
Definition: GnashKey.h:152
SWF.h
gnash::SWFStream::read_u16
std::uint16_t read_u16()
Read a aligned unsigned 16-bit value from the stream.
Definition: SWFStream.cpp:332
gnash::IOChannel::read_byte
std::uint8_t read_byte()
Read a single byte from the stream.
Definition: IOChannel.cpp:63
gnash::key::c
@ c
Definition: GnashKey.h:149
DSOEXPORT
#define DSOEXPORT
Definition: dsodefs.h:55
gnash::SWFStream::read_u8
std::uint8_t read_u8()
Read a aligned unsigned 8-bit value from the stream.
Definition: SWFStream.cpp:319
gnash::SWFStream::~SWFStream
~SWFStream()
Definition: SWFStream.cpp:45
gnash::SWFStream::read_bit
bool read_bit()
Reads a single bit off the stream and returns it.
Definition: SWFStream.cpp:88
gnash::SWFStream::skip_V32
void skip_V32()
Skip a variable length unsigned 32-bit value in the stream. This is faster than doing the bitwise ari...
Definition: SWFStream.h:220
gnash::SWFStream::read_V32
std::uint32_t read_V32()
Read a variable length unsigned 32-bit value from the stream. These values continue until either the ...
Definition: SWFStream.h:191
gnash::IOChannel::go_to_end
virtual void go_to_end()=0
Seek to the end of the stream.
gnash::IOChannel::tell
virtual std::streampos tell() const =0
Return current stream position.
gnash::SWFStream::read_string_with_length
void read_string_with_length(std::string &to)
Reads a sized string into a provided std::string.
Definition: SWFStream.cpp:411
gnash::SWFStream
SWF stream wrapper class.
Definition: SWFStream.h:59
gnash::SWFStream::seek
bool seek(unsigned long pos)
Set the file position to the given value (byte aligned)
Definition: SWFStream.cpp:456
gnash::SWFStream::align
void align()
Consume all bits of current byte.
Definition: SWFStream.h:135
gnash::SWFStream::ensureBytes
void ensureBytes(unsigned long needed)
Ensure the requested number of bytes are available for an aligned read in the currently opened tag.
Definition: SWFStream.cpp:50
gnash::key::u
@ u
Definition: GnashKey.h:167
GnashException.h
gnash::SWFStream::skip_bytes
bool skip_bytes(unsigned num)
Discard given number of bytes.
Definition: SWFStream.h:345
SWFStream.h
data
SimpleBuffer data
Definition: LocalConnection_as.cpp:151
IOChannel.h
gnash::IOChannel::read
virtual std::streamsize read(void *dst, std::streamsize num)=0
Read the given number of bytes from the stream.