different results for same method call [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
i do have a class CheckPrograminstallation(which is part of a eclipse plugin), with a method check, which checks whether a program is installed. It return true when installed and false otherwise.
public class CheckPrograminstallation{
public static boolean check(String programname, String OsName)
throws Exception {
// Get installation path of programname
String foundpath = "";
String dirName = "";
String line;
String programpath = null;
Process process = null;
boolean IsInstalled = false;
if (OsName.equals("Windows")) {
try {
// get Windows Directory first
process = Runtime.getRuntime().exec("cmd /c echo %windir%");
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
// read from stream
if ((line = reader.readLine()) != null) {
foundpath = line.toString();
// cut off "\Windows" from the found path
int last = foundpath.lastIndexOf("\\");
dirName = foundpath.subSequence(0, last).toString();
process = null;
// get program installation path
process = Runtime.getRuntime().exec(
"cmd /c where /R " + dirName + " " + programname);
reader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
if ((line = reader.readLine()) != null) {
programpath = line.toString();
System.out.println(programpath);
IsInstalled = true;
}
}
} catch (Exception e) {
DO SOMETHING);
}
}
When i call the method from a test class, it works.
But when i call the same method while running the Plugin:
...boolean isInstalledPscp;
boolean IsWindows;
...
if (IsWindows == true) {
// for Windows: check if pscp is installed
isInstalledPscp = CheckIfInstalled.check("pscp", "Windows");
if (isInstalledPscp == false) {
do something }
}
...it always returns false.
How can that be?
This has been driving me crazy for a whole day. Using .equals for String comparison, and still getting false as result. So this is not a string comparison problem IMHO.

Change your string comparison from:
if (OsName == "Windows") {
To:
if (OsName.equals("Windows")) {
Since your if doesn't succeed, it never goes into if and hence it returns your false.

You compare strings using the equals() method and not logical equals operator ==
I also recommend that you follow java naming conventions and use variables names starting with lower case letters such as osName instead of OsName.

Print out what are the paths that are returned inside your code (if any), I suspect that from within the plugin the runtime parameters are different.
Also maybe System.getEnv System.getProperties is a better way to find windows dir than starting a new process.

Related

Compare a string to CMD output using Java

I'm trying to create a method that returns true or false based off of the result from sfc /scannow but for some reason the string comparison always returns false even though it prints as exactly what I'm comparing it to. Any ideas?
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", "sfc /scannow");
builder.redirectErrorStream(true);
Process p = builder.start();
Scanner sn = new Scanner(new InputStreamReader(p.getInputStream()));
while (sn.hasNextLine()) {
String line = sn.nextLine();
System.out.println(line);
if(line.equalsIgnoreCase("Windows Resource Protection did not find any integrity violations.")) {
isHealthy = true;
break;
}
}
if(isHealthy == true) {
return true;
}
else if(isHealthy == false) {
return false;
}
In this case your are comparing Objects and not always the value itself, so you'll be good checking using contentEquals:
...
if(line.contentEquals("What Do you want to verify")) { condition }
Let me know if this works for you!
The String#equals() not only compares the String's contents, but also checks if the other object is also an instance of a String . The String#contentEquals() only compares the contents (the character sequence) and does not check if the other object is also an instance of String

How do I convert a condition written in string to a Java "if" condition

I have a UI where the user can build a query to then apply those conditions to search in a text file.
Let's assume the string is as follows: A and (B or C) I also have access to each value (A, B, C), logical operators (and, or) and grouping brackets.
So what I need to have is: line.contains(A) && (line.contains(B) || line.contains(C))
boolean found = false;
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line = null;
while ((line = reader.readLine()) != null && !contains) {
if (line.contains(A) && (line.contains(B) || line.contains(C))) {
found = true;
}
}
return found;
The above specific conditions might also not work since I'm searching for that in each line and the conditions might be in different lines. But this is another issue I have to deal with :)
Any idea on how to do this?
Based on your comments I was able to resolve my question by using ScriptEngineManager. I'm building the condition I want to evaluate using JavaScript language and doing engine.eval(query).
private boolean containsSearchQuery(InputStream input, String searchQuery) {
boolean match = false;
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String lines = reader.lines().collect(Collectors.joining());
engine.put("lines", lines);
try {
match = (boolean) engine.eval(searchQuery);
} catch (ScriptException e) {
System.out.println("Error: " + e.getMessage());
}
return match;
}

How does java Runtime.getRuntime().exec(...) search for executables on windows?

I'm trying to do a proof of concept exploit to show how changing the path variable can replace standard programs for malicious ends. I put a dummy program called "cmd.exe" in a directory "C:\path\to\fake_exe\" and changed the path to have that at the front.
Below is the function I'm using to demonstrate, but it runs normally (i.e., it passes the arguments to the correct cmd.exe instead of my fake one). I even passed "cmd" to the function, and it opened my dummy program! So the path variable is definitely set to find my fake cmd.exe correctly, but the exec(..) function is finding the proper cmd.exe regardless.
How does the exec(...) function find executables? Where is this documented?
static void unsafeExec(String cmd) throws IOException, InterruptedException {
String[] run = new String[3];
run[0] = "cmd.exe";
run[1] = "/C";
run[2] = cmd;
Process p = Runtime.getRuntime().exec(run);
BufferedReader stdIN = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdER = new BufferedReader(new InputStreamReader(p.getErrorStream()));
p.waitFor();
String s;
while ((s = stdIN.readLine()) != null) {
System.out.println(s);
}
while ((s = stdER.readLine()) != null) {
System.out.print(s);
}
}

Begin the reading of a file from a specific line

i have a file similaire to this :
...
The hotspot server JVM has specific code-path optimizations
# which yield an approximate 10% gain over the client version.
export CATALINA_OPTS="$CATALINA_OPTS -server"
#############HDK1001#############
# Disable remote (distributed) garbage collection by Java clients
# and remove ability for applications to call explicit GC collection
export CATALINA_OPTS="$CATALINA_OPTS -XX:+DisableExplicitGC"
# Check for application specific parameters at startup
if [ -r "$CATALINA_BASE/bin/appenv.sh" ]; then
. "$CATALINA_BASE/bin/appenv.sh"
fi
#############HDK7564#############
# Disable remote (distributed) garbage collection by Java clients
# and remove ability for applications to call explicit GC collection
export CATALINA_OPTS="$CATALINA_OPTS -XX:+DisableExplicitGC"
i want to begin the reading from the line where exists the word "HDK1001" and end it where the world "HDK7564"
i tryed with this code but i am unable to do the limitation
public static HashMap<String, String> getEnvVariables(String scriptFile,String config) {
HashMap<String, String> vars = new HashMap<String, String>();
try {
FileInputStream fstream = new FileInputStream(scriptFile);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
String var= "HDK1001";
while ((strLine = br.readLine()) != null ) {
if (strLine.startsWith("export") && !strLine.contains("$")) {
strLine = strLine.substring(7);
Scanner scanner = new Scanner(strLine);
scanner.useDelimiter("=");
if (scanner.hasNext()) {
String name = scanner.next();
String value = scanner.next();
System.out.println(name+"="+value);
vars.put(name, value);
}
}
Help me please
try this code.
public static HashMap<String, String> getEnvVariables(String scriptFile,
String config) {
HashMap<String, String> vars = new HashMap<String, String>();
BufferedReader br = null;
try {
FileInputStream fstream = new FileInputStream(scriptFile);
br = new BufferedReader(new InputStreamReader(fstream));
String strLine = null;
String stopvar = "HDK7564";
String startvar = "HDK1001";
String keyword = "export";
do {
if (strLine != null && strLine.contains(startvar)) {
if (strLine.contains(stopvar)) {
return vars;
}
while (strLine != null && !strLine.contains(stopvar)) {
strLine = br.readLine();
if (strLine.startsWith(keyword)) {
strLine = strLine.substring(keyword.length())
.trim();
String[] split = strLine.split("=");
String name = split[0];
String value = split[1];
System.out.println(name + "=" + value);
vars.put(name, value);
}
}
}
} while ((strLine = br.readLine()) != null);
} catch (Exception e) {
e.printStackTrace();
}
return vars;
}
Your example code is quite far off, and I don't intend to rewrite all of your code, I will give you some pointers though. You are already doing:
if (strLine.startsWith("export") && !strLine.contains("$"))
This is your conditional that should be testing for the "HDK1001" string instead of whatever it's doing right now. I'm not sure why you are checking for the word "export" when it seems like it doesn't matter for your program.
There isn't a way to just magically start and end at specific words in the file, you MUST start at the beginning and go line by line checking all of them until you find your desired first and last line. Once you find that first line, you can continue reading until you reach your desired end line and then bail out.
this is pseudo code that follows the kind of logic you would want to be able to accomplish this task.
flag = false
inside a loop
{
read in a line
if( line != #############HDK1001############# && flag == false){ //check to see if you found your starting place
nothing useful here. lets go around the loop and try again
else // if i found it, set a flag to true
flag = true;
if( flag == true) // am i after my starting place but before my end place?
{
if( line == #############HDK1001#############)
do nothing and go back through the loop, this line is not useful to us
else if( line == #############HDK7564#############) //did i find my end place?
flag = false // yes i did, so lets not be able to assign stuff any more
else // im not at the start, im not at the end. I must be inbetwee. lets read the data and assign it.
read in the lines and assign it to variables that you want
}

Getting value of one string variable correctly in Java if i do the debug but same values is null when i run the program

I am facing pretty weird problem here. I have one java project in eclipse. When I do the debug on program, It returns me value of one String variable properly, But when I run same program, i get that value as a null.
What could be the problem ?
/*Piece of code*/
version = FindVersion(fileName,filePath,tmpDir);
/*Find version function*/
String version = null;
String finalvalue = null;
File script = File.createTempFile("xxxxx", ".vbs");
File result = File.createTempFile("xxxxx", ".txt");
String fullPath = tmpDir + filePath + fileName;
FileWriter fwrt = new FileWriter(script);
fwrt.write("Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n");
fwrt.write("Wscript.Echo objFSO.GetFileVersion(\"" + fullPath + "\")");
fwrt.close();
Process p = Runtime.getRuntime().exec("cmd.exe /c"
+ "cscript "
+ script.getAbsolutePath()
+ " >" + result.getAbsolutePath());
int ret = p.waitFor();
if (ret != 0)
{
System.out.println("Error :( Exit code = " + ret);
}
else
{
BufferedReader rd = null;
rd = new BufferedReader(new FileReader(result));
while((version = rd.readLine()) != null )
{
if(version.matches("^[\\d\\.]+$"))
{
finalvalue = version;
rd.close();
script.delete();
result.delete();
return finalvalue;
//break;
}
}
rd.close();
script.delete();
result.delete();
}
return null;
}
My guess is that version never matches that pattern
if(version.matches("^[\\d\\.]+$"))
So, after reading the whole file, it gets null again, and finalvalue never takes a value.
Thus you get the two of them as nulls.
Does the flow get into that if condition ?
Are you sure that this pattern matches what you want ? "^[\\d\\.]+$"
Also is this correct ? Should there be a space or something ? or is it just a weird string split you have there ?
Process p = Runtime.getRuntime().exec("cmd.exe /c"
+"cscript " ..
translates to:
Process p = Runtime.getRuntime().exec("cmd.exe /ccscript " ..
I think you are misinterpreting the flow of your program. If version were to be null as you stated in one of your comments, the while loop would be finished, so you would never be returning finalValue in the first place; instead, the last line return null; would be executing. Put a debug line inside the while loop to verify.
while(...)
System.out.println(version);
How are you verifying that "version is null and in tern finalValue is null"?
(edit)
Also note that this is assuming you mean that version is null immediately (first iteration of while loop) when you state that "version is null."

Categories

Resources