how to fix a double substring call? - string

in my homework I need to extract the server name from the url
at the same time, I need to take into account that there may not be a slash after the server name
I'm not allowed to use a loop
At the same time, I am once again trying to redo a remark from my teacher:
"Now substring can be done twice (if it goes into if). You need to make sure that only one substring is made for any variant of the function execution"
how can this be fixed? I've tried everything
public class Url {
public static String getServerName(String url) {
int index1 = url.indexOf("://") + 3;
String serverName = url.substring(index1);
int index2 = serverName.indexOf("/");
if (index2 >= 0) {
return url.substring(index1, index1 + index2);
}
return serverName;
}
public static void main(String[] args) {
String url = "https://SomeServerName";
System.out.println(getServerName(url));
}
}

Related

Java help: running 2 loops interconnected. scanner with while

Can anyone guide me on this, please?
The main idea is to have 2 loops which are called to run
public class time9 {
static void userInput() {
Scanner input = new Scanner(System.in);
String input2check = input.next();
//condition when there is an input to stop loop
}
static void timeUnit() {
for(int i = 1; i<60; i++) {
**//this makes seconds, minutes and hours**
}
}
public static void main(String[] args) {
for (int i = 1; i<60; i++){
userInput(input2check);
timeUnit(i);
**// for every i in timeUnit check user input.
// if no user input, time loop continues
// if there is user input, stop time loop**
}
}
}
You declare static void userInput() as taking no parameters, but you attempt to pass in 1 parameter: userInput(input2check). You should also make userInput
static boolean userInput(), because you are looking for a true/false statement as to whether the loop should break. Therefore, in your second for loop, you would have an if statement referring to userInput():
public class time9 {
static boolean userInput() {
Scanner input = new Scanner(System.in);
String input2check = input.next();
return (input2check != null);
/*true/false statement: return whether input2check is not null. Return true if not null, false otherwise.*/
}
static void timeUnit() {
for(int i = 1; i<60; i++) {
**//this makes seconds, minutes and hours**
}
}
public static void main(String[] args) {
for (int i = 1; i<60; i++){
if (userInput()){break;}
else{timeUnit);
}
}
}
You again tried to pass parameter i into static void timeUnit() which takes no parameters. Don't do it. Either declare a method like
[accessModifier] [returnType] [methodName] (parameter(s)),
and call it as [methodName](parameters)
or declare it as [accessModifier] [returnType] [methodName](), and call it as [methodName]().
If you pass params into a method that takes none, it has no algorithm to deal with those params and will not compile. If you pass no params into a method that takes params, it will not have an algorithm to deal with the lack of params, and will not compile.
Lastly, please know that your time loop should have nothing to do with the number 60 except by coincidence. Iterating 60 times through a for loop will NOT take 60 seconds. For loops can iterate several hundreds of thousands of times per second, so your 60 iteration for loop would take a matter of nanoseconds, unless you are using something like Thread.sleep(millis, nanos) which pauses the process for the milliseconds and nanos you set it to.

If Else: String Equality (Java)

Lab Description : Compare two strings to see if each of the two strings contains the same letters in the
same order.
This is what I have so far far:
import static java.lang.System.*;
public class StringEquality
{
private String wordOne, wordTwo;
public StringEquality()
{
}
public StringEquality(String one, String two)
{
setWords (wordOne, wordTwo);
}
public void setWords(String one, String two)
{
wordOne = one;
wordTwo = two;
}
public boolean checkEquality()
{
if (wordOne == wordTwo)
return true;
else
return false;
}
public String toString()
{
String output = "";
if (checkEquality())
output += wordOne + " does not have the same letters as " + wordTwo;
else
output += wordOne + " does have the same letters as " + wordTwo;
return output;
}
}
My runner looks like this:
import static java.lang.System.*;
public class StringEqualityRunner
{
public static void main(String args[])
{
StringEquality test = new StringEquality();
test.setWords(hello, goodbye);
out.println(test);
}
}
Everything is compiling except for the runner. It keeps saying that hello and goodbye aren't variables. How can I fix this so that the program does not read hello and goodbye as variables, but as Strings?
You need to quote strings otherwise they are treated as variables.
"hello"
"goodbye"
so this would work better.
test.setWords("hello", "goodbye");
Problem with your code is with checkEquality(), you are comparing the string's position in memory when you use == use .equals() to check the string
public boolean checkEquality()
{
if (wordOne == wordTwo) //use wordOne.equals(wordTwo) here
return true;
else
return false;
}
Enclose them in double-quotes.

Getting highest available string in java

