private void ProcessDuplicates(TextObjectBase obj)
        {
            if (duplicates.ContainsKey(obj.Name))
            {
                List <TextObjectBase> list    = duplicates[obj.Name];
                TextObjectBase        lastObj = list[list.Count - 1];

                bool isDuplicate = true;
                // compare Text
                if (obj.Text != lastObj.Text)
                {
                    isDuplicate = false;
                }
                else
                {
                    float lastObjBottom = (lastObj.Parent as ReportComponentBase).Bottom;
                    float objTop        = (obj.Parent as ReportComponentBase).Top;
                    if (Math.Abs(objTop - lastObjBottom) > 0.5f)
                    {
                        isDuplicate = false;
                    }
                }

                if (isDuplicate)
                {
                    list.Add(obj);
                }
                else
                {
                    // close duplicates
                    CloseDuplicates(list);
                    // add new obj
                    list.Clear();
                    list.Add(obj);
                }
            }
            else
            {
                List <TextObjectBase> list = new List <TextObjectBase>();
                list.Add(obj);
                duplicates.Add(obj.Name, list);
            }
        }
 public TextObjectBaseTests()
 {
     textObject = new TextObjectBase();
 }
        private void InternalCompile()
        {
            // set the current folder
            string currentFolder = Config.ApplicationFolder;

            if (Config.WebMode)
            {
                try
                {
                    if (Directory.Exists(currentFolder + @"Bin\"))
                    {
                        currentFolder += @"Bin\";
                    }
                }
                catch
                {
                }
            }
            // Commented by Samuray
            //Directory.SetCurrentDirectory(currentFolder);

            // configure compiler options
            CompilerParameters cp = new CompilerParameters();

            AddFastReportAssemblies(cp.ReferencedAssemblies);
#if NETCOREAPP
            cp.ReferencedAssemblies.Add("System.Drawing.Primitives");
#endif
            AddReferencedAssemblies(cp.ReferencedAssemblies, currentFolder);
            ReviewReferencedAssemblies(cp.ReferencedAssemblies);
            cp.GenerateInMemory = true;
            // sometimes the system temp folder is not accessible...
            if (Config.TempFolder != null)
            {
                cp.TempFiles = new TempFileCollection(Config.TempFolder, false);
            }

            // find assembly in cache
            StringBuilder assemblyHashSB = new StringBuilder();
            foreach (string a in cp.ReferencedAssemblies)
            {
                assemblyHashSB.Append(a);
            }
            assemblyHashSB.Append(scriptText.ToString());
            byte[] hash = null;
            using (HMACSHA1 hMACSHA1 = new HMACSHA1(Encoding.ASCII.GetBytes(shaKey)))
            {
                hash = hMACSHA1.ComputeHash(Encoding.Unicode.GetBytes(assemblyHashSB.ToString()));
            }
            string   assemblyHash   = Convert.ToBase64String(hash);
            Assembly cachedAssembly = null;
            if (FAssemblyCache.TryGetValue(assemblyHash, out cachedAssembly))
            {
                assembly = cachedAssembly;
                InitInstance(assembly.CreateInstance("FastReport.ReportScript"));
                return;
            }

            // compile report script
            using (CodeDomProvider provider = Report.CodeHelper.GetCodeProvider())
            {
                CompilerResults cr = provider.CompileAssemblyFromSource(cp, scriptText.ToString());
                assembly = null;
                instance = null;
                bool needException = true; // shows need to throw exception or errors can be handled without exception
                if (cr.Errors.Count > 0)
                {
                    string errors = "";
                    foreach (CompilerError ce in cr.Errors)
                    {
                        int line = GetScriptLine(ce.Line);
                        // error is inside own items
                        if (line == -1)
                        {
                            string errObjName = GetErrorObjectName(ce.Line);

                            // handle division by zero errors
                            if (ce.ErrorNumber == "CS0020")
                            {
                                TextObjectBase text = Report.FindObject(errObjName) as TextObjectBase;
                                text.CanGrow   = true;
                                text.FillColor = Color.Red;
                                text.Text      = "DIVISION BY ZERO!";
                                if (cr.Errors.Count == 1) // there are only division by zero errors, exception does't needed
                                {
                                    needException = false;
                                }
                            }
                            else
                            {
                                errors += String.Format("({0}): " + Res.Get("Messages,Error") + " {1}: {2}", new object[] { errObjName, ce.ErrorNumber, ce.ErrorText }) + "\r\n";
                                ErrorMsg(errObjName, ce);
                            }
                        }
                        else
                        {
                            errors += String.Format("({0},{1}): " + Res.Get("Messages,Error") + " {2}: {3}", new object[] { line, ce.Column, ce.ErrorNumber, ce.ErrorText }) + "\r\n";
                            ErrorMsg(ce, line);
                        }
                    }
                    if (needException) // throw exception if errors were not handled
                    {
                        throw new CompilerException(errors);
                    }
                }
                else
                {
#if DOTNET_4
                    FAssemblyCache.TryAdd(assemblyHash, cr.CompiledAssembly);
#else
                    FAssemblyCache.Add(assemblyHash, cr.CompiledAssembly);
#endif
                    assembly = cr.CompiledAssembly;
                    InitInstance(assembly.CreateInstance("FastReport.ReportScript"));
                }
            }
        }
 public ProcessInfo(TextObjectBase obj, XmlItem item)
 {
     textObject = obj;
     xmlItem    = item;
 }
Beispiel #5
0
        /// <summary>
        /// Handle compile errors
        /// </summary>
        /// <returns>Returns <b>true</b> if all errors were handled</returns>
        private bool HandleCompileErrors(CompilerParameters cp, CompilerResults cr, out string errors)
        {
            errors = string.Empty;
            List <string> additionalAssemblies = new List <string>(4);
            Regex         regex;

            if (Config.WebMode && Config.EnableScriptSecurity)
            {
                for (int i = 0; i < cr.Errors.Count;)
                {
                    CompilerError ce = cr.Errors[i];
                    if (ce.ErrorNumber == "CS1685") // duplicate class
                    {
                        cr.Errors.Remove(ce);
                        continue;
                    }
                    else if (ce.ErrorNumber == "CS0436") // user using a forbidden type
                    {
                        const string pattern = "[\"'](\\S+)[\"']";
                        regex = new Regex(pattern, RegexOptions.Compiled);
                        string typeName = regex.Match(ce.ErrorText).Value;

                        const string res     = "Web,ScriptSecurity,ForbiddenType";
                        string       message = Res.TryGet(res);
                        if (string.Equals(res, message))
                        {
                            message = "Please, don't use the type " + typeName;
                        }
                        else
                        {
                            message = message.Replace("{typeName}", typeName); //$"Please, don't use the type {typeName}";
                        }
                        ce.ErrorText = message;
                    }
                    else if (ce.ErrorNumber == "CS0117") // user using a forbidden method
                    {
                        const string pattern = "[\"'](\\S+)[\"']";
                        regex = new Regex(pattern, RegexOptions.Compiled);
                        MatchCollection mathes = regex.Matches(ce.ErrorText);
                        if (mathes.Count > 1)
                        {
                            string methodName = mathes[1].Value;

                            const string res     = "Web,ScriptSecurity,ForbiddenMethod";
                            string       message = Res.TryGet(res);
                            if (string.Equals(res, message))
                            {
                                message = "Please, don't use the method " + methodName;
                            }
                            else
                            {
                                message = message.Replace("{methodName}", methodName); //$"Please, don't use the method {methodName}";
                            }
                            ce.ErrorText = message;
                        }
                    }

                    i++;
                }
            }

            foreach (CompilerError ce in cr.Errors)
            {
                if (ce.ErrorNumber == "CS0012") // missing reference on assembly
                {
                    // try to add reference
                    try
                    {
                        // in .Net Core compiler will return other quotes
#if NETSTANDARD || NETCOREAPP
                        const string quotes = "\'";
#else
                        const string quotes = "\"";
#endif
                        const string pattern = quotes + @"(\S{1,}),";
                        regex = new Regex(pattern, RegexOptions.Compiled);
                        string assemblyName = regex.Match(ce.ErrorText).Groups[1].Value;   // Groups[1] include string without quotes and , symbols
                        if (!additionalAssemblies.Contains(assemblyName))
                        {
                            additionalAssemblies.Add(assemblyName);
                        }
                        continue;
                    }
                    catch { }
                }

                int line = GetScriptLine(ce.Line);
                // error is inside own items
                if (line == -1)
                {
                    string errObjName = GetErrorObjectName(ce.Line);

                    // handle division by zero errors
                    if (ce.ErrorNumber == "CS0020")
                    {
                        TextObjectBase text = Report.FindObject(errObjName) as TextObjectBase;
                        text.CanGrow   = true;
                        text.FillColor = Color.Red;
                        text.Text      = "DIVISION BY ZERO!";
                        if (cr.Errors.Count == 1) // there are only division by zero errors, exception does't needed
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        errors += String.Format("({0}): " + Res.Get("Messages,Error") + " {1}: {2}", new object[] { errObjName, ce.ErrorNumber, ce.ErrorText }) + "\r\n";
                        ErrorMsg(errObjName, ce);
                    }
                }
                else
                {
                    errors += String.Format("({0},{1}): " + Res.Get("Messages,Error") + " {2}: {3}", new object[] { line, ce.Column, ce.ErrorNumber, ce.ErrorText }) + "\r\n";
                    ErrorMsg(ce, line);
                }
            }

            if (additionalAssemblies.Count > 0)  // need recompile
            {
                return(ReCompile(cp, cr, additionalAssemblies));
            }

            return(false);
        }
        private FastString GetSpanText(TextObjectBase obj, FastString text,
                                       float top, float width,
                                       float ParagraphOffset)
        {
            FastString style = new FastString();

            style.Append("display:block;border:0;width:").Append(Px(width * Zoom));
            if (ParagraphOffset != 0)
            {
                style.Append("text-indent:").Append(Px(ParagraphOffset * Zoom));
            }
            if (obj.Padding.Left != 0)
            {
                style.Append("padding-left:").Append(Px((obj.Padding.Left) * Zoom));
            }
            if (obj.Padding.Right != 0)
            {
                style.Append("padding-right:").Append(Px(obj.Padding.Right * Zoom));
            }
            if (top != 0)
            {
                style.Append("margin-top:").Append(Px(top * Zoom));
            }

            // we need to apply border width in order to position our div perfectly
            float borderLeft   = 0;
            float borderRight  = 0;
            float borderTop    = 0;
            float borderBottom = 0;

            if (HTMLBorderWidthValues(obj, out borderLeft, out borderTop, out borderRight, out borderBottom))
            {
                style.Append("position:absolute;")
                .Append("left:").Append(Px(-1 * borderLeft / 2f))
                .Append("top:").Append(Px(-1 * borderTop / 2f));
            }

            string href = String.Empty;

            if (!String.IsNullOrEmpty(obj.Hyperlink.Value))
            {
                string hrefStyle = String.Empty;
                if (obj is TextObject)
                {
                    TextObject textObject = obj as TextObject;
                    hrefStyle = String.Format("style=\"color:{0}{1}\"",
                                              ExportUtils.HTMLColor(textObject.TextColor),
                                              !textObject.Font.Underline ? ";text-decoration:none" : String.Empty
                                              );
                }
                string url = EncodeURL(obj.Hyperlink.Value);
                if (obj.Hyperlink.Kind == HyperlinkKind.URL)
                {
                    href = String.Format("<a {0} href=\"{1}\"" + (obj.Hyperlink.OpenLinkInNewTab ? "target=\"_blank\"" : "") + ">", hrefStyle, obj.Hyperlink.Value);
                }
                else if (obj.Hyperlink.Kind == HyperlinkKind.DetailReport)
                {
                    url = String.Format("{0},{1},{2}",
                                        EncodeURL(obj.Name), // object name for security reasons
                                        EncodeURL(obj.Hyperlink.ReportParameter),
                                        EncodeURL(obj.Hyperlink.Value));
                    string onClick = String.Format(OnClickTemplate, ReportID, "detailed_report", url);
                    href = String.Format("<a {0} href=\"#\" onclick=\"{1}\">", hrefStyle, onClick);
                }
                else if (obj.Hyperlink.Kind == HyperlinkKind.DetailPage)
                {
                    url = String.Format("{0},{1},{2}",
                                        EncodeURL(obj.Name),
                                        EncodeURL(obj.Hyperlink.ReportParameter),
                                        EncodeURL(obj.Hyperlink.Value));
                    string onClick = String.Format(OnClickTemplate, ReportID, "detailed_page", url);
                    href = String.Format("<a {0} href=\"#\" onclick=\"{1}\">", hrefStyle, onClick);
                }
                else if (SinglePage)
                {
                    if (obj.Hyperlink.Kind == HyperlinkKind.Bookmark)
                    {
                        href = String.Format("<a {0} href=\"#{1}\">", hrefStyle, url);
                    }
                    else if (obj.Hyperlink.Kind == HyperlinkKind.PageNumber)
                    {
                        href = String.Format("<a {0} href=\"#PageN{1}\">", hrefStyle, url);
                    }
                }
                else
                {
                    string onClick = String.Empty;
                    if (obj.Hyperlink.Kind == HyperlinkKind.Bookmark)
                    {
                        onClick = String.Format(OnClickTemplate, ReportID, "bookmark", url);
                    }
                    else if (obj.Hyperlink.Kind == HyperlinkKind.PageNumber)
                    {
                        onClick = String.Format(OnClickTemplate, ReportID, "goto", url);
                    }

                    if (onClick != String.Empty)
                    {
                        href = String.Format("<a {0} href=\"#\" onclick=\"{1}\">", hrefStyle, onClick);
                    }
                }
            }

            FastString result = new FastString(128);

            result.Append("<div ").
            Append(GetStyleTag(UpdateCSSTable(style.ToString()))).Append(">").
            Append(href).Append(text).Append(href != String.Empty ? "</a>" : String.Empty).
            Append("</div>");

            return(result);
        }
Beispiel #7
0
        /// <summary>
        /// Handle compile errors
        /// </summary>
        /// <returns>Returns <"true"> if all errors were handled</returns>
        private bool HandleCompileErrors(CompilerParameters cp, CompilerResults cr, out string errors)
        {
            errors = string.Empty;
            List <string> assemblyList = new List <string>(4);

            foreach (CompilerError ce in cr.Errors)
            {
                if (ce.ErrorNumber == "CS0012") // missing reference on assembly
                {
                    // try to add reference
                    try
                    {
                        const string pattern      = @"'(\S{1,}),";
                        Regex        regex        = new Regex(pattern);
                        string       assemblyName = regex.Match(ce.ErrorText).Groups[1].Value; // Groups[1] include string without ' and , symbols
                        if (!assemblyList.Contains(assemblyName))
                        {
                            assemblyList.Add(assemblyName);
                        }
                        continue;
                    }
                    catch { }
                }

                int line = GetScriptLine(ce.Line);
                // error is inside own items
                if (line == -1)
                {
                    string errObjName = GetErrorObjectName(ce.Line);

                    // handle division by zero errors
                    if (ce.ErrorNumber == "CS0020")
                    {
                        TextObjectBase text = Report.FindObject(errObjName) as TextObjectBase;
                        text.CanGrow   = true;
                        text.FillColor = Color.Red;
                        text.Text      = "DIVISION BY ZERO!";
                        if (cr.Errors.Count == 1) // there are only division by zero errors, exception does't needed
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        errors += String.Format("({0}): " + Res.Get("Messages,Error") + " {1}: {2}", new object[] { errObjName, ce.ErrorNumber, ce.ErrorText }) + "\r\n";
                        ErrorMsg(errObjName, ce);
                    }
                }
                else
                {
                    errors += String.Format("({0},{1}): " + Res.Get("Messages,Error") + " {2}: {3}", new object[] { line, ce.Column, ce.ErrorNumber, ce.ErrorText }) + "\r\n";
                    ErrorMsg(ce, line);
                }
            }

            if (assemblyList.Count > 0)  // need recompile
            {
                return(ReCompile(cp, cr, assemblyList));
            }

            return(false);
        }