• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "sms_wap_push_buffer.h"
17 
18 #include "securec.h"
19 #include "string_utils.h"
20 #include "telephony_log_wrapper.h"
21 
22 namespace OHOS {
23 namespace Telephony {
SmsWapPushBuffer()24 SmsWapPushBuffer::SmsWapPushBuffer() {}
25 
~SmsWapPushBuffer()26 SmsWapPushBuffer::~SmsWapPushBuffer()
27 {
28     if (pduBuffer_ != nullptr) {
29         pduBuffer_.reset();
30     }
31 }
32 
ReadDataBuffer(uint32_t desLen)33 std::unique_ptr<char[]> SmsWapPushBuffer::ReadDataBuffer(uint32_t desLen)
34 {
35     return ReadDataBuffer(curPosition_, desLen);
36 }
37 
ReadDataBuffer(uint32_t offset,uint32_t desLen)38 std::unique_ptr<char[]> SmsWapPushBuffer::ReadDataBuffer(uint32_t offset, uint32_t desLen)
39 {
40     if ((desLen > totolLength_) || ((offset + desLen) > totolLength_)) {
41         return nullptr;
42     }
43     std::unique_ptr<char[]> result = std::make_unique<char[]>(desLen);
44     if (result == nullptr) {
45         return nullptr;
46     }
47     if (memcpy_s(result.get(), desLen, &pduBuffer_[offset], desLen) != EOK) {
48         return nullptr;
49     }
50     return result;
51 }
52 
WriteRawStringBuffer(const std::string & inSrc)53 bool SmsWapPushBuffer::WriteRawStringBuffer(const std::string &inSrc)
54 {
55     uint32_t len = inSrc.length();
56     if (len > CODE_BUFFER_MAX_SIZE) {
57         TELEPHONY_LOGE("create wappush input source string over length error.");
58         return false;
59     }
60 
61     if (pduBuffer_) {
62         pduBuffer_.reset();
63     }
64 
65     pduBuffer_ = std::make_unique<char[]>(len);
66     if (!pduBuffer_) {
67         TELEPHONY_LOGE("wap push make unique fail.");
68         return false;
69     }
70     if (memcpy_s(pduBuffer_.get(), len, inSrc.data(), len) != EOK) {
71         TELEPHONY_LOGE("wap push memcpy_s fail.");
72         return false;
73     }
74     totolLength_ = len;
75     return true;
76 }
77 
WriteDataBuffer(std::unique_ptr<char[]> inBuff,uint32_t len)78 bool SmsWapPushBuffer::WriteDataBuffer(std::unique_ptr<char[]> inBuff, uint32_t len)
79 {
80     if (inBuff == nullptr) {
81         TELEPHONY_LOGE("wap push inBuff is null.");
82         return false;
83     }
84     if (len <= 0 || len > CODE_BUFFER_MAX_SIZE) {
85         TELEPHONY_LOGE("wap push len invalid .");
86         return false;
87     }
88 
89     if (pduBuffer_) {
90         pduBuffer_.reset();
91     }
92 
93     pduBuffer_ = std::make_unique<char[]>(len);
94     if (!pduBuffer_) {
95         TELEPHONY_LOGE("wap push make unique fail.");
96         return false;
97     }
98     if (memcpy_s(pduBuffer_.get(), len, inBuff.get(), len) != EOK) {
99         TELEPHONY_LOGE("wap push memcpy_s fail.");
100         return false;
101     }
102     totolLength_ = len;
103     return true;
104 }
105 
GetCurPosition() const106 uint32_t SmsWapPushBuffer::GetCurPosition() const
107 {
108     return curPosition_;
109 }
110 
GetSize() const111 uint32_t SmsWapPushBuffer::GetSize() const
112 {
113     return totolLength_;
114 }
115 
PeekOneByte(uint8_t & oneByte)116 bool SmsWapPushBuffer::PeekOneByte(uint8_t &oneByte)
117 {
118     if (curPosition_ >= totolLength_) {
119         TELEPHONY_LOGE("wap push current position invalid.");
120         return false;
121     }
122     oneByte = pduBuffer_[curPosition_];
123     return true;
124 }
125 
GetOneByte(uint8_t & oneByte)126 bool SmsWapPushBuffer::GetOneByte(uint8_t &oneByte)
127 {
128     if (curPosition_ >= totolLength_) {
129         TELEPHONY_LOGE("wap push current position invalid.");
130         return false;
131     }
132     oneByte = pduBuffer_[curPosition_];
133     curPosition_++;
134     return true;
135 }
136 
IncreasePointer(uint32_t offset)137 bool SmsWapPushBuffer::IncreasePointer(uint32_t offset)
138 {
139     if ((offset > totolLength_) || ((curPosition_ + offset) > totolLength_)) {
140         TELEPHONY_LOGE("wap push current position invalid.");
141         return false;
142     }
143     curPosition_ += offset;
144     return true;
145 }
146 
DecreasePointer(uint32_t offset)147 bool SmsWapPushBuffer::DecreasePointer(uint32_t offset)
148 {
149     if (offset > curPosition_) {
150         TELEPHONY_LOGE("wap push current position invalid.");
151         return false;
152     }
153     curPosition_ -= offset;
154     return true;
155 }
156 
157 /**
158  * @brief DecodeUintvar
159  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
160  * Uintvar-integer = 1*5 OCTET
161  * @param uintVar
162  * @param count
163  * @return true
164  * @return false
165  */
DecodeUintvar(uint32_t & uintVar,uint32_t & count)166 bool SmsWapPushBuffer::DecodeUintvar(uint32_t &uintVar, uint32_t &count)
167 {
168     const uint8_t setNotHighestBitZero = 0x80;
169     const uint8_t setHighestBitZero = 0x7f;
170 
171     count = 0;
172     uint8_t oneByte = 0;
173     if (!GetOneByte(oneByte)) {
174         TELEPHONY_LOGE("wap push GetOneByte fail.");
175         return false;
176     }
177     count++;
178     uintVar = 0;
179     while ((oneByte & setNotHighestBitZero) != 0) {
180         uintVar = uintVar << 0x07;
181         uintVar |= oneByte & setHighestBitZero;
182 
183         if (!GetOneByte(oneByte)) {
184             TELEPHONY_LOGE("wap push GetOneByte fail.");
185             return false;
186         }
187         count++;
188     }
189     uintVar = uintVar << 0x07;
190     uintVar |= oneByte & setHighestBitZero;
191     return true;
192 }
193 
194 /**
195  * @brief DecodeShortLength
196  * wap-230-wsp-20010705-a.pdf   section:8.4.2.2 Length
197  * Short-length = <Any octet 0-30>
198  * @param sValueLength
199  * @return true
200  * @return false
201  */
DecodeShortLength(uint8_t & sValueLength)202 bool SmsWapPushBuffer::DecodeShortLength(uint8_t &sValueLength)
203 {
204     const unsigned char minShortOctet = 30;
205 
206     uint8_t oneByte = 0;
207     if (!GetOneByte(oneByte)) {
208         TELEPHONY_LOGE("wap push GetOneByte fail.");
209         return false;
210     }
211     if (oneByte <= minShortOctet) {
212         sValueLength = oneByte;
213         return true;
214     }
215     return false;
216 }
217 
218 /**
219  * @brief DecodeValueLengthReturnLen
220  * value-length = short-length | (Length-quote Length)
221  * short-length = 0~30
222  * Length-quote = 31
223  * (Length-quote Length) = Length-quote + Uintvar-length
224  * @param valueLength
225  * @return true
226  * @return false
227  */
DecodeValueLengthReturnLen(uint32_t & valueLength,uint32_t & length)228 bool SmsWapPushBuffer::DecodeValueLengthReturnLen(uint32_t &valueLength, uint32_t &length)
229 {
230     const uint8_t lengthQuote = 0x1f;
231     const uint8_t maxShortLength = 30;
232 
233     length = 0;
234     valueLength = 0;
235     uint32_t uintvar = 0;
236     uint8_t oneByte = 0;
237     if (!GetOneByte(oneByte)) {
238         DecreasePointer(1);
239         TELEPHONY_LOGE("wap push GetOneByte fail.");
240         return false;
241     }
242 
243     if (oneByte <= maxShortLength) {
244         valueLength = oneByte;
245         length = 1;
246         return true;
247     } else if (oneByte == lengthQuote) {
248         /* Length-quote = 0x1F */
249         uint32_t count = 0;
250         if (!DecodeUintvar(uintvar, count)) {
251             TELEPHONY_LOGE("wap push DecodeUintvar fail.");
252             return false;
253         }
254         valueLength = uintvar;
255         length = count + 1;
256         return true;
257     }
258     return false;
259 }
260 
261 /**
262  * @brief DecodeValueLength
263  * value-length = short-length | (Length-quote Length)
264  * short-length = 0~30
265  * Length-quote = 31
266  * (Length-quote Length) = Length-quote + Uintvar-length
267  * @param valueLength
268  * @return true
269  * @return false
270  */
DecodeValueLength(uint32_t & valueLength)271 bool SmsWapPushBuffer::DecodeValueLength(uint32_t &valueLength)
272 {
273     const uint8_t lengthQuote = 0x1f;
274     const uint8_t maxShortLength = 30;
275 
276     valueLength = 0;
277     uint32_t uintvar = 0;
278     uint8_t oneByte = 0;
279     if (!GetOneByte(oneByte)) {
280         DecreasePointer(1);
281         TELEPHONY_LOGE("wap push GetOneByte fail.");
282         return false;
283     }
284 
285     if (oneByte <= maxShortLength) {
286         valueLength = oneByte;
287         return true;
288     } else if (oneByte == lengthQuote) {
289         /* Length-quote = 0x1F */
290         uint32_t count = 0;
291         if (!DecodeUintvar(uintvar, count)) {
292             TELEPHONY_LOGE("wap push DecodeUintvar fail.");
293             return false;
294         }
295         valueLength = uintvar;
296         return true;
297     }
298     return false;
299 }
300 
301 /**
302  * @brief CharIsToken
303  * RFC2616   section:2.2 Basic Rules
304  * CHAR           = <any US-ASCII character (octets 0 - 127)>
305  * CTL            = <any US-ASCII control character
306  *                   (octets 0 - 31) and DEL (127)>
307  * separators     = "(" | ")" | "<" | ">" | "@"
308  *                     | "," | ";" | ":" | "\" | <">
309  *                     | "/" | "[" | "]" | "?" | "="
310  *                     | "{" | "}" | SP | HT
311  * @param oneByte
312  * @return true
313  * @return false
314  */
CharIsToken(uint8_t oneByte)315 bool SmsWapPushBuffer::CharIsToken(uint8_t oneByte)
316 {
317     const uint8_t minToken = 33;
318     const uint8_t maxToken = 126;
319 
320     if (oneByte < minToken || oneByte > maxToken) {
321         return false;
322     }
323 
324     std::set<uint8_t> token = { '"', '(', ')', '/', ',', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{', '}' };
325     return !token.count(oneByte);
326 }
327 
328 /**
329  * @brief DecodeTokenText
330  * wap-230-wsp-20010705-a   section:8.4.2.2 Length
331  * Token-text = Token End-of-string
332  * End-of-string = <Octet 0>
333  * @param str
334  * @param len
335  * @return true
336  * @return false
337  */
DecodeTokenText(std::string & str,uint32_t & len)338 bool SmsWapPushBuffer::DecodeTokenText(std::string &str, uint32_t &len)
339 {
340     const uint8_t minToken = 33;
341     const uint8_t maxToken = 126;
342 
343     len = 0;
344     str.clear();
345     uint8_t oneByte = 0;
346     if (!PeekOneByte(oneByte)) {
347         TELEPHONY_LOGE("wap push PeekOneByte fail.");
348         return false;
349     }
350     if (oneByte < minToken || oneByte > maxToken) {
351         TELEPHONY_LOGE("wap push DecodeTokenText fail.");
352         return false;
353     }
354     while (GetOneByte(oneByte)) {
355         if (oneByte != 0) {
356             if (CharIsToken(oneByte)) {
357                 str += oneByte;
358                 len++;
359             }
360         } else {
361             break;
362         }
363     }
364     return (len > 0) ? true : false;
365 }
366 
367 /**
368  * @brief DecodeText
369  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
370  * Text-string = [Quote] *TEXT End-of-string
371  * Quote = <Octet 127>
372  * End-of-string = <Octet 0>
373  * @param str
374  * @param len
375  * @return true
376  * @return false
377  */
DecodeText(std::string & str,uint32_t & len)378 bool SmsWapPushBuffer::DecodeText(std::string &str, uint32_t &len)
379 {
380     const unsigned char quoteChar = 127;
381 
382     len = 0;
383     str.clear();
384     uint8_t oneByte = 0;
385     if (!GetOneByte(oneByte)) {
386         TELEPHONY_LOGE("wap push GetOneByte fail.");
387         return false;
388     }
389 
390     // ignore quote
391     if (oneByte != quoteChar) {
392         this->DecreasePointer(1);
393     } else {
394         len++;
395     }
396 
397     while (GetOneByte(oneByte)) {
398         if (oneByte != 0) {
399             str += oneByte;
400             len++;
401         } else {
402             break;
403         }
404     }
405     return (len > 0) ? true : false;
406 }
407 
408 /**
409  * @brief DecodeQuotedText
410  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
411  * Quoted-string = <Octet 34> *TEXT End-of-string
412  * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
413  * @param str
414  * @param len
415  * @return true
416  * @return false
417  */
DecodeQuotedText(std::string & str,uint32_t & len)418 bool SmsWapPushBuffer::DecodeQuotedText(std::string &str, uint32_t &len)
419 {
420     const uint8_t quotedFlag = 0x22;
421     uint8_t oneByte = 0;
422     len = 0;
423     str.clear();
424     while (GetOneByte(oneByte)) {
425         if (oneByte != 0) {
426             if (oneByte != quotedFlag) {
427                 str += oneByte;
428             }
429             len++;
430         } else {
431             break;
432         }
433     }
434     return (len > 0) ? true : false;
435 }
436 
437 /**
438  * @brief DecodeShortInteger
439  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
440  * Short-integer = OCTET
441  * Integers in range 0-127 shall be encoded as a one octet value with
442  * the most significant bit set to one (1xxx xxxx) and with the value
443  * in the remaining least significant bits
444  * @param sInteger
445  * @return true
446  * @return false
447  */
DecodeShortInteger(uint8_t & sInteger)448 bool SmsWapPushBuffer::DecodeShortInteger(uint8_t &sInteger)
449 {
450     const uint8_t setHighestBitZero = 0x7f;
451     const uint8_t maxShortInteger = 0x7f;
452 
453     sInteger = 0;
454     uint8_t oneByte = 0;
455     if (!GetOneByte(oneByte)) {
456         TELEPHONY_LOGE("wap push GetOneByte fail.");
457         return false;
458     }
459     if (oneByte > maxShortInteger) {
460         sInteger = oneByte & setHighestBitZero;
461         return true;
462     }
463     return false;
464 }
465 
466 /**
467  * @brief DecodeLongInteger
468  * Long-integer = [Short-length] [Multi-octet-integer]
469  * Short-length = 1 byte
470  * Multi-octet-integer = <Short-length> bytes
471  * @param value
472  * @return true
473  * @return false
474  */
DecodeLongInteger(uint64_t & value)475 bool SmsWapPushBuffer::DecodeLongInteger(uint64_t &value)
476 {
477     unsigned char oneByte = 0;
478     uint64_t result = 0;
479     uint32_t valuelength = 0;
480     if (GetOneByte(oneByte) != true) {
481         TELEPHONY_LOGE("wap push GetOneByte fail.");
482         return false;
483     }
484     if (oneByte > LONG_VALUE_LEN_MAX) {
485         return false;
486     }
487     valuelength = oneByte;
488 
489     for (uint32_t i = 0; i < valuelength; i++) {
490         if (GetOneByte(oneByte) != true) {
491             TELEPHONY_LOGE("wap push GetOneByte fail.");
492             return false;
493         }
494         result = (result << 0x08);
495         result |= oneByte;
496     }
497     value = result;
498     return true;
499 }
500 
501 /**
502  * @brief DecodeInteger
503  * Integer-Value = Short-integer | Long-integer
504  * @param iInteger
505  * @return true
506  * @return false
507  */
DecodeInteger(uint64_t & iInteger)508 bool SmsWapPushBuffer::DecodeInteger(uint64_t &iInteger)
509 {
510     iInteger = 0;
511     if (DecodeIsShortInt()) {
512         uint8_t sInteger = 0;
513         if (DecodeShortInteger(sInteger)) {
514             iInteger = sInteger;
515             return true;
516         }
517     } else {
518         if (DecodeLongInteger(iInteger)) {
519             return true;
520         }
521     }
522     return false;
523 }
524 
525 /**
526  * @brief DecodeIsShortInt
527  * (128 - 255) It is an encoded 7-bit value; this header has no more data
528  * @return true
529  * @return false
530  */
DecodeIsShortInt()531 bool SmsWapPushBuffer::DecodeIsShortInt()
532 {
533     uint8_t oneByte = 0;
534     PeekOneByte(oneByte);
535     if (oneByte > 0x7F) {
536         return true;
537     }
538     return false;
539 }
540 
541 /**
542  * @brief DecodeIsString
543  * (32 - 127) The value is a text string, terminated by a zero octet (NUL character)
544  * @return true
545  * @return false
546  */
DecodeIsString()547 bool SmsWapPushBuffer::DecodeIsString()
548 {
549     uint8_t oneByte = 0;
550     PeekOneByte(oneByte);
551     if (0x20 <= oneByte && 0x7f >= oneByte) {
552         return true;
553     }
554     return false;
555 }
556 
557 /**
558  * @brief DecodeIsValueLength
559  * (0 - 30) This octet is followed by the indicated number (0 –30) of data octets
560  * 31 This octet is followed by a uintvar, which indicates the number of data octets after it
561  * @return true
562  * @return false
563  */
DecodeIsValueLength()564 bool SmsWapPushBuffer::DecodeIsValueLength()
565 {
566     uint8_t oneByte = 0;
567     PeekOneByte(oneByte);
568     if (oneByte <= 0x1f) {
569         return true;
570     }
571     return false;
572 }
573 
574 /**
575  * @brief DecodeExtensionMedia
576  *
577  * @return true
578  * @return false
579  */
DecodeExtensionMedia()580 bool SmsWapPushBuffer::DecodeExtensionMedia()
581 {
582     return false;
583 }
584 
585 /**
586  * @brief DecodeConstrainedEncoding
587  *
588  * @return true
589  * @return false
590  */
DecodeConstrainedEncoding()591 bool SmsWapPushBuffer::DecodeConstrainedEncoding()
592 {
593     return false;
594 }
595 
DecodeTextValue(std::string & str,bool & isNoValue)596 bool SmsWapPushBuffer::DecodeTextValue(std::string &str, bool &isNoValue)
597 {
598     const uint8_t minTextToken = 31;
599 
600     str.clear();
601     unsigned char oneByte = 0;
602     if (GetOneByte(oneByte) != true) {
603         TELEPHONY_LOGE("wap push GetOneByte fail.");
604         return false;
605     }
606     if ((oneByte & 0x80) == 0x00 && oneByte > minTextToken) {
607         std::string field = "";
608         uint32_t fieldLength = 0;
609         if (!DecodeTokenText(field, fieldLength)) {
610             TELEPHONY_LOGE("wap push DecodeTokenText fail.");
611             return false;
612         }
613     } else {
614         uint64_t fieldId = 0;
615         if (!DecodeInteger(fieldId)) {
616             TELEPHONY_LOGE("wap push DecodeInteger fail.");
617             return false;
618         }
619     }
620     bool bNoValue = false;
621     if (!DecodeNoValue(bNoValue)) {
622         TELEPHONY_LOGE("wap push DecodeNoValue fail.");
623         return false;
624     }
625     if (bNoValue) {
626         isNoValue = true;
627         return true;
628     } else {
629         if (DecreasePointer(1) != true) {
630             TELEPHONY_LOGE("wap push DecreasePointer fail.");
631             return false;
632         }
633     }
634     uint64_t fieldValue = 0;
635     if (DecodeInteger(fieldValue)) {
636         str = std::to_string(fieldValue);
637         return true;
638     }
639     uint32_t valueLength = 0;
640     if (DecodeTokenText(str, valueLength)) {
641         if (str.length() > 1 && str.at(0) == '\"') {
642             str = str.substr(1, str.length() - 1);
643         }
644         return true;
645     }
646     return false;
647 }
648 
DecodeNoValue(bool & isNoValue)649 bool SmsWapPushBuffer::DecodeNoValue(bool &isNoValue)
650 {
651     unsigned char oneByte = 0;
652     if (GetOneByte(oneByte) != true) {
653         TELEPHONY_LOGE("wap push GetOneByte fail.");
654         return false;
655     }
656     isNoValue = (oneByte == 0) ? true : false;
657     return true;
658 }
659 
MarkPosition()660 void SmsWapPushBuffer::MarkPosition()
661 {
662     savePosition_ = curPosition_;
663 }
664 
UnMarkPosition()665 void SmsWapPushBuffer::UnMarkPosition()
666 {
667     curPosition_ = savePosition_;
668 }
669 } // namespace Telephony
670 } // namespace OHOS
671