private static CompileInternal ( string strText, |
||
strText | string | |
ctx | ||
uRecursionLevel | uint | |
Résultat | string |
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); }
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 }
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); }
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)); }
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); }
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); }
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); }
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); }