// XXX taken from Windows PWSTreeCtrl.cpp
// XXX move to core
static StringX GetPathElem(StringX &sxPath)
{
  // Get first path element and chop it off, i.e., if
  // path = "a.b.c.d"
  // will return "a" and path will be "b.c.d"
  // path = "a..b.c.d"
  // will return "a." and path will be "b.c.d"
   // (assuming GROUP_SEP is '.')

  StringX sxElement;
  size_t dotPos = sxPath.find_first_of(GROUP_SEP);
  size_t len=sxPath.length();
  if (dotPos == StringX::npos){
    sxElement = sxPath;
    sxPath = wxT("");
  } else {
    while ((dotPos < len) && (sxPath[dotPos] == GROUP_SEP)) {// look for consecutive dots
      dotPos++;
    }
    if (dotPos < len) {
      sxElement = sxPath.substr(0, dotPos-1);
      sxPath = sxPath.substr(dotPos);
    }
    else { // trailing dots
      sxElement = sxPath;
      sxPath = wxT("");
    }
  }
  return sxElement;
}
// Return whether first '«g» «t» «u»' is greater than the second '«g» «t» «u»'
// used in std::sort below.
// Need this as '»' is not in the correct lexical order for blank fields in entry
bool MergeSyncGTUCompare(const StringX &elem1, const StringX &elem2)
{
  StringX g1, t1, u1, g2, t2, u2, tmp1, tmp2;

  StringX::size_type i1 = elem1.find(L'\xbb');
  g1 = (i1 == StringX::npos) ? elem1 : elem1.substr(0, i1 - 1);
  StringX::size_type i2 = elem2.find(L'\xbb');
  g2 = (i2 == StringX::npos) ? elem2 : elem2.substr(0, i2 - 1);
  if (g1 != g2)
    return g1.compare(g2) < 0;

  tmp1 = elem1.substr(g1.length() + 3);
  tmp2 = elem2.substr(g2.length() + 3);
  i1 = tmp1.find(L'\xbb');
  t1 = (i1 == StringX::npos) ? tmp1 : tmp1.substr(0, i1 - 1);
  i2 = tmp2.find(L'\xbb');
  t2 = (i2 == StringX::npos) ? tmp2 : tmp2.substr(0, i2 - 1);
  if (t1 != t2)
    return t1.compare(t2) < 0;

  tmp1 = tmp1.substr(t1.length() + 3);
  tmp2 = tmp2.substr(t2.length() + 3);
  i1 = tmp1.find(L'\xbb');
  u1 = (i1 == StringX::npos) ? tmp1 : tmp1.substr(0, i1 - 1);
  i2 = tmp2.find(L'\xbb');
  u2 = (i2 == StringX::npos) ? tmp2 : tmp2.substr(0, i2 - 1);
  return u1.compare(u2) < 0;
}
Ejemplo n.º 3
0
static void ParseNotes(StringX &sxNotes,
                       std::vector<StringX> &vsxnotes_lines)
{
  if (!sxNotes.empty()) {
    // Use \n and \r to tokenise this line
    StringX::size_type st_start(0), st_end(0);
    const StringX sxdelim = _T("\r\n");
    StringX sxline;
    StringX::size_type st_index;
    while (st_end != StringX::npos) {
      st_end = sxNotes.find(sxdelim, st_start);
      sxline = (sxNotes.substr(st_start, 
                   (st_end == StringX::npos) ? StringX::npos : st_end - st_start));
      st_index = 0;
      // Remove all tabs - \t
      for (;;) {
        st_index = sxline.find(_T("\\t"), st_index);
        if (st_index == StringX::npos)
          break;
        sxline.replace(st_index, 2, _T(""));
        st_index += 1;
      }
      vsxnotes_lines.push_back(sxline);
      st_start = ((st_end > (StringX::npos - sxdelim.size()))
                          ? StringX::npos : st_end + sxdelim.size());
    }
  }
}
Ejemplo n.º 4
0
pws_os::CUUID::CUUID(const StringX &s)
    : m_ua(NULL), m_canonic(false)
{
    // s is a hex string as returned by cast to StringX
    ASSERT(s.length() == 32);
    unsigned char *uu = m_uuid;

    int x;
    for (int i = 0; i < 16; i++) {
        iStringXStream is(s.substr(i*2, 2));
        is >> hex >> x;
        uu[i] = static_cast<unsigned char>(x);
    }
}
Ejemplo n.º 5
0
pws_os::CUUID::CUUID(const StringX &s)
  : m_ua(NULL), m_canonic(false)
{
  // s is a hex string as returned by cast to StringX
  ASSERT(s.length() == 32);
  uuid_array_t ua;

  unsigned int x(0);
  for (size_t i = 0; i < 16; i++) {
    iStringXStream is(s.substr(i * 2, 2));
    is >> hex >> x;
    ua[i] = static_cast<unsigned char>(x);
  }
  array2UUUID(ua, m_uuid);
}
Ejemplo n.º 6
0
static void ExtractURL(StringX &notesStr, StringX &outurl)
{
  StringX instr(notesStr);
  // Extract first instance of (http|https|ftp)://[^ \t\r\n]+
  StringX::size_type left = instr.find(_T("http://"));
  if (left == StringX::npos)
    left = instr.find(_T("https://"));
  if (left == StringX::npos)
    left = instr.find(_T("ftp://"));
  if (left == StringX::npos) {
    outurl = _T("");
  } else {
    StringX url(instr);
    instr = notesStr.substr(0, left);
    url = url.substr(left); // throw out everything left of URL
    StringX::size_type right = url.find_first_of(_T(" \t\r\n"));
    if (right != StringX::npos) {
      instr += url.substr(right);
      url = url.substr(0, right);
    }
    outurl = url;
    notesStr = instr;
  }
}
static void GetFilterTestXML(const st_FilterRow &st_fldata,
                             ostringstream &oss, bool bFile)
{
  CUTF8Conv utf8conv;
  const unsigned char *utf8 = NULL;
  size_t utf8Len = 0;

  const char *sztab4, *sztab5, *szendl;
  if (bFile) {
    sztab4 = "\t\t\t\t";
    sztab5 = "\t\t\t\t\t";
    szendl = "\n";
  } else {
    sztab4 = sztab5 = "\0";
    szendl = "\0";
  }

  if (st_fldata.mtype != PWSMatch::MT_BOOL)
    oss << sztab4 << "<test>" << szendl;

  switch (st_fldata.mtype) {
    case PWSMatch::MT_STRING:
      // Even if rule == 'present'/'not present', need to put 'string' & 'case' XML
      // elements to make schema work, since W3C Schema V1.0 does NOT support 
      // conditional processing :-(
      // 'string' needs special processing to place within CDATA XML construct
      if (!st_fldata.fstring.empty()) { // string empty if 'present' or 'not present'
        PWSUtil::WriteXMLField(oss, "string", st_fldata.fstring, utf8conv, sztab5);
      } else {
        oss << sztab5 << "<string></string>" << szendl;
      }
      oss << sztab5 << "<case>" << st_fldata.fcase 
          << "</case>" << szendl;
      break;
    case PWSMatch::MT_PASSWORD:
      // 'string' needs special processing to place within CDATA XML construct
      PWSUtil::WriteXMLField(oss, "string", st_fldata.fstring, utf8conv, sztab5);
      oss << sztab5 << "<case>" << st_fldata.fcase 
                                              << "</case>" << szendl;
      oss << sztab5 << "<warn>" << st_fldata.fcase 
                                              << "</warn>" << szendl;
      break;
    case PWSMatch::MT_INTEGER:
      oss << sztab5 << "<num1>" << st_fldata.fnum1 
                                              << "</num1>" << endl;
      oss << sztab5 << "<num2>" << st_fldata.fnum2 
                                              << "</num2>" << endl;
      break;
    case PWSMatch::MT_DATE:
    {
      if (st_fldata.fdatetype == 0 /* DTYPE_ABS */) {
        const StringX tmp1 = PWSUtil::ConvertToDateTimeString(st_fldata.fdate1, PWSUtil::TMC_XML);
        utf8conv.ToUTF8(tmp1.substr(0, 10), utf8, utf8Len);
        oss << sztab5 << "<date1>" << utf8
                                                << "</date1>" << szendl;
        const StringX tmp2 = PWSUtil::ConvertToDateTimeString(st_fldata.fdate2, PWSUtil::TMC_XML);
        utf8conv.ToUTF8(tmp2.substr(0, 10), utf8, utf8Len);
        oss << sztab5 << "<date2>" << utf8
                                                << "</date2>" << szendl;
      } else {
        oss << sztab5 << "<num1>" << st_fldata.fnum1 
                                                << "</num1>" << endl;
        oss << sztab5 << "<num2>" << st_fldata.fnum2 
                                                << "</num2>" << endl;
      }
      break;
    }
    case PWSMatch::MT_ENTRYTYPE:
    {
      // Get index for string values
      int index(0);
      switch (st_fldata.etype) {
        case CItemData::ET_NORMAL:       index = 0; break;
        case CItemData::ET_ALIASBASE:    index = 1; break;
        case CItemData::ET_ALIAS:        index = 2; break;
        case CItemData::ET_SHORTCUTBASE: index = 3; break;
        case CItemData::ET_SHORTCUT:     index = 4; break;
        default:
          ASSERT(0);
      }
      oss << sztab5 << "<type>" << szentry[index]
                                              << "</type>" << szendl;
      break;
    }
    case PWSMatch::MT_DCA:
      oss << sztab5 << "<dca>" << st_fldata.fdca 
                                              << "</dca>" << szendl;
      break;
    case PWSMatch::MT_SHIFTDCA:
      oss << sztab5 << "<shiftdca>" << st_fldata.fdca 
                                              << "</shiftdca>" << szendl;
      break;
    case PWSMatch::MT_ENTRYSTATUS:
    {
      // Get index for string values
      int index(0);
      switch (st_fldata.estatus) {
        case CItemData::ES_CLEAN:    index = 0; break;
        case CItemData::ES_ADDED:    index = 1; break;
        case CItemData::ES_MODIFIED: index = 2; break;
        case CItemData::ES_DELETED:  index = 3; break;
        default:
          ASSERT(0);
      }
      oss << sztab5 << "<status>" << szstatus[index]
                                              << "</status>" << szendl;
      break;
    }
    case PWSMatch::MT_ENTRYSIZE:
      oss << sztab5 << "<num1>" << st_fldata.fnum1 
                                              << "</num1>" << endl;
      oss << sztab5 << "<num2>" << st_fldata.fnum2 
                                              << "</num2>" << endl;
      oss << sztab5 << "<unit>" << st_fldata.funit 
                                              << "</unit>" << endl;
      break;
    case PWSMatch::MT_BOOL:
      break;
    default:
      ASSERT(0);
  }
  if (st_fldata.mtype != PWSMatch::MT_BOOL)
    oss << sztab4 << "</test>" << szendl;
}
Ejemplo n.º 8
0
//-----------------------------------------------------------------
// Externally visible functions
//-----------------------------------------------------------------
StringX PWSAuxParse::GetExpandedString(const StringX &sxRun_Command,
                                       const StringX &sxCurrentDB, 
                                       const CItemData *pci, bool &bAutoType,
                                       StringX &sxAutotype, stringT &serrmsg, 
                                       StringX::size_type &st_column,
                                       bool &bURLSpecial)
{
  std::vector<st_RunCommandTokens> v_rctokens;
  std::vector<st_RunCommandTokens>::iterator rc_iter;
  StringX sxretval(_T("")), sxurl;
  stringT spath, sdrive, sdir, sfname, sextn;
  stringT sdbdir;
  bURLSpecial = false;

  UINT uierr = ParseRunCommand(sxRun_Command, v_rctokens, 
                               bAutoType, sxAutotype, 
                               serrmsg, st_column);

  // if called with NULL ci, then we just parse to validate
  if (uierr > 0 || pci == NULL || sxCurrentDB.empty()) {
    v_rctokens.clear();
    return sxretval;
  }

  // derive current db's directory and basename:
  spath = sxCurrentDB.c_str();
  pws_os::splitpath(spath, sdrive, sdir, sfname, sextn);
  sdbdir = pws_os::makepath(sdrive, sdir, _T(""), _T(""));

  for (rc_iter = v_rctokens.begin(); rc_iter < v_rctokens.end(); rc_iter++) {
    st_RunCommandTokens &st_rctoken = *rc_iter;

    if (!st_rctoken.is_variable) {
      sxretval += st_rctoken.sxname.c_str();
      continue;
    }

    if (st_rctoken.sxname == _T("appdir")) {
      sxretval += pws_os::getexecdir().c_str();
    } else
    if (st_rctoken.sxname == _T("dbdir")) {
      sxretval += sdbdir.c_str();
    } else
    if (st_rctoken.sxname == _T("fulldb")) {
      sxretval += spath.c_str();
    } else
    if (st_rctoken.sxname == _T("dbname")) {
      sxretval += sfname.c_str();
    } else
    if (st_rctoken.sxname == _T("dbextn")) {
      sxretval += sextn.c_str();
    } else
    if (st_rctoken.sxname == _T("g") || st_rctoken.sxname == _T("group")) {
      sxretval += pci->GetGroup();
    } else
    if (st_rctoken.sxname == _T("G") || st_rctoken.sxname == _T("GROUP")) {
      StringX sxg = pci->GetGroup();
      StringX::size_type st_index;
      st_index = sxg.rfind(_T("."));
      if (st_index != StringX::npos) {
        sxg = sxg.substr(st_index + 1);
      }
      sxretval += sxg;
    } else
    if (st_rctoken.sxname == _T("t") || st_rctoken.sxname == _T("title")) {
      sxretval += pci->GetTitle();
    } else
    if (st_rctoken.sxname == _T("u") || st_rctoken.sxname == _T("user")) {
      sxretval += pci->GetUser();
    } else
    if (st_rctoken.sxname == _T("p") || st_rctoken.sxname == _T("password")) {
      sxretval += pci->GetPassword();
    } else
      if (st_rctoken.sxname == _T("e") || st_rctoken.sxname == _T("email")) {
      sxretval += pci->GetEmail();
    } else
    if (st_rctoken.sxname == _T("a") || st_rctoken.sxname == _T("autotype")) {
      // Do nothing - autotype variable handled elsewhere
    } else
    if (st_rctoken.sxname == _T("url")) {
      sxurl = pci->GetURL();
      if (sxurl.length() > 0) {
        // Remove 'Browse to' specifics
        StringX::size_type ipos;
        ipos = sxurl.find(_T("[alt]"));
        if (ipos != StringX::npos) {
          bURLSpecial = true;
          sxurl.erase(ipos, 5);
        }
        ipos = sxurl.find(_T("[ssh]"));
        if (ipos != StringX::npos) {
          bURLSpecial = true;
          sxurl.erase(ipos, 5);
        }
        ipos = sxurl.find(_T("{alt}"));
        if (ipos != StringX::npos) {
          bURLSpecial = true;
          sxurl.erase(ipos, 5);
        }
        ipos = sxurl.find(_T("[autotype]"));
        if (ipos != StringX::npos) {
          sxurl.erase(ipos, 10);
        }
        ipos = sxurl.find(_T("[xa]"));
        if (ipos != StringX::npos) {
          sxurl.erase(ipos, 4);
        }
        sxretval += sxurl;
      }
    } else
    if (st_rctoken.sxname == _T("n") || st_rctoken.sxname == _T("notes")) {
      StringX sx_notes = pci->GetNotes();

      if (st_rctoken.index == 0) {
        sxretval += sx_notes;
      } else {
        std::vector<StringX> vsxnotes_lines;
        ParseNotes(sx_notes, vsxnotes_lines);
        // If line there - use it; otherwise ignore it
        if (st_rctoken.index > 0 && st_rctoken.index <= static_cast<int>(vsxnotes_lines.size())) {
          sxretval += vsxnotes_lines[st_rctoken.index - 1];
        } else
        if (st_rctoken.index < 0 &&
            abs(st_rctoken.index) <= static_cast<int>(vsxnotes_lines.size())) {
          sxretval += vsxnotes_lines[vsxnotes_lines.size() + st_rctoken.index];
        }
      }
    } else {
      // Unknown variable name - rebuild it
      sxretval += _T("$");
      if (st_rctoken.has_brackets)
        sxretval += _T("(");
      sxretval += st_rctoken.sxname.c_str();
      if (st_rctoken.index != 0)
        sxretval += st_rctoken.sxindex.c_str();
      if (st_rctoken.has_brackets)
        sxretval += _T(")");
    }
  }
  v_rctokens.clear();
  return sxretval;
}
Ejemplo n.º 9
0
//-----------------------------------------------------------------
// Internal functions
//-----------------------------------------------------------------
static UINT ParseRunCommand(const StringX &sxInputString,
                            std::vector<st_RunCommandTokens> &v_rctokens,
                            bool &bDoAutoType, StringX &sxAutoType,
                            stringT &serrmsg, StringX::size_type &st_column)
{
  // tokenize into separate elements
  std::vector<st_RunCommandTokens>::iterator rc_iter;
  std::vector<size_t> v_pos;
  StringX::iterator str_Iter;
  st_RunCommandTokens st_rctoken;
  size_t st_num_quotes(0);

  UINT uierr(0);
  int var_index(0);

  const stringT alphanum =
    _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");

  if (sxInputString.empty()) {
  // String is empty!
    uierr = IDSC_EXS_INPUTEMPTY;
    goto exit;
  }

  for (StringX::size_type l = 0; l < sxInputString.length(); l++) {
    if (sxInputString[l] == _T('"'))
      st_num_quotes++;
  }

  if (st_num_quotes % 2 != 0) {
    st_column = sxInputString.find(_T('"'));
    // Unmatched quotes
    uierr = IDSC_EXS_UNMATCHEDQUOTES;
    goto exit;
  }

  // tokenize into separate elements using $ as the field separator
  for (StringX::size_type st_startpos = 0;
       st_startpos < sxInputString.size();
       /* st_startpos advanced in body */) {
    StringX::size_type st_next = sxInputString.find(_T('$'), st_startpos);
    if (st_next == StringX::npos)
      st_next = sxInputString.size();
    if (st_next > 0) {
      st_rctoken.sxname = sxInputString.substr(st_startpos, st_next - st_startpos);
      st_rctoken.sxindex = _T("");
      st_rctoken.index = 0;
      st_rctoken.is_variable  = st_startpos == 0 ? false : true;
      st_rctoken.has_brackets = false;
      v_rctokens.push_back(st_rctoken);
      v_pos.push_back(st_startpos);
    }
    st_startpos = st_next + 1; // too complex for for statement
  } // tokenization for loop

  // Check if escaped - ending character of previous token == '\'
  // Make sure this '\' is not escaped itself!
  for (size_t st_idx = v_rctokens.size() - 1; st_idx > 0 ; st_idx--) {
    st_RunCommandTokens &st_rctokens = v_rctokens[st_idx - 1];
    StringX::size_type name_len = st_rctokens.sxname.length();
    if (name_len == 0 || (name_len >= 2 &&
            st_rctokens.sxname.substr(name_len - 2, 2).compare(_T("\\\\")) == 0))
      continue;

    if (st_rctokens.sxname.substr(name_len - 1, 1).compare(_T("\\")) == 0) {
      st_rctokens.sxname = st_rctokens.sxname.substr(0, name_len - 1) + 
                         _T("$") + v_rctokens[st_idx].sxname;
      v_rctokens.erase(v_rctokens.begin() + st_idx);
    }
  }

  // Check if variable enclosed in curly brackets
  for (size_t st_idx = 0; st_idx < v_rctokens.size(); st_idx++) {
    if (v_rctokens[st_idx].sxname.length() == 0)
      continue;

    str_Iter = v_rctokens[st_idx].sxname.begin();
    // Does it start with a curly bracket?
    if (*str_Iter == _T('{')) {
      v_rctokens[st_idx].has_brackets = true;
      StringX sxvar, sxnonvar, sxindex(_T(""));
      // Yes - Find end curly bracket
      StringX::size_type st_end_cb = v_rctokens[st_idx].sxname.find(_T('}'));
      if (st_end_cb == StringX::npos) {
        st_column = v_pos[st_idx] + v_rctokens[st_idx].sxname.length();
        // Missing end curly bracket
        uierr = IDSC_EXS_MISSINGCURLYBKT;
        goto exit;
      }
      // Now see if there is an Index here
      StringX::size_type st_start_sb = v_rctokens[st_idx].sxname.find(_T('['));
      if (st_start_sb != StringX::npos) {
        // Yes  - find end square bracket
        if (st_start_sb > st_end_cb) {
          // Square backet after end of variable
          sxvar = v_rctokens[st_idx].sxname.substr(1, st_end_cb - 1);
          sxnonvar = v_rctokens[st_idx].sxname.substr(st_end_cb + 1);
          v_rctokens[st_idx].sxname = sxvar;
          if (sxnonvar.length() > 0) {
            st_rctoken.sxname = sxnonvar;
            st_rctoken.sxindex = _T("");
            st_rctoken.index = 0;
            st_rctoken.is_variable = false;
            st_rctoken.has_brackets = false;
            v_rctokens.insert(v_rctokens.begin() + st_idx + 1, st_rctoken);
            v_pos.insert(v_pos.begin() + st_idx + 1, v_pos[st_idx] + st_end_cb);
          }
          continue;
        }
        StringX::size_type st_end_sb = v_rctokens[st_idx].sxname.find(_T(']'), st_start_sb);
        if (st_end_sb == StringX::npos) {
          st_column = v_pos[st_idx] + 1;
          // Missing end square bracket
          uierr = IDSC_EXS_MISSINGSQUAREBKT;
          goto exit;
        }
        // The end-curly backet must immediately follow the end-square bracket
        if (st_end_cb != st_end_sb + 1) {
          st_column = v_pos[st_idx] + st_end_sb + 1;
          // Characters between ']' and ')'
          uierr = IDSC_EXS_INVALIDBRACKETS;
          goto exit;
        }
        sxindex = v_rctokens[st_idx].sxname.substr(st_start_sb + 1, st_end_sb - st_start_sb - 1);
        v_rctokens[st_idx].sxindex = sxindex;
        // Now check index
        uierr = ProcessIndex(sxindex, var_index, st_column);
        if (uierr > 0) {
          st_column += v_pos[st_idx];
          goto exit;
        }

        v_rctokens[st_idx].index = var_index;
        sxvar = v_rctokens[st_idx].sxname.substr(1, st_start_sb - 1);
        sxnonvar = v_rctokens[st_idx].sxname.substr(st_end_cb + 1);
      } else {
        // No square bracket
        // Split current token into 'variable' and 'non-variable' parts
        sxvar = v_rctokens[st_idx].sxname.substr(1, st_end_cb - 1);
        sxnonvar = v_rctokens[st_idx].sxname.substr(st_end_cb + 1);
      }
      v_rctokens[st_idx].sxname = sxvar;
      if (sxnonvar.length() > 0) {
        st_rctoken.sxname = sxnonvar;
        st_rctoken.sxindex = _T("");
        st_rctoken.index = 0;
        st_rctoken.is_variable = false;
        st_rctoken.has_brackets = false;
        v_rctokens.insert(v_rctokens.begin() + st_idx + 1, st_rctoken);
        v_pos.insert(v_pos.begin() + st_idx + 1, v_pos[st_idx] + st_end_cb);
      }
    }
  }

  // Now use rules of variables to get the real variable
  for (size_t st_idx = 0; st_idx < v_rctokens.size(); st_idx++) {
    if (!v_rctokens[st_idx].is_variable)
      continue;

    if (v_rctokens[st_idx].sxname.length() == 0) {
      st_column = v_pos[st_idx];
      // Variable name is empty
      uierr = IDSC_EXS_VARNAMEEMPTY;
      goto exit;
    }

    str_Iter = v_rctokens[st_idx].sxname.begin();
    if (!isalpha(*str_Iter)) {
      st_column = v_pos[st_idx];
      // First character of variable is not alphabetic
      uierr = IDSC_EXS_FIRSTNOTALPHA;
      goto exit;
    }
    StringX::size_type st_next = v_rctokens[st_idx].sxname.find_first_not_of(alphanum.c_str());
    if (st_next != StringX::npos) {
      // Split current token into 'variable' and 'non-variable' parts
      StringX sxvar = v_rctokens[st_idx].sxname.substr(0, st_next);
      StringX sxnonvar = v_rctokens[st_idx].sxname.substr(st_next);
      v_rctokens[st_idx].sxname = sxvar;
      // Before saving non-variable part - check if it is an Index e.g. var[i]
      if (sxnonvar.c_str()[0] == _T('[')) {
        // Find ending square bracket
        StringX::size_type st_end_sb = sxnonvar.find(_T(']'));
        if (st_end_sb == StringX::npos) {
          st_column = v_pos[st_idx] + sxvar.length() + 2;
          // Missing end square bracket
          uierr = IDSC_EXS_MISSINGSQUAREBKT;
          goto exit;
        }
        StringX sxindex = sxnonvar.substr(1, st_end_sb - 1);
        v_rctokens[st_idx].sxindex = sxindex;
        // Now check index
        uierr = ProcessIndex(sxindex, var_index, st_column);
        if (uierr > 0) {
          st_column += v_pos[st_idx] + sxvar.length();
          goto exit;
        }

        v_rctokens[st_idx].index = var_index;
        sxnonvar = sxnonvar.substr(st_end_sb + 1);
      } else {
        // Not a square bracket
        if (v_rctokens[st_idx].has_brackets) {
          st_column = v_pos[st_idx] + st_next + 1;
          // Variable must be alphanumeric
          uierr = IDSC_EXS_VARNAMEINVALID;
          goto exit;
        }
      }
      if (!sxnonvar.empty()) {
        st_rctoken.sxname = sxnonvar;
        st_rctoken.sxindex = _T("");
        st_rctoken.index = 0;
        st_rctoken.is_variable = false;
        st_rctoken.has_brackets = false;
        v_rctokens.insert(v_rctokens.begin() + st_idx + 1, st_rctoken);
        v_pos.insert(v_pos.begin() + st_idx + 1, v_pos[st_idx] + st_next);
      }
    }
  }

  // Special Autotype processing
  bDoAutoType = false;
  sxAutoType = _T("");
  for (size_t st_idx = 0; st_idx < v_rctokens.size(); st_idx++) {
    if (!v_rctokens[st_idx].is_variable)
      continue;

    // Is it a autotype variable?
    if (v_rctokens[st_idx].sxname == _T("a") ||
        v_rctokens[st_idx].sxname == _T("autotype")) {
      bDoAutoType = true;
      // Is the next token text and starts with '('?
      if (st_idx + 1 < v_rctokens.size() &&
          !v_rctokens[st_idx + 1].is_variable &&
          v_rctokens[st_idx + 1].sxname.c_str()[0] == _T('(')) {
        // Find ending round bracket
        StringX sx_autotype = v_rctokens[st_idx + 1].sxname;
        StringX::size_type st_end_rb = sx_autotype.find(_T(')'));
        if (st_end_rb == StringX::npos) {
          st_column = v_pos[st_idx + 1] + sx_autotype.length() + 2;
          // Missing end round bracket
          uierr = IDSC_EXS_MISSINGROUNDBKT;
          goto exit;
        }
        sxAutoType = sx_autotype.substr(1, st_end_rb - 1);
        v_rctokens[st_idx + 1].sxname = sx_autotype.substr(st_end_rb + 1);
        // Check if anything left in this text - none -> delete
        if (v_rctokens[st_idx + 1].sxname.length() == 0)
          v_rctokens.erase(v_rctokens.begin() + st_idx + 1);
        // Now delete Autotype variable
        v_rctokens.erase(v_rctokens.begin() + st_idx);
        break;
      }
    }
  }

exit:
  if (uierr != 0)
    LoadAString(serrmsg, uierr);
  else
    serrmsg = _T("");

  if (uierr > 0) {
    v_rctokens.clear();
  }
  v_pos.clear();
  return uierr;
}
Ejemplo n.º 10
0
StringX PWSAuxParse::GetAutoTypeString(const StringX &sx_in_autotype,
                                       const StringX &sx_group,
                                       const StringX &sx_title,
                                       const StringX &sx_user,
                                       const StringX &sx_pwd,
                                       const StringX &sx_notes,
                                       const StringX &sx_url,
                                       const StringX &sx_email,
                                       std::vector<size_t> &vactionverboffsets)
{
  StringX sxtmp(_T(""));
  StringX sxNotes(sx_notes);
  TCHAR curChar;
  StringX sx_autotype(sx_in_autotype);
  StringX::size_type st_index;
  std::vector<StringX> vsxnotes_lines;

  vactionverboffsets.clear();

  // If empty, try the database default
  if (sx_autotype.empty()) {
    sx_autotype = PWSprefs::GetInstance()->
              GetPref(PWSprefs::DefaultAutotypeString);

    // If still empty, take this default
    if (sx_autotype.empty()) {
      // checking for user and password for default settings
      if (!sx_pwd.empty()){
        if (!sx_user.empty())
          sx_autotype = DEFAULT_AUTOTYPE;
        else
          sx_autotype = _T("\\p\\n");
      }
    }
  }

  // No recursive substitution (e.g. \p or \u), although '\t' will be replaced by a tab
  if (!sx_notes.empty()) {
    // Use \n and \r to tokenise this line
    StringX::size_type st_start(0), st_end(0);
    const StringX sxdelim = _T("\r\n");
    StringX sxline;
    while (st_end != StringX::npos) {
      st_end = sxNotes.find_first_of(sxdelim, st_start);
      sxline = (sxNotes.substr(st_start, (st_end == StringX::npos) ? 
                              StringX::npos : st_end - st_start));
      st_index = 0;
      for (;;) {
        st_index = sxline.find(_T("\\t"), st_index);
        if (st_index == StringX::npos)
          break;
        sxline.replace(st_index, 2, _T("\t"));
        st_index += 1;
      }
      vsxnotes_lines.push_back(sxline);
      // If we just hit a "\r\n", move past it.  Or else, it is a "\r" without
      // a following "\n" or a "\n", so just move past one single char
      if (st_end != StringX::npos) {
        st_start = st_end + (sxNotes.compare(st_end, 2, sxdelim) == 0 ? 2 : 1);
        if (st_start >= sxNotes.length())
          break;
      }
    }
    // Now change '\n' to '\r' in the complete notes field
    st_index = 0;
    for (;;) {
      st_index = sxNotes.find(sxdelim, st_index);
      if (st_index == StringX::npos)
        break;
      sxNotes.replace(st_index, 2, _T("\r"));
      st_index += 1;
    }
    st_index = 0;
    for (;;) {
      st_index = sxNotes.find(_T("\\t"), st_index);
      if (st_index == StringX::npos)
        break;
      sxNotes.replace(st_index, 2, _T("\t"));
      st_index += 1;
    }
  }

  const size_t N = sx_autotype.length();
  const StringX sxZeroes = _T("000");
  int gNumIts;

  for (size_t n = 0; n < N; n++){
    curChar = sx_autotype[n];
    if (curChar == TCHAR('\\')) {
      n++;
      if (n < N)
        curChar = sx_autotype[n];

      switch (curChar){
        case TCHAR('\\'):
          sxtmp += TCHAR('\\');
          break;
        case TCHAR('n'):
        case TCHAR('r'):
          sxtmp += TCHAR('\r');
          break;
        case TCHAR('t'):
          sxtmp += TCHAR('\t');
          break;
        case TCHAR('s'):
          sxtmp += TCHAR('\v');
          break;
        case TCHAR('g'):
          sxtmp += sx_group;
          break;
        case TCHAR('i'):
          sxtmp += sx_title;
          break;
        case TCHAR('u'):
          sxtmp += sx_user;
          break;
        case TCHAR('p'):
          sxtmp += sx_pwd;
          break;
        case TCHAR('l'):
          sxtmp += sx_url;
          break;
        case TCHAR('m'):
          sxtmp += sx_email;
          break;

        case TCHAR('o'):
        {
          if (n == (N - 1)) {
            // This was the last character - send the lot!
            sxtmp += sxNotes;
            break;
          }
          size_t line_number(0);
          gNumIts = 0;
          for (n++; n < N && (gNumIts < 3); ++gNumIts, n++) {
            if (_istdigit(sx_autotype[n])) {
              line_number *= 10;
              line_number += (sx_autotype[n] - TCHAR('0'));
            } else
              break; // for loop
          }
          if (line_number == 0) {
            // Send the lot
            sxtmp += sx_notes;
          } else
          if (line_number <= vsxnotes_lines.size()) {
            // User specifies a too big a line number - ignore the lot
            sxtmp += vsxnotes_lines[line_number - 1];
          }

          // Backup the extra character that delimited the \oNNN string
          n--;
          break; // case 'o'
        }

        // Action Verbs:
        // These are the only ones processed specially by the UI as they involve
        // actions it performs whilst doing the key sending.
        // Copy them to output string unchanged.
        case TCHAR('b'):  // backspace!
        case TCHAR('z'):  // Use older method
          vactionverboffsets.push_back(sxtmp.length());
          sxtmp += _T("\\");
          sxtmp += curChar;
          break; // case 'b' & 'z'

        case TCHAR('d'):  // Delay
        case TCHAR('w'):  // Wait milli-seconds
        case TCHAR('W'):  // Wait seconds
        {
          // Need to ensure that the field length is 3, even if it wasn't
          vactionverboffsets.push_back(sxtmp.length());
          sxtmp += _T("\\");
          sxtmp += curChar;

          gNumIts = 0;
          size_t i = n;
          for (i++; i < N && (gNumIts < 3); ++gNumIts, i++) {
            if (!_istdigit(sx_autotype[i]))
              break;
          }
          // Insert sufficient zeroes to ensure field is 3 characters long
          sxtmp += sxZeroes.substr(0, 3 - gNumIts);
          break; // case 'd', 'w' & 'W'
        }

        // Also copy explicit control characters to output string unchanged.
        case TCHAR('a'): // bell (can't hear it during testing!)
        case TCHAR('v'): // vertical tab
        case TCHAR('f'): // form feed
        case TCHAR('e'): // escape
        case TCHAR('x'): // hex digits (\xNN)
        // and any others we have forgotten!
        // '\cC', '\uXXXX', '\OOO', '\<any other charatcer not recognised above>'
        default:
          sxtmp += L'\\';
          sxtmp += curChar;
          break;
      }
    } else
      sxtmp += curChar;
  }

  vsxnotes_lines.clear();
  return sxtmp;
}