1 /*
2 * Split narrow string 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 <memory.h>
24 #include <narrow_string.h>
25 #include <types.h>
26
27 #include "libcsplit_libcerror.h"
28 #include "libcsplit_narrow_split_string.h"
29 #include "libcsplit_types.h"
30
31 /* Creates a split string
32 * Make sure the value split_string is referencing, is set to NULL
33 * Returns 1 if successful or -1 on error
34 */
libcsplit_narrow_split_string_initialize(libcsplit_narrow_split_string_t ** split_string,const char * string,size_t string_size,int number_of_segments,libcerror_error_t ** error)35 int libcsplit_narrow_split_string_initialize(
36 libcsplit_narrow_split_string_t **split_string,
37 const char *string,
38 size_t string_size,
39 int number_of_segments,
40 libcerror_error_t **error )
41 {
42 libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
43 static char *function = "libcsplit_narrow_split_string_initialize";
44
45 if( split_string == NULL )
46 {
47 libcerror_error_set(
48 error,
49 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51 "%s: invalid split string.",
52 function );
53
54 return( -1 );
55 }
56 if( *split_string != NULL )
57 {
58 libcerror_error_set(
59 error,
60 LIBCERROR_ERROR_DOMAIN_RUNTIME,
61 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62 "%s: invalid split string value already set.",
63 function );
64
65 return( -1 );
66 }
67 if( number_of_segments < 0 )
68 {
69 libcerror_error_set(
70 error,
71 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
72 LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
73 "%s: invalid number of segments less than zero.",
74 function );
75
76 return( -1 );
77 }
78 internal_split_string = memory_allocate_structure(
79 libcsplit_internal_narrow_split_string_t );
80
81 if( internal_split_string == NULL )
82 {
83 libcerror_error_set(
84 error,
85 LIBCERROR_ERROR_DOMAIN_MEMORY,
86 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
87 "%s: unable to create split string.",
88 function );
89
90 goto on_error;
91 }
92 if( memory_set(
93 internal_split_string,
94 0,
95 sizeof( libcsplit_internal_narrow_split_string_t ) ) == NULL )
96 {
97 libcerror_error_set(
98 error,
99 LIBCERROR_ERROR_DOMAIN_MEMORY,
100 LIBCERROR_MEMORY_ERROR_SET_FAILED,
101 "%s: unable to clear split string.",
102 function );
103
104 memory_free(
105 internal_split_string );
106
107 return( -1 );
108 }
109 if( ( string != NULL )
110 && ( string_size > 0 ) )
111 {
112 internal_split_string->string = narrow_string_allocate(
113 string_size );
114
115 if( internal_split_string->string == NULL )
116 {
117 libcerror_error_set(
118 error,
119 LIBCERROR_ERROR_DOMAIN_MEMORY,
120 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
121 "%s: unable to create string.",
122 function );
123
124 goto on_error;
125 }
126 if( memory_copy(
127 internal_split_string->string,
128 string,
129 sizeof( char ) * ( string_size - 1 ) ) == NULL )
130 {
131 libcerror_error_set(
132 error,
133 LIBCERROR_ERROR_DOMAIN_MEMORY,
134 LIBCERROR_MEMORY_ERROR_SET_FAILED,
135 "%s: unable to copy string.",
136 function );
137
138 goto on_error;
139 }
140 internal_split_string->string[ string_size - 1 ] = 0;
141 internal_split_string->string_size = string_size;
142 }
143 if( number_of_segments > 0 )
144 {
145 internal_split_string->segments = (char **) memory_allocate(
146 sizeof( char * ) * number_of_segments );
147
148 if( internal_split_string->segments == NULL )
149 {
150 libcerror_error_set(
151 error,
152 LIBCERROR_ERROR_DOMAIN_MEMORY,
153 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
154 "%s: unable to create segments.",
155 function );
156
157 goto on_error;
158 }
159 if( memory_set(
160 internal_split_string->segments,
161 0,
162 sizeof( char * ) * number_of_segments ) == NULL )
163 {
164 libcerror_error_set(
165 error,
166 LIBCERROR_ERROR_DOMAIN_MEMORY,
167 LIBCERROR_MEMORY_ERROR_SET_FAILED,
168 "%s: unable to clear segments.",
169 function );
170
171 goto on_error;
172 }
173 internal_split_string->segment_sizes = (size_t *) memory_allocate(
174 sizeof( size_t ) * number_of_segments );
175
176 if( internal_split_string->segment_sizes == NULL )
177 {
178 libcerror_error_set(
179 error,
180 LIBCERROR_ERROR_DOMAIN_MEMORY,
181 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
182 "%s: unable to create segment sizes.",
183 function );
184
185 goto on_error;
186 }
187 if( memory_set(
188 internal_split_string->segment_sizes,
189 0,
190 sizeof( size_t ) * number_of_segments ) == NULL )
191 {
192 libcerror_error_set(
193 error,
194 LIBCERROR_ERROR_DOMAIN_MEMORY,
195 LIBCERROR_MEMORY_ERROR_SET_FAILED,
196 "%s: unable to clear segment sizes.",
197 function );
198
199 goto on_error;
200 }
201 }
202 internal_split_string->number_of_segments = number_of_segments;
203
204 *split_string = (libcsplit_narrow_split_string_t *) internal_split_string;
205
206 return( 1 );
207
208 on_error:
209 if( internal_split_string != NULL )
210 {
211 if( internal_split_string->segment_sizes != NULL )
212 {
213 memory_free(
214 internal_split_string->segment_sizes );
215 }
216 if( internal_split_string->segments != NULL )
217 {
218 memory_free(
219 internal_split_string->segments );
220 }
221 if( internal_split_string->string != NULL )
222 {
223 memory_free(
224 internal_split_string->string );
225 }
226 memory_free(
227 internal_split_string );
228 }
229 return( -1 );
230 }
231
232 /* Frees a split string
233 * Returns 1 if successful or -1 on error
234 */
libcsplit_narrow_split_string_free(libcsplit_narrow_split_string_t ** split_string,libcerror_error_t ** error)235 int libcsplit_narrow_split_string_free(
236 libcsplit_narrow_split_string_t **split_string,
237 libcerror_error_t **error )
238 {
239 libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
240 static char *function = "libcsplit_narrow_split_string_free";
241
242 if( split_string == NULL )
243 {
244 libcerror_error_set(
245 error,
246 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
247 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
248 "%s: invalid split string.",
249 function );
250
251 return( -1 );
252 }
253 if( *split_string != NULL )
254 {
255 internal_split_string = (libcsplit_internal_narrow_split_string_t *) *split_string;
256 *split_string = NULL;
257
258 if( internal_split_string->string != NULL )
259 {
260 memory_free(
261 internal_split_string->string );
262 }
263 if( internal_split_string->segments != NULL )
264 {
265 memory_free(
266 internal_split_string->segments );
267 }
268 if( internal_split_string->segment_sizes != NULL )
269 {
270 memory_free(
271 internal_split_string->segment_sizes );
272 }
273 memory_free(
274 internal_split_string );
275 }
276 return( 1 );
277 }
278
279 /* Retrieves the string
280 * Returns 1 if successful or -1 on error
281 */
libcsplit_narrow_split_string_get_string(libcsplit_narrow_split_string_t * split_string,char ** string,size_t * string_size,libcerror_error_t ** error)282 int libcsplit_narrow_split_string_get_string(
283 libcsplit_narrow_split_string_t *split_string,
284 char **string,
285 size_t *string_size,
286 libcerror_error_t **error )
287 {
288 libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
289 static char *function = "libcsplit_narrow_split_string_get_string";
290
291 if( split_string == NULL )
292 {
293 libcerror_error_set(
294 error,
295 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
296 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
297 "%s: invalid split string.",
298 function );
299
300 return( -1 );
301 }
302 internal_split_string = (libcsplit_internal_narrow_split_string_t *) split_string;
303
304 if( string == NULL )
305 {
306 libcerror_error_set(
307 error,
308 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
309 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
310 "%s: invalid string.",
311 function );
312
313 return( -1 );
314 }
315 if( string_size == NULL )
316 {
317 libcerror_error_set(
318 error,
319 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
320 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
321 "%s: invalid string size.",
322 function );
323
324 return( -1 );
325 }
326 *string = internal_split_string->string;
327 *string_size = internal_split_string->string_size;
328
329 return( 1 );
330 }
331
332 /* Retrieves the number of segments
333 * Returns 1 if successful or -1 on error
334 */
libcsplit_narrow_split_string_get_number_of_segments(libcsplit_narrow_split_string_t * split_string,int * number_of_segments,libcerror_error_t ** error)335 int libcsplit_narrow_split_string_get_number_of_segments(
336 libcsplit_narrow_split_string_t *split_string,
337 int *number_of_segments,
338 libcerror_error_t **error )
339 {
340 libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
341 static char *function = "libcsplit_narrow_split_string_get_number_of_segments";
342
343 if( split_string == NULL )
344 {
345 libcerror_error_set(
346 error,
347 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
348 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
349 "%s: invalid split string.",
350 function );
351
352 return( -1 );
353 }
354 internal_split_string = (libcsplit_internal_narrow_split_string_t *) split_string;
355
356 if( number_of_segments == NULL )
357 {
358 libcerror_error_set(
359 error,
360 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
362 "%s: invalid number of segments.",
363 function );
364
365 return( -1 );
366 }
367 *number_of_segments = internal_split_string->number_of_segments;
368
369 return( 1 );
370 }
371
372 /* Retrieves a specific segment
373 * Returns 1 if successful or -1 on error
374 */
libcsplit_narrow_split_string_get_segment_by_index(libcsplit_narrow_split_string_t * split_string,int segment_index,char ** string_segment,size_t * string_segment_size,libcerror_error_t ** error)375 int libcsplit_narrow_split_string_get_segment_by_index(
376 libcsplit_narrow_split_string_t *split_string,
377 int segment_index,
378 char **string_segment,
379 size_t *string_segment_size,
380 libcerror_error_t **error )
381 {
382 libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
383 static char *function = "libcsplit_narrow_split_string_get_segment_by_index";
384
385 if( split_string == NULL )
386 {
387 libcerror_error_set(
388 error,
389 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
390 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
391 "%s: invalid split string.",
392 function );
393
394 return( -1 );
395 }
396 internal_split_string = (libcsplit_internal_narrow_split_string_t *) split_string;
397
398 if( ( segment_index < 0 )
399 || ( segment_index >= internal_split_string->number_of_segments ) )
400 {
401 libcerror_error_set(
402 error,
403 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
404 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
405 "%s: invalid segment index value out of bounds.",
406 function );
407
408 return( -1 );
409 }
410 if( string_segment == NULL )
411 {
412 libcerror_error_set(
413 error,
414 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
415 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
416 "%s: invalid string segment.",
417 function );
418
419 return( -1 );
420 }
421 if( string_segment_size == NULL )
422 {
423 libcerror_error_set(
424 error,
425 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
426 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
427 "%s: invalid string segment size.",
428 function );
429
430 return( -1 );
431 }
432 *string_segment = internal_split_string->segments[ segment_index ];
433 *string_segment_size = internal_split_string->segment_sizes[ segment_index ];
434
435 return( 1 );
436 }
437
438 /* Sets a specific segment
439 * Returns 1 if successful or -1 on error
440 */
libcsplit_narrow_split_string_set_segment_by_index(libcsplit_narrow_split_string_t * split_string,int segment_index,char * string_segment,size_t string_segment_size,libcerror_error_t ** error)441 int libcsplit_narrow_split_string_set_segment_by_index(
442 libcsplit_narrow_split_string_t *split_string,
443 int segment_index,
444 char *string_segment,
445 size_t string_segment_size,
446 libcerror_error_t **error )
447 {
448 libcsplit_internal_narrow_split_string_t *internal_split_string = NULL;
449 static char *function = "libcsplit_narrow_split_string_set_segment_by_index";
450 size_t string_segment_offset = 0;
451
452 if( split_string == NULL )
453 {
454 libcerror_error_set(
455 error,
456 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
457 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
458 "%s: invalid split string.",
459 function );
460
461 return( -1 );
462 }
463 internal_split_string = (libcsplit_internal_narrow_split_string_t *) split_string;
464
465 if( ( segment_index < 0 )
466 || ( segment_index >= internal_split_string->number_of_segments ) )
467 {
468 libcerror_error_set(
469 error,
470 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
471 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
472 "%s: invalid segment index value out of bounds.",
473 function );
474
475 return( -1 );
476 }
477 if( string_segment_size > (size_t) SSIZE_MAX )
478 {
479 libcerror_error_set(
480 error,
481 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
482 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
483 "%s: invalid string segment size value exceeds maximum.",
484 function );
485
486 return( -1 );
487 }
488 if( string_segment == NULL )
489 {
490 if( string_segment_size != 0 )
491 {
492 libcerror_error_set(
493 error,
494 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
495 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
496 "%s: invalid string segment size value out of bounds.",
497 function );
498
499 return( -1 );
500 }
501 }
502 else
503 {
504 if( string_segment < internal_split_string->string )
505 {
506 libcerror_error_set(
507 error,
508 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
509 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
510 "%s: invalid string segment value out of bounds.",
511 function );
512
513 return( -1 );
514 }
515 string_segment_offset = (size_t) ( string_segment - internal_split_string->string );
516
517 if( string_segment_offset >= internal_split_string->string_size )
518 {
519 libcerror_error_set(
520 error,
521 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
522 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
523 "%s: invalid string segment value out of bounds.",
524 function );
525
526 return( -1 );
527 }
528 string_segment_offset += string_segment_size;
529
530 if( string_segment_offset > internal_split_string->string_size )
531 {
532 libcerror_error_set(
533 error,
534 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
535 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
536 "%s: invalid string segment value out of bounds.",
537 function );
538
539 return( -1 );
540 }
541 }
542 internal_split_string->segments[ segment_index ] = string_segment;
543 internal_split_string->segment_sizes[ segment_index ] = string_segment_size;
544
545 return( 1 );
546 }
547
548