I want to get the highest available string value in java how can i achieve this.
Example: hello jameswangfron
I want to get the highest string "jameswangfron"
String Text = request.getParameter("hello jameswangfron");
Please code example.
public class HelloWorld{
public static void main(String []args){
String text = "hello jameswangfron";
String[] textArray = text.split(" ");
String biggestString = "";
for(int i=0; i<textArray.length; i++){
if(i==0) {
textArray[i].length();
biggestString = textArray[i];
} else {
if(textArray[i].length()>textArray[i-1].length()){
biggestString = textArray[i];
}
}
}
System.out.println("Biggest String : "+biggestString);
}
}
And it shows the output as
Biggest String : jameswangfron
Maybe this will be easyer to understand
public class HelloWorld {
public static void main(String[] args) {
System.out.println(StringManipulator.getMaxLengthString("hello jameswangfron", " "));
}
}
class StringManipulator{
public static String getMaxLengthString(String data, String separator){
String[] stringArray = data.split(separator);
String toReturn = "";
int maxLengthSoFar = 0;
for (String string : stringArray) {
if(string.length()>maxLengthSoFar){
maxLengthSoFar = string.length();
toReturn = string;
}
}
return toReturn;
}
}
But there is a catch. If you pay attention to split method from class String, you will find out that the spliter is actually a regex. For your code, i see that you want to separate the words (which means blank space). if you want an entire text to search, you have to pass a regex.
Here's a tip. If you want your words to be separated by " ", ".", "," (you get the ideea) then you should replace the " " from getMaxLengthString method with the following
"[^a-zA-Z0-9]"
If you want digits to split up words, simply put
"[^a-zA-Z]"
This tells us that we use the separators as anything that is NOT a lower case letter or upper case letter. (the ^ character means you don't want the characters you listed in your brackets [])
Here is another way of doing this
"[^\\w]"
\w it actually means word characters. so if you negate this (with ^) you should be fine

How to fix "Path Manipulation Vulnerability" in some Java Code?

The below simple java code getting Fortify Path Manipulation error. Please help me to resolve this. I am struggling from long time.
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
}
}
Try to normalize the URL before using it
https://docs.oracle.com/javase/7/docs/api/java/net/URI.html#normalize()
Path path = Paths.get("/foo/../bar/../baz").normalize();
or use normalize from org.apache.commons.io.FilenameUtils
https://commons.apache.org/proper/commons-io/javadocs/api-1.4/org/apache/commons/io/FilenameUtils.html#normalize(java.lang.String)
Stirng path = FilenameUtils.normalize("/foo/../bar/../baz");
For both the result will be \baz
Looking at the OWASP page for Path Manipulation, it says
An attacker can specify a path used in an operation on the filesystem
You are opening a file as defined by a user-given input. Your code is almost a perfect example of the vulnerability! Either
Don't use the above code (don't let the user specify the input file as an argument)
Let the user choose from a list of files that you supply (an array of files with an integer choice)
Don't let the user supply the filename at all, remove the configurability
Accept the vulnerability but protect against it by checking the filename (although this is the worst thing to do - someone may get round it anyway).
Or re-think your application's design.
Fortify will flag the code even if the path/file doesn't come from user input like a property file. The best way to handle these is to canonicalize the path first, then validate it against a white list of allowed paths.
Bad:
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
}
}
Good:
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
if (!isInSecureDir(file)) {
throw new IllegalArgumentException();
}
String canonicalPath = file.getCanonicalPath();
if (!canonicalPath.equals("/img/java/file1.txt") &&
!canonicalPath.equals("/img/java/file2.txt")) {
// Invalid file; handle error
}
FileInputStream fis = new FileInputStream(f);
}
Source: https://www.securecoding.cert.org/confluence/display/java/FIO16-J.+Canonicalize+path+names+before+validating+them
Only allow alnum and a period in input. That means you filter out the control chars, "..", "/", "\" which would make your files vulnerable. For example, one should not be able to enter /path/password.txt.
Once done, rescan and then run Fortify AWB.
I have a solution to the Fortify Path Manipulation issues.
What it is complaining about is that if you take data from an external source, then an attacker can use that source to manipulate your path. Thus, enabling the attacker do delete files or otherwise compromise your system.
The suggested remedy to this problem is to use a whitelist of trusted directories as valid inputs; and, reject everything else.
This solution is not always viable in a production environment. So, I suggest an alternative solution. Parse the input for a whitelist of acceptable characters. Reject from the input, any character you don't want in the path. It could be either removed or replaced.
Below is an example. This does pass the Fortify review. It is important to remember here to return the literal and not the char being checked. Fortify keeps track of the parts that came from the original input. If you use any of the original input, you may still get the error.
public class CleanPath {
public static String cleanString(String aString) {
if (aString == null) return null;
String cleanString = "";
for (int i = 0; i < aString.length(); ++i) {
cleanString += cleanChar(aString.charAt(i));
}
return cleanString;
}
private static char cleanChar(char aChar) {
// 0 - 9
for (int i = 48; i < 58; ++i) {
if (aChar == i) return (char) i;
}
// 'A' - 'Z'
for (int i = 65; i < 91; ++i) {
if (aChar == i) return (char) i;
}
// 'a' - 'z'
for (int i = 97; i < 123; ++i) {
if (aChar == i) return (char) i;
}
// other valid characters
switch (aChar) {
case '/':
return '/';
case '.':
return '.';
case '-':
return '-';
case '_':
return '_';
case ' ':
return ' ';
}
return '%';
}
}
Assuming you're running Fortify against a web application, during your triage of Fortify vulnerabilities that would likely get marked as "Not an issue". Reasoning being A) obviously this is test code and B) unless you have multiple personality disorder you're not going to be doing a path manipulation exploit against your self when you run that test app.
If very common to see little test utilities committed to a repository which produces this style of false positive.
As for your compilation errors, that generally comes down to classpath issues.
We have code like below which was raising Path Manipulation high category issue in fortify .
String.join(delimeter,string1,string2,string2,string4);
Our program is to deal with AWS S3 bucket so, we changed as below and it worked .
com.amazonaws.util.StringUtils.join(delimeter,string1,string2,string2,string4);
Using the Tika library FilenameUtils.normalize solves the fortify issue.
import org.apache.tika.io.FilenameUtils;
public class Test {
public static void main(String[] args) {
String filePath = FilenameUtils.normalize(args[0]); //This line solve issue.
File file=new File(filePath);
}
}
Try this for replacing FileInputStream. You will need to close your project and open again to accurately see whether changes worked.
File to byte[] in Java
Use Normalize() function in C# and it resolved the fortify vulnerability in next scan.
string s = #:c:\temp\scan.log".Normalize();
Use regex to validate the file path and file name
fileName = args[0];
final String regularExpression = "([\\w\\:\\\\w ./-]+\\w+(\\.)?\\w+)";
Pattern pattern = Pattern.compile(regularExpression);
boolean isMatched = pattern.matcher(fileName).matches();

