1 /*
2  * Library support functions test program
3  *
4  * Copyright (C) 2012-2021, 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 <file_stream.h>
24 #include <narrow_string.h>
25 #include <system_string.h>
26 #include <types.h>
27 #include <wide_string.h>
28 
29 #if defined( HAVE_STDLIB_H ) || defined( WINAPI )
30 #include <stdlib.h>
31 #endif
32 
33 #include "modi_test_functions.h"
34 #include "modi_test_getopt.h"
35 #include "modi_test_libbfio.h"
36 #include "modi_test_libcdirectory.h"
37 #include "modi_test_libcerror.h"
38 #include "modi_test_libcpath.h"
39 #include "modi_test_libmodi.h"
40 #include "modi_test_macros.h"
41 #include "modi_test_memory.h"
42 #include "modi_test_unused.h"
43 
44 #if !defined( LIBMODI_HAVE_BFIO )
45 
46 LIBMODI_EXTERN \
47 int libmodi_check_file_signature_file_io_handle(
48      libbfio_handle_t *file_io_handle,
49      libcerror_error_t **error );
50 
51 #endif /* !defined( LIBMODI_HAVE_BFIO ) */
52 
53 /* Tests the libmodi_get_version function
54  * Returns 1 if successful or 0 if not
55  */
modi_test_get_version(void)56 int modi_test_get_version(
57      void )
58 {
59 	const char *version_string = NULL;
60 	int result                 = 0;
61 
62 	version_string = libmodi_get_version();
63 
64 	result = narrow_string_compare(
65 	          version_string,
66 	          LIBMODI_VERSION_STRING,
67 	          9 );
68 
69 	MODI_TEST_ASSERT_EQUAL_INT(
70 	 "result",
71 	 result,
72 	 0 );
73 
74 	return( 1 );
75 
76 on_error:
77 	return( 0 );
78 }
79 
80 /* Tests the libmodi_get_access_flags_read function
81  * Returns 1 if successful or 0 if not
82  */
modi_test_get_access_flags_read(void)83 int modi_test_get_access_flags_read(
84      void )
85 {
86 	int access_flags = 0;
87 
88 	access_flags = libmodi_get_access_flags_read();
89 
90 	MODI_TEST_ASSERT_EQUAL_INT(
91 	 "access_flags",
92 	 access_flags,
93 	 LIBMODI_ACCESS_FLAG_READ );
94 
95 	return( 1 );
96 
97 on_error:
98 	return( 0 );
99 }
100 
101 /* Tests the libmodi_get_codepage function
102  * Returns 1 if successful or 0 if not
103  */
modi_test_get_codepage(void)104 int modi_test_get_codepage(
105      void )
106 {
107 	libcerror_error_t *error = NULL;
108 	int codepage             = 0;
109 	int result               = 0;
110 
111 	result = libmodi_get_codepage(
112 	          &codepage,
113 	          &error );
114 
115 	MODI_TEST_ASSERT_EQUAL_INT(
116 	 "result",
117 	 result,
118 	 1 );
119 
120 	MODI_TEST_ASSERT_IS_NULL(
121 	 "error",
122 	 error );
123 
124 	/* Test error cases
125 	 */
126 	result = libmodi_get_codepage(
127 	          NULL,
128 	          &error );
129 
130 	MODI_TEST_ASSERT_EQUAL_INT(
131 	 "result",
132 	 result,
133 	 -1 );
134 
135 	MODI_TEST_ASSERT_IS_NOT_NULL(
136 	 "error",
137 	 error );
138 
139 	libcerror_error_free(
140 	 &error );
141 
142 	return( 1 );
143 
144 on_error:
145 	if( error != NULL )
146 	{
147 		libcerror_error_free(
148 		 &error );
149 	}
150 	return( 0 );
151 }
152 
153 /* Tests the libmodi_set_codepage function
154  * Returns 1 if successful or 0 if not
155  */
modi_test_set_codepage(void)156 int modi_test_set_codepage(
157      void )
158 {
159 	libcerror_error_t *error = NULL;
160 	int result               = 0;
161 
162 	result = libmodi_set_codepage(
163 	          0,
164 	          &error );
165 
166 	MODI_TEST_ASSERT_EQUAL_INT(
167 	 "result",
168 	 result,
169 	 1 );
170 
171 	MODI_TEST_ASSERT_IS_NULL(
172 	 "error",
173 	 error );
174 
175 	/* Test error cases
176 	 */
177 	result = libmodi_set_codepage(
178 	          -1,
179 	          &error );
180 
181 	MODI_TEST_ASSERT_EQUAL_INT(
182 	 "result",
183 	 result,
184 	 -1 );
185 
186 	MODI_TEST_ASSERT_IS_NOT_NULL(
187 	 "error",
188 	 error );
189 
190 	libcerror_error_free(
191 	 &error );
192 
193 	return( 1 );
194 
195 on_error:
196 	if( error != NULL )
197 	{
198 		libcerror_error_free(
199 		 &error );
200 	}
201 	return( 0 );
202 }
203 
204 /* Tests the libmodi_check_file_signature function
205  * Returns 1 if successful or 0 if not
206  */
modi_test_check_file_signature(const system_character_t * source)207 int modi_test_check_file_signature(
208      const system_character_t *source )
209 {
210 	char narrow_source[ 256 ];
211 
212 	libcerror_error_t *error = NULL;
213 	int result               = 0;
214 
215 	if( source != NULL )
216 	{
217 		/* Initialize test
218 		 */
219 		result = modi_test_get_narrow_source(
220 		          source,
221 		          narrow_source,
222 		          256,
223 		          &error );
224 
225 		MODI_TEST_ASSERT_EQUAL_INT(
226 		 "result",
227 		 result,
228 		 1 );
229 
230 		MODI_TEST_ASSERT_IS_NULL(
231 		 "error",
232 		 error );
233 
234 		/* Test check file signature
235 		 */
236 		result = libmodi_check_file_signature(
237 		          narrow_source,
238 		          &error );
239 
240 		/* Note that libmodi_check_file_signature will return 0 for a "raw" modi file
241 		 */
242 		MODI_TEST_ASSERT_NOT_EQUAL_INT(
243 		 "result",
244 		 result,
245 		 -1 );
246 
247 		MODI_TEST_ASSERT_IS_NULL(
248 		 "error",
249 		 error );
250 	}
251 	/* Test error cases
252 	 */
253 	result = libmodi_check_file_signature(
254 	          NULL,
255 	          &error );
256 
257 	MODI_TEST_ASSERT_EQUAL_INT(
258 	 "result",
259 	 result,
260 	 -1 );
261 
262 	MODI_TEST_ASSERT_IS_NOT_NULL(
263 	 "error",
264 	 error );
265 
266 	libcerror_error_free(
267 	 &error );
268 
269 	result = libmodi_check_file_signature(
270 	          "",
271 	          &error );
272 
273 	MODI_TEST_ASSERT_EQUAL_INT(
274 	 "result",
275 	 result,
276 	 -1 );
277 
278 	MODI_TEST_ASSERT_IS_NOT_NULL(
279 	 "error",
280 	 error );
281 
282 	libcerror_error_free(
283 	 &error );
284 
285 	return( 1 );
286 
287 on_error:
288 	if( error != NULL )
289 	{
290 		libcerror_error_free(
291 		 &error );
292 	}
293 	return( 0 );
294 }
295 
296 #if defined( HAVE_WIDE_CHARACTER_TYPE )
297 
298 /* Tests the libmodi_check_file_signature_wide function
299  * Returns 1 if successful or 0 if not
300  */
modi_test_check_file_signature_wide(const system_character_t * source)301 int modi_test_check_file_signature_wide(
302      const system_character_t *source )
303 {
304 	wchar_t wide_source[ 256 ];
305 
306 	libcerror_error_t *error = NULL;
307 	int result               = 0;
308 
309 	if( source != NULL )
310 	{
311 		/* Initialize test
312 		 */
313 		result = modi_test_get_wide_source(
314 		          source,
315 		          wide_source,
316 		          256,
317 		          &error );
318 
319 		MODI_TEST_ASSERT_EQUAL_INT(
320 		 "result",
321 		 result,
322 		 1 );
323 
324 		MODI_TEST_ASSERT_IS_NULL(
325 		 "error",
326 		 error );
327 
328 		/* Test check file signature
329 		 */
330 		result = libmodi_check_file_signature_wide(
331 		          wide_source,
332 		          &error );
333 
334 		MODI_TEST_ASSERT_EQUAL_INT(
335 		 "result",
336 		 result,
337 		 1 );
338 
339 		MODI_TEST_ASSERT_IS_NULL(
340 		 "error",
341 		 error );
342 	}
343 	/* Test error cases
344 	 */
345 	result = libmodi_check_file_signature_wide(
346 	          NULL,
347 	          &error );
348 
349 	MODI_TEST_ASSERT_EQUAL_INT(
350 	 "result",
351 	 result,
352 	 -1 );
353 
354 	MODI_TEST_ASSERT_IS_NOT_NULL(
355 	 "error",
356 	 error );
357 
358 	libcerror_error_free(
359 	 &error );
360 
361 	result = libmodi_check_file_signature_wide(
362 	          L"",
363 	          &error );
364 
365 	MODI_TEST_ASSERT_EQUAL_INT(
366 	 "result",
367 	 result,
368 	 -1 );
369 
370 	MODI_TEST_ASSERT_IS_NOT_NULL(
371 	 "error",
372 	 error );
373 
374 	libcerror_error_free(
375 	 &error );
376 
377 	return( 1 );
378 
379 on_error:
380 	if( error != NULL )
381 	{
382 		libcerror_error_free(
383 		 &error );
384 	}
385 	return( 0 );
386 }
387 
388 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
389 
390 /* Tests the libmodi_check_file_signature_file_io_handle function
391  * Returns 1 if successful or 0 if not
392  */
modi_test_check_file_signature_file_io_handle(const system_character_t * source)393 int modi_test_check_file_signature_file_io_handle(
394      const system_character_t *source )
395 {
396 	uint8_t empty_block[ 8192 ];
397 
398 	libbfio_handle_t *file_io_handle     = NULL;
399 	libcdirectory_directory_t *directory = NULL;
400 	libcerror_error_t *error             = NULL;
401 	system_character_t *info_plist_path  = NULL;
402 	void *memset_result                  = NULL;
403 	size_t info_plist_path_size          = 0;
404 	size_t source_length                 = 0;
405 	int is_directory                     = 0;
406 	int result                           = 0;
407 
408 	/* Initialize test
409 	 */
410 	memset_result = memory_set(
411 	                 empty_block,
412 	                 0,
413 	                 sizeof( uint8_t ) * 8192 );
414 
415 	MODI_TEST_ASSERT_IS_NOT_NULL(
416 	 "memset_result",
417 	 memset_result );
418 
419 	if( source != NULL )
420 	{
421 		/* Initialize test
422 		 */
423 		result = libcdirectory_directory_initialize(
424 		          &directory,
425 		          &error );
426 
427 		MODI_TEST_ASSERT_EQUAL_INT(
428 		 "result",
429 		 result,
430 		 1 );
431 
432 	        MODI_TEST_ASSERT_IS_NOT_NULL(
433 	         "directory",
434 	         directory );
435 
436 	        MODI_TEST_ASSERT_IS_NULL(
437 	         "error",
438 	         error );
439 
440 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
441 		is_directory = libcdirectory_directory_open_wide(
442 		                directory,
443 		                source,
444 		                NULL );
445 #else
446 		is_directory = libcdirectory_directory_open(
447 		                directory,
448 		                source,
449 		                NULL );
450 #endif
451 
452 		result = libcdirectory_directory_free(
453 		          &directory,
454 		          &error );
455 
456 		MODI_TEST_ASSERT_EQUAL_INT(
457 		 "result",
458 		 result,
459 		 1 );
460 
461 		MODI_TEST_ASSERT_IS_NULL(
462 	         "directory",
463 	         directory );
464 
465 	        MODI_TEST_ASSERT_IS_NULL(
466 	         "error",
467 	         error );
468 
469 		result = libbfio_file_initialize(
470 		          &file_io_handle,
471 		          &error );
472 
473 		MODI_TEST_ASSERT_EQUAL_INT(
474 		 "result",
475 		 result,
476 		 1 );
477 
478 		MODI_TEST_ASSERT_IS_NOT_NULL(
479 		 "file_io_handle",
480 		 file_io_handle );
481 
482 		MODI_TEST_ASSERT_IS_NULL(
483 		 "error",
484 		 error );
485 
486 		source_length = system_string_length(
487 		                 source );
488 
489 		if( is_directory == 1 )
490 		{
491 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
492 			result = libcpath_path_join_wide(
493 			          &info_plist_path,
494 			          &info_plist_path_size,
495 			          source,
496 			          source_length,
497 			          L"Info.plist",
498 			          10,
499 			          &error );
500 #else
501 			result = libcpath_path_join(
502 			          &info_plist_path,
503 			          &info_plist_path_size,
504 			          source,
505 			          source_length,
506 			          "Info.plist",
507 			          10,
508 			          &error );
509 #endif
510 
511 			MODI_TEST_ASSERT_EQUAL_INT(
512 			 "result",
513 			 result,
514 			 1 );
515 
516 		        MODI_TEST_ASSERT_IS_NOT_NULL(
517 		         "info_plist_path",
518 		         info_plist_path );
519 
520 		        MODI_TEST_ASSERT_IS_NULL(
521 		         "error",
522 		         error );
523 
524 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
525 			result = libbfio_file_set_name_wide(
526 			          file_io_handle,
527 			          info_plist_path,
528 			          info_plist_path_size - 1,
529 			          &error );
530 #else
531 			result = libbfio_file_set_name(
532 			          file_io_handle,
533 			          info_plist_path,
534 			          info_plist_path_size - 1,
535 			          &error );
536 #endif
537 		}
538 		else
539 		{
540 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
541 			result = libbfio_file_set_name_wide(
542 			          file_io_handle,
543 			          source,
544 			          source_length,
545 			          &error );
546 #else
547 			result = libbfio_file_set_name(
548 			          file_io_handle,
549 			          source,
550 			          source_length,
551 			          &error );
552 #endif
553 		}
554 		MODI_TEST_ASSERT_EQUAL_INT(
555 		 "result",
556 		 result,
557 		 1 );
558 
559 	        MODI_TEST_ASSERT_IS_NULL(
560 	         "error",
561 	         error );
562 
563 		if( info_plist_path != NULL )
564 		{
565 			memory_free(
566 			 info_plist_path );
567 
568 			info_plist_path = NULL;
569 		}
570 		result = libbfio_handle_open(
571 		          file_io_handle,
572 		          LIBBFIO_OPEN_READ,
573 		          &error );
574 
575 		MODI_TEST_ASSERT_EQUAL_INT(
576 		 "result",
577 		 result,
578 		 1 );
579 
580 		MODI_TEST_ASSERT_IS_NULL(
581 		 "error",
582 		 error );
583 
584 		/* Test check file signature
585 		 */
586 		result = libmodi_check_file_signature_file_io_handle(
587 		          file_io_handle,
588 		          &error );
589 
590 		/* Note that libmodi_check_file_signature_file_io_handle will return 0 for a "raw" modi file
591 		 */
592 		MODI_TEST_ASSERT_NOT_EQUAL_INT(
593 		 "result",
594 		 result,
595 		 -1 );
596 
597 		MODI_TEST_ASSERT_IS_NULL(
598 		 "error",
599 		 error );
600 	}
601 	/* Test error cases
602 	 */
603 	result = libmodi_check_file_signature_file_io_handle(
604 	          NULL,
605 	          &error );
606 
607 	MODI_TEST_ASSERT_EQUAL_INT(
608 	 "result",
609 	 result,
610 	 -1 );
611 
612 	MODI_TEST_ASSERT_IS_NOT_NULL(
613 	 "error",
614 	 error );
615 
616 	libcerror_error_free(
617 	 &error );
618 
619 	/* Clean up
620 	 */
621 	if( source != NULL )
622 	{
623 		result = libbfio_handle_close(
624 		          file_io_handle,
625 		          &error );
626 
627 		MODI_TEST_ASSERT_EQUAL_INT(
628 		 "result",
629 		 result,
630 		 0 );
631 
632 		MODI_TEST_ASSERT_IS_NULL(
633 		 "error",
634 		 error );
635 
636 		result = libbfio_handle_free(
637 		          &file_io_handle,
638 		          &error );
639 
640 		MODI_TEST_ASSERT_EQUAL_INT(
641 		 "result",
642 		 result,
643 		 1 );
644 
645 		MODI_TEST_ASSERT_IS_NULL(
646 		 "file_io_handle",
647 		 file_io_handle );
648 
649 		MODI_TEST_ASSERT_IS_NULL(
650 		 "error",
651 		 error );
652 	}
653 	/* Test check file signature with data too small
654 	 */
655 	result = modi_test_open_file_io_handle(
656 	          &file_io_handle,
657 	          empty_block,
658 	          sizeof( uint8_t ) * 1,
659 	          &error );
660 
661 	MODI_TEST_ASSERT_EQUAL_INT(
662 	 "result",
663 	 result,
664 	 1 );
665 
666 	MODI_TEST_ASSERT_IS_NOT_NULL(
667 	 "file_io_handle",
668 	 file_io_handle );
669 
670 	MODI_TEST_ASSERT_IS_NULL(
671 	 "error",
672 	 error );
673 
674 	result = libmodi_check_file_signature_file_io_handle(
675 	          file_io_handle,
676 	          &error );
677 
678 	MODI_TEST_ASSERT_EQUAL_INT(
679 	 "result",
680 	 result,
681 	 0 );
682 
683 	MODI_TEST_ASSERT_IS_NULL(
684 	 "error",
685 	 error );
686 
687 	libcerror_error_free(
688 	 &error );
689 
690 	result = modi_test_close_file_io_handle(
691 	          &file_io_handle,
692 	          &error );
693 
694 	MODI_TEST_ASSERT_EQUAL_INT(
695 	 "result",
696 	 result,
697 	 0 );
698 
699 	MODI_TEST_ASSERT_IS_NULL(
700 	 "error",
701 	 error );
702 
703 	/* Test check file signature with empty block
704 	 */
705 	result = modi_test_open_file_io_handle(
706 	          &file_io_handle,
707 	          empty_block,
708 	          sizeof( uint8_t ) * 8192,
709 	          &error );
710 
711 	MODI_TEST_ASSERT_EQUAL_INT(
712 	 "result",
713 	 result,
714 	 1 );
715 
716 	MODI_TEST_ASSERT_IS_NOT_NULL(
717 	 "file_io_handle",
718 	 file_io_handle );
719 
720 	MODI_TEST_ASSERT_IS_NULL(
721 	 "error",
722 	 error );
723 
724 	result = libmodi_check_file_signature_file_io_handle(
725 	          file_io_handle,
726 	          &error );
727 
728 	MODI_TEST_ASSERT_EQUAL_INT(
729 	 "result",
730 	 result,
731 	 0 );
732 
733 	MODI_TEST_ASSERT_IS_NULL(
734 	 "error",
735 	 error );
736 
737 	result = modi_test_close_file_io_handle(
738 	          &file_io_handle,
739 	          &error );
740 
741 	MODI_TEST_ASSERT_EQUAL_INT(
742 	 "result",
743 	 result,
744 	 0 );
745 
746 	MODI_TEST_ASSERT_IS_NULL(
747 	 "error",
748 	 error );
749 
750 	return( 1 );
751 
752 on_error:
753 	if( error != NULL )
754 	{
755 		libcerror_error_free(
756 		 &error );
757 	}
758 	if( file_io_handle != NULL )
759 	{
760 		libbfio_handle_free(
761 		 &file_io_handle,
762 		 NULL );
763 	}
764 	if( info_plist_path != NULL )
765 	{
766 		memory_free(
767 		 info_plist_path );
768 	}
769 	if( directory != NULL )
770 	{
771 		libcdirectory_directory_free(
772 		 &directory,
773 		 NULL );
774 	}
775 	return( 0 );
776 }
777 
778 /* The main program
779  */
780 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
wmain(int argc,wchar_t * const argv[])781 int wmain(
782      int argc,
783      wchar_t * const argv[] )
784 #else
785 int main(
786      int argc,
787      char * const argv[] )
788 #endif
789 {
790 	system_character_t *source = NULL;
791 	system_integer_t option    = 0;
792 
793 	while( ( option = modi_test_getopt(
794 	                   argc,
795 	                   argv,
796 	                   _SYSTEM_STRING( "" ) ) ) != (system_integer_t) -1 )
797 	{
798 		switch( option )
799 		{
800 			case (system_integer_t) '?':
801 			default:
802 				fprintf(
803 				 stderr,
804 				 "Invalid argument: %" PRIs_SYSTEM ".\n",
805 				 argv[ optind - 1 ] );
806 
807 				return( EXIT_FAILURE );
808 		}
809 	}
810 	if( optind < argc )
811 	{
812 		source = argv[ optind ];
813 	}
814 	MODI_TEST_RUN(
815 	 "libmodi_get_version",
816 	 modi_test_get_version );
817 
818 	MODI_TEST_RUN(
819 	 "libmodi_get_access_flags_read",
820 	 modi_test_get_access_flags_read );
821 
822 	MODI_TEST_RUN(
823 	 "libmodi_get_codepage",
824 	 modi_test_get_codepage );
825 
826 	MODI_TEST_RUN(
827 	 "libmodi_set_codepage",
828 	 modi_test_set_codepage );
829 
830 #if !defined( __BORLANDC__ ) || ( __BORLANDC__ >= 0x0560 )
831 
832 	MODI_TEST_RUN_WITH_ARGS(
833 	 "libmodi_check_file_signature",
834 	 modi_test_check_file_signature,
835 	 source );
836 
837 #if defined( HAVE_WIDE_CHARACTER_TYPE )
838 
839 	MODI_TEST_RUN_WITH_ARGS(
840 	 "libmodi_check_file_signature_wide",
841 	 modi_test_check_file_signature_wide,
842 	 source );
843 
844 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
845 
846 	MODI_TEST_RUN_WITH_ARGS(
847 	 "libmodi_check_file_signature_file_io_handle",
848 	 modi_test_check_file_signature_file_io_handle,
849 	 source );
850 
851 #endif /* !defined( __BORLANDC__ ) || ( __BORLANDC__ >= 0x0560 ) */
852 
853 	return( EXIT_SUCCESS );
854 
855 on_error:
856 	return( EXIT_FAILURE );
857 }
858 
859