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 <boost/cstdint.hpp> // 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_short_float();
119 
121  //
124  float read_long_float();
125 
127  //
130  double read_d64();
131 
133  //
141  void align()
142  {
143  m_unused_bits=0;
144  // m_current_byte = 0; // this is not needed
145  }
146 
148  //
151  unsigned read(char *buf, unsigned count);
152 
154  //
157  boost::uint8_t read_u8();
158 
160  //
163  boost::int8_t read_s8();
164 
166  //
169  boost::uint16_t read_u16();
170 
172  //
175  boost::int16_t read_s16();
176 
178  //
181  boost::uint32_t read_u32();
182 
185  //
188  boost::int32_t read_s32();
189 
194  //
197  boost::uint32_t read_V32()
198  {
199  ensureBytes(1);
200  boost::uint32_t res = read_u8();
201  if (!(res & 0x00000080)) return res;
202 
203  ensureBytes(1);
204  res = (res & 0x0000007F) | read_u8() << 7;
205  if (!(res & 0x00004000)) return res;
206 
207  ensureBytes(1);
208  res = (res & 0x00003FFF) | read_u8() << 14;
209  if (!(res & 0x00200000)) return res;
210 
211  ensureBytes(1);
212  res = (res & 0x001FFFFF) | read_u8() << 21;
213  if (!(res & 0x10000000)) return res;
214 
215  ensureBytes(1);
216  res = (res & 0x0FFFFFFF) | read_u8() << 28;
217  return res;
218  }
219 
226  void skip_V32()
227  {
228  ensureBytes(1);
229  if (!(read_u8() & 0x80)) return;
230  ensureBytes(1);
231  if (!(read_u8() & 0x80)) return;
232  ensureBytes(1);
233  if (!(read_u8() & 0x80)) return;
234  ensureBytes(1);
235  if (!(read_u8() & 0x80)) return;
236  ensureBytes(1);
237  static_cast<void> (read_u8());
238  }
239 
242  //
251  {
252  ensureBytes(1);
253  unsigned count = read_u8();
254  if (count == 0xFF)
255  {
256  ensureBytes(2);
257  count = read_u16();
258  }
259  return count;
260  };
261 
271  void read_string(std::string& to);
272 
274  //
284  void read_string_with_length(std::string& to);
285 
287  //
299  void read_string_with_length(unsigned len, std::string& to);
300 
302  //
310  unsigned long tell();
311 
313  //
323  bool seek(unsigned long pos);
324 
326  unsigned long get_tag_end_position();
327 
329  //
332  SWF::TagType open_tag();
333 
335  void close_tag();
336 
338  //
351  bool skip_bytes(unsigned num)
352  {
353  // there's probably a better way, but
354  // it's the interface that counts atm
355  size_t curpos = tell();
356  return seek(curpos+num);
357  }
358 
361  {
362  // seek will call align...
363  seek(get_tag_end_position());
364  }
365 
369  //
376  void ensureBytes(unsigned long needed);
377 
381  //
388  void ensureBits(unsigned long needed)
389  {
390 #ifndef GNASH_TRUST_SWF_INPUT
391  if ( _tagBoundsStack.empty() ) return; // not in a tag (should we check file length ?)
392  unsigned long int bytesLeft = get_tag_end_position() - tell();
393  unsigned long int bitsLeft = (bytesLeft*8)+m_unused_bits;
394  if ( bitsLeft < needed )
395  {
396  std::stringstream ss;
397  ss << "premature end of tag: need to read " << needed << " bytes, but only " << bitsLeft << " left in this tag";
398  throw ParserException(ss.str());
399  }
400 #endif
401  }
402 
404  //
419  void consumeInput();
420 
421 private:
422 
423  IOChannel* m_input;
424  boost::uint8_t m_current_byte;
425  boost::uint8_t m_unused_bits;
426 
427  typedef std::pair<unsigned long,unsigned long> TagBoundaries;
428  // position of start and end of tag
429  std::vector<TagBoundaries> _tagBoundsStack;
430 };
431 
432 
433 } // namespace gnash
434 
435 
436 #endif // GNASH_STREAM_H
437 
438 
439 // Local Variables:
440 // mode: C++
441 // c-basic-offset: 8
442 // tab-width: 8
443 // indent-tabs-mode: t
444 // End:
A virtual IO channel.
Definition: IOChannel.h:41
TagType
SWF tag types. Symbolic names copied from Ming.
Definition: SWF.h:30
An SWF parsing exception.
Definition: GnashException.h:89
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:226
void align()
Consume all bits of current byte.
Definition: SWFStream.h:141
void ensureBits(unsigned long needed)
Ensure the requested number of bits are available for a bitwise read in currently opened tag...
Definition: SWFStream.h:388
void skip_to_tag_end()
Discard all bytes up to end of tag.
Definition: SWFStream.h:360
#define DSOEXPORT
Definition: dsodefs.h:55
bool skip_bytes(unsigned num)
Discard given number of bytes.
Definition: SWFStream.h:351
SWF stream wrapper class.
Definition: SWFStream.h:58
unsigned read_variable_count()
Read a length in a byte or three.
Definition: SWFStream.h:250
boost::uint32_t read_V32()
Read a variable length unsigned 32-bit value from the stream. These values continue until either the ...
Definition: SWFStream.h:197