bool FX_atonum(const CFX_ByteStringC& strc, void* pData) { if (strc.Find('.') != -1) { FX_FLOAT* pFloat = static_cast<FX_FLOAT*>(pData); *pFloat = FX_atof(strc); return false; } // Note, numbers in PDF are typically of the form 123, -123, etc. But, // for things like the Permissions on the encryption hash the number is // actually an unsigned value. We use a uint32_t so we can deal with the // unsigned and then check for overflow if the user actually signed the value. // The Permissions flag is listed in Table 3.20 PDF 1.7 spec. pdfium::base::CheckedNumeric<uint32_t> integer = 0; bool bNegative = false; bool bSigned = false; int cc = 0; if (strc[0] == '+') { cc++; bSigned = true; } else if (strc[0] == '-') { bNegative = true; bSigned = true; cc++; } while (cc < strc.GetLength() && std::isdigit(strc[cc])) { integer = integer * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc)); if (!integer.IsValid()) break; cc++; } // We have a sign, and the value was greater then a regular integer // we've overflowed, reset to the default value. if (bSigned) { if (bNegative) { if (integer.ValueOrDefault(kDefaultIntValue) > static_cast<uint32_t>(std::numeric_limits<int>::max()) + 1) { integer = kDefaultIntValue; } } else if (integer.ValueOrDefault(kDefaultIntValue) > static_cast<uint32_t>(std::numeric_limits<int>::max())) { integer = kDefaultIntValue; } } // Switch back to the int space so we can flip to a negative if we need. int value = static_cast<int>(integer.ValueOrDefault(kDefaultIntValue)); if (bNegative) value = -value; int* pInt = static_cast<int*>(pData); *pInt = value; return true; }
FX_FLOAT FX_atof(const CFX_ByteStringC& strc) { if (strc.IsEmpty()) return 0.0; int cc = 0; bool bNegative = false; int len = strc.GetLength(); if (strc[0] == '+') { cc++; } else if (strc[0] == '-') { bNegative = TRUE; cc++; } while (cc < len) { if (strc[cc] != '+' && strc[cc] != '-') { break; } cc++; } FX_FLOAT value = 0; while (cc < len) { if (strc[cc] == '.') { break; } value = value * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc)); cc++; } int scale = 0; if (cc < len && strc[cc] == '.') { cc++; while (cc < len) { value += FXSYS_FractionalScale(scale, FXSYS_toDecimalDigit(strc.CharAt(cc))); scale++; if (scale == FXSYS_FractionalScaleCount()) break; cc++; } } return bNegative ? -value : value; }
int64_t FX_atoi64(const char* nptr) { int c; /* current char */ int64_t total; /* current total */ int sign; /* if '-', then negative, otherwise positive */ /* skip whitespace */ while (isspace((int)(unsigned char)*nptr)) ++nptr; c = (int)(unsigned char)*nptr++; sign = c; /* save sign indication */ if (c == '-' || c == '+') c = (int)(unsigned char)*nptr++; /* skip sign */ total = 0; while (isdigit(c)) { total = 10 * total + FXSYS_toDecimalDigit(c); /* accumulate digit */ c = (int)(unsigned char)*nptr++; /* get next char */ } return sign == '-' ? -total : total; }
CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString( const CFX_ByteString& dtStr) { int strLength = dtStr.GetLength(); if (strLength > 0) { int i = 0; int j, k; FX_CHAR ch; while (i < strLength && !std::isdigit(dtStr[i])) ++i; if (i >= strLength) return *this; j = 0; k = 0; while (i < strLength && j < 4) { ch = dtStr[i]; k = k * 10 + FXSYS_toDecimalDigit(ch); j++; if (!std::isdigit(ch)) break; i++; } dt.year = (int16_t)k; if (i >= strLength || j < 4) return *this; j = 0; k = 0; while (i < strLength && j < 2) { ch = dtStr[i]; k = k * 10 + FXSYS_toDecimalDigit(ch); j++; if (!std::isdigit(ch)) break; i++; } dt.month = (uint8_t)k; if (i >= strLength || j < 2) return *this; j = 0; k = 0; while (i < strLength && j < 2) { ch = dtStr[i]; k = k * 10 + FXSYS_toDecimalDigit(ch); j++; if (!std::isdigit(ch)) break; i++; } dt.day = (uint8_t)k; if (i >= strLength || j < 2) return *this; j = 0; k = 0; while (i < strLength && j < 2) { ch = dtStr[i]; k = k * 10 + FXSYS_toDecimalDigit(ch); j++; if (!std::isdigit(ch)) break; i++; } dt.hour = (uint8_t)k; if (i >= strLength || j < 2) return *this; j = 0; k = 0; while (i < strLength && j < 2) { ch = dtStr[i]; k = k * 10 + FXSYS_toDecimalDigit(ch); j++; if (!std::isdigit(ch)) break; i++; } dt.minute = (uint8_t)k; if (i >= strLength || j < 2) return *this; j = 0; k = 0; while (i < strLength && j < 2) { ch = dtStr[i]; k = k * 10 + FXSYS_toDecimalDigit(ch); j++; if (!std::isdigit(ch)) break; i++; } dt.second = (uint8_t)k; if (i >= strLength || j < 2) return *this; ch = dtStr[i++]; if (ch != '-' && ch != '+') return *this; if (ch == '-') dt.tzHour = -1; else dt.tzHour = 1; j = 0; k = 0; while (i < strLength && j < 2) { ch = dtStr[i]; k = k * 10 + FXSYS_toDecimalDigit(ch); j++; if (!std::isdigit(ch)) break; i++; } dt.tzHour *= (FX_CHAR)k; if (i >= strLength || j < 2) return *this; ch = dtStr[i++]; if (ch != '\'') return *this; j = 0; k = 0; while (i < strLength && j < 2) { ch = dtStr[i]; k = k * 10 + FXSYS_toDecimalDigit(ch); j++; if (!std::isdigit(ch)) break; i++; } dt.tzMinute = (uint8_t)k; if (i >= strLength || j < 2) return *this; } return *this; }
extern "C" double FXstrtod(const char* nptr, char** endptr) { double ret = 0.0; const char* ptr = nptr; const char* exp_ptr = NULL; int e_number = 0, e_signal = 0, e_point = 0, is_negative = 0; int exp_ret = 0, exp_sig = 1, fra_ret = 0, fra_count = 0, fra_base = 1; if (nptr == NULL) { return 0.0; } for (;; ptr++) { if (!e_number && !e_point && (*ptr == '\t' || *ptr == ' ')) continue; if (std::isdigit(*ptr)) { if (!e_number) e_number = 1; if (!e_point) { ret *= 10; ret += FXSYS_toDecimalDigit(*ptr); } else { fra_count++; fra_ret *= 10; fra_ret += FXSYS_toDecimalDigit(*ptr); } continue; } if (!e_point && *ptr == '.') { e_point = 1; continue; } if (!e_number && !e_point && !e_signal) { switch (*ptr) { case '-': is_negative = 1; case '+': e_signal = 1; continue; } } if (e_number && (*ptr == 'e' || *ptr == 'E')) { exp_ptr = ptr++; if (*ptr == '+' || *ptr == '-') { exp_sig = (*ptr++ == '+') ? 1 : -1; if (!std::isdigit(*ptr)) { if (endptr) { *endptr = (char*)exp_ptr; } break; } EXPONENT_DETECT(ptr); } else if (std::isdigit(*ptr)) { EXPONENT_DETECT(ptr); } else { if (endptr) { *endptr = (char*)exp_ptr; } break; } break; } if (ptr != nptr && !e_number) { if (endptr) { *endptr = (char*)nptr; } break; } if (endptr) { *endptr = (char*)ptr; } break; } while (fra_count--) { fra_base *= 10; } ret += (double)fra_ret / (double)fra_base; if (exp_sig == 1) { while (exp_ret--) { ret *= 10.0; } } else { while (exp_ret--) { ret /= 10.0; } } return is_negative ? -ret : ret; }
uint32_t CXML_Parser::GetCharRef() { m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; if (IsEOF()) { return 0; } uint8_t ch; int32_t iState = 0; CFX_ByteTextBuf buf; uint32_t code = 0; do { while (m_dwIndex < m_dwBufferSize) { ch = m_pBuffer[m_dwIndex]; switch (iState) { case 0: if (ch == '#') { m_dwIndex++; iState = 2; break; } iState = 1; case 1: m_dwIndex++; if (ch == ';') { CFX_ByteStringC ref = buf.AsStringC(); if (ref == "gt") { code = '>'; } else if (ref == "lt") { code = '<'; } else if (ref == "amp") { code = '&'; } else if (ref == "apos") { code = '\''; } else if (ref == "quot") { code = '"'; } iState = 10; break; } buf.AppendByte(ch); break; case 2: if (ch == 'x') { m_dwIndex++; iState = 4; break; } iState = 3; case 3: m_dwIndex++; if (ch == ';') { iState = 10; break; } if (g_FXCRT_XML_IsDigital(ch)) code = code * 10 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); break; case 4: m_dwIndex++; if (ch == ';') { iState = 10; break; } uint8_t nHex = g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_HexChar; if (nHex) { if (nHex == FXCRTM_XML_CHARTYPE_HexDigital) { code = (code << 4) + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)); } else if (nHex == FXCRTM_XML_CHARTYPE_HexLowerLetter) { code = (code << 4) + ch - 87; } else { code = (code << 4) + ch - 55; } } break; } if (iState == 10) { break; } } m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) { break; } } while (ReadNextBlock()); return code; }
CFX_ByteString CPDF_StreamParser::ReadString() { if (!PositionIsInBounds()) return CFX_ByteString(); int ch = m_pBuf[m_Pos++]; CFX_ByteTextBuf buf; int parlevel = 0; int status = 0, iEscCode = 0; while (1) { switch (status) { case 0: if (ch == ')') { if (parlevel == 0) { if (buf.GetLength() > MAX_STRING_LENGTH) { return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); } return buf.GetByteString(); } parlevel--; buf.AppendChar(')'); } else if (ch == '(') { parlevel++; buf.AppendChar('('); } else if (ch == '\\') { status = 1; } else { buf.AppendChar((char)ch); } break; case 1: if (ch >= '0' && ch <= '7') { iEscCode = FXSYS_toDecimalDigit(ch); status = 2; break; } if (ch == 'n') { buf.AppendChar('\n'); } else if (ch == 'r') { buf.AppendChar('\r'); } else if (ch == 't') { buf.AppendChar('\t'); } else if (ch == 'b') { buf.AppendChar('\b'); } else if (ch == 'f') { buf.AppendChar('\f'); } else if (ch == '\r') { status = 4; break; } else if (ch == '\n') { } else { buf.AppendChar(ch); } status = 0; break; case 2: if (ch >= '0' && ch <= '7') { iEscCode = iEscCode * 8 + FXSYS_toDecimalDigit(ch); status = 3; } else { buf.AppendChar(iEscCode); status = 0; continue; } break; case 3: if (ch >= '0' && ch <= '7') { iEscCode = iEscCode * 8 + FXSYS_toDecimalDigit(ch); buf.AppendChar(iEscCode); status = 0; } else { buf.AppendChar(iEscCode); status = 0; continue; } break; case 4: status = 0; if (ch != '\n') { continue; } break; } if (!PositionIsInBounds()) break; ch = m_pBuf[m_Pos++]; } if (PositionIsInBounds()) ch = m_pBuf[m_Pos++]; if (buf.GetLength() > MAX_STRING_LENGTH) { return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); } return buf.GetByteString(); }