Application infinite loop with processMessage failed error - javascript

My Cordova app not running in browser and mobile it shows an error
processMessage failed
Screenshot:
and goes infinite loop and it freezes the device any solution?
This question is already in asked here Cordova not running normally but there is not an answer so thats why I have to asked it again.

Getting the same issue (using Chrome with the phonegap desktop emulator. What I see as happening is this.
There seems to be a bug in Cordova.js that fails to check for an empty message.
When the app sends out alerts:
gap_init:2
gap:[0,"StatusBar","_ready","StatusBar1593157203"]
gap:[0,"App","show","App1593157204"]
gap:[0,"File","requestAllPaths","File1593157205"]
gap:[0,"NetworkStatus","getConnectionInfo","NetworkStatus1593157206"]
gap:[0,"Device","getDeviceInfo","Device1593157207"]
and you just hit 'OK', instead of clearing out the contents of that dialog box it going on to cause an infinite loooooop. I don't know the significance of these messages yes as I'm pretty new to Cordova, but it's hell and gone from the principle of least surprise!
So you can clear out the messages, or modify the cordova.js code where it gets stuck in the loop. You also could turn off the alerts that also works.
the function processMessage() (see below) doesn't test for an empty string, which in and of itself might be fine, but it is called from a while loop which only checks for "*" if its going to pop.
while (messagesFromNative.length) {
var msg = popMessageFromQueue();
// The Java side can send a * message to indicate that it
// still has messages waiting to be retrieved.
if (msg == '*' && messagesFromNative.length === 0) {
setTimeout(pollOnce, 0);
return;
}
processMessage(msg);
}
// Processes a single message, as encoded by NativeToJsMessageQueue.java.
function processMessage(message) {
try {
var firstChar = message.charAt(0);
if (firstChar == 'J') {
eval(message.slice(1));
} else if (firstChar == 'S' || firstChar == 'F') {
var success = firstChar == 'S';
var keepCallback = message.charAt(1) == '1';
var spaceIdx = message.indexOf(' ', 2);
var status = +message.slice(2, spaceIdx);
var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
var payloadKind = message.charAt(nextSpaceIdx + 1);
var payload;
if (payloadKind == 's') {
payload = message.slice(nextSpaceIdx + 2);
} else if (payloadKind == 't') {
payload = true;
} else if (payloadKind == 'f') {
payload = false;
} else if (payloadKind == 'N') {
payload = null;
} else if (payloadKind == 'n') {
payload = +message.slice(nextSpaceIdx + 2);
} else if (payloadKind == 'A') {
var data = message.slice(nextSpaceIdx + 2);
var bytes = window.atob(data);
var arraybuffer = new Uint8Array(bytes.length);
for (var i = 0; i < bytes.length; i++) {
arraybuffer[i] = bytes.charCodeAt(i);
}
payload = arraybuffer.buffer;
} else if (payloadKind == 'S') {
payload = window.atob(message.slice(nextSpaceIdx + 2));
} else {
payload = JSON.parse(message.slice(nextSpaceIdx + 1));
}
cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
} else {
console.log("processMessage failed: invalid message: " + JSON.stringify(message));
}
} catch (e) {
console.log("processMessage failed: Error: " + e);
console.log("processMessage failed: Stack: " + e.stack);
console.log("processMessage failed: Message: " + message);
}
}

Check your cordova js loading properly? is the path for cordova js is proper?
give path like this in your index.html:
<script type="text/javascript" src="cordova.js">

I had the problem in an Angular 6 project. It was simply solved by deleting cordova.js which was under src folder.

I was not able to resolve this issue when viewing the /android platform option for cordova serve; however, the /ios platform option did function properly.
Not much of a solution, but perhaps a mildly helpful workaround for those who follow.

Related

Agora can not switch the camera getting : Cannot read properties of undefined (reading 'deviceId')

I am trying to use Agora.io. Everything was working as it should. Until I add switching between cameras. I'm trying to switch between cameras thanks to the code below. But the problem is that I get this error: Uncaught TypeError: Cannot read properties of undefined (reading 'deviceId')
The error line is in the changeStreamSource() :
deviceId = devices.cameras[deviceIndex].deviceId;
Can you guide me on this?
function changeStreamSource (deviceIndex, deviceType) {
console.log('Switching stream sources for: ' + deviceType);
var deviceId;
var existingStream = false;
if (deviceType === "video") {
deviceId = devices.cameras[deviceIndex].deviceId;
}
localStreams.camera.stream.switchDevice(deviceType, deviceId, function(){
console.log('successfully switched to new device with id: ' + JSON.stringify(deviceId));
// set the active device ids
if(deviceType === "audio") {
localStreams.camera.micId = deviceId;
} else if (deviceType === "video") {
localStreams.camera.camId = deviceId;
} else {
console.log("unable to determine deviceType: " + deviceType);
}
}, function(){
console.log('failed to switch to new device with id: ' + JSON.stringify(deviceId));
});
}
devices isn't defined in your code. You can get a list of devices using AgoraRTC.getDevices method.

How to execute node.js protoype function from html?

I have a program that will work to start a motion sensor when running the file from the command line, but when I try to call the function from HTML, it recognizes the prototype as 'undefined' and will not execute.
Here is the full code:
var sleep = require('sleep');
var Gpio = require('onoff').Gpio;
var LED = new Gpio(18, 'out');
var sensor = new Gpio(17, 'in', 'both');
sensor.watch(function(err, value){
if (err){
console.log('error');
exit();
}
if(value == 1) {
console.log('Motion Detected');
LED.writeSync(value);
sleep.sleep(3);
}
else if(value == 0) {
console.log('No Motion');
LED.writeSync(value);
sleep.sleep(3);
}
});
function exit() {
LED.unexport();
sensor.unexport();
process.exit();
}
dev tools says 'sensor' is undefined.
How do I run sensor.watch(callback) from html?
Thanks!

Plupload retry if error

I'm trying to setup plupload so that if a file upload fails according to a certain error code, plupload will try to upload it again. Without success.
What I currently have
Here is my piece of code for now :
var attempts = 0; // number of attempts
function init(uploader) {
uploader.bind('Error', function(up, file) {
var code = JSON.parse(file.response).error.code;
console.log(code); //logs the error code
if(code === 503 && attempts > 3) {
up.stop();
file.status = plupload.FAILED;
file.retry = false;
// do stuff...
up.state = plupload.STARTED;
up.trigger("StateChanged");
attempts = 0;
}
else {
console.log("attempt : "+ attempts);
up.stop();
file.status = plupload.QUEUED;
attempts++;
file.retry = true;
up.state = plupload.STARTED;
up.trigger("StateChanged");
up.trigger("QueueChanged"); // ERROR HERE
}
})
}
Where I indicated the "ERROR HERE", my console shows me this :
TypeError: n.getSource is not a function
What am I doing wrong ?
Thanks a lot !
Why don't you add the file again on the queue?
http://www.plupload.com/docs/Uploader#addFile-filefileName-method
addFile(file, [fileName])

PhantomJS / Javascript: write to file instead of to console

From PhantomJS, how do I write to a log instead of to the console?
In the examples https://github.com/ariya/phantomjs/wiki/Examples, it always (in the ones I have looked at) says something like:
console.log('some stuff I wrote');
This is not so useful.
The following can write contents to the file directly by phantomjs:
var fs = require('fs');
try {
fs.write("/home/username/sampleFileName.txt", "Message to be written to the file", 'w');
} catch(e) {
console.log(e);
}
phantom.exit();
The command in the answer by user984003 fails when there is some warning or exceptions occurred. And sometimes does not fall into our specific requirements because in some codebase I am getting the following message always which will also be logged to that file.
Refused to display document because display forbidden by X-Frame-Options.
So I figured it out:
>phantomjs.exe file_to_run.js > my_log.txt
You can override original console.log function, take a look at this :
Object.defineProperty(console, "toFile", {
get : function() {
return console.__file__;
},
set : function(val) {
if (!console.__file__ && val) {
console.__log__ = console.log;
console.log = function() {
var fs = require('fs');
var msg = '';
for (var i = 0; i < arguments.length; i++) {
msg += ((i === 0) ? '' : ' ') + arguments[i];
}
if (msg) {
fs.write(console.__file__, msg + '\r\n', 'a');
}
};
}
else if (console.__file__ && !val) {
console.log = console.__log__;
}
console.__file__ = val;
}
});
Then you can do this:
console.log('this will go to console');
console.toFile = 'test.txt';
console.log('this will go to the test.txt file');
console.toFile = '';
console.log('this will again go to the console');

How can I get the SSL Certificate info for the *current* page in a Firefox Add On

I'm trying to develop a Firefox extension/add-on that needs access to the SSL Certificate information of the page that is currently loaded. Once I have this information I plan on modifying the contents of the page based on the SSL information. Though, before I get there I first need to get the SSL info.
The approach outlined here makes a separate XMLHTTPRequest to get the security certificate. I would rather not do that if I could avoid it because it presents a security problem.
For example, a malicious site/man-in-the-middle could provide one certificate on the first request for the page (which the browser would verify) and then provide another certificate for the XMLHTTPRequest that my extension would make. This would result in the extension modifying site contents based on inconsistent information. Hence, I'd like to get the SSL Cert information that the browser itself used when verifying the site.
With that in mind I combined the above approach with the method outlined in Altering HTTP Responses in Firefox Extension to intercept all the HTTP responses by adding an observer of the "http-on-examine-response" event. I thought that with this method I could simply grab the cert info as it was being downloaded from the site.
Here is the meat of my code, much of it taken from the above links (the rest is Firefox extension boilerplate):
function dumpSecurityInfo(channel) {
const Cc = Components.classes
const Ci = Components.interfaces;
// Do we have a valid channel argument?
if (! channel instanceof Ci.nsIChannel) {
dump("No channel available\n");
return;
}
var secInfo = channel.securityInfo;
// Print general connection security state
if (secInfo instanceof Ci.nsITransportSecurityInfo) {
dump("name: " + channel.name + "\n");
secInfo.QueryInterface(Ci.nsITransportSecurityInfo);
dump("\tSecurity state: ");
// Check security state flags
if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_SECURE) == Ci.nsIWebProgressListener.STATE_IS_SECURE)
dump("secure\n");
else if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_INSECURE) == Ci.nsIWebProgressListener.STATE_IS_INSECURE)
dump("insecure\n");
else if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_BROKEN) == Ci.nsIWebProgressListener.STATE_IS_BROKEN)
dump("unknown\n");
dump("\tSecurity description: " + secInfo.shortSecurityDescription + "\n");
dump("\tSecurity error message: " + secInfo.errorMessage + "\n");
}
// Print SSL certificate details
if (secInfo instanceof Ci.nsISSLStatusProvider) {
var cert = secInfo.QueryInterface(Ci.nsISSLStatusProvider).
SSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
dump("\nCertificate Status:\n");
var verificationResult = cert.verifyForUsage(Ci.nsIX509Cert.CERT_USAGE_SSLServer);
dump("\tVerification: ");
switch (verificationResult) {
case Ci.nsIX509Cert.VERIFIED_OK:
dump("OK");
break;
case Ci.nsIX509Cert.NOT_VERIFIED_UNKNOWN:
dump("not verfied/unknown");
break;
case Ci.nsIX509Cert.CERT_REVOKED:
dump("revoked");
break;
case Ci.nsIX509Cert.CERT_EXPIRED:
dump("expired");
break;
case Ci.nsIX509Cert.CERT_NOT_TRUSTED:
dump("not trusted");
break;
case Ci.nsIX509Cert.ISSUER_NOT_TRUSTED:
dump("issuer not trusted");
break;
case Ci.nsIX509Cert.ISSUER_UNKNOWN:
dump("issuer unknown");
break;
case Ci.nsIX509Cert.INVALID_CA:
dump("invalid CA");
break;
default:
dump("unexpected failure");
break;
}
dump("\n");
dump("\tCommon name (CN) = " + cert.commonName + "\n");
dump("\tOrganisation = " + cert.organization + "\n");
dump("\tIssuer = " + cert.issuerOrganization + "\n");
dump("\tSHA1 fingerprint = " + cert.sha1Fingerprint + "\n");
var validity = cert.validity.QueryInterface(Ci.nsIX509CertValidity);
dump("\tValid from " + validity.notBeforeGMT + "\n");
dump("\tValid until " + validity.notAfterGMT + "\n");
}
}
function TracingListener() {
}
TracingListener.prototype =
{
originalListener: null,
onDataAvailable: function(request, context, inputStream, offset, count) {
try
{
dumpSecurityInfo(request)
this.originalListener.onDataAvailable(request, context, inputStream, offset, count);
} catch (err) {
dump(err);
if (err instanceof Ci.nsIException)
{
request.cancel(e.result);
}
}
},
onStartRequest: function(request, context) {
try
{
dumpSecurityInfo(request)
this.originalListener.onStartRequest(request, context);
} catch (err) {
dump(err);
if (err instanceof Ci.nsIException)
{
request.cancel(e.result);
}
}
},
onStopRequest: function(request, context, statusCode) {
this.originalListener.onStopRequest(request, context, statusCode);
},
QueryInterface: function (aIID) {
const Ci = Components.interfaces;
if ( iid.equals(Ci.nsIObserver) ||
iid.equals(Ci.nsISupportsWeakReference) ||
iid.equals(Ci.nsISupports))
{
return this;
}
throw Components.results.NS_NOINTERFACE;
}
}
var httpRequestObserver =
{
observe: function(aSubject, aTopic, aData)
{
const Ci = Components.interfaces;
if (aTopic == "http-on-examine-response")
{
var newListener = new TracingListener();
aSubject.QueryInterface(Ci.nsITraceableChannel);
newListener.originalListener = aSubject.setNewListener(newListener);
}
},
QueryInterface : function (aIID)
{
const Ci = Components.interfaces;
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupports))
{
return this;
}
throw Components.results.NS_NOINTERFACE;
}
};
var test =
{
run: function() {
const Ci = Components.interfaces;
dump("run");
var observerService = Components.classes["#mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(httpRequestObserver,
"http-on-examine-response", false);
}
};
window.addEventListener("load", function () { test.run(); }, false);
What I found is that this implementation is inconsistent. When I load gmail.com in Firefox I'll sometimes get the certificate information and sometimes I won't. I suspect this is a caching issue as refreshing the page will usually result in the certificate information being downloaded/printed.
For my intended application this behavior is not acceptable. This is for a research project so, if I have to, I would be willing to modify the Firefox source code, but my preference would be to do this using the extension/add-on API.
Is there a better, more consistent way to get the SSL Certificate information?
Building on this answer:
The trick is to register a progress listener and check aState when the onSecurityChange function is called. If the Ci.nsIWebProgressListener.STATE_IS_SECURE flag is set then the page is using an SSL connection. That isn't enough however, the aRequest parameter may not be an instance of Ci.nsIChannel, that should be verified first with if (aRequest instanceof Ci.nsIChannel).
Here is the working code:
function dumpSecurityInfo(channel) {
const Cc = Components.classes
const Ci = Components.interfaces;
// Do we have a valid channel argument?
if (! channel instanceof Ci.nsIChannel) {
dump("No channel available\n");
return;
}
var secInfo = channel.securityInfo;
// Print general connection security state
if (secInfo instanceof Ci.nsITransportSecurityInfo) {
dump("name: " + channel.name + "\n");
secInfo.QueryInterface(Ci.nsITransportSecurityInfo);
dump("\tSecurity state: ");
// Check security state flags
if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_SECURE) == Ci.nsIWebProgressListener.STATE_IS_SECURE)
dump("secure\n");
else if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_INSECURE) == Ci.nsIWebProgressListener.STATE_IS_INSECURE)
dump("insecure\n");
else if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_BROKEN) == Ci.nsIWebProgressListener.STATE_IS_BROKEN)
dump("unknown\n");
dump("\tSecurity description: " + secInfo.shortSecurityDescription + "\n");
dump("\tSecurity error message: " + secInfo.errorMessage + "\n");
}
else {
dump("\tNo security info available for this channel\n");
}
// Print SSL certificate details
if (secInfo instanceof Ci.nsISSLStatusProvider) {
var cert = secInfo.QueryInterface(Ci.nsISSLStatusProvider).
SSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
dump("\nCertificate Status:\n");
var verificationResult = cert.verifyForUsage(Ci.nsIX509Cert.CERT_USAGE_SSLServer);
dump("\tVerification: ");
switch (verificationResult) {
case Ci.nsIX509Cert.VERIFIED_OK:
dump("OK");
break;
case Ci.nsIX509Cert.NOT_VERIFIED_UNKNOWN:
dump("not verfied/unknown");
break;
case Ci.nsIX509Cert.CERT_REVOKED:
dump("revoked");
break;
case Ci.nsIX509Cert.CERT_EXPIRED:
dump("expired");
break;
case Ci.nsIX509Cert.CERT_NOT_TRUSTED:
dump("not trusted");
break;
case Ci.nsIX509Cert.ISSUER_NOT_TRUSTED:
dump("issuer not trusted");
break;
case Ci.nsIX509Cert.ISSUER_UNKNOWN:
dump("issuer unknown");
break;
case Ci.nsIX509Cert.INVALID_CA:
dump("invalid CA");
break;
default:
dump("unexpected failure");
break;
}
dump("\n");
dump("\tCommon name (CN) = " + cert.commonName + "\n");
dump("\tOrganisation = " + cert.organization + "\n");
dump("\tIssuer = " + cert.issuerOrganization + "\n");
dump("\tSHA1 fingerprint = " + cert.sha1Fingerprint + "\n");
var validity = cert.validity.QueryInterface(Ci.nsIX509CertValidity);
dump("\tValid from " + validity.notBeforeGMT + "\n");
dump("\tValid until " + validity.notAfterGMT + "\n");
}
}
var myListener =
{
QueryInterface: function(aIID)
{
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
onStateChange: function(aWebProgress, aRequest, aFlag, aStatus) { },
onLocationChange: function(aProgress, aRequest, aURI) { },
onProgressChange: function(aWebProgress, aRequest, curSelf, maxSelf, curTot, maxTot) { },
onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) { },
onSecurityChange: function(aWebProgress, aRequest, aState)
{
// check if the state is secure or not
if(aState & Ci.nsIWebProgressListener.STATE_IS_SECURE)
{
// this is a secure page, check if aRequest is a channel,
// since only channels have security information
if (aRequest instanceof Ci.nsIChannel)
{
dumpSecurityInfo(aRequest);
}
}
}
}
var test =
{
run: function() {
dump("run\n");
gBrowser.addProgressListener(myListener);
}
};
window.addEventListener("load", function () { test.run(); }, false);
The way you query the channel to get its security info seems sane. I suspect that your problem is actually timing - you query it at the wrong time. Tracing all requests is really the wrong approach if security info is all you are interested in. It makes far more sense to register a progress listener (there are examples) and to look at the channel whenever onSecurityChange is being called. You are likely to be only interested in requests where aState contains STATE_IS_SECURE flag. Note that aRequest parameter is usually an nsIChannel instance but could also be a plain nsIRequest - instanceof check is required.

Categories