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:
A virtual IO channel.
Definition: IOChannel.h:42
TagType
SWF tag types. Symbolic names copied from Ming.
Definition: SWF.h:30
An SWF parsing exception.
Definition: GnashException.h:89
Anonymous namespace for callbacks, local functions, event handlers etc.
Definition: dbus_ext.cpp:40
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
void align()
Consume all bits of current byte.
Definition: SWFStream.h:135
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
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
void skip_to_tag_end()
Discard all bytes up to end of tag.
Definition: SWFStream.h:354
#define DSOEXPORT
Definition: dsodefs.h:55
bool skip_bytes(unsigned num)
Discard given number of bytes.
Definition: SWFStream.h:345
SWF stream wrapper class.
Definition: SWFStream.h:58
unsigned read_variable_count()
Read a length in a byte or three.
Definition: SWFStream.h:244