1 /*
2 * Byte stream functions
3 *
4 * Copyright (C) 2008-2020, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <types.h>
24
25 #include "libuna_byte_stream.h"
26 #include "libuna_definitions.h"
27 #include "libuna_libcerror.h"
28 #include "libuna_types.h"
29 #include "libuna_unicode_character.h"
30
31 /* Determines the size of a byte stream from an UTF-8 string
32 * Returns 1 if successful or -1 on error
33 */
libuna_byte_stream_size_from_utf8(const libuna_utf8_character_t * utf8_string,size_t utf8_string_size,int codepage,size_t * byte_stream_size,libcerror_error_t ** error)34 int libuna_byte_stream_size_from_utf8(
35 const libuna_utf8_character_t *utf8_string,
36 size_t utf8_string_size,
37 int codepage,
38 size_t *byte_stream_size,
39 libcerror_error_t **error )
40 {
41 static char *function = "libuna_byte_stream_size_from_utf8";
42 size_t utf8_string_index = 0;
43 libuna_unicode_character_t unicode_character = 0;
44
45 if( utf8_string == NULL )
46 {
47 libcerror_error_set(
48 error,
49 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51 "%s: invalid UTF-8 string.",
52 function );
53
54 return( -1 );
55 }
56 if( utf8_string_size > (size_t) SSIZE_MAX )
57 {
58 libcerror_error_set(
59 error,
60 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
61 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
62 "%s: invalid UTF-8 string size value exceeds maximum.",
63 function );
64
65 return( -1 );
66 }
67 if( byte_stream_size == NULL )
68 {
69 libcerror_error_set(
70 error,
71 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
72 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
73 "%s: invalid byte stream size.",
74 function );
75
76 return( -1 );
77 }
78 *byte_stream_size = 0;
79
80 while( utf8_string_index < utf8_string_size )
81 {
82 /* Convert the UTF-8 character bytes into an Unicode character
83 */
84 if( libuna_unicode_character_copy_from_utf8(
85 &unicode_character,
86 utf8_string,
87 utf8_string_size,
88 &utf8_string_index,
89 error ) != 1 )
90 {
91 libcerror_error_set(
92 error,
93 LIBCERROR_ERROR_DOMAIN_CONVERSION,
94 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
95 "%s: unable to copy Unicode character from UTF-8.",
96 function );
97
98 return( -1 );
99 }
100 /* Determine how many byte stream character bytes are required
101 */
102 if( libuna_unicode_character_size_to_byte_stream(
103 unicode_character,
104 codepage,
105 byte_stream_size,
106 error ) != 1 )
107 {
108 libcerror_error_set(
109 error,
110 LIBCERROR_ERROR_DOMAIN_CONVERSION,
111 LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
112 "%s: unable to unable to determine size of Unicode character in byte stream.",
113 function );
114
115 return( -1 );
116 }
117 if( unicode_character == 0 )
118 {
119 break;
120 }
121 }
122 return( 1 );
123 }
124
125 /* Copies a byte stream from an UTF-8 string
126 * Returns 1 if successful or -1 on error
127 */
libuna_byte_stream_copy_from_utf8(uint8_t * byte_stream,size_t byte_stream_size,int codepage,const libuna_utf8_character_t * utf8_string,size_t utf8_string_size,libcerror_error_t ** error)128 int libuna_byte_stream_copy_from_utf8(
129 uint8_t *byte_stream,
130 size_t byte_stream_size,
131 int codepage,
132 const libuna_utf8_character_t *utf8_string,
133 size_t utf8_string_size,
134 libcerror_error_t **error )
135 {
136 static char *function = "libuna_byte_stream_copy_from_utf8";
137 size_t byte_stream_index = 0;
138 size_t utf8_string_index = 0;
139 libuna_unicode_character_t unicode_character = 0;
140
141 if( byte_stream == NULL )
142 {
143 libcerror_error_set(
144 error,
145 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
146 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
147 "%s: invalid byte stream.",
148 function );
149
150 return( -1 );
151 }
152 if( byte_stream_size > (size_t) SSIZE_MAX )
153 {
154 libcerror_error_set(
155 error,
156 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
157 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
158 "%s: invalid byte stream size value exceeds maximum.",
159 function );
160
161 return( -1 );
162 }
163 if( utf8_string == NULL )
164 {
165 libcerror_error_set(
166 error,
167 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
168 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
169 "%s: invalid UTF-8 string.",
170 function );
171
172 return( -1 );
173 }
174 if( utf8_string_size > (size_t) SSIZE_MAX )
175 {
176 libcerror_error_set(
177 error,
178 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
179 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
180 "%s: invalid UTF-8 string size value exceeds maximum.",
181 function );
182
183 return( -1 );
184 }
185 while( utf8_string_index < utf8_string_size )
186 {
187 /* Convert the UTF-8 string bytes into an Unicode character
188 */
189 if( libuna_unicode_character_copy_from_utf8(
190 &unicode_character,
191 utf8_string,
192 utf8_string_size,
193 &utf8_string_index,
194 error ) != 1 )
195 {
196 libcerror_error_set(
197 error,
198 LIBCERROR_ERROR_DOMAIN_CONVERSION,
199 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
200 "%s: unable to copy Unicode character from UTF-8 string.",
201 function );
202
203 return( -1 );
204 }
205 /* Convert the Unicode character into a byte stream
206 */
207 if( libuna_unicode_character_copy_to_byte_stream(
208 unicode_character,
209 byte_stream,
210 byte_stream_size,
211 &byte_stream_index,
212 codepage,
213 error ) != 1 )
214 {
215 libcerror_error_set(
216 error,
217 LIBCERROR_ERROR_DOMAIN_CONVERSION,
218 LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
219 "%s: unable to copy Unicode character to byte stream.",
220 function );
221
222 return( -1 );
223 }
224 if( unicode_character == 0 )
225 {
226 break;
227 }
228 }
229 return( 1 );
230 }
231
232 /* Determines the size of a byte stream from an UTF-16 string
233 * Returns 1 if successful or -1 on error
234 */
libuna_byte_stream_size_from_utf16(const libuna_utf16_character_t * utf16_string,size_t utf16_string_size,int codepage,size_t * byte_stream_size,libcerror_error_t ** error)235 int libuna_byte_stream_size_from_utf16(
236 const libuna_utf16_character_t *utf16_string,
237 size_t utf16_string_size,
238 int codepage,
239 size_t *byte_stream_size,
240 libcerror_error_t **error )
241 {
242 static char *function = "libuna_byte_stream_size_from_utf16";
243 size_t utf16_string_index = 0;
244 libuna_unicode_character_t unicode_character = 0;
245
246 if( utf16_string == NULL )
247 {
248 libcerror_error_set(
249 error,
250 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
251 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
252 "%s: invalid UTF-16 string.",
253 function );
254
255 return( -1 );
256 }
257 if( utf16_string_size > (size_t) SSIZE_MAX )
258 {
259 libcerror_error_set(
260 error,
261 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
262 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
263 "%s: invalid UTF-16 string size value exceeds maximum.",
264 function );
265
266 return( -1 );
267 }
268 if( byte_stream_size == NULL )
269 {
270 libcerror_error_set(
271 error,
272 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
273 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
274 "%s: invalid byte stream size.",
275 function );
276
277 return( -1 );
278 }
279 *byte_stream_size = 0;
280
281 while( utf16_string_index < utf16_string_size )
282 {
283 /* Convert the UTF-16 character bytes into an Unicode character
284 */
285 if( libuna_unicode_character_copy_from_utf16(
286 &unicode_character,
287 utf16_string,
288 utf16_string_size,
289 &utf16_string_index,
290 error ) != 1 )
291 {
292 libcerror_error_set(
293 error,
294 LIBCERROR_ERROR_DOMAIN_CONVERSION,
295 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
296 "%s: unable to copy Unicode character from UTF-16.",
297 function );
298
299 return( -1 );
300 }
301 /* Determine how many byte stream character bytes are required
302 */
303 if( libuna_unicode_character_size_to_byte_stream(
304 unicode_character,
305 codepage,
306 byte_stream_size,
307 error ) != 1 )
308 {
309 libcerror_error_set(
310 error,
311 LIBCERROR_ERROR_DOMAIN_CONVERSION,
312 LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
313 "%s: unable to unable to determine size of Unicode character in byte stream.",
314 function );
315
316 return( -1 );
317 }
318 if( unicode_character == 0 )
319 {
320 break;
321 }
322 }
323 return( 1 );
324 }
325
326 /* Copies a byte stream from an UTF-16 string
327 * Returns 1 if successful or -1 on error
328 */
libuna_byte_stream_copy_from_utf16(uint8_t * byte_stream,size_t byte_stream_size,int codepage,const libuna_utf16_character_t * utf16_string,size_t utf16_string_size,libcerror_error_t ** error)329 int libuna_byte_stream_copy_from_utf16(
330 uint8_t *byte_stream,
331 size_t byte_stream_size,
332 int codepage,
333 const libuna_utf16_character_t *utf16_string,
334 size_t utf16_string_size,
335 libcerror_error_t **error )
336 {
337 static char *function = "libuna_byte_stream_copy_from_utf16";
338 size_t byte_stream_index = 0;
339 size_t utf16_string_index = 0;
340 libuna_unicode_character_t unicode_character = 0;
341
342 if( byte_stream == NULL )
343 {
344 libcerror_error_set(
345 error,
346 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
347 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
348 "%s: invalid byte stream.",
349 function );
350
351 return( -1 );
352 }
353 if( byte_stream_size > (size_t) SSIZE_MAX )
354 {
355 libcerror_error_set(
356 error,
357 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
358 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
359 "%s: invalid byte stream size value exceeds maximum.",
360 function );
361
362 return( -1 );
363 }
364 if( utf16_string == NULL )
365 {
366 libcerror_error_set(
367 error,
368 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
369 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
370 "%s: invalid UTF-16 string.",
371 function );
372
373 return( -1 );
374 }
375 if( utf16_string_size > (size_t) SSIZE_MAX )
376 {
377 libcerror_error_set(
378 error,
379 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
380 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
381 "%s: invalid UTF-16 string size value exceeds maximum.",
382 function );
383
384 return( -1 );
385 }
386 while( utf16_string_index < utf16_string_size )
387 {
388 /* Convert the UTF-16 string bytes into an Unicode character
389 */
390 if( libuna_unicode_character_copy_from_utf16(
391 &unicode_character,
392 utf16_string,
393 utf16_string_size,
394 &utf16_string_index,
395 error ) != 1 )
396 {
397 libcerror_error_set(
398 error,
399 LIBCERROR_ERROR_DOMAIN_CONVERSION,
400 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
401 "%s: unable to copy Unicode character from UTF-16 string.",
402 function );
403
404 return( -1 );
405 }
406 /* Convert the Unicode character into a byte stream
407 */
408 if( libuna_unicode_character_copy_to_byte_stream(
409 unicode_character,
410 byte_stream,
411 byte_stream_size,
412 &byte_stream_index,
413 codepage,
414 error ) != 1 )
415 {
416 libcerror_error_set(
417 error,
418 LIBCERROR_ERROR_DOMAIN_CONVERSION,
419 LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
420 "%s: unable to copy Unicode character to byte stream.",
421 function );
422
423 return( -1 );
424 }
425 if( unicode_character == 0 )
426 {
427 break;
428 }
429 }
430 return( 1 );
431 }
432
433 /* Determines the size of a byte stream from an UTF-32 string
434 * Returns 1 if successful or -1 on error
435 */
libuna_byte_stream_size_from_utf32(const libuna_utf32_character_t * utf32_string,size_t utf32_string_size,int codepage,size_t * byte_stream_size,libcerror_error_t ** error)436 int libuna_byte_stream_size_from_utf32(
437 const libuna_utf32_character_t *utf32_string,
438 size_t utf32_string_size,
439 int codepage,
440 size_t *byte_stream_size,
441 libcerror_error_t **error )
442 {
443 static char *function = "libuna_byte_stream_size_from_utf32";
444 size_t utf32_string_index = 0;
445 libuna_unicode_character_t unicode_character = 0;
446
447 if( utf32_string == NULL )
448 {
449 libcerror_error_set(
450 error,
451 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
452 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
453 "%s: invalid UTF-32 string.",
454 function );
455
456 return( -1 );
457 }
458 if( utf32_string_size > (size_t) SSIZE_MAX )
459 {
460 libcerror_error_set(
461 error,
462 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
463 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
464 "%s: invalid UTF-32 string size value exceeds maximum.",
465 function );
466
467 return( -1 );
468 }
469 if( byte_stream_size == NULL )
470 {
471 libcerror_error_set(
472 error,
473 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
474 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
475 "%s: invalid byte stream size.",
476 function );
477
478 return( -1 );
479 }
480 *byte_stream_size = 0;
481
482 while( utf32_string_index < utf32_string_size )
483 {
484 /* Convert the UTF-32 character bytes into an Unicode character
485 */
486 if( libuna_unicode_character_copy_from_utf32(
487 &unicode_character,
488 utf32_string,
489 utf32_string_size,
490 &utf32_string_index,
491 error ) != 1 )
492 {
493 libcerror_error_set(
494 error,
495 LIBCERROR_ERROR_DOMAIN_CONVERSION,
496 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
497 "%s: unable to copy Unicode character from UTF-32.",
498 function );
499
500 return( -1 );
501 }
502 /* Determine how many byte stream character bytes are required
503 */
504 if( libuna_unicode_character_size_to_byte_stream(
505 unicode_character,
506 codepage,
507 byte_stream_size,
508 error ) != 1 )
509 {
510 libcerror_error_set(
511 error,
512 LIBCERROR_ERROR_DOMAIN_CONVERSION,
513 LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
514 "%s: unable to unable to determine size of Unicode character in byte stream.",
515 function );
516
517 return( -1 );
518 }
519 if( unicode_character == 0 )
520 {
521 break;
522 }
523 }
524 return( 1 );
525 }
526
527 /* Copies a byte stream from an UTF-32 string
528 * Returns 1 if successful or -1 on error
529 */
libuna_byte_stream_copy_from_utf32(uint8_t * byte_stream,size_t byte_stream_size,int codepage,const libuna_utf32_character_t * utf32_string,size_t utf32_string_size,libcerror_error_t ** error)530 int libuna_byte_stream_copy_from_utf32(
531 uint8_t *byte_stream,
532 size_t byte_stream_size,
533 int codepage,
534 const libuna_utf32_character_t *utf32_string,
535 size_t utf32_string_size,
536 libcerror_error_t **error )
537 {
538 static char *function = "libuna_byte_stream_copy_from_utf32";
539 size_t byte_stream_index = 0;
540 size_t utf32_string_index = 0;
541 libuna_unicode_character_t unicode_character = 0;
542
543 if( byte_stream == NULL )
544 {
545 libcerror_error_set(
546 error,
547 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
548 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
549 "%s: invalid byte stream.",
550 function );
551
552 return( -1 );
553 }
554 if( byte_stream_size > (size_t) SSIZE_MAX )
555 {
556 libcerror_error_set(
557 error,
558 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
559 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
560 "%s: invalid byte stream size value exceeds maximum.",
561 function );
562
563 return( -1 );
564 }
565 if( utf32_string == NULL )
566 {
567 libcerror_error_set(
568 error,
569 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
570 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
571 "%s: invalid UTF-32 string.",
572 function );
573
574 return( -1 );
575 }
576 if( utf32_string_size > (size_t) SSIZE_MAX )
577 {
578 libcerror_error_set(
579 error,
580 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
581 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
582 "%s: invalid UTF-32 string size value exceeds maximum.",
583 function );
584
585 return( -1 );
586 }
587 while( utf32_string_index < utf32_string_size )
588 {
589 /* Convert the UTF-32 string bytes into an Unicode character
590 */
591 if( libuna_unicode_character_copy_from_utf32(
592 &unicode_character,
593 utf32_string,
594 utf32_string_size,
595 &utf32_string_index,
596 error ) != 1 )
597 {
598 libcerror_error_set(
599 error,
600 LIBCERROR_ERROR_DOMAIN_CONVERSION,
601 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
602 "%s: unable to copy Unicode character from UTF-32 string.",
603 function );
604
605 return( -1 );
606 }
607 /* Convert the Unicode character into a byte stream
608 */
609 if( libuna_unicode_character_copy_to_byte_stream(
610 unicode_character,
611 byte_stream,
612 byte_stream_size,
613 &byte_stream_index,
614 codepage,
615 error ) != 1 )
616 {
617 libcerror_error_set(
618 error,
619 LIBCERROR_ERROR_DOMAIN_CONVERSION,
620 LIBCERROR_CONVERSION_ERROR_OUTPUT_FAILED,
621 "%s: unable to copy Unicode character to byte stream.",
622 function );
623
624 return( -1 );
625 }
626 if( unicode_character == 0 )
627 {
628 break;
629 }
630 }
631 return( 1 );
632 }
633
634