📄 perdecoder.cxx
字号:
/* * PERDecoder.cxx * * Abstract Syntax Notation 1 Encoding Rules * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * Copyright (c) 2001 Institute for Information Industry, Taiwan, Republic of China * (http://www.iii.org.tw/iiia/ewelcome.htm) * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): Huang-Ming Huang * * The code is adapted from asner.cxx of PWLib, but the dependancy on PWLib has * been removed. * * $Log: PERDecoder.cxx,v $ * Revision 1.6 2002/07/10 07:25:48 btrummer * Minor simplification at the end of PERDecoder::decodeChoicePreamle(). * * Revision 1.5 2002/07/03 08:15:30 btrummer * Fixed the assignment to beginPosition in PERDecoder::setPosition(). * * Revision 1.4 2002/07/03 06:26:38 btrummer * Introduced an upper bound for the size of strings and arrays, * like PWLib's PERDecoder does. Otherwise, broken data may make the * PERDecoder allocate hundrets of Megabytes RAM... * * Revision 1.3 2002/07/02 04:45:13 mangelo * Modify for VC.Net and GCC 3.1 * * Revision 1.2 2001/10/05 19:10:42 mangelo * Added Log * * 2001/07/16 Huang-Ming Huang * Optional components of SEQUENCE is now created on demand. * * 2001/06/26 Huang-Ming Huang * Version 2.1 Reimplemented to minimize the code size. * * 2001/05/01 * Fixed problem with en/decoding more than 16 extension fields in a sequence * in accordance with PWLib asner.cxx Revision 1.41. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "asn1.h"namespace ASN1 {// When resizing strings or vectors, these values will be used as upper limit.static unsigned MaximumArraySize = 128;static unsigned MaximumStringSize = 16*1024;extern unsigned CountBits(unsigned range);bool PERDecoder::decodeBitMap(std::vector<char>& bitData, unsigned nBit){ unsigned theBits; int idx = 0; unsigned bitsLeft = nBit; while (bitsLeft >= 8) { if (!decodeMultiBit(8, theBits)) return false; bitData[idx++] = (unsigned char)theBits; bitsLeft -= 8; } if (bitsLeft > 0) { if (!decodeMultiBit(bitsLeft, theBits)) return false; bitData[idx] = (unsigned char)(theBits << (8-bitsLeft)); } return true;}inline bool PERDecoder::atEnd() { return beginPosition >= endPosition; }bool PERDecoder::do_visit(Null& value){ return true;}bool PERDecoder::do_visit(BOOLEAN& value){ if (atEnd()) return false; // X.931 Section 11 value = decodeSingleBit(); return true;}bool PERDecoder::do_visit(INTEGER& integer){ // X.931 Sections 12 unsigned value; if ((integer.getConstraintType() == ExtendableConstraint && decodeSingleBit()) || integer.getConstraintType() < FixedConstraint) { // 12.1 unsigned len; if (decodeLength(0, INT_MAX, len) != 0) return false; if (!decodeMultiBit(len*8, value)) return false; if (!integer.constrained() && (value & 1 << ((len*8)-1) ) ) // negative value value = (0xFFFFFFFF << (len*8)) | value; integer = value; return true; } if ((unsigned)integer.getLowerLimit() != integer.getUpperLimit()) // 12.2.1 if (decodeUnsigned(integer.getLowerLimit(), integer.getUpperLimit(), value) == 0) // 12.2.2 which devolves to 10.5 { integer = value; return true; } integer = integer.getLowerLimit(); return true;}bool PERDecoder::do_visit(ENUMERATED& value){ // X.691 Section 13 unsigned v; if (value.extendable()) { // 13.3 if (decodeSingleBit()) { unsigned len = 0; if ( decodeSmallUnsigned(len) && len > 0 && decodeUnsigned(0, len-1, v) == 0) { value.setFromInt(v); return true; } } } if (decodeUnsigned(0, value.getMaximum(), v)==0) // 13.2 { value.setFromInt(v); return true; } return false;}bool PERDecoder::do_visit(OBJECT_IDENTIFIER& value){ // X.691 Section 23 unsigned dataLen; if (decodeLength(0, 255, dataLen) < 0) return false; beginPosition += dataLen; if (atEnd()) return false; return value.decodeCommon(beginPosition-dataLen, dataLen);}bool PERDecoder::do_visit(BIT_STRING& value){ // X.691 Section 15 if (decodeConstrainedLength(value, value.totalBits) < 0) return false; if (value.totalBits > MaximumStringSize) return false; value.resize(value.totalBits); if (value.size() == 0) return true; // 15.7 if (value.size() > getBitsLeft()) return false; if (value.size() > 16 && aligned()) { unsigned nBytes = (value.size()+7)/8; return decodeBlock(&*(value.bitData.begin()), nBytes) == nBytes; // 15.9 } return decodeBitMap( value.bitData, value.size());}bool PERDecoder::do_visit(OCTET_STRING& value){ // X.691 Section 16 unsigned nBytes; if (decodeConstrainedLength(value, nBytes) < 0) return false; if (nBytes > MaximumStringSize) return false; value.resize(nBytes); // 16.5 unsigned theBits; switch (nBytes) { case 0 : break; case 1 : // 16.6 if (!decodeMultiBit(8, theBits)) return false; value[0] = (char)theBits; break; case 2 : // 16.6 if (!decodeMultiBit(8, theBits)) return false; value[0] = (char)theBits; if (!decodeMultiBit(8, theBits)) return false; value[1] = (char)theBits; break; default: // 16.7 return decodeBlock(&(*value.begin()), nBytes) == nBytes; } return true;}bool PERDecoder::do_visit(AbstractString& value){ // X.691 Section 26 unsigned len; if (decodeConstrainedLength(value, len) < 0) return false; unsigned nBits = value.getNumBits(aligned()); if (len > MaximumStringSize) return false; value.resize(len); if (value.getConstraintType() == Unconstrained || value.getUpperLimit()*nBits > 16) { if (nBits == 8) { if (decodeBlock(&(*value.begin()), len) != len) value.resize(0); return value.size() == len; } if (aligned()) byteAlign(); } unsigned i; for (i = 0; i < (unsigned)len; i++) { unsigned theBits; if (!decodeMultiBit(nBits, theBits)) return false; if (nBits >= value.getCanonicalSetBits() && value.getCanonicalSetBits() > 4) value[i] = (char)theBits; else value[i] = value.getCharacterSet()[theBits]; } return true;}bool PERDecoder::do_visit(BMPString& value){ // X.691 Section 26 unsigned len; if (decodeConstrainedLength(value, len) < 0) return false; if (len > MaximumStringSize) return false; value.resize(len); unsigned nBits = value.getNumBits(aligned()); if ((value.getConstraintType() == Unconstrained || value.getUpperLimit()*nBits > 16) && aligned()) byteAlign(); for (unsigned i = 0; i < (unsigned)len; i++) { unsigned theBits; if (!decodeMultiBit(nBits, theBits)) return false; value[i] = (wchar_t)(theBits + value.getFirstChar()); } return true;}bool PERDecoder::decodeChoicePreamle(CHOICE& value, memento_type& nextPosition){ // X.691 Section 22 if (atEnd()) { return false; } bool ok = true; unsigned choiceID; if (value.extendable()) { if (decodeSingleBit()) { if (!decodeSmallUnsigned(choiceID)) return false; choiceID += value.getNumChoices(); unsigned len; if (decodeLength(0, INT_MAX, len) != 0) return false; nextPosition.bytePosition = beginPosition + len; nextPosition.bitPosition = 8; return value.select(choiceID); } } if (value.getNumChoices() < 2) choiceID = 0; else { if (decodeUnsigned(0, value.getNumChoices()-1, choiceID) < 0) return false; } nextPosition.bytePosition = 0; return value.select(choiceID);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -