1 /**
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <android/IMediaExtractor.h>
18 #include <dlfcn.h>
19
20 #include "../includes/common.h"
21 #include "../includes/memutils.h"
22
23 #if _32_BIT
24 #define LIBNAME "/system/lib/extractors/libmidiextractor.so"
25 #define LIBNAME_APEX "/apex/com.android.media/lib/extractors/libmidiextractor.so"
26 #elif _64_BIT
27 #define LIBNAME "/system/lib64/extractors/libmidiextractor.so"
28 #define LIBNAME_APEX "/apex/com.android.media/lib64/extractors/libmidiextractor.so"
29 #endif
30
31 char enable_selective_overload = ENABLE_NONE;
32
33 using namespace android;
34
35 bool isTestInProgress = false;
36
37 struct sigaction new_action, old_action;
38
39 int fdData, fdInfo;
40
41 void *libHandle = nullptr;
42
sigsegv_handler(int signum,siginfo_t * info,void * context)43 void sigsegv_handler(int signum, siginfo_t *info, void *context) {
44 if (isTestInProgress && info->si_signo == SIGSEGV) {
45 (*old_action.sa_sigaction)(signum, info, context);
46 return;
47 }
48 _exit(EXIT_FAILURE);
49 }
50
51 class XMFDataSource : public DataSource {
52 public:
53 int mFdData;
54 int mFdInfo;
XMFDataSource(int fdData,int fdInfo)55 XMFDataSource(int fdData, int fdInfo) {
56 mFdData = fdData;
57 mFdInfo = fdInfo;
58 }
59
60 ~XMFDataSource() = default;
61
readAt(off64_t offset,void * data,size_t size)62 virtual ssize_t readAt(off64_t offset __attribute__((unused)), void *data, size_t size) {
63 uint32_t infoOffset, infoSize;
64 read(mFdInfo, &infoSize, sizeof(int32_t));
65 read(mFdInfo, &infoOffset, sizeof(int32_t));
66 lseek(mFdData, infoOffset, SEEK_SET);
67 read(mFdData, data, infoSize);
68 return size;
69 }
70
getSize(off64_t * size)71 virtual status_t getSize(off64_t *size) {
72 *size = 0x10000;
73 return 0;
74 }
initCheck() const75 virtual status_t initCheck() const { return 0; }
76 };
77
close_resources()78 void close_resources() {
79 if (fdData >= 0) {
80 ::close(fdData);
81 }
82 if (fdInfo >= 0) {
83 ::close(fdInfo);
84 }
85 if (libHandle) {
86 dlclose(libHandle);
87 }
88 }
89
main(int argc,char ** argv)90 int main(int argc, char **argv) {
91 atexit(close_resources);
92
93 sigemptyset(&new_action.sa_mask);
94 new_action.sa_flags = SA_SIGINFO;
95 new_action.sa_sigaction = sigsegv_handler;
96 sigaction(SIGSEGV, &new_action, &old_action);
97
98 FAIL_CHECK(argc == 3);
99 libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
100 if (!libHandle) {
101 libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
102 FAIL_CHECK(libHandle);
103 }
104
105 GetExtractorDef getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
106 FAIL_CHECK(getDef);
107
108 fdData = open(argv[1], O_RDONLY);
109 FAIL_CHECK(fdData >= 0);
110
111 fdInfo = open(argv[2], O_RDONLY);
112 FAIL_CHECK(fdInfo >= 0);
113
114 sp<DataSource> dataSource = (sp<DataSource>)new XMFDataSource(fdData, fdInfo);
115 FAIL_CHECK(dataSource);
116
117 enable_selective_overload = ENABLE_ALL;
118 isTestInProgress = true;
119
120 void *meta = nullptr;
121 FreeMetaFunc freeMeta = nullptr;
122 float confidence = 0.0f;
123 if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
124 getDef().u.v2.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
125 } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
126 getDef().u.v3.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
127 }
128
129 isTestInProgress = false;
130 enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
131 return EXIT_SUCCESS;
132 }
133