CompileInternal() private static method

private static CompileInternal ( string strText, SprContext ctx, uint uRecursionLevel ) : string
strText string
ctx SprContext
uRecursionLevel uint
return string
コード例 #1
0
ファイル: SprEngine.cs プロジェクト: vallades/KeePass2.x
        private static string FillIfExists(string strData, string strPlaceholder,
                                           ProtectedString psParsable, SprContext ctx, uint uRecursionLevel)
        {
            // // The UrlRemoveSchemeOnce property of ctx must be cleared
            // // before this method returns and before any recursive call
            // bool bRemoveScheme = false;
            // if(ctx != null)
            // {
            //	bRemoveScheme = ctx.UrlRemoveSchemeOnce;
            //	ctx.UrlRemoveSchemeOnce = false;
            // }

            if (strData == null)
            {
                Debug.Assert(false); return(string.Empty);
            }
            if (strPlaceholder == null)
            {
                Debug.Assert(false); return(strData);
            }
            if (strPlaceholder.Length == 0)
            {
                Debug.Assert(false); return(strData);
            }
            if (psParsable == null)
            {
                Debug.Assert(false); return(strData);
            }

            if (strData.IndexOf(strPlaceholder, SprEngine.ScMethod) >= 0)
            {
                string strReplacement = SprEngine.CompileInternal(
                    psParsable.ReadString(), ctx.WithoutContentTransformations(),
                    uRecursionLevel + 1);

                // if(bRemoveScheme)
                //	strReplacement = UrlUtil.RemoveScheme(strReplacement);

                return(SprEngine.FillPlaceholder(strData, strPlaceholder,
                                                 strReplacement, ctx));
            }

            return(strData);
        }
コード例 #2
0
        private static string ShowCharPickDlg(string strWord, uint uCharCount,
                                              bool?bInitHide, SprContext ctx, uint uRecursionLevel)
        {
            string strPick = SprEngine.CompileInternal(strWord,
                                                       ctx.WithoutContentTransformations(), uRecursionLevel + 1);

            // No need to show the dialog when there's nothing to pick from
            // (this also prevents the dialog from showing up MaxRecursionDepth
            // times in case of a cyclic {PICKCHARS})
            if (string.IsNullOrEmpty(strPick))
            {
                return(string.Empty);
            }

            ProtectedString psWord    = new ProtectedString(false, strPick);
            string          strPicked = CharPickerForm.ShowAndRestore(psWord,
                                                                      true, true, uCharCount, bInitHide);

            return(strPicked ?? string.Empty);              // Don't transform here
        }
コード例 #3
0
        public static string Compile(string strText, SprContext ctx)
        {
            if (strText == null)
            {
                Debug.Assert(false); return(string.Empty);
            }
            if (strText.Length == 0)
            {
                return(string.Empty);
            }

            if (ctx == null)
            {
                ctx = new SprContext();
            }
            ctx.RefCache.Clear();

            string str = SprEngine.CompileInternal(strText, ctx, 0);

            // if(bEscapeForAutoType && !bIsAutoTypeSequence)
            //	str = SprEncoding.MakeAutoTypeSequence(str);

            return(str);
        }
コード例 #4
0
        private static string ReplacePickPwPlaceholder(string str,
                                                       string strPlaceholder, uint uCharCount, SprContext ctx,
                                                       uint uRecursionLevel)
        {
            if (str.IndexOf(strPlaceholder, StrUtil.CaseIgnoreCmp) < 0)
            {
                return(str);
            }

            ProtectedString ps = ctx.Entry.Strings.Get(PwDefs.PasswordField);

            if (ps != null)
            {
                string strPassword = ps.ReadString();

                string strPick = SprEngine.CompileInternal(strPassword,
                                                           ctx.WithoutContentTransformations(), uRecursionLevel + 1);

                if (!string.IsNullOrEmpty(strPick))
                {
                    ProtectedString psPick = new ProtectedString(false, strPick);
                    CharPickerForm  dlg    = new CharPickerForm();
                    dlg.InitEx(psPick, true, true, uCharCount, null);

                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        str = StrUtil.ReplaceCaseInsensitive(str, strPlaceholder,
                                                             SprEngine.TransformContent(
                                                                 dlg.SelectedCharacters.ReadString(), ctx));
                    }
                    UIUtil.DestroyForm(dlg);
                }
            }

            return(StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, string.Empty));
        }