How to create a method at runtime using Reflection.emit

I'm creating an object at runtime using reflection emit. I successfully created the fields, properties and get set methods.
Now I want to add a method. For the sake of simplicity let's say the method just returns a random number. How do I define the method body?
EDIT:
Yes, I've been looking at the msdn documentation along with other references and I'm starting to get my head wrapped around this stuff.
I see how the example above is adding and/or multplying, but what if my method is doing other stuff. How do I define that "stuff"
Suppose I was generating the class below dynamically, how would I create the body of GetDetails() method?
class TestClass
{
public string Name { get; set; }
public int Size { get; set; }
public TestClass()
{
}
public TestClass(string Name, int Size)
{
this.Name = Name;
this.Size = Size;
}
public string GetDetails()
{
string Details = "Name = " + this.Name + ", Size = " + this.Size.ToString();
return Details;
}
}
You use a MethodBuilder to define methods. To define the method body, you call GetILGenerator() to get an ILGenerator, and then call the Emit methods to emit individual IL instructions. There is an example on the MSDN documentation for MethodBuilder, and you can find other examples of how to use reflection emit on the Using Reflection Emit page:
public static void AddMethodDynamically(TypeBuilder myTypeBld,
string mthdName,
Type[] mthdParams,
Type returnType,
string mthdAction)
{
MethodBuilder myMthdBld = myTypeBld.DefineMethod(
mthdName,
MethodAttributes.Public |
MethodAttributes.Static,
returnType,
mthdParams);
ILGenerator ILout = myMthdBld.GetILGenerator();
int numParams = mthdParams.Length;
for (byte x = 0; x < numParams; x++)
{
ILout.Emit(OpCodes.Ldarg_S, x);
}
if (numParams > 1)
{
for (int y = 0; y < (numParams - 1); y++)
{
switch (mthdAction)
{
case "A": ILout.Emit(OpCodes.Add);
break;
case "M": ILout.Emit(OpCodes.Mul);
break;
default: ILout.Emit(OpCodes.Add);
break;
}
}
}
ILout.Emit(OpCodes.Ret);
}
It sounds like you're looking for resources on writing MSIL. One important resource is the OpCodes class, which has a member for every IL instruction. The documentation describes how each instruction works. Another important resource is either Ildasm or Reflector. These will let you see the IL for compiled code, which will help you understand what IL you want to write. Running your GetDetailsMethod through Reflector and setting the language to IL yields:
.method public hidebysig instance string GetDetails() cil managed
{
.maxstack 4
.locals init (
[0] string Details,
[1] string CS$1$0000,
[2] int32 CS$0$0001)
L_0000: nop
L_0001: ldstr "Name = "
L_0006: ldarg.0
L_0007: call instance string ConsoleApplication1.TestClass::get_Name()
L_000c: ldstr ", Size = "
L_0011: ldarg.0
L_0012: call instance int32 ConsoleApplication1.TestClass::get_Size()
L_0017: stloc.2
L_0018: ldloca.s CS$0$0001
L_001a: call instance string [mscorlib]System.Int32::ToString()
L_001f: call string [mscorlib]System.String::Concat(string, string, string, string)
L_0024: stloc.0
L_0025: ldloc.0
L_0026: stloc.1
L_0027: br.s L_0029
L_0029: ldloc.1
L_002a: ret
}
To generate a method like that dynamically, you will need to call ILGenerator.Emit for each instruction:
ilGen.Emit(OpCodes.Nop);
ilGen.Emit(OpCodes.Ldstr, "Name = ");
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.Emit(OpCodes.Call, nameProperty.GetGetMethod());
// etc..
You may also want to look for introductions to MSIL, such as this one: Introduction to IL Assembly Language.

Resources