Migrate to openssl3
[platform/core/security/drm-service-core-tizen.git] / tadcore / XMLParser / CXMLFile.cpp
1 /*
2  * Copyright (c) 2000-2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 <climits>
18
19 #include "CXMLFile.h"
20 #include "TADC_IF.h"
21 #include "TADC_ErrorCode.h"
22
23 #define _tcsstr strstr
24 #define _tcschr strchr
25
26 #define _MAX_NAME_LENGTH  4096
27 #define _MAX_VALUE_LENGTH 4096
28
29
30 #define _SKIP_WHITESPACE() \
31         while ((*m_pszXML == ' ') || \
32                         (*m_pszXML == '\n') || \
33                         (*m_pszXML == '\r') || \
34                         (*m_pszXML == 0x09)) m_pszXML++
35
36 typedef struct _tagESCAPE_CHARSET {
37         LPCTSTR         pszEscape;
38         TCHAR           chReplace;
39 } T_ESCAPE_CHARSET;
40
41 //////////////////////////////////////////////////////////////////////
42 // Construction/Destruction
43 //////////////////////////////////////////////////////////////////////
44
45 CXMLFile::CXMLFile()
46 {
47         m_nQueueIndex = 0;
48         m_pRoot = NULL;
49
50         for (int i = 0; i < ELEMENT_QUEUE_MAX; ++i)
51                 m_paElementQueue[i] = NULL;
52
53         m_pszXML = NULL;
54 }
55
56 CXMLFile::~CXMLFile()
57 {
58         if (m_pRoot)
59                 delete m_pRoot;
60 }
61
62 int CXMLFile::LoadFromStream(LPCTSTR pszXML)
63 {
64         int nResult = 0;
65
66         m_nQueueIndex = 0;
67
68         if (m_pRoot)
69                 delete m_pRoot;
70
71         m_pRoot = NULL;
72         m_pszXML = pszXML;
73
74         nResult = _Parse();
75
76         if (nResult)
77                 goto finish;
78
79 finish:
80
81         if (nResult)
82                 DRM_TAPPS_EXCEPTION("CXMLFile::LoadFromStream() Error! \n");
83
84         return nResult;
85 }
86
87 int CXMLFile::LoadFromFile(LPCTSTR pszFileName)
88 {
89         int  nResult;
90         FILE *hFile = NULL;
91         DWORD dwFileSize, dwReadBytes;
92         LPBYTE pbBuffer = NULL;
93         LPTSTR pszXML = NULL;
94
95         hFile = fopen(pszFileName, "rb");
96
97         if (!hFile) {
98                 nResult = -1;
99                 goto finish;
100         }
101
102         if (fseek(hFile, 0, SEEK_END) != 0) {
103                 nResult = -1;
104                 goto finish;
105         }
106         dwFileSize = ftell(hFile);
107         if (fseek(hFile, 0, SEEK_SET) != 0) {
108                 nResult = -1;
109                 goto finish;
110         }
111
112         if (dwFileSize > LONG_MAX - 256) {
113                 nResult = -1;
114                 goto finish;
115         }
116         pbBuffer = new BYTE[dwFileSize + 1];
117         IF_TRUE_GOTO(pbBuffer == NULL, TADC_MEMAlOC_ERROR);
118
119         dwReadBytes = fread(pbBuffer, 1, dwFileSize + 1, hFile);
120
121         IF_TRUE_GOTO(dwFileSize != dwReadBytes, TADC_PARAMETER_ERROR);
122
123         pbBuffer[dwFileSize] = 0;
124
125         pszXML = new CHAR[dwFileSize + 256];
126         IF_TRUE_GOTO(pszXML == NULL, TADC_MEMAlOC_ERROR);
127
128 #ifdef _UNICODE
129         nResult = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pbBuffer, -1, pszXML,
130                                                                   dwFileSize + 256);
131 #else
132         memcpy(pszXML, pbBuffer, dwFileSize + 1);
133 #endif
134
135         nResult = LoadFromStream(pszXML);
136
137         if (nResult)
138                 goto finish;
139
140         nResult = 0;
141
142 finish:
143
144         if (hFile)
145                 fclose(hFile);
146
147         if (nResult)
148                 DRM_TAPPS_EXCEPTION("CXMLFile::LoadFromFile() Error! \n");
149
150         if (pbBuffer)
151                 delete []pbBuffer;
152
153         if (pszXML)
154                 delete []pszXML;
155
156         return nResult;
157 }
158
159 int CXMLFile::_Parse()
160 {
161         int nResult, i;
162         CXMLElement *pXMLElement = NULL;
163         CXMLElement *pCurrentElement = NULL;
164         CXMLElement *pTemp = NULL;
165         TCHAR szElementName[_MAX_NAME_LENGTH];
166         TCHAR szValue[_MAX_VALUE_LENGTH];
167         LPCTSTR psz;
168         size_t orig_pszXML_len = strlen(m_pszXML);
169         size_t tmp_pszXML_len = orig_pszXML_len;
170
171         _SKIP_WHITESPACE();
172
173         while (*m_pszXML != 0) {
174                 _SKIP_WHITESPACE();
175
176                 if (*m_pszXML == 0)
177                         break;
178
179                 if (*m_pszXML == '<') {
180                         m_pszXML++;
181
182                         _SKIP_WHITESPACE();
183
184                         if (*m_pszXML == '!') {
185                                 //------------------------------------------------------------------------
186                                 //
187                                 // Comment
188                                 //
189                                 //------------------------------------------------------------------------
190                         } else if (*m_pszXML == '?') {
191                                 //------------------------------------------------------------------------
192                                 //
193                                 // <? ... ?>
194                                 //
195                                 //------------------------------------------------------------------------
196                                 psz = _tcsstr(m_pszXML, _T("?>"));
197
198                                 if (!psz) {
199                                         nResult = -1;
200                                         goto finish;
201                                 }
202
203                                 m_pszXML = psz + 2;
204                         } else if (*m_pszXML == '/') {
205                                 m_pszXML++;
206                                 //------------------------------------------------------------------------
207                                 //
208                                 // End Tag
209                                 //
210                                 //------------------------------------------------------------------------
211                                 nResult = _GetElementName((LPTSTR)szElementName);
212
213                                 if (nResult != 0)
214                                         goto finish;
215
216                                 //2011.04.27
217                                 if (!pCurrentElement) {
218                                         nResult = -1;
219                                         goto finish;
220                                 }
221
222                                 if (TADC_IF_StrCmp(pCurrentElement->GetName(), (LPTSTR)szElementName) != 0) {
223                                         nResult = -1;
224                                         goto finish;
225                                 }
226
227                                 tmp_pszXML_len = orig_pszXML_len;
228
229                                 while (*m_pszXML != '>' && tmp_pszXML_len > 0) {
230                                         tmp_pszXML_len--;
231                                         m_pszXML++;
232                                 }
233
234                                 m_pszXML++;
235
236                                 pTemp = _Pop();
237
238                                 if (pTemp)
239                                         pCurrentElement = pTemp;
240                                 else
241                                         pCurrentElement = m_pRoot;
242                         } else {
243                                 pXMLElement = new CXMLElement;
244                                 IF_TRUE_GOTO(pXMLElement == NULL, TADC_MEMAlOC_ERROR);
245
246                                 nResult = _GetElementName((LPTSTR)szElementName);
247
248                                 if (nResult)
249                                         goto finish;
250
251                                 pXMLElement->SetName((LPTSTR)szElementName);
252
253                                 if (!m_pRoot)
254                                         m_pRoot = pXMLElement;
255
256                                 if (pCurrentElement) {
257                                         pCurrentElement->AddChild(pXMLElement);
258                                         _Push(pCurrentElement);
259                                 }
260
261                                 pCurrentElement = pXMLElement;
262                         }
263                 } else if (*m_pszXML == '/') {
264                         m_pszXML++;
265
266                         if (*m_pszXML != '>') {
267                                 nResult = -1;
268                                 goto finish;
269                         }
270
271                         pCurrentElement = _Pop();
272                 } else if (*m_pszXML == '>') {
273                         m_pszXML++;
274                         _SKIP_WHITESPACE();
275
276                         i = 0;
277
278                         tmp_pszXML_len = orig_pszXML_len;
279
280                         while (*m_pszXML != '<' && tmp_pszXML_len > 0) {
281                                 tmp_pszXML_len--;
282                                 szValue[i] = *m_pszXML;
283                                 i++;
284                                 m_pszXML++;
285                         }
286
287                         szValue[i] = 0;
288
289                         if (pCurrentElement)
290                                 pCurrentElement->SetValue((LPTSTR)szValue);
291                 } else {
292                         _SKIP_WHITESPACE();
293
294                         nResult = _GetAttributeNameAndValue((LPTSTR)szElementName, (LPTSTR)szValue);
295
296                         if (nResult)
297                                 goto finish;
298
299                         if (pCurrentElement)
300                                 pCurrentElement->AddAttribute((LPTSTR)szElementName, (LPTSTR)szValue);
301                 }
302         }
303
304         nResult = 0;
305
306 finish:
307
308         if (nResult)
309                 DRM_TAPPS_EXCEPTION("CXMLFile::_Parse() Error!. nResult[%d]", nResult);
310
311         return nResult;
312 }
313
314 int CXMLFile::_GetElementName(LPTSTR pszElementName)
315 {
316         _SKIP_WHITESPACE();
317
318         while ((*m_pszXML != 0)
319                         && (*m_pszXML != ' ')
320                         && (*m_pszXML != '>')
321                         && (*m_pszXML != '/')) {
322                 *pszElementName = *m_pszXML;
323                 m_pszXML++;
324                 pszElementName++;
325         }
326
327         *pszElementName = 0;
328
329         return 0;
330 }
331
332 CXMLElement *CXMLFile::_Pop()
333 {
334         if (m_nQueueIndex < 1)
335                 return NULL;
336
337         return m_paElementQueue[--m_nQueueIndex];
338 }
339
340 int CXMLFile::_Push(CXMLElement *p)
341 {
342         if (m_nQueueIndex >= (int)sizeof(m_paElementQueue) / (int)sizeof(
343                                 m_paElementQueue[0]))
344                 return ERROR_INSUFFICIENT_BUFFER;
345
346         m_paElementQueue[m_nQueueIndex++] = p;
347
348         return 0;
349 }
350
351 int CXMLFile::_GetAttributeNameAndValue(LPTSTR pszName, LPTSTR pszValue)
352 {
353         int nResult, nLength, i;
354         LPCTSTR psz;
355         TCHAR chQuotation;
356         bool isFound;
357         LPTSTR origValueAddr = pszValue;
358         static T_ESCAPE_CHARSET stEscape[] = {
359                 { _T("&amp"), _T('&') },
360                 { _T("&qt"), _T('>') },
361                 { _T("&lt"), _T('<') },
362                 { _T("&quot"), _T('"') },
363                 { _T("&apos"), _T('\'') }
364         };
365
366         _SKIP_WHITESPACE();
367
368         psz = _tcschr(m_pszXML, '=');
369
370         if (!psz) {
371                 nResult = -1; //ERRORMSG(ERROR_SXS_XML_E_BADXMLDECL, NULL);
372                 goto finish;
373         }
374
375         nLength = (int)(psz - m_pszXML);
376
377         if (_MAX_NAME_LENGTH < nLength + 1) {
378                 nResult = -1;
379                 goto finish;
380         }
381
382         memcpy(pszName, m_pszXML, nLength + 1);
383
384         m_pszXML = psz + 1;
385
386         _SKIP_WHITESPACE();
387
388         if ((*m_pszXML == '\'') || (*m_pszXML == '"')) {
389                 chQuotation = *m_pszXML;
390                 m_pszXML++;
391         } else {
392                 chQuotation = ' ';
393         }
394
395         while (*m_pszXML != 0 && ((pszValue - origValueAddr) < _MAX_VALUE_LENGTH)) {
396                 if (*m_pszXML == '&') {
397                         isFound = FALSE;
398
399                         for (i = 0; i < (int)sizeof(stEscape) / (int)sizeof(stEscape[0]); i++) {
400                                 if (TADC_IF_StrNCmp(m_pszXML, stEscape[i].pszEscape,
401                                                                         TADC_IF_StrLen(stEscape[i].pszEscape)) == 0) {
402                                         *pszValue = stEscape[i].chReplace;
403                                         pszValue++;
404                                         m_pszXML += TADC_IF_StrLen(stEscape[i].pszEscape);
405                                         isFound = TRUE;
406
407                                         break;
408                                 }
409                         }
410
411                         if (isFound == FALSE) {
412                                 *pszValue = *m_pszXML;
413                                 pszValue++;
414                                 m_pszXML++;
415                         }
416                 } else if (*m_pszXML == chQuotation) {
417                         m_pszXML++;
418                         break;
419                 } else if (*m_pszXML == '/' || *m_pszXML == '>') {
420                         if (chQuotation == ' ')
421                                 break;
422
423                         *pszValue = *m_pszXML;
424                         pszValue++;
425                         m_pszXML++;
426                 } else {
427                         *pszValue = *m_pszXML;
428                         pszValue++;
429                         m_pszXML++;
430                 }
431         }
432
433         *pszValue = 0;
434         nResult = 0;
435
436 finish:
437
438         if (nResult)
439                 DRM_TAPPS_EXCEPTION("CXMLFile::_GetAttributeNameAndValue() Error!");
440
441         return nResult;
442 }