コード例 #5
0
        private static string FillRefPlaceholders(string strSeq, SprContext ctx,
                                                  uint uRecursionLevel)
        {
            if (ctx.Database == null)
            {
                return(strSeq);
            }

            string str = strSeq;

            int nOffset = 0;

            for (int iLoop = 0; iLoop < 20; ++iLoop)
            {
                str = ctx.RefCache.Fill(str, ctx);

                int nStart = str.IndexOf(StrRefStart, nOffset, SprEngine.ScMethod);
                if (nStart < 0)
                {
                    break;
                }
                int nEnd = str.IndexOf(StrRefEnd, nStart + 1, SprEngine.ScMethod);
                if (nEnd <= nStart)
                {
                    break;
                }

                string  strFullRef = str.Substring(nStart, nEnd - nStart + 1);
                char    chScan, chWanted;
                PwEntry peFound = FindRefTarget(strFullRef, ctx, out chScan, out chWanted);

                if (peFound != null)
                {
                    string strInsData;
                    if (chWanted == 'T')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.TitleField);
                    }
                    else if (chWanted == 'U')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.UserNameField);
                    }
                    else if (chWanted == 'A')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.UrlField);
                    }
                    else if (chWanted == 'P')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.PasswordField);
                    }
                    else if (chWanted == 'N')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.NotesField);
                    }
                    else if (chWanted == 'I')
                    {
                        strInsData = peFound.Uuid.ToHexString();
                    }
                    else
                    {
                        nOffset = nStart + 1; continue;
                    }

                    if ((chWanted == 'P') && !ctx.ForcePlainTextPasswords &&
                        Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password))
                    {
                        strInsData = PwDefs.HiddenPassword;
                    }

                    SprContext sprSub = ctx.WithoutContentTransformations();
                    sprSub.Entry = peFound;

                    string strInnerContent = SprEngine.CompileInternal(strInsData,
                                                                       sprSub, uRecursionLevel + 1);
                    strInnerContent = SprEngine.TransformContent(strInnerContent, ctx);

                    // str = str.Substring(0, nStart) + strInnerContent + str.Substring(nEnd + 1);
                    ctx.RefCache.Add(strFullRef, strInnerContent, ctx);
                    str = ctx.RefCache.Fill(str, ctx);
                }
                else
                {
                    nOffset = nStart + 1; continue;
                }
            }

            return(str);
        }
