• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "cm_param.h"
17 
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 
22 #include "cm_log.h"
23 #include "cm_mem.h"
24 #include "cm_type_inner.h"
25 
GetTagType(enum CmTag tag)26 enum CmTagType GetTagType(enum CmTag tag)
27 {
28     return (enum CmTagType)((uint32_t)tag & CM_TAG_TYPE_MASK);
29 }
30 
CmInitParamSet(struct CmParamSet ** paramSet)31 int32_t CmInitParamSet(struct CmParamSet **paramSet)
32 {
33     if (paramSet == NULL) {
34         CM_LOG_E("invalid init params!");
35         return CMR_ERROR_INVALID_ARGUMENT;
36     }
37 
38     *paramSet = (struct CmParamSet *)CmMalloc(CM_DEFAULT_PARAM_SET_SIZE);
39     if (*paramSet == NULL) {
40         CM_LOG_E("malloc init param set failed!");
41         return CMR_ERROR_MALLOC_FAIL;
42     }
43     (*paramSet)->paramsCnt = 0;
44     (*paramSet)->paramSetSize = sizeof(struct CmParamSet);
45     return CM_SUCCESS;
46 }
47 
CmCheckParamSet(const struct CmParamSet * paramSet,uint32_t size)48 static int32_t CmCheckParamSet(const struct CmParamSet *paramSet, uint32_t size)
49 {
50     if (paramSet == NULL) {
51         return CMR_ERROR_NULL_POINTER;
52     }
53 
54     if ((size < sizeof(struct CmParamSet)) || (size > CM_PARAM_SET_MAX_SIZE) ||
55         (paramSet->paramSetSize != size) ||
56         (paramSet->paramsCnt > ((size - sizeof(struct CmParamSet)) / sizeof(struct CmParam)))) {
57         CM_LOG_E("invalid param set!");
58         return CMR_ERROR_INVALID_ARGUMENT;
59     }
60     return CM_SUCCESS;
61 }
62 
CmFreshParamSet(struct CmParamSet * paramSet,bool isCopy)63 static int32_t CmFreshParamSet(struct CmParamSet *paramSet, bool isCopy)
64 {
65     if (paramSet == NULL) {
66         CM_LOG_E("invalid NULL paramSet");
67         return CMR_ERROR_NULL_POINTER;
68     }
69     int32_t ret = CmCheckParamSet(paramSet, paramSet->paramSetSize);
70     if (ret != CM_SUCCESS) {
71         CM_LOG_E("invalid fresh paramSet");
72         return ret;
73     }
74 
75     uint32_t size = paramSet->paramSetSize;
76     uint32_t offset = sizeof(struct CmParamSet) + sizeof(struct CmParam) * paramSet->paramsCnt;
77 
78     for (uint32_t i = 0; i < paramSet->paramsCnt; i++) {
79         if (offset > size) {
80             CM_LOG_E("invalid param set offset!");
81             return CMR_ERROR_INVALID_ARGUMENT;
82         }
83         if (GetTagType(paramSet->params[i].tag) == CM_TAG_TYPE_BYTES) {
84             if (CmIsAdditionOverflow(offset, paramSet->params[i].blob.size)) {
85                 CM_LOG_E("blob size overflow!");
86                 return CMR_ERROR_INVALID_ARGUMENT;
87             }
88 
89             if (isCopy && (memcpy_s((uint8_t *)paramSet + offset, size - offset,
90                 paramSet->params[i].blob.data, paramSet->params[i].blob.size) != EOK)) {
91                 CM_LOG_E("copy param blob failed!");
92                 return CMR_ERROR_INVALID_OPERATION;
93             }
94             paramSet->params[i].blob.data = (uint8_t *)paramSet + offset;
95             offset += paramSet->params[i].blob.size;
96         }
97     }
98 
99     if (paramSet->paramSetSize != offset) {
100         CM_LOG_E("invalid param set size!");
101         return CMR_ERROR_INVALID_ARGUMENT;
102     }
103     return CM_SUCCESS;
104 }
105 
BuildParamSet(struct CmParamSet ** paramSet)106 static int32_t BuildParamSet(struct CmParamSet **paramSet)
107 {
108     struct CmParamSet *freshParamSet = *paramSet;
109     uint32_t size = freshParamSet->paramSetSize;
110     uint32_t offset = sizeof(struct CmParamSet) + sizeof(struct CmParam) * freshParamSet->paramsCnt;
111 
112     if (size > CM_DEFAULT_PARAM_SET_SIZE) {
113         freshParamSet = (struct CmParamSet *)CmMalloc(size);
114         if (freshParamSet == NULL) {
115             CM_LOG_E("malloc params failed!");
116             return CMR_ERROR_MALLOC_FAIL;
117         }
118         if (memcpy_s(freshParamSet, size, *paramSet, offset) != EOK) {
119             CM_FREE_PTR(freshParamSet);
120             CM_LOG_E("copy params failed!");
121             return CMR_ERROR_INVALID_OPERATION;
122         }
123         CM_FREE_PTR(*paramSet);
124         *paramSet = freshParamSet;
125     }
126 
127     return CmFreshParamSet(freshParamSet, true);
128 }
129 
CmBuildParamSet(struct CmParamSet ** paramSet)130 int32_t CmBuildParamSet(struct CmParamSet **paramSet)
131 {
132     if ((paramSet == NULL) || (*paramSet == NULL)) {
133         return CMR_ERROR_NULL_POINTER;
134     }
135 
136     int ret = CmCheckParamSet(*paramSet, (*paramSet)->paramSetSize);
137     if (ret != CM_SUCCESS) {
138         CM_LOG_E("invalid build params!");
139         return ret;
140     }
141 
142     return BuildParamSet(paramSet);
143 }
144 
CmFreeParamSet(struct CmParamSet ** paramSet)145 void CmFreeParamSet(struct CmParamSet **paramSet)
146 {
147     if (paramSet == NULL) {
148         CM_LOG_E("invalid free paramset!");
149         return;
150     }
151     CM_FREE_PTR(*paramSet);
152 }
153 
CheckBeforeAddParams(const struct CmParamSet * paramSet,const struct CmParam * params,uint32_t paramCnt)154 static int32_t CheckBeforeAddParams(const struct CmParamSet *paramSet, const struct CmParam *params,
155     uint32_t paramCnt)
156 {
157     if ((params == NULL) || (paramSet == NULL) || (paramSet->paramSetSize > CM_PARAM_SET_MAX_SIZE) ||
158         (paramCnt > CM_DEFAULT_PARAM_CNT) || ((paramSet->paramsCnt + paramCnt) > CM_DEFAULT_PARAM_CNT)) {
159         CM_LOG_E("invalid params or paramset!");
160         return CMR_ERROR_INVALID_ARGUMENT;
161     }
162 
163     for (uint32_t i = 0; i < paramCnt; i++) {
164         if ((GetTagType(params[i].tag) == CM_TAG_TYPE_BYTES) &&
165             (params[i].blob.data == NULL)) {
166             CM_LOG_E("invalid blob param!");
167             return CMR_ERROR_INVALID_ARGUMENT;
168         }
169     }
170     return CM_SUCCESS;
171 }
172 
CmAddParams(struct CmParamSet * paramSet,const struct CmParam * params,uint32_t paramCnt)173 int32_t CmAddParams(struct CmParamSet *paramSet, const struct CmParam *params, uint32_t paramCnt)
174 {
175     int32_t ret = CheckBeforeAddParams(paramSet, params, paramCnt);
176     if (ret != CM_SUCCESS) {
177         return ret;
178     }
179 
180     for (uint32_t i = 0; i < paramCnt; i++) {
181         paramSet->paramSetSize += sizeof(struct CmParam);
182         if (GetTagType(params[i].tag) == CM_TAG_TYPE_BYTES) {
183             if (CmIsAdditionOverflow(paramSet->paramSetSize, params[i].blob.size)) {
184                 CM_LOG_E("params size overflow!");
185                 paramSet->paramSetSize -= sizeof(struct CmParam);
186                 return CMR_ERROR_INVALID_ARGUMENT;
187             }
188             paramSet->paramSetSize += params[i].blob.size;
189         }
190         (void)memcpy_s(&paramSet->params[paramSet->paramsCnt++], sizeof(struct CmParam), &params[i],
191             sizeof(struct CmParam));
192     }
193     return CM_SUCCESS;
194 }
195