binary_cookies/
decoder.rs

1use crate::{cookie::Cookie, errno::BinaryCookieError, page::Page};
2use std::{fs::File, io::Read};
3
4pub struct BinaryCookiesReader {
5    cookie_size: u32,
6    bits_offset: usize,
7    data: Vec<u8>,
8    pages_size: Vec<u32>,
9    pages_data: Vec<Page>,
10    check_sum: [u8; 8],
11}
12
13impl BinaryCookiesReader {
14    /// # BinaryCookiesReader - new
15    ///
16    /// need a .binarycookies file path to build, return a BinaryCookiesReader
17    ///
18    /// ## Arguments
19    ///
20    /// * `target` - type is String, .binarycookies file path
21    ///
22    /// ## Returns
23    ///
24    /// `Result<(), BinaryCookieError>`
25    ///
26    /// ## Examples
27    ///
28    /// ```rust
29    /// let target_file_path: String = String::from("/Users/foo/Library/HTTPStorages/boo.binarycookies");
30    /// let mut bc_decoder = BinaryCookiesReader::new(&target_file_path).unwrap();
31    /// let _ = bc_decoder.decoder().unwrap();
32    /// for page in bc_decoder.origin_pages():
33    ///     for cookie in page.cookies():
34    ///         println!("{} | {} | {}", cookie.name_str(), cookie.value_str(), cookie.http_only)
35    /// ```
36
37    pub fn new(target: &String) -> Result<Self, BinaryCookieError> {
38        let mut target_file = File::open(target)?;
39        let mut data = vec![];
40        let _ = target_file.read_to_end(&mut data)?;
41        Ok(Self {
42            cookie_size: 0,
43            bits_offset: 0,
44            data,
45            pages_size: vec![],
46            pages_data: vec![],
47            check_sum: [0; 8],
48        })
49    }
50
51    /// # BinaryCookiesReader - from_vec
52    ///
53    /// need a Vec<u8> data to build
54    ///
55    /// ## Arguments
56    ///
57    /// * `target` - type is Vec<u8>, after read_binary...
58    ///
59    /// ## Returns
60    ///
61    /// `BinaryCookiesReader`
62    ///
63    /// ## Examples
64    ///
65    /// ```rust
66    /// use std::fs::File;
67    ///
68    /// let target_file_path: String = String::from("/Users/foo/Library/HTTPStorages/boo.binarycookies");
69    /// let mut buf = Vec::new();
70    /// let mut f = File::open(&target_file_path);
71    /// let _ = f.read_to_end(&mut buf);
72    /// let mut bc_decoder = BinaryCookiesReader::from_vec(&buf).unwrap();
73    /// let _ = bc_decoder.decoder().unwrap();
74    /// for page in bc_decoder.origin_pages():
75    ///     for cookie in page.cookies():
76    ///         println!("{} | {} | {}", cookie.name_str(), cookie.value_str(), cookie.http_only)
77    /// ```
78
79    pub fn from_vec(target: &Vec<u8>) -> Self {
80        let mut data = Vec::<u8>::with_capacity(target.len());
81        data.extend(target.iter());
82        Self {
83            cookie_size: 0,
84            bits_offset: 0,
85            data,
86            pages_size: vec![],
87            pages_data: vec![],
88            check_sum: [0; 8],
89        }
90    }
91
92    fn read4bits(&mut self) -> Result<[u8; 4], BinaryCookieError> {
93        let mut bits: [u8; 4] = [0; 4];
94        for i in 0..4 {
95            if let Some(&value) = self.data.get(self.bits_offset + i) {
96                bits[i] = value;
97            } else {
98                return Err(BinaryCookieError::InvalidIndexOverBounds);
99            };
100        }
101        self.bits_offset += 4;
102        return Ok(bits);
103    }
104
105    fn read8bits(&mut self) -> Result<[u8; 8], BinaryCookieError> {
106        let mut bits: [u8; 8] = [0; 8];
107        for i in 0..8 {
108            if let Some(&value) = self.data.get(self.bits_offset + i) {
109                bits[i] = value;
110            } else {
111                return Err(BinaryCookieError::InvalidIndexOverBounds);
112            }
113        }
114        self.bits_offset += 8;
115        return Ok(bits);
116    }
117
118    fn read_bits(&mut self, size: u32) -> Result<Vec<u8>, BinaryCookieError> {
119        let cap = size as usize;
120        let mut bits: Vec<u8> = Vec::with_capacity(cap);
121        for i in 0..cap {
122            if let Some(&value) = self.data.get(self.bits_offset + i) {
123                bits.push(value);
124            } else {
125                return Err(BinaryCookieError::InvalidIndexOverBounds);
126            }
127        }
128        self.bits_offset += cap;
129        Ok(bits)
130    }
131
132    #[deprecated(since = "0.1.4", note = "use `decode()` function instead")]
133    pub fn deocde(&mut self) -> Result<(), BinaryCookieError> {
134        let magic_signature = [99, 111, 111, 107];
135        let next: [u8; 4] = self.read4bits()?;
136        if next != magic_signature {
137            return Err(BinaryCookieError::InvalidSignature);
138        }
139        let next: [u8; 4] = self.read4bits()?;
140        self.cookie_size = u32::from_be_bytes(next);
141        for _ in 0..self.cookie_size {
142            let next: [u8; 4] = self.read4bits()?;
143            self.pages_size.push(u32::from_be_bytes(next));
144        }
145        for _ in 0..self.cookie_size {
146            let start_code = self.read4bits()?;
147            if start_code != [0x00, 0x00, 0x01, 0x00] {
148                return Err(BinaryCookieError::InvalidStartCode);
149            };
150            let length_info = self.read4bits()?;
151            let length = u32::from_le_bytes(length_info) as usize;
152            let mut offset: Vec<u32> = Vec::with_capacity(length);
153            for _ in 0..length {
154                let next: [u8; 4] = self.read4bits()?;
155                let data = u32::from_le_bytes(next);
156                offset.push(data);
157            }
158            let mut page = Page::new(length, offset);
159            let end_code = self.read4bits()?;
160            if end_code != [0x00, 0x00, 0x00, 0x00] {
161                return Err(BinaryCookieError::EndCodeError);
162            }
163            for _ in 0..length {
164                let mut cookie = Cookie::default();
165                let next = self.read4bits()?;
166                cookie.init_cookie_size(next);
167                let next = self.read4bits()?;
168                cookie.init_unknown_one(next);
169                let next = self.read4bits()?;
170                cookie.init_flags(next);
171                let next = self.read4bits()?;
172                cookie.init_unknown_two(next);
173                let next = self.read4bits()?;
174                cookie.init_domain_offset(next);
175                let next = self.read4bits()?;
176                cookie.init_name_offset(next);
177                let next = self.read4bits()?;
178                cookie.init_path_offset(next);
179                let next = self.read4bits()?;
180                cookie.init_value_offset(next);
181                let next = self.read4bits()?;
182                cookie.init_comment_offset(next);
183                let next = self.read4bits()?;
184                if !cookie.is_end_header(next) {
185                    return Err(BinaryCookieError::EndHeaderCodeError);
186                };
187                let next = self.read8bits()?;
188                cookie.init_page_expires(next);
189                let next = self.read8bits()?;
190                cookie.init_page_creation(next);
191                if cookie.check_over_size() {
192                    return Err(BinaryCookieError::DataOverSize);
193                };
194                let comment_size = cookie.page_comment_size();
195                if comment_size > 0 {
196                    let next = self.read_bits(comment_size)?;
197                    cookie.init_comment(next);
198                };
199                let domain_size = cookie.page_domain_size();
200                if domain_size > 0 {
201                    let next = self.read_bits(domain_size)?;
202                    cookie.init_domain(next)
203                };
204                let name_size = cookie.page_name_size();
205                if name_size > 0 {
206                    let next = self.read_bits(name_size)?;
207                    cookie.init_name(next)
208                };
209                let path_size = cookie.page_path_size();
210                if path_size > 0 {
211                    let next = self.read_bits(path_size)?;
212                    cookie.init_path(next);
213                };
214                let value_size = cookie.page_value_size();
215                if value_size > 0 {
216                    let next = self.read_bits(value_size)?;
217                    cookie.init_value(next)
218                };
219                page.mut_cookies().push(cookie);
220            }
221            self.pages_data.push(page);
222        }
223        self.check_sum = self.read8bits()?;
224        Ok(())
225    }
226
227    pub fn decode(&mut self) -> Result<(), BinaryCookieError> {
228        let magic_signature = [99, 111, 111, 107];
229        let next: [u8; 4] = self.read4bits()?;
230        if next != magic_signature {
231            return Err(BinaryCookieError::InvalidSignature);
232        }
233        let next: [u8; 4] = self.read4bits()?;
234        self.cookie_size = u32::from_be_bytes(next);
235        for _ in 0..self.cookie_size {
236            let next: [u8; 4] = self.read4bits()?;
237            self.pages_size.push(u32::from_be_bytes(next));
238        }
239        for _ in 0..self.cookie_size {
240            let start_code = self.read4bits()?;
241            if start_code != [0x00, 0x00, 0x01, 0x00] {
242                return Err(BinaryCookieError::InvalidStartCode);
243            };
244            let length_info = self.read4bits()?;
245            let length = u32::from_le_bytes(length_info) as usize;
246            let mut offset: Vec<u32> = Vec::with_capacity(length);
247            for _ in 0..length {
248                let next: [u8; 4] = self.read4bits()?;
249                let data = u32::from_le_bytes(next);
250                offset.push(data);
251            }
252            let mut page = Page::new(length, offset);
253            let end_code = self.read4bits()?;
254            if end_code != [0x00, 0x00, 0x00, 0x00] {
255                return Err(BinaryCookieError::EndCodeError);
256            }
257            for _ in 0..length {
258                let mut cookie = Cookie::default();
259                let next = self.read4bits()?;
260                cookie.init_cookie_size(next);
261                let next = self.read4bits()?;
262                cookie.init_unknown_one(next);
263                let next = self.read4bits()?;
264                cookie.init_flags(next);
265                let next = self.read4bits()?;
266                cookie.init_unknown_two(next);
267                let next = self.read4bits()?;
268                cookie.init_domain_offset(next);
269                let next = self.read4bits()?;
270                cookie.init_name_offset(next);
271                let next = self.read4bits()?;
272                cookie.init_path_offset(next);
273                let next = self.read4bits()?;
274                cookie.init_value_offset(next);
275                let next = self.read4bits()?;
276                cookie.init_comment_offset(next);
277                let next = self.read4bits()?;
278                if !cookie.is_end_header(next) {
279                    return Err(BinaryCookieError::EndHeaderCodeError);
280                };
281                let next = self.read8bits()?;
282                cookie.init_page_expires(next);
283                let next = self.read8bits()?;
284                cookie.init_page_creation(next);
285                if cookie.check_over_size() {
286                    return Err(BinaryCookieError::DataOverSize);
287                };
288                let comment_size = cookie.page_comment_size();
289                if comment_size > 0 {
290                    let next = self.read_bits(comment_size)?;
291                    cookie.init_comment(next);
292                };
293                let domain_size = cookie.page_domain_size();
294                if domain_size > 0 {
295                    let next = self.read_bits(domain_size)?;
296                    cookie.init_domain(next)
297                };
298                let name_size = cookie.page_name_size();
299                if name_size > 0 {
300                    let next = self.read_bits(name_size)?;
301                    cookie.init_name(next)
302                };
303                let path_size = cookie.page_path_size();
304                if path_size > 0 {
305                    let next = self.read_bits(path_size)?;
306                    cookie.init_path(next);
307                };
308                let value_size = cookie.page_value_size();
309                if value_size > 0 {
310                    let next = self.read_bits(value_size)?;
311                    cookie.init_value(next)
312                };
313                page.mut_cookies().push(cookie);
314            }
315            self.pages_data.push(page);
316        }
317        self.check_sum = self.read8bits()?;
318        Ok(())
319    }
320
321    pub fn origin_pages(&mut self) -> &Vec<Page> {
322        return &self.pages_data;
323    }
324}