コード例 #6
0
        private static string FillUriSpecial(string strText, SprContext ctx,
                                             string strPlhInit, string strData, bool bDataIsEncoded,
                                             uint uRecursionLevel)
        {
            Debug.Assert(strPlhInit.StartsWith(@"{") && !strPlhInit.EndsWith(@"}"));
            Debug.Assert(strData != null);

            string[] vPlhs = new string[] {
                strPlhInit + @"}",
                strPlhInit + @":RMVSCM}",
                strPlhInit + @":SCM}",
                strPlhInit + @":HOST}",
                strPlhInit + @":PORT}",
                strPlhInit + @":PATH}",
                strPlhInit + @":QUERY}",
                strPlhInit + @":USERINFO}",
                strPlhInit + @":USERNAME}",
                strPlhInit + @":PASSWORD}"
            };

            string str        = strText;
            string strDataCmp = null;
            Uri    uri        = null;

            for (int i = 0; i < vPlhs.Length; ++i)
            {
                string strPlh = vPlhs[i];
                if (str.IndexOf(strPlh, SprEngine.ScMethod) < 0)
                {
                    continue;
                }

                if (strDataCmp == null)
                {
                    SprContext ctxData = (bDataIsEncoded ?
                                          ctx.WithoutContentTransformations() : ctx);
                    strDataCmp = SprEngine.CompileInternal(strData, ctxData,
                                                           uRecursionLevel + 1);
                }

                string strRep = null;
                if (i == 0)
                {
                    strRep = strDataCmp;
                }
                // UrlUtil supports prefixes like cmd://
                else if (i == 1)
                {
                    strRep = UrlUtil.RemoveScheme(strDataCmp);
                }
                else if (i == 2)
                {
                    strRep = UrlUtil.GetScheme(strDataCmp);
                }
                else
                {
                    try
                    {
                        if (uri == null)
                        {
                            uri = new Uri(strDataCmp);
                        }

                        int t;
                        switch (i)
                        {
                        // case 2: strRep = uri.Scheme; break; // No cmd:// support
                        case 3: strRep = uri.Host; break;

                        case 4:
                            strRep = uri.Port.ToString(
                                NumberFormatInfo.InvariantInfo);
                            break;

                        case 5: strRep = uri.AbsolutePath; break;

                        case 6: strRep = uri.Query; break;

                        case 7: strRep = uri.UserInfo; break;

                        case 8:
                            strRep = uri.UserInfo;
                            t      = strRep.IndexOf(':');
                            if (t >= 0)
                            {
                                strRep = strRep.Substring(0, t);
                            }
                            break;

                        case 9:
                            strRep = uri.UserInfo;
                            t      = strRep.IndexOf(':');
                            if (t < 0)
                            {
                                strRep = string.Empty;
                            }
                            else
                            {
                                strRep = strRep.Substring(t + 1);
                            }
                            break;

                        default: Debug.Assert(false); break;
                        }
                    }
                    catch (Exception) { }                    // Invalid URI
                }
                if (strRep == null)
                {
                    strRep = string.Empty;                                // No assert
                }
                str = StrUtil.ReplaceCaseInsensitive(str, strPlh, strRep);
            }

            return(str);
        }
