I'm setting a python application that uses an external module padelpy that wraps the access to a rest API: from padelpy import padeldescriptor
I have a dictionary with settings names and values:
settings = {
'fingerprints': False,
'd2_d': False,
...
}
I loop through the received POST.request parameters to check which setting(s) to communicate as true:
for setting in settings.keys():
if setting in request.POST:
settings.update({setting: request.POST.get(setting)})
str_conf = '%s=TRUE' % setting
padeldescriptor(str_conf)
if I use
padeldescriptor(fingerprints=TRUE)
it works
but if I use
padeldescriptor(str_conf)
it's the same as sending padeldescriptor("fingerprints=TRUE")
and I get an error back from the server:
Exception in thread "main" java.lang.NumberFormatException: For input string: "fingerprints=TRUE"
How can I send the settings without using strings?
Thanks
You can use Dictionary unpacking to do this
padeldescriptor(**settings) should work. What that does is unpack everything in your dictionary as keyword arguments to that function.
Related
I have a relatively simple JMeter test plan setup as shown here:
https://imgur.com/c8BIzBB
The relevant part of this is the BeanShell Preprocessor (shown as Setup element data) and its relationship to the HTTP Request sampler (shown as POST /elements). Both of these are inside a Loop Controller (shown as Do a few times).
The Preprocessor gets an array of data stored on the bsh.shared object and randomly selects one item. It then sets a variable called elementTypeId.
When I run this test, elementTypeId gets logged (and I therefore assume is set) correctly. However, the first time around, the variable is not set correctly and still appears as ${elementTypeId}. Further samples appear to be set but use the n-1th value.
The first, failing sample is shown here: https://imgur.com/Gj2YAje
The final sample (and logged values) are shown here: https://imgur.com/OW5HSsS
Setup element data - BeanShell Preprocessor code:
import java.util.Random;
import com.eclipsesource.json.*;
Random rand = new Random();
int idx = rand.nextInt(bsh.shared.elementTypes.size());
JsonValue elementType = bsh.shared.elementTypes.get(idx);
String elementTypeId = String.valueOf(elementType.get("id").asInt());
log.info(elementTypeId);
vars.put("elementTypeId", elementTypeId);
It looks to me as if the sampler is firing before the preprocessor has set the variable - which seems counter to what should be happening.
Update following UBIK's answer
When I disable the SetQueryParams PreProcessor, it appears that the variable is set correctly (although the request fails as it needs a query parameter to be added).
SetQueryParams PreProcessor:
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
if (sampler instanceof HTTPSamplerBase &&
sampler.getMethod().equalsIgnoreCase("post")) {
// add query parameter to url
var customPath = sampler.getPath() + '?' + sampler.getQueryString();
sampler.setPath(customPath);
// remove query parameter from body
arguments = sampler.getArguments();
while (arguments.getArgumentCount() > 1) {
arguments.removeArgument(arguments.getArgumentCount() - 1);
}
sampler.setArguments(arguments);
}
Is it possible to have both preprocessors applied to the POST request?
I think you issue might be coming from the other PreProcessor :
SetQueryParams PreProcessor
As per scoping rules , this one runs for every HTTP Sampler.
Check in console for the exception thrown.
try resolving that
if nothing is working please copy your script, delete Beanshell preprocessor and add BeanShell again and paste your script.
This may be silly but it worked for me.
Here in My HTTP Request I extracted some variables using JSON Path Extractor. I want to create a Java Request it will validate the above variables. i.e I want to check the value of reqVar1 is equal to resVar1 or not and reqVar2 is equal to resVar2 or not like that.
You are making things over complicated, you could achieve the same using normal Response Assertion.
For example, if you have a JMeter Variable ${var1} and you need to compare it to ${var2}, ${var3} and ${var4} you can just configure the Response Assertion like:
More information on conditionally marking sampler results as successful or failed: How to Use JMeter Assertions in Three Easy Steps
Instead of Java Request sampler, you can add BeanShell Assertion to compare the values. following is the code:
if(vars.get("reqVar1").equals(vars.get("resVar1")))
{
if(vars.get("reqVar2").equals(vars.get("resVar2")))
{
SampleResult.setResponseCode("200");
SampleResult.setResponseMessage("SUCESS");
}
else{
SampleResult.setResponseCode("403"); // keep error code as per your wish
SampleResult.setResponseMessage("reqVar2 and reqVar2 are NOT same" + vars.get("reqVar2") + vars.get("resVar2"));
}
}
else{
SampleResult.setResponseCode("403"); // keep error code as per your wish
SampleResult.setResponseMessage("reqVar1 and reqVar1 are NOT same" + vars.get("reqVar1") + vars.get("resVar1"));
}
Add the BeanShell Assertion as a child element to the HTTP Sampler in which you are getting the values for reqVar1, reqVar2, resVar1, resVar2
Once the decision is taken based on If condition, you can change the response code and message using SampleResult
Check the following reference that shows all methods available to you:
https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html
Image reference:
I am trying to write values of jmeter variables into a file using BSF post processor, but am getting an error if I call a variable which has no value
temp6 = vars.get("host_2_g1");
out.write(temp6);
Following is the message I am seeing in the jmeter log file
2015/11/08 21:47:29 WARN - jmeter.extractor.BSFPostProcessor: Problem in BSF script org.apache.bsf.BSFException: BeanShell script error: Sourced file: inline evaluation of: // VALUES is the Reference Name in regex ext . . . '' : vars .get ( "host_2_g1" )
BSF info: [script] at line: 0 column: columnNo
I already know that there is no variable being returned by the name "host_2_g1", how can i handle it so that at-least my code works?
There are multiple problems with your script:
out should be uppercase: OUT
OUT is a shorthand for PrintStream. It won't write strings, is expects byte array, so you need to convert your host_2_g1 variable to byte array via getBytes() method
If your host_2_g1 variable may be not set - it's better to add explicit check.
Modified code:
temp6 = vars.get("host_2_g1");
if (temp6 != null) {
OUT.write(temp6.getBytes());
}
else {
OUT.write("host_2_g1 is null".getBytes());
}
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for more information on Beanshell scripting in JMeter.
I have a java class I am using in my jruby project and in ruby I can set a value to an object via the send method. I am doing the same in jruby but using the java_send method instead. However, when I try using this I get the following error TypeError: can't convert Java::JavaIo::File into Array from org/jruby/java/proxies/JavaProxy.java:321:in 'java_send'
I have a java instance and I need to call the object via a symbol. Below is what I am doing in the code:
OUTPUT_FILES = [:make, :model]
javaArgs = javaArgs.new
OUTPUT_FILES.each do |filename|
file = java.io.File.new(path, "#{filename.to_s.underscore}.csv")
file.createNewFile
javaArgs.java_send(filename, file)
end
and just to make sure when I do javaArgs.make = file it works without any problems.
java_send expects its arguments passed as an array: javaArgs.java_send filename, [ file ]
I have a Spring application on the backend and a GWT application on the frontend.
When the user is logged in ''index.jsp'' will output the user information as a javascript variable.
I am using AutoBeanFactory to encode and decode the user information as json.
Because the user can register and the user information are stored in the database I try to follow the OWASP XSS Preventing cheat sheet by escaping the user information in the JSP page.
I am using the esapi library to do the encoding. The server side code looks like this:
public static String serializeUserToJson(CustomUser user) {
String json;
AppUserProxy appUserProxy = appUserFactory.appuser().as();
appUserProxy.setFirstname(encoder.encodeForHTML(user.getFirstname()));
appUserProxy.setLastname(encoder.encodeForHTML(user.getLastname()));
AutoBean<AppUserProxy> bean = appUserFactory.appuser(appUserProxy);
json = AutoBeanCodex.encode(bean).getPayload();
return json;
}
I tried to use encodeForHTML and encodeForJavaScript().
This works fine for normal characters however as soon as I use Umlaute characters (ü, ä, ö) I run into problems.
If I use the encodeforHTML() function the javascript variable looks like this (note firstname has an ü):
var data = {'user':'{"email":"john.doe#gmail.com","lastname":"Doe","firstname":"Über"}'};
Decoding with Autobean works fine however the character ü is not displayed properly but the HTML escaped one (Über).
When I use the encodeForJavaScript() function the output is as follows:
var data = {'user':'{"email":"john.doe#gmail.com","lastname":"Doe","firstname":"\\xDCber"}'};
When I try to decode the JSON string I run into a weird problem. In Development Mode/Hosted Mode decoding works fine and the Umlaut is properly displayed.
However as soon as I run the code in Production Mode I get an uncaught Exception:
java.lang.IllegalArgumentException: Error parsing JSON: SyntaxError: Unexpected token x
{"email":"john.doe#gmail.com","lastname":"Doe","firstname":"\xDCber"}
at Unknown.java_lang_RuntimeException_RuntimeException__Ljava_lang_String_2V(Unknown Source)
at Unknown.java_lang_IllegalArgumentException_IllegalArgumentException__Ljava_lang_String_2V(Unknown Source)
at Unknown.com_google_gwt_core_client_JsonUtils_throwIllegalArgumentException__Ljava_lang_String_2Ljava_lang_String_2V(Unknown Source)
at Unknown.com_google_gwt_core_client_JsonUtils_safeEval__Ljava_lang_String_2Lcom_google_gwt_core_client_JavaScriptObject_2(Unknown Source)
at Unknown.com_google_web_bindery_autobean_shared_impl_StringQuoter_split__Ljava_lang_String_2Lcom_google_web_bindery_autobean_shared_Splittable_2(Unknown Source)
at Unknown.com_google_web_bindery_autobean_shared_AutoBeanCodex_decode__Lcom_google_web_bindery_autobean_shared_AutoBeanFactory_2Ljava_lang_Class_2Ljava_lang_String_2Lcom_google_web_bindery_autobean_shared_AutoBean_2(Unknown Source)
at Unknown.com_gmi_nordborglab_browser_client_mvp_main_UserInfoPresenter_onBind__V(Unknown Source)
I can think of following solutions:
Rely only on input validation (when the data is stored in the db) and remove the output encoding. But that's not the recommended approach.
Replace the Umlaute with normal ASCII characters (ü => ue) and continue to use output encoding
use some library which escapes the XSS characters but leaves the Umlaute alone.
I am thankful for some feedback
Update: Based on Thomas suggestions I am now passing a JsoSplittable from JSNI and then passing this to the AutoBeanCodex.decode function. It works fine in Production Mode however in Hosted Mode I get following NPE:
java.lang.NullPointerException: null
at com.google.gwt.dev.shell.CompilingClassLoader$MyInstanceMethodOracle.findOriginalDeclaringClass(CompilingClassLoader.java:428)
at com.google.gwt.dev.shell.rewrite.WriteJsoImpl.isObjectMethod(WriteJsoImpl.java:307)
at com.google.gwt.dev.shell.rewrite.WriteJsoImpl.visitMethod(WriteJsoImpl.java:289)
at com.google.gwt.dev.shell.rewrite.WriteJsoImpl$ForJsoInterface.visitMethod(WriteJsoImpl.java:228)
at com.google.gwt.dev.asm.ClassAdapter.visitMethod(ClassAdapter.java:115)
at com.google.gwt.dev.shell.rewrite.RewriteJsniMethods.visitMethod(RewriteJsniMethods.java:350)
at com.google.gwt.dev.asm.ClassReader.accept(ClassReader.java:774)
at com.google.gwt.dev.asm.ClassReader.accept(ClassReader.java:420)
at com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.rewrite(HostedModeClassRewriter.java:251)
at com.google.gwt.dev.shell.CompilingClassLoader.findClassBytes(CompilingClassLoader.java:1236)
at com.google.gwt.dev.shell.CompilingClassLoader.findClass(CompilingClassLoader.java:1059)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
The code which causes this exception is following:
private native final JsoSplittable getJsoUserdata() /*-{
if (typeof $wnd.user !== 'undefined')
return $wnd.user;
return null;
}-*/;
#Override
public JsoSplittable getUserdata() {
JsoSplittable user = null;
user = getJsoUserdata();
if (user != null) {
String payload = user.getPayload();
Window.alert(payload);
}
return user;
}
Window.alert(payload) works fine in production mode. In Hosted mode when I step into user.getPayload() I get a NPE in findOriginalDeclaringClass function of the CompilingClassLoader.java. It seems that declaringClasses is null
You shouldn't explicitly escape anything; AutoBeans do it for you already. Or rather, if you want to escape something, escape the output of AutoBean's getPayload(), not the innards.
Your problem is that AutoBeans uses native JSON.parse() when possible (for both performance and safety reasons) which, per spec, only supports \uNNNN kinds of escapes, and not the \xHH that encodeForJavaScript outputs. In other words, ESAPI would need an encodeForJSON.