1use arrayvec::ArrayVec;
2use buffer::with_buffer;
3use buffer::Buffer;
4use buffer::BufferRef;
5use buffer::CapacityError;
6use libtw2_common::num::Cast;
7use libtw2_common::unwrap_or_return;
8use std::iter;
9use std::mem;
10use std::slice;
11#[cfg(feature = "uuid")]
12use uuid::Uuid;
13use warn::Warn;
14
15#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
16pub enum Warning {
17 OverlongIntEncoding,
18 NonZeroIntPadding,
19 ExcessData,
20}
21
22#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
23pub struct ExcessData;
24
25#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
26pub struct WeirdStringTermination;
27
28impl From<ExcessData> for Warning {
29 fn from(_: ExcessData) -> Warning {
30 Warning::ExcessData
31 }
32}
33
34#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
35pub struct ControlCharacters;
36
37#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
38pub struct IntOutOfRange;
39
40#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
41pub struct UnexpectedEnd;
42
43fn read_int<W>(warn: &mut W, iter: &mut slice::Iter<u8>) -> Result<i32, UnexpectedEnd>
52where
53 W: Warn<Warning>,
54{
55 let mut result = 0;
56 let mut len = 1;
57
58 let mut src = *unwrap_or_return!(iter.next(), Err(UnexpectedEnd));
59 let sign = ((src >> 6) & 1) as i32;
60
61 result |= (src & 0b0011_1111) as i32;
62
63 for i in 0..4 {
64 if src & 0b1000_0000 == 0 {
65 break;
66 }
67 src = *unwrap_or_return!(iter.next(), Err(UnexpectedEnd));
68 len += 1;
69 if i == 3 && src & 0b1111_0000 != 0 {
70 warn.warn(Warning::NonZeroIntPadding);
71 }
72 result |= ((src & 0b0111_1111) as i32) << (6 + 7 * i);
73 }
74
75 if len > 1 && src == 0b0000_0000 {
76 warn.warn(Warning::OverlongIntEncoding);
77 }
78
79 result ^= -sign;
80
81 Ok(result)
82}
83
84fn to_bit(b: bool, bit: u32) -> u8 {
86 assert!(bit < 8);
87 if b {
88 1 << bit
89 } else {
90 0
91 }
92}
93
94fn write_int<E, F: FnMut(&[u8]) -> Result<(), E>>(int: i32, f: F) -> Result<(), E> {
95 let mut f = f;
96 let mut buf: ArrayVec<[u8; 5]> = ArrayVec::new();
97 let sign = if int < 0 { 1 } else { 0 };
98 let mut int = (int ^ -sign) as u32;
99 let next = (int & 0b0011_1111) as u8;
100 int >>= 6;
101 buf.push(to_bit(int != 0, 7) | to_bit(sign != 0, 6) | next);
102 while int != 0 {
103 let next = (int & 0b0111_1111) as u8;
104 int >>= 7;
105 buf.push(to_bit(int != 0, 7) | next);
106 }
107 f(&buf)
108}
109
110fn read_string<'a>(iter: &mut slice::Iter<'a, u8>) -> Result<&'a [u8], UnexpectedEnd> {
111 let slice = iter.as_slice();
112 for (i, b) in iter.by_ref().cloned().enumerate() {
114 if b == 0 {
115 return Ok(&slice[..i]);
116 }
117 }
118 Err(UnexpectedEnd)
119}
120
121fn write_string<E, F: FnMut(&[u8]) -> Result<(), E>>(string: &[u8], f: F) -> Result<(), E> {
122 let mut f = f;
123 assert!(string.iter().all(|&b| b != 0));
124 f(string)?;
125 f(&[0])?;
126 Ok(())
127}
128
129pub struct Packer<'d, 's> {
130 buf: BufferRef<'d, 's>,
131}
132
133impl<'r, 'd, 's> Buffer<'d> for &'r mut Packer<'d, 's> {
134 type Intermediate = buffer::BufferRefBuffer<'r, 'd, 's>;
135 fn to_to_buffer_ref(self) -> Self::Intermediate {
136 (&mut self.buf).to_to_buffer_ref()
137 }
138}
139
140impl<'d, 's> Packer<'d, 's> {
141 fn new(buf: BufferRef<'d, 's>) -> Packer<'d, 's> {
142 Packer { buf: buf }
143 }
144 pub fn write_string(&mut self, string: &[u8]) -> Result<(), CapacityError> {
145 write_string(string, |b| self.buf.write(b))
146 }
147 pub fn write_int(&mut self, int: i32) -> Result<(), CapacityError> {
148 write_int(int, |b| self.buf.write(b))
149 }
150 pub fn write_data(&mut self, data: &[u8]) -> Result<(), CapacityError> {
151 self.write_int(data.len().try_i32().ok_or(CapacityError)?)?;
152 self.buf.write(data)?;
153 Ok(())
154 }
155 pub fn write_raw(&mut self, data: &[u8]) -> Result<(), CapacityError> {
156 self.buf.write(data)
157 }
158 #[cfg(feature = "uuid")]
159 pub fn write_uuid(&mut self, uuid: Uuid) -> Result<(), CapacityError> {
160 self.write_raw(uuid.as_bytes())
161 }
162 pub fn write_rest(&mut self, data: &[u8]) -> Result<(), CapacityError> {
163 self.buf.write(data)
165 }
166 pub fn written(self) -> &'d [u8] {
167 self.buf.initialized()
168 }
169}
170
171pub fn with_packer<'a, B: Buffer<'a>, F, R>(buf: B, f: F) -> R
172where
173 F: for<'b> FnOnce(Packer<'a, 'b>) -> R,
174{
175 with_buffer(buf, |b| f(Packer::new(b)))
176}
177
178pub struct Unpacker<'a> {
179 original: &'a [u8],
180 iter: slice::Iter<'a, u8>,
181 demo: bool,
182}
183
184impl<'a> Unpacker<'a> {
185 fn new_impl(data: &[u8], demo: bool) -> Unpacker {
186 Unpacker {
187 original: data,
188 iter: data.iter(),
189 demo: demo,
190 }
191 }
192 pub fn new(data: &[u8]) -> Unpacker {
193 Unpacker::new_impl(data, false)
194 }
195 pub fn new_from_demo(data: &[u8]) -> Unpacker {
196 assert!(
197 data.len() % 4 == 0,
198 "demo data must be padded to a multiple of four bytes"
199 );
200 Unpacker::new_impl(data, true)
201 }
202 pub fn is_empty(&self) -> bool {
203 self.iter.len() == 0
204 }
205 fn use_up(&mut self) {
206 self.iter.by_ref().count();
208 }
209 fn error<T>(&mut self) -> Result<T, UnexpectedEnd> {
210 self.use_up();
211 Err(UnexpectedEnd)
212 }
213 pub fn read_string(&mut self) -> Result<&'a [u8], UnexpectedEnd> {
214 read_string(&mut self.iter)
215 }
216 pub fn read_int<W: Warn<Warning>>(&mut self, warn: &mut W) -> Result<i32, UnexpectedEnd> {
217 read_int(warn, &mut self.iter)
218 }
219 pub fn read_data<W: Warn<Warning>>(&mut self, warn: &mut W) -> Result<&'a [u8], UnexpectedEnd> {
220 let len = match self.read_int(warn).map(|l| l.try_usize()) {
221 Ok(Some(l)) => l,
222 _ => return self.error(),
223 };
224 let slice = self.iter.as_slice();
225 if len > slice.len() {
226 return self.error();
227 }
228 let (data, remaining) = slice.split_at(len);
229 self.iter = remaining.iter();
230 Ok(data)
231 }
232 pub fn read_rest(&mut self) -> Result<&'a [u8], UnexpectedEnd> {
233 let result = Ok(self.iter.as_slice());
235 self.use_up();
236 result
237 }
238 pub fn read_raw(&mut self, len: usize) -> Result<&'a [u8], UnexpectedEnd> {
239 let slice = self.iter.as_slice();
240 if slice.len() < len {
241 self.use_up();
242 return Err(UnexpectedEnd);
243 }
244 let (raw, rest) = slice.split_at(len);
245 self.iter = rest.iter();
246 Ok(raw)
247 }
248 #[cfg(feature = "uuid")]
249 pub fn read_uuid(&mut self) -> Result<Uuid, UnexpectedEnd> {
250 Ok(Uuid::from_slice(self.read_raw(mem::size_of::<Uuid>())?).unwrap())
251 }
252 pub fn finish<W: Warn<Warning>>(&mut self, warn: &mut W) {
253 if !self.demo {
254 if !self.is_empty() {
255 warn.warn(Warning::ExcessData);
256 }
257 } else {
258 let rest = self.as_slice();
259 if rest.len() >= 4 || rest.iter().any(|&b| b != 0) {
260 warn.warn(Warning::ExcessData);
261 }
262 }
263 self.use_up();
264 }
265 pub fn as_slice(&self) -> &'a [u8] {
266 self.iter.as_slice()
267 }
268 pub fn num_bytes_read(&self) -> usize {
269 self.original.len() - self.iter.len()
270 }
271}
272
273pub struct IntUnpacker<'a> {
274 iter: iter::Cloned<slice::Iter<'a, i32>>,
275}
276
277impl<'a> IntUnpacker<'a> {
278 pub fn new(slice: &[i32]) -> IntUnpacker {
279 IntUnpacker {
280 iter: slice.iter().cloned(),
281 }
282 }
283 pub fn read_int(&mut self) -> Result<i32, UnexpectedEnd> {
284 self.iter.next().ok_or(UnexpectedEnd)
285 }
286 pub fn finish<W: Warn<ExcessData>>(&mut self, warn: &mut W) {
287 if self.iter.len() != 0 {
289 warn.warn(ExcessData);
290 }
291 }
292}
293
294pub fn in_range(v: i32, min: i32, max: i32) -> Result<i32, IntOutOfRange> {
295 if min <= v && v <= max {
296 Ok(v)
297 } else {
298 Err(IntOutOfRange)
299 }
300}
301
302pub fn at_least(v: i32, min: i32) -> Result<i32, IntOutOfRange> {
303 if min <= v {
304 Ok(v)
305 } else {
306 Err(IntOutOfRange)
307 }
308}
309
310pub fn to_bool(v: i32) -> Result<bool, IntOutOfRange> {
311 Ok(in_range(v, 0, 1)? != 0)
312}
313
314pub fn sanitize<'a, W: Warn<Warning>>(
315 warn: &mut W,
316 v: &'a [u8],
317) -> Result<&'a [u8], ControlCharacters> {
318 if v.iter().any(|&b| b < b' ') {
319 return Err(ControlCharacters);
320 }
321 let _ = warn;
322 Ok(v)
324}
325
326pub fn positive(v: i32) -> Result<i32, IntOutOfRange> {
327 if v >= 0 {
328 Ok(v)
329 } else {
330 Err(IntOutOfRange)
331 }
332}
333
334pub fn string_to_ints(result: &mut [i32], string: &[u8]) {
335 assert!(string.iter().all(|&b| b != 0));
336 assert!(string.len() < result.len() * mem::size_of::<i32>());
338 let mut output = result.iter_mut();
339 let mut input = string.iter().cloned();
340 while let Some(o) = output.next() {
341 let v0 = input.next().unwrap_or(0).wrapping_add(0x80);
342 let v1 = input.next().unwrap_or(0).wrapping_add(0x80);
343 let v2 = input.next().unwrap_or(0).wrapping_add(0x80);
344 let v3 = input
346 .next()
347 .unwrap_or(if output.len() != 0 { 0 } else { 0x80 })
348 .wrapping_add(0x80);
349 *o = (v0 as i32) << 24 | (v1 as i32) << 16 | (v2 as i32) << 8 | (v3 as i32);
350 }
351}
352
353pub fn string_to_ints3(string: &[u8]) -> [i32; 3] {
354 let mut result: [i32; 3] = Default::default();
355 string_to_ints(&mut result, string);
356 result
357}
358pub fn string_to_ints4(string: &[u8]) -> [i32; 4] {
359 let mut result: [i32; 4] = Default::default();
360 string_to_ints(&mut result, string);
361 result
362}
363pub fn string_to_ints6(string: &[u8]) -> [i32; 6] {
364 let mut result: [i32; 6] = Default::default();
365 string_to_ints(&mut result, string);
366 result
367}
368
369pub fn ints_to_bytes(result: &mut [u8], input: &[i32]) {
370 assert!(result.len() == input.len() * mem::size_of::<i32>());
371 for (output, input) in result.chunks_mut(mem::size_of::<i32>()).zip(input) {
372 output[0] = (((input >> 24) & 0xff) - 0x80) as u8;
373 output[1] = (((input >> 16) & 0xff) - 0x80) as u8;
374 output[2] = (((input >> 8) & 0xff) - 0x80) as u8;
375 output[3] = (((input >> 0) & 0xff) - 0x80) as u8;
376 }
377}
378
379pub fn bytes_to_string<'a, W>(warn: &mut W, bytes: &'a [u8]) -> &'a [u8]
380where
381 W: Warn<WeirdStringTermination>,
382{
383 if bytes.is_empty() {
384 warn.warn(WeirdStringTermination);
385 return bytes;
386 }
387 let end = bytes
388 .iter()
389 .position(|&b| b == 0)
390 .unwrap_or(bytes.len() - 1);
391 let (string, nuls) = bytes.split_at(end);
392 if !nuls.iter().all(|&b| b == 0) {
393 warn.warn(WeirdStringTermination);
394 }
395 string
396}
397
398pub fn string_to_bytes<'a, B: Buffer<'a>>(
399 buf: B,
400 string: &[u8],
401) -> Result<&'a [u8], CapacityError> {
402 with_buffer(buf, |buf| string_to_bytes_buffer_ref(buf, string))
403}
404
405fn string_to_bytes_buffer_ref<'d, 's>(
406 mut buf: BufferRef<'d, 's>,
407 string: &[u8],
408) -> Result<&'d [u8], CapacityError> {
409 assert!(string.iter().all(|&b| b != 0));
410 buf.write(string)?;
411 buf.write(&[0])?;
412 Ok(buf.initialized())
413}
414
415#[cfg(test)]
416#[rustfmt::skip]
417mod test {
418 use arrayvec::ArrayVec;
419 use quickcheck::quickcheck;
420 use std::i32;
421 use super::Unpacker;
422 use super::Warning::*;
423 use super::Warning;
424 use super::with_packer;
425 use warn::Ignore;
426 use warn::Panic;
427
428 fn assert_int_err(bytes: &[u8]) {
429 let mut unpacker = Unpacker::new(bytes);
430 unpacker.read_int(&mut Panic).unwrap_err();
431 }
432
433 fn assert_int_warnings(bytes: &[u8], int: i32, warnings: &[Warning]) {
434 let mut vec = vec![];
435 let mut unpacker = Unpacker::new(bytes);
436 assert_eq!(unpacker.read_int(&mut vec).unwrap(), int);
437 assert!(unpacker.as_slice().is_empty());
438 assert_eq!(vec, warnings);
439
440 let mut buf: ArrayVec<[u8; 5]> = ArrayVec::new();
441 let written = with_packer(&mut buf, |mut p| {
442 p.write_int(int).unwrap();
443 p.written()
444 });
445 if warnings.is_empty() {
446 assert_eq!(written, bytes);
447 } else {
448 assert!(written != bytes);
449 }
450 }
451
452 fn assert_int_warn(bytes: &[u8], int: i32, warning: Warning) {
453 assert_int_warnings(bytes, int, &[warning]);
454 }
455
456 fn assert_int(bytes: &[u8], int: i32) {
457 assert_int_warnings(bytes, int, &[]);
458 }
459
460 fn assert_str(bytes: &[u8], string: &[u8], remaining: &[u8]) {
461 let mut unpacker = Unpacker::new(bytes);
462 assert_eq!(unpacker.read_string().unwrap(), string);
463 assert_eq!(unpacker.as_slice(), remaining);
464
465 let mut buf = Vec::with_capacity(4096);
466 let written = with_packer(&mut buf, |mut p| {
467 p.write_string(string).unwrap();
468 p.write_rest(remaining).unwrap();
469 p.written()
470 });
471 assert_eq!(written, bytes);
472 }
473
474 fn assert_str_err(bytes: &[u8]) {
475 let mut unpacker = Unpacker::new(bytes);
476 unpacker.read_string().unwrap_err();
477 }
478
479 #[test] fn int_0() { assert_int(b"\x00", 0) }
480 #[test] fn int_1() { assert_int(b"\x01", 1) }
481 #[test] fn int_63() { assert_int(b"\x3f", 63) }
482 #[test] fn int_m1() { assert_int(b"\x40", -1) }
483 #[test] fn int_64() { assert_int(b"\x80\x01", 64) }
484 #[test] fn int_m65() { assert_int(b"\xc0\x01", -65) }
485 #[test] fn int_m64() { assert_int(b"\x7f", -64) }
486 #[test] fn int_min() { assert_int(b"\xff\xff\xff\xff\x0f", i32::min_value()) }
487 #[test] fn int_max() { assert_int(b"\xbf\xff\xff\xff\x0f", i32::max_value()) }
488 #[test] fn int_quirk1() { assert_int_warn(b"\xff\xff\xff\xff\xff", 0, NonZeroIntPadding) }
489 #[test] fn int_quirk2() { assert_int_warn(b"\xbf\xff\xff\xff\xff", -1, NonZeroIntPadding) }
490 #[test] fn int_empty() { assert_int_err(b"") }
491 #[test] fn int_extend_empty() { assert_int_err(b"\x80") }
492 #[test] fn int_overlong1() { assert_int_warn(b"\x80\x00", 0, OverlongIntEncoding) }
493 #[test] fn int_overlong2() { assert_int_warn(b"\xc0\x00", -1, OverlongIntEncoding) }
494
495 #[test] fn str_empty() { assert_str(b"\0", b"", b"") }
496 #[test] fn str_none() { assert_str_err(b"") }
497 #[test] fn str_no_nul() { assert_str_err(b"abc") }
498 #[test] fn str_rest1() { assert_str(b"abc\0def", b"abc", b"def") }
499 #[test] fn str_rest2() { assert_str(b"abc\0", b"abc", b"") }
500 #[test] fn str_rest3() { assert_str(b"abc\0\0", b"abc", b"\0") }
501 #[test] fn str_rest4() { assert_str(b"\0\0", b"", b"\0") }
502
503 #[test]
504 fn excess_data() {
505 let mut warnings = vec![];
506 let mut unpacker = Unpacker::new(b"\x00");
507 unpacker.finish(&mut warnings);
508 assert_eq!(warnings, [ExcessData]);
509 }
510
511 quickcheck! {
512 fn int_roundtrip(int: i32) -> bool {
513 let mut buf: ArrayVec<[u8; 5]> = ArrayVec::new();
514 let mut unpacker = Unpacker::new(with_packer(&mut buf, |mut p| {
515 p.write_int(int).unwrap();
516 p.written()
517 }));
518 let read_int = unpacker.read_int(&mut Panic).unwrap();
519 int == read_int && unpacker.as_slice().is_empty()
520 }
521
522 fn int_no_panic(data: Vec<u8>) -> bool {
523 let mut unpacker = Unpacker::new(&data);
524 let _ = unpacker.read_int(&mut Ignore);
525 true
526 }
527
528 fn string_no_panic(data: Vec<u8>) -> bool {
529 let mut unpacker = Unpacker::new(&data);
530 let _ = unpacker.read_string();
531 true
532 }
533 }
534}