javascript - Chrome 插件随机向我的 C++ native 主机应用程序发送垃圾

标签 javascript c++ qt google-chrome google-chrome-extension

我正在尝试为我的大学项目编写一个简单的家长控制应用程序,但我是浏览器插件方面的新手。我想使用 Chrome 插件将用户实时查看的主机发送到 Qt 应用程序,它将分析用户行为。问题是,有时 chrome 会发送正确的主机,而有时它会发送带有空字符串或超长消息的垃圾,而我的 Qt 应用程序会对其进行过滤。但是这些“错误”消息是无限循环发送的,要使其再次运行,我必须重新启动扩展程序或 chrome 甚至整个 PC。

Chrome 插件 list :

{
    "name": "AM Chrome addon",
    "version": "0.7",
    "description": "Get your activity supervised!",
    "background": {
        "scripts": [
            "background.js"
        ],
        "persistent": false
    },
    "permissions": [
        "tabs",
        "nativeMessaging",
        "background"
    ],
    "manifest_version": 2
}

插件 background.js 文件:

var current = undefined;
var port = null;
tryConnectagain();

function tryConnectagain() {
    port = chrome.runtime.connectNative('<Native host app-name>');
    port.onDisconnect.addListener(onDisconnect);
}

function onDisconnect() {
    port = null;
        console.log("last error: ", chrome.runtime.lastError.message);
        setTimeout(tryConnectagain, 1000);
}

function sendMessageToNativeApp(message) {
    if (port != null) port.postMessage({ message: message });
}

function newUrl(u) {
    if (u != undefined && !u.includes(current) && !u.includes("chrome-extension://") && u.includes('.')) {
        var u = new URL(u);
        var domain = u.hostname.replace("www.", "");
        if (domain != current) {
            current = domain;
            sendMessageToNativeApp(current);
            console.log(current);
        }
    }
    else if (current != "NotURL") {
        current = "NotURL";
        sendMessageToNativeApp(current);
        console.log(current);
    }
}

// Here I'm trying to intercept all URL change situations

chrome.tabs.onActivated.addListener(function (activeInfo) {
    chrome.tabs.get(activeInfo.tabId, function (tab) {
        if (tab.active && tab.highlighted) newUrl(tab.url);
    });
});

chrome.tabs.onAttached.addListener(function (tabId, attachInfo) {
    chrome.tabs.get(tabId, function (tab) {
        if (tab.active && tab.highlighted) newUrl(tab.url);
    });
});

chrome.tabs.onReplaced.addListener(function (addedTabId, removedTabId) {
    chrome.tabs.get(addedTabId, function (tab) {
        if (tab.active && tab.highlighted) newUrl(tab.url);
    });
});

chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
    if (changeInfo.url && tab.active && tab.highlighted) newUrl(changeInfo.url);
});

chrome.windows.onFocusChanged.addListener(function (windowId) {
    if (windowId > -1) {
        var getInfo = { populate: true, windowTypes: ['normal'] };
        chrome.windows.getLastFocused(getInfo, function (window) {
            for (var t = 0; t < window.tabs.length; t++) {
                if (window.tabs[t].active && window.tabs[t].highlighted) {
                    newUrl(window.tabs[t].url);
                    break;
                }
            }
        })
    }
});

native 主机应用程序 list :

{
  "name": "<Native host app-name>",
  "description": "Hostname Identifier",
  "path": "<Hostname app Path>",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://<extension-ID>/"
  ]
}

以及从插件接收数据的 C++ qt 代码片段: 插件消息接收者.h:

#ifndef ADDONMESSAGERECEIVER_H
#define ADDONMESSAGERECEIVER_H

#include <qthread.h>
#include <QJsonDocument>
#include <QJsonObject>

#include <iostream>
#include <string>

class AddonMessageReceiver : public QThread
{
    Q_OBJECT
public:
    void run();
signals:
    void UpdateMessage(const QString &);
};

#endif // ADDONMESSAGERECEIVER_H

addonmessagereceiver.cpp:

#include "addonmessagereceiver.h"
#include <qdebug.h>
using namespace std;

void AddonMessageReceiver::run()
{
    do{
        char nextMessageLen[4];
        cin.read(nextMessageLen, 4);
        unsigned long int messageLength = *reinterpret_cast<unsigned long int *>(nextMessageLen);
        qDebug() << messageLength << static_cast<int>(nextMessageLen[0]) << static_cast<int>(nextMessageLen[1]) << static_cast<int>(nextMessageLen[2]) << static_cast<int>(nextMessageLen[3]);
        if(messageLength<1024 && messageLength>1)
        {
            char *incomingMessage = new char[messageLength+1];
            memset(incomingMessage,'\0',messageLength+1);
            cin.read(incomingMessage, messageLength);
            QString message = QString::fromLatin1(incomingMessage);
            delete[] incomingMessage;
            qDebug() << messageLength << message;
            if(message.length()>5)
            {
                QJsonDocument json = QJsonDocument::fromJson(message.toLatin1());
                QJsonObject obj = json.object();
                QString host = obj.value("message").toString();
                emit UpdateMessage(host);
            }
        }
        QThread::msleep(100);
    }while(true);
}

