Apply tizen coding rule
[platform/framework/web/download-provider.git] / agent / download-agent-encoding.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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 <string.h>
18 #include <stdlib.h>
19 #include "glib.h"
20 #include <curl/curl.h>
21
22 #include "download-agent-debug.h"
23 #include "download-agent-encoding.h"
24
25 da_ret_t _parsing_base64_encoded_str(const char *in_encoded_str,
26         char **out_charset_type,
27         char *out_encoding_type,
28         char **out_raw_encoded_str);
29
30 da_bool_t is_base64_encoded_word(const char *in_str)
31 {
32         const char *haystack = DA_NULL;
33         char first_needle[8] = {0,};
34         char second_needle[8] = {0,};
35         char *found_str = DA_NULL;
36
37         if (!in_str) {
38                 DA_LOGE("input string is NULL");
39                 return DA_FALSE;
40         }
41
42         haystack = in_str;
43         if (haystack[0] == '"') {
44                 snprintf(first_needle, sizeof(first_needle), "%s", "\"=?");     // "=?
45                 snprintf(second_needle, sizeof(second_needle), "%s", "?=\"");   // ?="
46         } else {
47                 snprintf(first_needle, sizeof(first_needle), "%s", "=?");       // =?
48                 snprintf(second_needle, sizeof(second_needle), "%s", "?=");     // ?=
49         }
50
51         found_str = strstr(haystack, first_needle);
52         if (found_str) {
53                 if (found_str == haystack) {
54                         haystack = haystack + strlen(haystack) - strlen(second_needle);
55                         if (!strcmp(haystack, second_needle))
56                                 return DA_TRUE;
57                 }
58         }
59         return DA_FALSE;
60 }
61
62 da_ret_t decode_base64_encoded_str(const char *in_encoded_str,
63         char **out_decoded_ascii_str)
64 {
65         da_ret_t ret = DA_RESULT_OK;
66         const char *org_str = DA_NULL;
67         char *charset_type = NULL;
68         char encoding_type = '\0';
69         char *raw_encoded_str = NULL;
70         char *decoded_str = NULL;
71         const gchar *g_encoded_text = NULL;
72         guchar *g_decoded_text = NULL;
73         gsize g_decoded_text_len = 0;
74
75         DA_SECURE_LOGD("input str = [%s]", in_encoded_str);
76
77         org_str = in_encoded_str;
78         if (!org_str) {
79                 DA_LOGE("Input string is NULL");
80                 ret = DA_ERR_INVALID_ARGUMENT;
81                 goto ERR;
82         }
83
84         ret = _parsing_base64_encoded_str(org_str, &charset_type,
85                 &encoding_type, &raw_encoded_str);
86         if (ret != DA_RESULT_OK)
87                 goto ERR;
88
89         if (encoding_type != 'B') {
90                 DA_LOGE("Encoded Word is not encoded with Base64, but %c. We can only handle Base64.", encoding_type);
91                 ret = DA_ERR_INVALID_ARGUMENT;
92                 goto ERR;
93         }
94
95         /*
96          * on glib/gtype.h
97          * typedef char   gchar;
98          * typedef unsigned char   guchar;
99          *
100          */
101         g_encoded_text = (const gchar*)raw_encoded_str;
102         g_decoded_text = g_base64_decode(g_encoded_text, &g_decoded_text_len);
103
104         if (g_decoded_text) {
105                 DA_SECURE_LOGD("g_decoded_text = [%s]", g_decoded_text);
106                 decoded_str = (char*)calloc(1, g_decoded_text_len+1);
107                 if (!decoded_str) {
108                         DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
109                         ret = DA_ERR_FAIL_TO_MEMALLOC;
110                         goto ERR;
111                 } else {
112                         memcpy(decoded_str, g_decoded_text, g_decoded_text_len);
113                 }
114         }
115         DA_SECURE_LOGD("decoded_str = [%s]", decoded_str);
116
117 ERR:
118         *out_decoded_ascii_str = decoded_str;
119         if (charset_type) {
120                 free(charset_type);
121                 charset_type = NULL;
122         }
123         if (raw_encoded_str) {
124                 free(raw_encoded_str);
125                 raw_encoded_str = NULL;
126         }
127         if (g_decoded_text)
128                 g_free(g_decoded_text);
129         return ret;
130 }
131
132 da_ret_t _parsing_base64_encoded_str(const char *in_encoded_str,
133         char **out_charset_type,
134         char *out_encoding_type,
135         char **out_raw_encoded_str)
136 {
137         da_ret_t ret = DA_RESULT_OK;
138         const char *org_str = DA_NULL;  // e.g. =?UTF-8?B?7Jew7JWE7JmA7IKs7J6QLmpwZw==?=
139         char *charset_type = NULL;              // e.g. UTF-8
140         char encoding_type = '\0';              // e.g. B (means Base64)
141         char *raw_encoded_str = NULL;   // e.g. 7Jew7JWE7JmA7IKs7J6QLmpwZw==
142         char *haystack = DA_NULL;
143         char needle[8] = {0,};
144         char *wanted_str = DA_NULL;
145         int wanted_str_len = 0;
146         char *wanted_str_start = DA_NULL;
147         char *wanted_str_end = DA_NULL;
148
149         org_str = in_encoded_str;
150         if (!org_str) {
151                 DA_LOGE("Input string is NULL");
152                 ret = DA_ERR_INVALID_ARGUMENT;
153                 goto ERR;
154         }
155
156         // strip "=?"
157         haystack = (char*)org_str;
158         snprintf(needle, sizeof(needle), "=?");
159         wanted_str_end = strstr(haystack, needle);
160         if (!wanted_str_end) {
161                 DA_LOGE("DA_ERR_INVALID_ARGUMENT");
162                 ret = DA_ERR_INVALID_ARGUMENT;
163                 goto ERR;
164         } else {
165                 wanted_str = wanted_str_end + strlen(needle);
166         }
167
168         // for charset
169         haystack = wanted_str_start = wanted_str;
170         needle[0] = '?';
171         wanted_str_end = strchr(haystack, needle[0]);
172         if (!wanted_str_end) {
173                 DA_LOGE("DA_ERR_INVALID_ARGUMENT");
174                 ret = DA_ERR_INVALID_ARGUMENT;
175                 goto ERR;
176         } else {
177                 wanted_str_len = wanted_str_end - wanted_str_start + 1;
178                 wanted_str = (char*)calloc(1, wanted_str_len+1);
179                 if (!wanted_str) {
180                         DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
181                         ret = DA_ERR_FAIL_TO_MEMALLOC;
182                         goto ERR;
183                 } else {
184                         snprintf(wanted_str, wanted_str_len+1, "%s", wanted_str_start);
185                         charset_type = wanted_str;
186                         wanted_str = DA_NULL;
187                 }
188
189                 DA_LOGV("charset [%s]", charset_type);
190         }
191
192         // for encoding
193         encoding_type = *(++wanted_str_end);
194         DA_LOGV("encoding [%c]", encoding_type);
195
196         // for raw encoded str
197         haystack = wanted_str_start = wanted_str_end + 1;
198         snprintf(needle, sizeof(needle), "?=");
199         wanted_str_end = strstr(haystack, needle);
200         if (!wanted_str_end) {
201                 DA_LOGE("DA_ERR_INVALID_ARGUMENT");
202                 ret = DA_ERR_INVALID_ARGUMENT;
203                 goto ERR;
204         } else {
205                 wanted_str_len = wanted_str_end - wanted_str_start + 1;
206                 wanted_str = (char*)calloc(1, wanted_str_len+1);
207                 if (!wanted_str) {
208                         DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
209                         ret = DA_ERR_FAIL_TO_MEMALLOC;
210                         goto ERR;
211                 } else {
212                         snprintf(wanted_str, wanted_str_len+1, "%s", wanted_str_start);
213                         raw_encoded_str = wanted_str;
214                         wanted_str = NULL;
215                 }
216
217                 DA_SECURE_LOGD("raw encoded str [%s]", raw_encoded_str);
218         }
219 ERR:
220         if (ret != DA_RESULT_OK) {
221                 if (charset_type) {
222                         free(charset_type);
223                         charset_type = NULL;
224                 }
225         }
226         *out_charset_type = charset_type;
227         *out_encoding_type = encoding_type;
228         *out_raw_encoded_str = raw_encoded_str;
229         return ret;
230 }