1 /*
2  * Copyright (C) 2021 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 "mms_quoted_printable.h"
17 
18 #include <string>
19 
20 #include "memory"
21 #include "securec.h"
22 #include "sms_constants_utils.h"
23 #include "telephony_log_wrapper.h"
24 
25 namespace OHOS {
26 namespace Telephony {
27 static constexpr int END_LINE_CHAR_NUM = 3;
28 
Encode(const std::string & input)29 std::string MmsQuotedPrintable::Encode(const std::string &input)
30 {
31     const unsigned char asciiMin = 33;
32     const unsigned char assciiMax = 126;
33     const unsigned char equalChar = 61;
34     const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
35     std::string codeString = "";
36     for (auto byte : input) {
37         if ((byte >= asciiMin && byte < equalChar) || (byte > equalChar && byte <= assciiMax)) {
38             codeString += byte;
39         } else {
40             codeString += '=';
41             codeString += hex[((byte >> 0x04) & 0x0F)];
42             codeString += hex[(byte & 0x0F)];
43         }
44     }
45     return codeString;
46 }
47 
Decode(const std::string src,std::string & dest)48 bool MmsQuotedPrintable::Decode(const std::string src, std::string &dest)
49 {
50     uint32_t inLength = 0;
51     inLength = src.length();
52     if (inLength == 0 || inLength > MAX_MMS_ATTACHMENT_LEN) {
53         TELEPHONY_LOGE("inLength size error");
54         return false;
55     }
56 
57     std::unique_ptr<char[]> tempBuffer = std::make_unique<char[]>(inLength + 1);
58     if (tempBuffer == nullptr) {
59         TELEPHONY_LOGE("tempBuffer nullptr error.");
60         return false;
61     }
62 
63     uint32_t index = 0;
64     uint32_t outLength = 0;
65     const char *input = src.data();
66     while (index < inLength) {
67         if (strncmp(input, "=/r/n", END_LINE_CHAR_NUM) == 0) {
68             input += END_LINE_CHAR_NUM;
69             index += END_LINE_CHAR_NUM;
70         } else {
71             uint32_t hexChar = 0;
72             if (*input == '=' && sscanf_s(input, "=%02X", &hexChar) >= 1) {
73                 tempBuffer[outLength] = static_cast<char>(hexChar);
74                 input += END_LINE_CHAR_NUM;
75                 index += END_LINE_CHAR_NUM;
76             } else {
77                 tempBuffer[outLength] = *input;
78                 input++;
79                 index++;
80             }
81             outLength++;
82         }
83     }
84     tempBuffer[outLength] = '\0';
85     dest = std::string(tempBuffer.get(), outLength);
86     if (tempBuffer) {
87         tempBuffer.reset();
88     }
89     return true;
90 }
91 } // namespace Telephony
92 } // namespace OHOS
93