• 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 <stdbool.h> /* bool */
17 #include <stddef.h> /* NULL */
18 #include <stdlib.h> /* malloc */
19 
20 #include "hilog/log_c.h"
21 #include "pm_ptr_util.h"
22 #include "pm_log_c.h"
23 #include "purgeable_mem_builder_c.h"
24 
25 #undef LOG_TAG
26 #define LOG_TAG "PurgeableMemC: Builder"
27 
28 /* purgeable mem builder */
29 struct PurgMemBuilder {
30     struct PurgMemBuilder *nextBuilder;
31     PurgMemBuilderFunc Build;
32     void *param;
33     const char *name;
34 };
35 
36 /* append a guest builder @newcomer to @head */
37 static void AppendBuilder(struct PurgMemBuilder *head, struct PurgMemBuilder *newcomer);
38 
PurgMemBuilderCreate(PurgMemBuilderFunc func,void * param,const char * name)39 struct PurgMemBuilder *PurgMemBuilderCreate(PurgMemBuilderFunc func, void *param, const char *name)
40 {
41     IF_NULL_LOG_ACTION(func, "func is NULL", return NULL);
42 
43     struct PurgMemBuilder *builder = NULL;
44     builder = (struct PurgMemBuilder *)malloc(sizeof(struct PurgMemBuilder));
45     if (!builder) {
46         PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: malloc struct PurgMemBuilder failed", __func__);
47         return NULL;
48     }
49     builder->Build = func;
50     builder->nextBuilder = NULL;
51     builder->param = param;
52     builder->name = name;
53     return builder;
54 }
55 
PurgMemBuilderDestroy(struct PurgMemBuilder * builder)56 bool PurgMemBuilderDestroy(struct PurgMemBuilder *builder)
57 {
58     IF_NULL_LOG_ACTION(builder, "builder is NULL", return true);
59 
60     struct PurgMemBuilder *curr = builder;
61     struct PurgMemBuilder *next = NULL;
62     while (curr) {
63         next = curr->nextBuilder;
64         free(curr);
65         curr = next;
66     }
67     /* set input para NULL to avoid UAF */
68     builder = NULL;
69     return true;
70 }
71 
PurgMemBuilderAppendFunc(struct PurgMemBuilder * builder,PurgMemBuilderFunc func,void * param,const char * name)72 bool PurgMemBuilderAppendFunc(struct PurgMemBuilder *builder, PurgMemBuilderFunc func, void *param,
73                               const char *name)
74 {
75     IF_NULL_LOG_ACTION(builder, "input builder is NULL", return false);
76     IF_NULL_LOG_ACTION(func, "input func is NULL", return false);
77 
78     struct PurgMemBuilder *newcomer = PurgMemBuilderCreate(func, param, name);
79     IF_NULL_LOG_ACTION(newcomer, "create new builder failed", return false);
80 
81     AppendBuilder(builder, newcomer);
82     return true;
83 }
84 
85 /* build @data content from @builder */
PurgMemBuilderBuildAll(struct PurgMemBuilder * builder,void * data,size_t size)86 bool PurgMemBuilderBuildAll(struct PurgMemBuilder *builder, void *data, size_t size)
87 {
88     if (!(builder->Build)) {
89         PM_HILOG_ERROR_C(LOG_CORE, "builder has no Build(), %{public}s", builder->name);
90         return true;
91     }
92     if (!(builder->Build(data, size, builder->param))) {
93         PM_HILOG_ERROR_C(LOG_CORE, "build data failed, name %{public}s", builder->name ?: "NULL");
94         return false;
95     }
96     if (!(builder->nextBuilder)) {
97         return true;
98     }
99     return PurgMemBuilderBuildAll(builder->nextBuilder, data, size);
100 }
101 
PurgMemBuilderAppendBuilder(struct PurgMemBuilder * builder,struct PurgMemBuilder * newcomer)102 bool PurgMemBuilderAppendBuilder(struct PurgMemBuilder *builder, struct PurgMemBuilder *newcomer)
103 {
104     IF_NULL_LOG_ACTION(builder, "input builder is NULL", return false);
105     IF_NULL_LOG_ACTION(newcomer, "input newcomer is NULL", return false);
106 
107     AppendBuilder(builder, newcomer);
108     return true;
109 }
110 
111 /* append a guest builder @newcomer to @head */
AppendBuilder(struct PurgMemBuilder * head,struct PurgMemBuilder * newcomer)112 static void AppendBuilder(struct PurgMemBuilder *head, struct PurgMemBuilder *newcomer)
113 {
114     if (!head->nextBuilder) {
115         head->nextBuilder = newcomer;
116         return;
117     }
118     return AppendBuilder(head->nextBuilder, newcomer);
119 }
120