Get output from JavaScript function in C++ - javascript

Hy,
I'm working at a project that must call from C++ a custom function made in JavaScript. I'm able to run the function
The project should work only on Windows (actually it's a Windows service), so it's ok to use interfaces IWebBrowser2 and IHtmlDocument2
The function's signature is string function(string). I'm able to run the function in C++, based on this tutorial (I'm using IWebBrowser2 and IHtmlDocument2 interface), but I'm not able to get the output from that JS function back in C++.
Is there any method to retrieve the output from that JS function back in C++, using those interfaces? ( or maybe other)
Thank you,

I'll answer to my own question, if someone will have the same question:
Short answer is you can't obtain the output of javascript script using these interfaces. The IWebBrowser2 and IHtmlDocument are running in a context based on IE, so you can't obtain the output of running scripts.
The solutions for this problem are:
V8 or SpiderMonkey
Active Script Interfaces
If you plan to use V8 in your application, the basic example for calling a function is provided at Calling a v8 javascript function from c++ with an argument (But, be aware of the Dispose() function, which is wrongly placed)
If you plan to use Active Script Interfaces, the basic example is provided at Run JavaScript function from C++ without MFC . It's a useful example that shows how to run a JavaScript function.

Related

User controll Webassembly access calls from c++ to java script

I am wondering if there is a way to restrict a c++ compiled wasm file to NOT be able to call any javascript from within the c++ code. The idea is to prove to the user that the c++ wasm compiled file is not calling any javascript methods from within c++ i.e. it is only taking the input that has been provided from javascript trough some linear memory input working on it an giving back some result, but during that process no call should be possible to java script from within the c++ code. i.e. to put the wasm in some kind of jail mode where the binary is not able to call any javascript AT ALL! This is important in cases where the wasm produces itself some binary output, and it is unknown what is in that output. Basically i want to make sure that the "add2Strings" method that is called on the webassembly is not doing something else except adding "String1+String2" and returning some ByteBuffer/vector that represent the result (String1+String2) and not something like "String1+String2+FingerprintString+emailAddress" which can later be send trough javascript over the network god knows where.
I am wondering if there is a way to restrict a c++ compiled wasm file to NOT be able to call any javascript from within the c++ code
This is already default WebAssembly behavior. It can't execute any JavaScript function that you don't explicitly pass to it in the imports object.

is there a way to write a Java method like toString in Javascript which if called on a method prints the source code of the method?

Sorry if this is a trivial question, so if this has already been asked, please direct me to the question.
I know that the tostring method in javascript, if called on a function will print the source code (more about it: link). Is it possible to do the same thing in Java?
So if I have the following identity function definition:
public class class1 {
int f1(int x){
return x;
}
}
And the following main function:
class Main {
public static void main(String args[]) {
class1 c1 = new class1();
????
}
}
Is there anything I can put in place of '????' that would print something like
int f1(int x){
return x;
}
Disclaimer: I'm not an expert at Java, or any programming language for that matter. However, I do know how to find information online.
This concept does not seem very doable within Java. To start:
JavaScript is an interpreted language, not a compiled language. A program such as C++ or Java needs to be compiled before it is run. The source code is passed through a program called a compiler, which translates it into bytecode that the machine understands and can execute. In contrast, JavaScript has no compilation step. Instead, an interpreter in the browser reads over the JavaScript code, interprets each line, and runs it. More modern browsers use a technology known as Just-In-Time (JIT) compilation, which compiles JavaScript to executable bytecode just as it is about to run.
Basically, JavaScript has the advantage of reading directly from the file with the source code, and executing it on the fly. Compiled languages such as Java won't have that sort of functionality built in by default for many reasons, including security. An application should be able to run without allowing hackers access to its source code as much as possible.
There have been attempts at doing various forms of what you're interested in, but the two easiest methods seem to be
Printing the original .java file line by line
Storing a string reference to the entire code or the method(s) required.
It also seems possible to print the method name, but not the body.
Aside from that, the only thing you might be able to get from a compiled, running java program, is bytecode, which would require a decompiler to have any hope of understanding the source behind it.
You can continue reading up on it through a few of the links here:
How do I print the method body reflectively?
Save a method into a variable, java 8
View a method's implementation (method body) using Java Reflection
Probably yes, but not a trivial one with a ready command. JavaScript is an interpreted language where the executing environment has access to the source code in its original form. That is how you can inspect it in a browser console and see the same variable names as are in the source code.
While the compiled/interpreted distinction is fuzzy for Java, it is definitely modified before execution. The bytecode used by Java's Just-in-Time compilation may be more readable than a fully compiled binary file, it is not the source. If the running program does not have access to the source code, it is less able to output it. A debugger running in an IDE can reference problems in the source; otherwise, you are limited to debugging the bytecodes.
This is why Keno Clayton suggested the question on Quine programs, which are meant to reproduce themselves. This answer outputs the source code by hard-coding it as a class attribute. You could take a similar approach with a pre-compilation script that went through all the methods and made strings out of their sources, but the result would be bulky and potentially sensitive.

write to Java console when my Javascript callback (made in Selenium) returns

I have learned how to create Javascript callback functions and I have a basic understanding of 'functional programming' since it seems easy enough. I am however, new to javascript and it's syntax and I can't find a good way to test said syntax while in my IntelliJ IDE.
What is it you're doing?
I'm creating a Selenium based tool to click on a webelement, wait for it to reload the page, become stale or wait for a timeout. The reason I'm doing this is to classify webelements into three categories: causes a page reload, becomes stale, doesn't change. To do this I've made a simple javascript script with the JavascriptExecutor that comes with Java. Most of my code is in java and that is the language I am proficient in. I want to learn how to use javascript with java to do the things I want with web pages.
Ok but what specifically is the problem?
I have a javascript callback function:
function test(callback) {callback();}
function Return() {SeleniumTest.isPageReloaded.JavascriptWorking}
window.addEventListener('onload', test(Return));
which is executed inside a Javascript Executor like so:
System.setProperty("webdriver.chrome.driver",
"C:\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
String script = "function test(callback) {callback();}" +
"function Return()" +
"{SeleniumTest.isPageReloaded.JavascriptWorking}" +
"window.addEventListener('onload', test(Return));";
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript(script);
Which is basically the Javascript script from before, executing as a String. As you can see I am attempting to call a java class. SeleniumTest is my package, isPageReloaded is the current class and JavascriptWorking is a static method within that class. That static method looks like this:
public static void JavascriptWorking(){
System.out.println("Javascript ran here");
}
Its meant to be a simple way to get something from the javascript to my java code. The reason I tried it this way is because I read this:
https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/bpm-appdev/invoking-java-methods-in-javascript.html
But then I realized that it wouldn't work and I dug deeper. I read that Javascript and Java are seperated by server and client and I gained some insight from this question:
calling java methods in javascript code
However I'm not 100% sure this is accurate to my case since the Javascript I'm executing isn't coming from the webpage I'm testing, Rather I made it myself inside the java code as a String. Additionally I'm still highly confused on if the answer to that question actually applies to me. There is only one and it basically just says, 'install some stuff because java is clientside and javascript is serverside'. I (kindof) understand what those terms mean but I'm not sure that the javascript I made in my class would be considered 'server-side' in fact it would seem to not be that way. What I need is clarification on A: is the javascript I'm running/creating in my java code actually serverside?
B: if yes then can someone give me a basic rundown on how I would go about calling java code from the server? does this require permissions? I assume I have to communicate with said server so does that mean I use GET and POSt requests?
C: If the Javascript Isn't server side then it must be clientside and I should be able to call it pretty easily right? How do I do this?
Show us what exactly you want
I want to be able to run:
System.setProperty("webdriver.chrome.driver",
"C:\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
String script = "function test(callback) {callback();}" +
"function Return()" +
"{//insert callback code here}" +
"window.addEventListener('onload', test(Return));";
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript(script);
and get either a static java method ran, something printed to console, or some other means that links the javascript code to the javacode. So for example if I inserted the correct code to call my static method:
SeleniumTest.IsPageReloaded.JavascriptWorking
(which again looks like):
public static void JavascriptWorking(){
System.out.println("Javascript ran here");
}
Then I'd want to see "Javascript ran here" on my java console. The driver being used is interchangebale, I just used chrome first because its fast. All that this needs is an enclosing main class and It ((should)) be runnable but no promises.
The purpose is to get something in java that I can then use as a flag to know that my asynchronous javascript is done in java and I can continue on with program execution. I can get the async javascript part and I understand it, I just need a link back to my java code.
Possible Solutions
I've been told that the common way to provide a flag for your java code is to create a certain webelement on the page with javascript and test for it in java (hence the link). I don't feel like adding to the webpages I test because I want to test them without actually editing/changing them. I'm generally open to other simple solutions but the biggest thing I need is clarification on the whole clientside serverside issue because its specific to my setup (Selenium java -> javascript -> java) where most questions only cover (javascript -> java) or vice versa.
The link you mentioned about JS invoking Java is for a specific application, that is meant to do that. Not saying it is impossible (I wrote FF plugins based on similar principle), but it is not applicable in this case. It also requires special application support (by default Javascript executed in browser is heavily sandboxed - it can't access anything out of its own scope. Invoking other apps on its own is a big no.).
The scripts you are injecting are always client side, they are executed only in the browser, that is isolated from the java code itself. With that said nothing is impossible.
Would like to mention two interesting features of the Selenium library that can come handy for you.
You mention a magic term many times "async Javascript execution" - and as I can see you are implementing your own version of executeAsyncScript. Webdriver does provide this method out of the box, pretty much for the purpose you want to use it with.
When you use executeScript, it will return pretty much immediately once it finished - in your case it will just inject your listener with your code, and then it returns. Using executeAsyncScript you can get a callback - just what you are doing. When calling executeAsyncScript, a default callback method is added to your code as the last argument, that needs to be called by your JS code for the method to return.
A simple example:
String script = "var callback = arguments[arguments.length - 1];" + //the last argument is the callback function
"var classToCall = 'SeleniumTest.IsPageReloaded';" + //the classname you want to return to call from Java in case of success)
"window.addEventListener('onload', callback(classToCall));";
//you can give any supported return value to the callback function. Here I assume that you want to call a static method. This is the class name that can be used later.
try {
JavascriptExecutor js = (JavascriptExecutor)driver;
//classToCall has the value we passed to the callback function
String classToCall = js.executeAsyncScript(script);
} catch (ScriptTimeoutException e) {
System.err.println("Uhhh... this failed I guess");
e.printStackTrace();
}
The executeAsyncScript does not return until the callback is called - to avoid infinite hangs, you can set the WebDriver.Timeouts.setScriptTimeout property to control this. If the script takes longer, JavascriptExecutor will throw an exception. Once returned, you can instantiate the returned class, and print like
Class clazz = Class.forName(classToCall); //it is only necessary if the classname is dynamic. If it is the same always, you can just go ahead with that.
((IsPageReloaded)clazz.newInstance()).JavascriptWorking();
Of course you can return a more complex datastructure also from the JS where you specify the method name also, but using reflection is really offtopic here.
Take a look at EventFiringWebdriver. This is a useful class that makes use of WebDriverEventListener to create custom Webdriver wrappers, with hooks on many events, allowing you to execute custom code before/after clicking, before/after pageload... and beside some others more importantly before/after executing javascript in the webdriver. You could leverage this to always call the same code around javascript execution - just create your own WebDriverEventListener.
You can find more info on the js executor here, and on WebDriverEventListener here.

Calling swift Code From Javascript

Is it possible to call Swift functions/callbacks from Javascript ?
In Android it is possible to use JavaVoidCallbacks, is there anything similar in Swift? Right now Im using JavaScriptCore,where i can call javascript functions from Swift.
Yes you can.
Please refer to this Tutorial: https://www.raywenderlich.com/124075/javascriptcore-tutorial
You are interested in the paragraph "Exposing Native Code"
In obj-c is very simple. You can do it just by using your jsContext as a normal dictionary.
context[#"functionName"] = ^ <#returnType#> (<#parameters#>) {
<#Your code#>
}
Hope it helped.
In Swift, the easiest way I found was to create a gateway object in Javascript, using e.g. evaluateScript(), and then adding functions to that object:
// x is JSContext
let gateway = x.objectForKeyedSubscript("gateway" as NSString)
let p: #convention(block) (Int, Double) -> () = { h, ms in
return self.swift_method(h, ms)
}
gateway!.setObject(p, forKeyedSubscript: "swift_method" as NSString)
After that you can call gateway.swift_method() in Javascript.
Most type conversions are automatic. I have used types Int, Double, String and [Int] as parameter and/or return types in the lambda.
I have the same question. When I saw the answers to this Q. I tried to use JavaScriptCore to call Swift methods from the JS side. I could inject Swift or JS methods into JSContext. However, the methods injected into JSContext are not accessible in my case.
I use WKWebView as an HTML viewer in the ViewController in my iOS native app. I use this kind of view controller to present some help information in my app. After several days of struggling, I finally found an alternative way to make Swift and JS interaction happen. The strategy is to use WKScriptMessageHandler as a gateway between Swift and JS. Refer to this good blog on how to do it in detail. Another blog, Using WebKit to call WKWebView JavaScript from Swift and Swift from JavaScript, provides another example case, which is very useful.
From my experience, WKScriptMessageHandler is based on a very elegant structure. Through WKUserContentController, you set up a message gateway between JS and Swift. There is This will allow a JS callback to Swift with messages. A delegate of WKWebViewConfiguration has to be implemented, my view controller with web view, or my custom class, to receive JS message calls with data. The message can take a JSON string as a parameter to pass data. On the Swift side, by using a similar JSContext syntax like evaluateJavaScript to specify JS a function with data.
By the way, I was told that in my case, JavaScriptCore is based on Java virtue machine. There may be performance issue and may pose a security risk. Apple has disabled the feature of JavaScriptCore in WKWebView.
The Xcode in my case is Version 13.4, and Swift is 5.
I have written a blog on this: Build a Bridge between Swift and JS

How compile function written in python to JavaScript (emscripten)?

I have a simple function written in python which I want to port to javascript.
I have compiled python 2.7 into a .so library, so thats not the issue.
The problem I'm having is that after I compile my program with cython, the function names get all scrambled up, which means I don't know how to preserve the functions when i run emcc.
Does anybody have any experience compiling python programs to js with emscripten?
Any information would be appreciated.
Note: I want to preserve the exact functionality to that of python, I don't want something that translates a python program into javascript.
This other question, with an accepted answer, complains about the same issue: Cython mangling function names and making it difficult to access from C++: Embed python function in C++
The accepted answer states that Cython isn't meant for this sort of thing at all, suggesting you can't do what you want in this fashion:
You're not going to be able to get the interoperation you want that way. If you open and inspect hello.c you won't find "static int say_hello" anywhere in there. Cython is designed for letting Python use C libraries, not letting C libraries use python.
The not-accepted next answer suggest that specifying public will not mangle the function name, although he also mentions linking problems.
# (in the generated C file hello.c)
__PYX_EXTERN_C DL_IMPORT(...) say_hello(...);
Worth a shot, but please consider the other options in the comments if it fails.

Categories

Resources