循环中 qDebug 错误的 nextMessageLen 示例:

还有一个很好的输入在循环中变成错误的例子:

你能告诉我那个扩展程序或 chrome 发生了什么,或者我对 native 应用程序有什么问题吗?谢谢你的回答。

最佳答案

基于 this answer我已经构建了一个监视“stdin”的类,获取文本并使用 QFile 对其进行解码:

nativemessenger.h

#ifndef NATIVEMESSENGER_H
#define NATIVEMESSENGER_H

#include <QObject>
#include <QFile>

class NativeMessenger : public QObject
{
    Q_OBJECT
public:
    explicit NativeMessenger(QObject *parent = nullptr);
public Q_SLOTS:
    void sendMessage(const QByteArray & message);
Q_SIGNALS:
    void messageChanged(const QByteArray & message);
private Q_SLOTS:
    void readyRead();
private:
    QFile m_qin;
    QFile m_qout;
};

#endif // NATIVEMESSENGER_H

nativemessenger.cpp

#include "nativemessenger.h"

#include <QCoreApplication>
#ifdef Q_OS_WIN
#include <QWinEventNotifier>
#include <windows.h>
#else
#include <QSocketNotifier>
#endif
NativeMessenger::NativeMessenger(QObject *parent) : QObject(parent)
{
#ifdef Q_OS_WIN
    // https://developer.chrome.com/apps/nativeMessaging#native-messaging-debugging
    _setmode(_fileno(stdin), _O_BINARY);
    _setmode(_fileno(stdout), _O_BINARY);
#endif

    m_qin.open(stdin, QIODevice::ReadOnly | QIODevice::Unbuffered);
    m_qout.open(stdout, QIODevice::WriteOnly);

#ifdef Q_OS_WIN
    QWinEventNotifier *m_notifier = new QWinEventNotifier(GetStdHandle(STD_INPUT_HANDLE));
    connect(m_notifier, &QWinEventNotifier::activated, this, &NativeMessenger::readyRead);
#else
    QSocketNotifier *m_notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this);
    connect(m_notifier, &QSocketNotifier::activated, this, &NativeMessenger::readyRead);
#endif
}

void NativeMessenger::sendMessage(const QByteArray &message){
    quint32 len = message.length();
    m_qout.write(reinterpret_cast<char *>(&len), sizeof(len));
    m_qout.write(message);
    m_qout.flush();
}

void NativeMessenger::readyRead(){
    m_qin.startTransaction();
    quint32 length = 0;
    qint64 rc = m_qin.read(reinterpret_cast<char *>(&length), sizeof(quint32));
    if (rc == -1) {
        m_qin.rollbackTransaction();
        return;
    }
    QByteArray message = m_qin.read(length);
    if (message.length() != int(length)) {
        m_qin.rollbackTransaction();
        return;
    }
    if (message.isEmpty()) {
        m_qin.rollbackTransaction();
        return;
    }
    m_qin.commitTransaction();
    Q_EMIT messageChanged(message);
}

main.cpp

#include <QCoreApplication>
#include <QJsonDocument>
#include <QJsonObject>

#include <QDebug>

#include "nativemessenger.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    NativeMessenger listener;
    QObject::connect(&listener, &NativeMessenger::messageChanged,
                     [&listener]
                     (const QByteArray & message){
        // decode message 
        QJsonParseError error;
        QJsonDocument json = QJsonDocument::fromJson(message, &error);
        if(error.error != QJsonParseError::NoError){
            qDebug() << error.errorString();
        }
        // build response
        QJsonObject object
        {
            {"data", json.object()},
            {"name", QCoreApplication::applicationName()}
        };
        QByteArray response = QJsonDocument(object).toJson(QJsonDocument::Compact);
        // send response
        listener.sendMessage(response);
    });
    return a.exec();
}

可以找到一个完整的例子here .

关于javascript - Chrome 插件随机向我的 C++ native 主机应用程序发送垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59336957/

相关文章:

javascript - 使用分页时只有表格的第一页是可点击的 - List.js

javascript - 如何解决与包 node-gyp 相关的 Node 包管理器错误?

c++ - Qt5 与 CMake : how to find qt translations dir?

c++ - 如何在Windows中使用Valgrind和vera++

javascript - Emberjs/Chrome/FFox : numeric Access-Control-Request-Headers in preflight

javascript - 在第一个数组元素的第二个数组元素中查找字母

c++ - 确保当前线程持有 C++11 互斥锁

c++ - 在没有序列化库的情况下,在 c++ 中从结构读取数据和从文件写入数据的最简单方法是什么?

c++ - 我的树节点缺少链接

html - 如何在 Qt 中用单个表格填充 QTextBrowser?