コード例 #7
0
        private static string CompileInternal(string strText, SprContext ctx,
                                              uint uRecursionLevel)
        {
            if (strText == null)
            {
                Debug.Assert(false); return(string.Empty);
            }
            if (ctx == null)
            {
                Debug.Assert(false); ctx = new SprContext();
            }

            if (uRecursionLevel >= SprEngine.MaxRecursionDepth)
            {
                Debug.Assert(false);                 // Most likely a recursive reference
                return(string.Empty);                // Do not return strText (endless loop)
            }

            string   str = strText;
            MainForm mf  = Program.MainForm;

            bool bExt = ((ctx.Flags & (SprCompileFlags.ExtActive |
                                       SprCompileFlags.ExtNonActive)) != SprCompileFlags.None);

            if (bExt && (SprEngine.FilterCompilePre != null))
            {
                SprEventArgs args = new SprEventArgs(str, ctx.Clone());
                SprEngine.FilterCompilePre(null, args);
                str = args.Text;
            }

            if ((ctx.Flags & SprCompileFlags.Comments) != SprCompileFlags.None)
            {
                str = RemoveComments(str);
            }

            // The following realizes {T-CONV:/Text/Raw/}, which should be
            // one of the first transformations (except comments)
            if ((ctx.Flags & SprCompileFlags.TextTransforms) != SprCompileFlags.None)
            {
                str = PerformTextTransforms(str, ctx, uRecursionLevel);
            }

            if ((ctx.Flags & SprCompileFlags.Run) != SprCompileFlags.None)
            {
                str = RunCommands(str, ctx, uRecursionLevel);
            }

            if ((ctx.Flags & SprCompileFlags.DataActive) != SprCompileFlags.None)
            {
                str = PerformClipboardCopy(str, ctx, uRecursionLevel);
            }

            if (((ctx.Flags & SprCompileFlags.DataNonActive) != SprCompileFlags.None) &&
                (str.IndexOf(@"{CLIPBOARD}", SprEngine.ScMethod) >= 0))
            {
                string strCb = null;
                try { strCb = ClipboardUtil.GetText(); }
                catch (Exception) { Debug.Assert(false); }
                str = Fill(str, @"{CLIPBOARD}", strCb ?? string.Empty, ctx, null);
            }

            if ((ctx.Flags & SprCompileFlags.AppPaths) != SprCompileFlags.None)
            {
                str = AppLocator.FillPlaceholders(str, ctx);
            }

            if (ctx.Entry != null)
            {
                if ((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None)
                {
                    str = ReplacePickPw(str, ctx, uRecursionLevel);
                }

                if ((ctx.Flags & SprCompileFlags.EntryStrings) != SprCompileFlags.None)
                {
                    str = FillEntryStrings(str, ctx, uRecursionLevel);
                }

                if ((ctx.Flags & SprCompileFlags.EntryStringsSpecial) != SprCompileFlags.None)
                {
                    str = FillEntryStringsSpecial(str, ctx, uRecursionLevel);
                }

                if (((ctx.Flags & SprCompileFlags.EntryProperties) != SprCompileFlags.None) &&
                    (str.IndexOf(@"{UUID}", SprEngine.ScMethod) >= 0))
                {
                    str = Fill(str, @"{UUID}", ctx.Entry.Uuid.ToHexString(), ctx, null);
                }

                if (((ctx.Flags & SprCompileFlags.PasswordEnc) != SprCompileFlags.None) &&
                    (str.IndexOf(@"{PASSWORD_ENC}", SprEngine.ScMethod) >= 0))
                {
                    string strPwCmp = SprEngine.CompileInternal(@"{PASSWORD}",
                                                                ctx.WithoutContentTransformations(), uRecursionLevel + 1);
                    str = Fill(str, @"{PASSWORD_ENC}", StrUtil.EncryptString(
                                   strPwCmp), ctx, null);
                }

                PwGroup pg = ctx.Entry.ParentGroup;
                if (((ctx.Flags & SprCompileFlags.Group) != SprCompileFlags.None) &&
                    (pg != null))
                {
                    str = FillGroupPlh(str, @"{GROUP", pg, ctx, uRecursionLevel);
                }
            }

            if ((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None)
            {
                if (mf != null)
                {
                    PwGroup pgSel = mf.GetSelectedGroup();
                    if (pgSel != null)
                    {
                        str = FillGroupPlh(str, @"{GROUP_SEL", pgSel, ctx, uRecursionLevel);
                    }
                }

                str = Fill(str, @"{APPDIR}", UrlUtil.GetFileDirectory(
                               WinUtil.GetExecutable(), false, false), ctx, uRecursionLevel);

                str = Fill(str, @"{ENV_DIRSEP}", Path.DirectorySeparatorChar.ToString(),
                           ctx, null);

                string strPF86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
                if (string.IsNullOrEmpty(strPF86))
                {
                    strPF86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
                }
                if (strPF86 != null)
                {
                    str = Fill(str, @"{ENV_PROGRAMFILES_X86}", strPF86, ctx, uRecursionLevel);
                }
                else
                {
                    Debug.Assert(false);
                }

                if (ctx.Database != null)
                {
                    string strPath = ctx.Database.IOConnectionInfo.Path;
                    string strDir  = UrlUtil.GetFileDirectory(strPath, false, false);
                    string strName = UrlUtil.GetFileName(strPath);

                    // For backward compatibility only
                    str = Fill(str, @"{DOCDIR}", strDir, ctx, uRecursionLevel);

                    str = Fill(str, @"{DB_PATH}", strPath, ctx, uRecursionLevel);
                    str = Fill(str, @"{DB_DIR}", strDir, ctx, uRecursionLevel);
                    str = Fill(str, @"{DB_NAME}", strName, ctx, uRecursionLevel);
                    str = Fill(str, @"{DB_BASENAME}", UrlUtil.StripExtension(
                                   strName), ctx, uRecursionLevel);
                    str = Fill(str, @"{DB_EXT}", UrlUtil.GetExtension(
                                   strPath), ctx, uRecursionLevel);
                }
            }

            if ((ctx.Flags & SprCompileFlags.AutoType) != SprCompileFlags.None)
            {
                // Use Bksp instead of Del (in order to avoid Ctrl+Alt+Del);
                // https://sourceforge.net/p/keepass/discussion/329220/thread/4f1aa6b8/
                str = StrUtil.ReplaceCaseInsensitive(str, @"{CLEARFIELD}",
                                                     @"{HOME}+({END}){BKSP}{DELAY 50}");
            }

            if (((ctx.Flags & SprCompileFlags.DateTime) != SprCompileFlags.None) &&
                (str.IndexOf(@"{DT_", SprEngine.ScMethod) >= 0))
            {
                DateTime dtNow = DateTime.UtcNow;
                str = Fill(str, @"{DT_UTC_YEAR}", dtNow.Year.ToString("D4"),
                           ctx, null);
                str = Fill(str, @"{DT_UTC_MONTH}", dtNow.Month.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_UTC_DAY}", dtNow.Day.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_UTC_HOUR}", dtNow.Hour.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_UTC_MINUTE}", dtNow.Minute.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_UTC_SECOND}", dtNow.Second.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_UTC_SIMPLE}", dtNow.ToString("yyyyMMddHHmmss"),
                           ctx, null);

                dtNow = dtNow.ToLocalTime();
                str   = Fill(str, @"{DT_YEAR}", dtNow.Year.ToString("D4"),
                             ctx, null);
                str = Fill(str, @"{DT_MONTH}", dtNow.Month.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_DAY}", dtNow.Day.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_HOUR}", dtNow.Hour.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_MINUTE}", dtNow.Minute.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_SECOND}", dtNow.Second.ToString("D2"),
                           ctx, null);
                str = Fill(str, @"{DT_SIMPLE}", dtNow.ToString("yyyyMMddHHmmss"),
                           ctx, null);
            }

            if ((ctx.Flags & SprCompileFlags.References) != SprCompileFlags.None)
            {
                str = SprEngine.FillRefPlaceholders(str, ctx, uRecursionLevel);
            }

            if (((ctx.Flags & SprCompileFlags.EnvVars) != SprCompileFlags.None) &&
                (str.IndexOf('%') >= 0))
            {
                foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
                {
                    string strKey = (de.Key as string);
                    if (string.IsNullOrEmpty(strKey))
                    {
                        Debug.Assert(false); continue;
                    }

                    string strValue = (de.Value as string);
                    if (strValue == null)
                    {
                        Debug.Assert(false); strValue = string.Empty;
                    }

                    str = Fill(str, @"%" + strKey + @"%", strValue, ctx, uRecursionLevel);
                }
            }

            if ((ctx.Flags & SprCompileFlags.Env) != SprCompileFlags.None)
            {
                str = FillUriSpecial(str, ctx, @"{BASE", (ctx.Base ?? string.Empty),
                                     ctx.BaseIsEncoded, uRecursionLevel);
            }

            str = EntryUtil.FillPlaceholders(str, ctx, uRecursionLevel);

            if ((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None)
            {
                str = ReplacePickChars(str, ctx, uRecursionLevel);
            }

            if (bExt && (SprEngine.FilterCompile != null))
            {
                SprEventArgs args = new SprEventArgs(str, ctx.Clone());
                SprEngine.FilterCompile(null, args);
                str = args.Text;
            }

            if (ctx.EncodeAsAutoTypeSequence)
            {
                str = StrUtil.NormalizeNewLines(str, false);
                str = str.Replace("\n", @"{ENTER}");
            }

            return(str);
        }
