Coverage Report

Created: 2024-02-25 07:20

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