C# - MessageBox - Message localization in resources and lines breaks - c#

I would like to show MessageBox (WinForms) with string from Resources with lines breaks.
example without Resources (WORKS):
string someMsg = "Message. Details:\n" + someDetails;
MessageBox.Show(someMsg);
Result:
Message. Details:
here are some details
When I move string "Message. Details:\n" into Resources:
string someMsg = GlobalStrings.MsgBoxJustTest + someDetails;
MessageBox.Show(someMsg);
Result:
Message. Details:\nhere are some details
When I moved string with "\n" to resources then MessageBox.Show() stopped to interpret it as newline.
Edit: I'm thinking about: someMsg.Replace(#'\n',Environment.NewLine);
but it's still quite annoying for so simple thing.

if you add that to resources it doesn't take \n as escape charecter
Just open your resource file in notepad to see this and cahnge in XML file(resx)
or
Type your data in notepad with new line.
Copy that and paste in your resource editor
edit:
or
Type/Paste your data into the resource editor UI, select the \n and replace it with an actual linebreak, with Shift-Enter.

You could do something like this (as long as your not .net 2.0):
public static class StringExt
{
public static String FixNewLines(this String str)
{
return str.Replace(#'\n',Environment.NewLine);
}
}
And then:
string someMsg = GlobalStrings.MsgBoxJustTest + someDetails;
MessageBox.Show(someMsg.FixNewLines());
However, this will affect ALL strings in your application (namespace scope)
It's a dirty fix, but it's a quick fix.
Personally, I would just fix my logic all the way through, rather than do something like the above.

Maybe you can Open the resx file as code and add the line breaks directly in the
XML
OR
Possibly they get lost when reading due to escape character maybe try using \\

One easy solution is to store “placeholders” in a resource strings. For instane, this string is stored in *.resx under “MessageDetails” key: "Message. Details:{0}{1}". Then, in your code, use it like this:
MessageBox.Show(String.Format(GlobalStrings.MessageDetails, Environment.NewLine, #"The message"));
The advantage here is a portability, as you can see.

Related

CWE 73 Error - Veracode Issue -.net application

I have been problem to solve an appointment of Veracode Scanner in my project. I created a function to validate a file but it did not pass in veracode scanner;
Here is the code of my function:
public static string GetSafeFileName(string fileNameToValidate)
{
fileNameToValidate= fileNameToValidate.Replace("'", "''").Replace(#"../", "").Replace(#"..\", "");
char[] blackListChars = System.IO.Path.GetInvalidPathChars();
char[] blackListFilename = System.IO.Path.GetInvalidFileNameChars();
foreach (var invalidChar in blackListChars)
{
if (fileNameToValidate.Contains(invalidChar))
{
fileNameToValidate = fileNameToValidate.Replace(invalidChar, ' ').Trim();
}
}
string fullPath = Path.GetFullPath(fileNameToValidate);
string directoryName = Path.GetDirectoryName(fullPath);
string fileName = Path.GetFileName(fullPath);
foreach (var invalidChar in blackListFilename)
{
if (fileName.Contains(invalidChar))
{
fileName = fileName.Replace(invalidChar, ' ').Trim();
}
}
string finalPath = Path.Combine(directoryName, fileName);
return finalPath;
}
What are the changes i have to fix the cwe 73 appointment in Veracode scanner? Anybody can help me?
My project is a windows forms running on .net 4.0
Thanks,
Bruno
Your problem is that Veracode doesn't actually detect what your code is doing, it detects what cleanser function is (or is not) being called. If you login to Veracode and search for help on "Supported Cleansing Functions" you'll find the list that are detected in your language.
Unfortunately, the list for .Net doesn't include anything for a CWE-73.
So, your solution is to specifically label your function as a cleanser for CWE-73 using a custom cleanser annotation. Search Veracode help for "Annotating Custom Cleansers".
using Veracode.Attributes;
[FilePathCleanser]
public static string GetSafeFileName(string fileNameToValidate)
{
...
That said, your implementation is not secure. Try passing in "C:\Windows\System32\notepad.exe" as a filename to be written to and you'll see the problem.
Blacklisting can only deal with what you expect. Whitelisting is a much stronger approach. Your approach should be based on a whitelist of directories, a whitelist of characters for filenames, and a whitelist of file extensions.
I have tried to solve similar problem but in java context. We used ESAPI as external library. You can review esapi project (for ideas how to realise a better solution in your project):https://github.com/ESAPI/esapi-java-legacy
Actually using esapi validator didn't solve the problem with veracode, but in my opinion reduce the risk for attack. With such a library you can enshure that user can't read file out of parent folder(you must hardcode such a directory) and that the user can't read a file with unproper extension -> you can add such a list with file extensions. But this library cant garantee that you can't manipulate files in the parent directory with allowed extensions.
So if you think that all needed verifications of filepaths are done you must ask for mitigation by design or develope a Map with all needed file resources in the project to enshure that there is no way the user to manipulate external files.
Also if you think that you have created a good filepath verification you can use cleanser annotation to mark your method. Here you can read more about custom cleansers
https://help.veracode.com/reader/DGHxSJy3Gn3gtuSIN2jkRQ/xrEjru~XmUHpO6~0FSae2Q

Revit API: Use String as Button Assembly Name with Current Path

I'm not entirely sure at all why this is happening...
So I have a ExternalCommand and an application for making a ribbon tab and button. These two programs are in the same solution and under the same namespace, which allows me to have fewer files to deal with. When I create a button for my command, I want to put in the current path of the application that is currently running. I do this with Directory.GetCurrentDirectory() + \AddInsAll\Ribbon17.dll (where AddInsAll is the folder and Ribbon17 is the dll, obviously). I use # when necessary to avoid escape sequences. This string contains the exact assembly name needed, but Revit tells me "Assembly does not exist." If I replace this String variable with the hard coded C:\ProgramData\Autodesk\Revit\Addins\2017\AddInsAll\Ribbon17.dll it works. I want it obviously more robust than that. My code will be below, thanks in advance.
FYI: I have a TaskDialog showing when it first runs, and the fullPath that it returns is exacly the same as the hard coded path. I have to do a replace (Program Files to ProgramData) due to some weird bug with the get directory. Also, I add "\AddInsAll\Ribbon17.dll" to the end of the string because the CurrentDirectory goes only to Addins\2017. Finally, if you think the problem is due to the #'s, I have already tried putting it and taking it off of variables and none of the attempts work. But if you think of them is the problem, I welcome the advice. Thanks.
public class RibApp : IExternalApplication
{
public Result OnStartup(Autodesk.Revit.UI.UIControlledApplication application)
{
// Create a custom ribbon tab
String tabName = "Add-Ins";
String fakeFullPath = #Directory.GetCurrentDirectory() + #"\AddInsAll\Ribbon17.dll";
String fullPath = fakeFullPath.Replace(#"\Program Files\", #"\ProgramData\");
TaskDialog.Show("Hi", #fullPath);
application.CreateRibbonTab(tabName);
//Create buttons and panel
// Create two push buttons
PushButtonData CommandButton = new PushButtonData("Command17", "Command",
#fullPath, "Ribbon17.Command");
I suggest you skip the # and replace each backslash \ by a forward slash /.
KISS!
Better still, use an approach similar to the CreateRibbonTab implementation in the HoloLens Escape Path Waypoint JSON Exporter.

Calling a Python script from C# - changing the script's filepath causes the program to not work

The following code works perfectly without flaw:
public partial class MainForm : Form
{
string pyInterp = File.ReadAllText(Directory.GetCurrentDirectory() + #"\config\pathToPythonInterpreter.txt");
string pyWeather = #"C:\getWeather.py";
public MainForm()
{
InitializeComponent();
UpdateWeather();
}
public void UpdateWeather()
{
labelWeather.Text = PySharp.ExecutePy(pyInterp, pyWeather);
}
}
However, when I change the path to getWeather.py to not be in an arbitrary random location, like this:
string pyWeather = Directory.GetCurrentDirectory() + #"\scripts\getWeather.py";
Then my program no longer obtains the script's output. The script still works: I launched it using IDLE and it completed its function properly. When I call it using C#, the console opens, yet no output is obtained.
The Python script is the following:
from requests import get
from bs4 import BeautifulSoup as soup
r = get("http://www.ilmateenistus.ee/ilm/prognoosid/4-oopaeva-prognoos/")
parsed = soup(r.content, "html.parser")
container = parsed.find("div",{"class":"point kuusiku"})
print(str(container["data-title"]))
(It webscrapes my local weather)
PySharp.ExecutePy() can be viewed here
By far the strangest bug I've ever encountered. Any ideas?
EDIT 1: It seems that C# is indeed reading something from the script. It just appears that this something is.. nothing. I gave the label a default sample text, and after running the program, the label's text is simply changed to an empty string. Hope this incredible discovery helps somehow.
EDIT 2: The program fails to call the script correctly when its filepath contains spaces. For example:
C:\foo bar\testing\pyWeather.py
does not work!
Try surrounding the path that contains spaces with 2 double quotes.
For e.g.
string pyWeather = #"""C:\Users\[myname]\Documents\Visual Studio 2017\Projects\testing\testing\scripts\getWeather.py""";
Similarly, you can do string pyWeather = Directory.GetCurrentDirectory() + #"\scripts\getWeather.py"; followed by pyWeather = "\"" + pyWeather + "\"";.
I would want you to return the answer instead of printing. Printer is an I/O based solution to display. So it will work super fine with IDLE however it may not return results as you expected. I strongly believe this will solve your problem.
instead of printing please try return. I can give more support after trying this.
return(str(container["data-title"]))

printing string in c# using \r\n to start new line

I have a asp.net and c# project.
I need to print this string out, i get it like this from the server:
Working...: 0/0\r\nNavigating: 0/0
It should be printed out in 2 separate lines (using the \r\n), shouldn't it be doing that automatically?
Am i doing something wrong?
I cant change the string but the way i use it, is:
I have a EO progress bar that i send a message like this:
_progressBar.UpdateProgress(_count, progress.Message);
And it displays the message under the progressBar.
The message is the string i posted on top.
Thanks
It seems like your string might contain #"\r\n" instead of "\r\n", case in which you'd have to parse the escape characters yourself.
For example, to replace backslash-r by CR and backslash-n by LF (not the most efficient way to do it):
string s0 = #"A\r\nB"; // s0 would print as: A\r\nB
string s = s0.Replace(#"\r","\r").Replace(#"\n","\n");
Now s contains:
A
B
use <br/> - that is a line break in HTML...
EDIT - as per comment:
string X = #"Working...: 0/0\r\nNavigating: 0/0";
string Y = X.Replace ( #"\r\n", #"<br/>" ); // Result is Working...: 0/0<br/>Navigating: 0/0
The server has to send to the client data that the latter understands. JSON, HTML, XML or whatever data type you're working with.
From the client's point of view \r\n is just a string like any other. In this case you may want to send something like:
Working...: 0/0<br/>Navigating: 0/0
And print it has HTML.
You probably are sending a backslash followed by an n or r and not a \r or \n.
If so you have to parse them yourself or get the output to be \r and \n
Yes it is automatic.
using System;
public class Test
{
public static void Main(string[] args)
{
string mesg = "Working...: 0/0\r\nNavigating: 0/0";
Console.WriteLine(mesg);
}
}
C:\temp>csc Test.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.
Copyright (C) Microsoft Corporation. All rights reserved
C:\temp>Test
Working...: 0/0
Navigating: 0/0
C:\temp

Does C# have an equivalent to JavaScript's encodeURIComponent()?

In JavaScript:
encodeURIComponent("©√") == "%C2%A9%E2%88%9A"
Is there an equivalent for C# applications? For escaping HTML characters I used:
txtOut.Text = Regex.Replace(txtIn.Text, #"[\u0080-\uFFFF]",
m => #"&#" + ((int)m.Value[0]).ToString() + ";");
But I'm not sure how to convert the match to the correct hexadecimal format that JS uses. For example this code:
txtOut.Text = Regex.Replace(txtIn.Text, #"[\u0080-\uFFFF]",
m => #"%" + String.Format("{0:x}", ((int)m.Value[0])));
Returns "%a9%221a" for "©√" instead of "%C2%A9%E2%88%9A". It looks like I need to split the string up into bytes or something.
Edit: This is for a windows app, the only items available in System.Web are: AspNetHostingPermission, AspNetHostingPermissionAttribute, and AspNetHostingPermissionLevel.
Uri.EscapeDataString or HttpUtility.UrlEncode is the correct way to escape a string meant to be part of a URL.
Take for example the string "Stack Overflow":
HttpUtility.UrlEncode("Stack Overflow") --> "Stack+Overflow"
Uri.EscapeUriString("Stack Overflow") --> "Stack%20Overflow"
Uri.EscapeDataString("Stack + Overflow") --> Also encodes "+" to "%2b" ---->Stack%20%2B%20%20Overflow
Only the last is correct when used as an actual part of the URL (as opposed to the value of one of the query string parameters)
HttpUtility.HtmlEncode / Decode
HttpUtility.UrlEncode / Decode
You can add a reference to the System.Web assembly if it's not available in your project
I tried to do full compatible analog of javascript's encodeURIComponent for c# and after my 4 hour experiments I found this
c# CODE:
string a = "!##$%^&*()_+ some text here али мамедов баку";
a = System.Web.HttpUtility.UrlEncode(a);
a = a.Replace("+", "%20");
the result is:
!%40%23%24%25%5e%26*()_%2b%20some%20text%20here%20%d0%b0%d0%bb%d0%b8%20%d0%bc%d0%b0%d0%bc%d0%b5%d0%b4%d0%be%d0%b2%20%d0%b1%d0%b0%d0%ba%d1%83
After you decode It with Javascript's decodeURLComponent();
you will get this:
!##$%^&*()_+ some text here али мамедов баку
Thank You for attention
System.Uri.EscapeUriString() didn't seem to do anything, but System.Uri.EscapeDataString() worked for me.
Try Server.UrlEncode(), or System.Web.HttpUtility.UrlEncode() for instances when you don't have access to the Server object. You can also use System.Uri.EscapeUriString() to avoid adding a reference to the System.Web assembly.
For a Windows Store App, you won't have HttpUtility. Instead, you have:
For an URI, before the '?':
System.Uri.EscapeUriString("example.com/Stack Overflow++?")
-> "example.com/Stack%20Overflow++?"
For an URI query name or value, after the '?':
System.Uri.EscapeDataString("Stack Overflow++")
-> "Stack%20Overflow%2B%2B"
For a x-www-form-urlencoded query name or value, in a POST content:
System.Net.WebUtility.UrlEncode("Stack Overflow++")
-> "Stack+Overflow%2B%2B"
You can use the Server object in the System.Web namespace
Server.UrlEncode, Server.UrlDecode, Server.HtmlEncode, and Server.HtmlDecode.
Edit: poster added that this was a windows application and not a web one as one would believe. The items listed above would be available from the HttpUtility class inside System.Web which must be added as a reference to the project.

Categories

Resources