コード例 #8
0
        private static string FillRefPlaceholders(string strSeq, PwDatabase pwDatabase,
                                                  SprContentFlags cf, uint uRecursionLevel, SprRefsCache vRefsCache)
        {
            if (pwDatabase == null)
            {
                return(strSeq);
            }

            string str = strSeq;

            const string strStart = @"{REF:";
            const string strEnd   = @"}";

            int nOffset = 0;

            for (int iLoop = 0; iLoop < 20; ++iLoop)
            {
                str = SprEngine.FillRefsUsingCache(str, vRefsCache);

                int nStart = str.IndexOf(strStart, nOffset, SprEngine.ScMethod);
                if (nStart < 0)
                {
                    break;
                }
                int nEnd = str.IndexOf(strEnd, nStart, SprEngine.ScMethod);
                if (nEnd < 0)
                {
                    break;
                }

                string strFullRef = str.Substring(nStart, nEnd - nStart + 1);

                string strRef = str.Substring(nStart + strStart.Length, nEnd -
                                              nStart - strStart.Length);
                if (strRef.Length <= 4)
                {
                    nOffset = nStart + 1; continue;
                }
                if (strRef[1] != '@')
                {
                    nOffset = nStart + 1; continue;
                }
                if (strRef[3] != ':')
                {
                    nOffset = nStart + 1; continue;
                }

                char chScan   = char.ToUpper(strRef[2]);
                char chWanted = char.ToUpper(strRef[0]);

                SearchParameters sp = SearchParameters.None;
                sp.SearchString = strRef.Substring(4);
                if (chScan == 'T')
                {
                    sp.SearchInTitles = true;
                }
                else if (chScan == 'U')
                {
                    sp.SearchInUserNames = true;
                }
                else if (chScan == 'A')
                {
                    sp.SearchInUrls = true;
                }
                else if (chScan == 'P')
                {
                    sp.SearchInPasswords = true;
                }
                else if (chScan == 'N')
                {
                    sp.SearchInNotes = true;
                }
                else if (chScan == 'I')
                {
                    sp.SearchInUuids = true;
                }
                else if (chScan == 'O')
                {
                    sp.SearchInOther = true;
                }
                else
                {
                    nOffset = nStart + 1; continue;
                }

                PwObjectList <PwEntry> lFound = new PwObjectList <PwEntry>();
                pwDatabase.RootGroup.SearchEntries(sp, lFound, true);
                if (lFound.UCount > 0)
                {
                    PwEntry peFound = lFound.GetAt(0);

                    string strInsData;
                    if (chWanted == 'T')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.TitleField);
                    }
                    else if (chWanted == 'U')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.UserNameField);
                    }
                    else if (chWanted == 'A')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.UrlField);
                    }
                    else if (chWanted == 'P')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.PasswordField);
                    }
                    else if (chWanted == 'N')
                    {
                        strInsData = peFound.Strings.ReadSafe(PwDefs.NotesField);
                    }
                    else if (chWanted == 'I')
                    {
                        strInsData = peFound.Uuid.ToHexString();
                    }
                    else
                    {
                        nOffset = nStart + 1; continue;
                    }

                    string strInnerContent = SprEngine.CompileInternal(strInsData,
                                                                       peFound, pwDatabase, null, uRecursionLevel + 1, vRefsCache);
                    strInnerContent = SprEngine.TransformContent(strInnerContent, cf);

                    // str = str.Substring(0, nStart) + strInnerContent + str.Substring(nEnd + 1);
                    SprEngine.AddRefToCache(strFullRef, strInnerContent, vRefsCache);
                    str = SprEngine.FillRefsUsingCache(str, vRefsCache);
                }
                else
                {
                    nOffset = nStart + 1; continue;
                }
            }

            return(str);
        }