Solve SonarCloud security hotspots and bugs (#7383)
* Test: allocLockCursorToScreenInfo_withState_setsState * Merge remote-tracking branch 'origin/master' into S1-1717-sonarcloud-issues * Remove header wrappers for gmock/gtest * Convenience wrapper script for tests * Use `std::copy` instead of `strcpy` * Use `std::ranges::copy` instead of `stdcpy` * Delete dead code * Add guitests VS Code config and test wrapper * Revert "Delete dead code" This reverts commit aa40f5cd35a22b4b69acfd1876aceea053088060. * Build guitests with CMake * Run all tests * Don't use --gtest_filter for Qt tests * Undo skip for GUI tests * Coverage for `IpcClient::sendCommand` * Remove provider and proxy * Use lamda for StreamProvider to reduce boilerplate * Restore version checker tests * Remove activation souces * Tasks for current/all tests * Change command for tasks * Mock QNetworkAccessManager * Create core app to satisfy Qt assertations * Use `std::copy` instead of `std::ranges::copy` * Remove integtests * Merge guitests into unittests * Use std::string::length * Remove include (resolves to root) * Fix memory leaks * Disable sigsegv tests * Fixed formatting * Remove guitests from CI * New MainWindowTests * Passing test for MainWindowTests * Use alternative to strlen in MainWindow::checkSecureSocket * Passing test for Log::print * Fixed dtor call order * Fixed var name typo * Use proxy instead of `#define protected public` * Add args test for log * Add license ctor * Fixed log test for release * Add error log test * Init qt with -platform offscreen * Back-out initQt function * Use QT_QPA_PLATFORM * Try QT_QPA_PLATFORM=offscreen * Use more readable env node * Set QT_QPA_PLATFORM in CI and CodeQL * Remove env not needed * Modernize Log::print * Calculate the length of the format string fmt during the initial scan loop * More direct and efficient alterative to `strlen` * Fixed major maint issues in AppConfig * New clang and cmake rules * Set `max_pargs_hwrap` to 4 * Undo clang format for now * Fix missing `Setting::` * Fixed missing `m_S` on Windows * Re-add accidental dep resolution (fix later) * Fixed missing buffer position increment * Turn on errors * Fixed tests and improve error message * Fixed segfault on log refactor * Extract log time to function * Copyright date * Update ChangeLog
This commit is contained in:
parent
783afbe1c0
commit
50d29edd05
94 changed files with 931 additions and 575 deletions
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
|
@ -109,13 +109,13 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
- name: "macos-11-arm64"
|
||||
- name: "macos-14-arm64"
|
||||
timeout: 10
|
||||
os: "macos-14"
|
||||
arch: arm64
|
||||
shell: "/usr/bin/arch -arch arm64e /bin/bash --noprofile --norc -eo pipefail {0}"
|
||||
|
||||
- name: "macos-10-intel"
|
||||
- name: "macos-14-x64"
|
||||
timeout: 20
|
||||
os: "macos-14-large"
|
||||
arch: x64
|
||||
|
|
@ -244,6 +244,8 @@ jobs:
|
|||
run: cmake --build build -j8
|
||||
|
||||
- name: Test
|
||||
env:
|
||||
QT_QPA_PLATFORM: offscreen
|
||||
run: ./build/bin/unittests
|
||||
|
||||
- name: Package
|
||||
|
|
|
|||
2
.github/workflows/sonarcloud-analysis.yml
vendored
2
.github/workflows/sonarcloud-analysis.yml
vendored
|
|
@ -64,6 +64,8 @@ jobs:
|
|||
build-wrapper-linux-x86-64 --out-dir bw-output make -j
|
||||
|
||||
- name: Make coverage
|
||||
env:
|
||||
QT_QPA_PLATFORM: offscreen
|
||||
run: |
|
||||
cd build
|
||||
make coverage
|
||||
|
|
|
|||
42
.vscode/tasks.json
vendored
42
.vscode/tasks.json
vendored
|
|
@ -27,15 +27,47 @@
|
|||
"dependsOn": ["build"]
|
||||
},
|
||||
{
|
||||
"label": "unittests",
|
||||
"type": "shell",
|
||||
"command": "./build/bin/unittests",
|
||||
"label": "gui",
|
||||
"type": "process",
|
||||
"command": "${workspaceFolder}/build/bin/synergy",
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
{
|
||||
"label": "integtests",
|
||||
"label": "unittests (current)",
|
||||
"type": "shell",
|
||||
"command": "./build/bin/integtests",
|
||||
"command": "python",
|
||||
"args": [
|
||||
"./scripts/tests.py",
|
||||
"--unit-tests",
|
||||
"--ignore-return-code",
|
||||
"--filter-file=${file}"
|
||||
],
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
{
|
||||
"label": "integtests (current)",
|
||||
"type": "shell",
|
||||
"command": "python",
|
||||
"args": [
|
||||
"./scripts/tests.py",
|
||||
"--integ-tests",
|
||||
"--ignore-return-code",
|
||||
"--filter-file=${file}"
|
||||
],
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
{
|
||||
"label": "unittests (all)",
|
||||
"type": "shell",
|
||||
"command": "python",
|
||||
"args": ["./scripts/tests.py", "--unit-tests", "--ignore-return-code"],
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
{
|
||||
"label": "integtests (all)",
|
||||
"type": "shell",
|
||||
"command": "python",
|
||||
"args": ["./scripts/tests.py", "--integ-tests", "--ignore-return-code"],
|
||||
"dependsOn": ["build"]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ Enhancements:
|
|||
- #7382 Re-run `macdeployqt6` to copy missing Qt 6 dependencies
|
||||
- #7384 Run `install_deps.py` script when building containers weekly
|
||||
- #7389 Correct Qt macOS target and drop `Core5Compat` lib
|
||||
- #7383 Solve SonarCloud security hotspots and bugs
|
||||
|
||||
# 1.14.6
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
format:
|
||||
# Solves line ending issues on Windows.
|
||||
line_ending: "auto"
|
||||
|
||||
# Any more than 4 args, and function calls become hard to read.
|
||||
max_pargs_hwrap: 4
|
||||
|
||||
markup:
|
||||
first_comment_is_literal: true
|
||||
|
|
|
|||
|
|
@ -164,8 +164,11 @@ set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
|
|||
"Flags used by the shared libraries linker during coverage builds."
|
||||
FORCE)
|
||||
mark_as_advanced(
|
||||
CMAKE_Fortran_FLAGS_COVERAGE CMAKE_CXX_FLAGS_COVERAGE CMAKE_C_FLAGS_COVERAGE
|
||||
CMAKE_EXE_LINKER_FLAGS_COVERAGE CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
|
||||
CMAKE_Fortran_FLAGS_COVERAGE
|
||||
CMAKE_CXX_FLAGS_COVERAGE
|
||||
CMAKE_C_FLAGS_COVERAGE
|
||||
CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(
|
||||
|
|
@ -196,10 +199,19 @@ function(setup_target_for_coverage_lcov)
|
|||
|
||||
set(options NO_DEMANGLE)
|
||||
set(oneValueArgs BASE_DIRECTORY NAME)
|
||||
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS
|
||||
GENHTML_ARGS)
|
||||
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN})
|
||||
set(multiValueArgs
|
||||
EXCLUDE
|
||||
EXECUTABLE
|
||||
EXECUTABLE_ARGS
|
||||
DEPENDENCIES
|
||||
LCOV_ARGS
|
||||
GENHTML_ARGS)
|
||||
cmake_parse_arguments(
|
||||
Coverage
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN})
|
||||
|
||||
if(NOT LCOV_PATH)
|
||||
message(FATAL_ERROR "lcov not found! Aborting...")
|
||||
|
|
@ -221,7 +233,12 @@ function(setup_target_for_coverage_lcov)
|
|||
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES}
|
||||
${COVERAGE_LCOV_EXCLUDES})
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.4)
|
||||
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
|
||||
get_filename_component(
|
||||
EXCLUDE
|
||||
${EXCLUDE}
|
||||
ABSOLUTE
|
||||
BASE_DIR
|
||||
${BASEDIR})
|
||||
endif()
|
||||
list(APPEND LCOV_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
|
|
@ -261,8 +278,10 @@ function(setup_target_for_coverage_lcov)
|
|||
COMMAND ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} -o
|
||||
${Coverage_NAME} ${Coverage_NAME}.info
|
||||
# Set output files as GENERATED (will be removed on 'make clean')
|
||||
BYPRODUCTS ${Coverage_NAME}.base ${Coverage_NAME}.capture
|
||||
${Coverage_NAME}.total ${Coverage_NAME}.info
|
||||
BYPRODUCTS ${Coverage_NAME}.base
|
||||
${Coverage_NAME}.capture
|
||||
${Coverage_NAME}.total
|
||||
${Coverage_NAME}.info
|
||||
${Coverage_NAME} # report directory
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
|
|
@ -305,8 +324,12 @@ function(setup_target_for_coverage_gcovr_xml)
|
|||
set(options NONE)
|
||||
set(oneValueArgs BASE_DIRECTORY NAME)
|
||||
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
||||
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN})
|
||||
cmake_parse_arguments(
|
||||
Coverage
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN})
|
||||
|
||||
if(NOT GCOVR_PATH)
|
||||
message(FATAL_ERROR "gcovr not found! Aborting...")
|
||||
|
|
@ -324,7 +347,12 @@ function(setup_target_for_coverage_gcovr_xml)
|
|||
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES}
|
||||
${COVERAGE_GCOVR_EXCLUDES})
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.4)
|
||||
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
|
||||
get_filename_component(
|
||||
EXCLUDE
|
||||
${EXCLUDE}
|
||||
ABSOLUTE
|
||||
BASE_DIR
|
||||
${BASEDIR})
|
||||
endif()
|
||||
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
|
|
@ -374,8 +402,12 @@ function(setup_target_for_coverage_gcovr_html)
|
|||
set(options NONE)
|
||||
set(oneValueArgs BASE_DIRECTORY NAME)
|
||||
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
||||
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}"
|
||||
"${multiValueArgs}" ${ARGN})
|
||||
cmake_parse_arguments(
|
||||
Coverage
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN})
|
||||
|
||||
if(NOT GCOVR_PATH)
|
||||
message(FATAL_ERROR "gcovr not found! Aborting...")
|
||||
|
|
@ -393,7 +425,12 @@ function(setup_target_for_coverage_gcovr_html)
|
|||
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES}
|
||||
${COVERAGE_GCOVR_EXCLUDES})
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.4)
|
||||
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
|
||||
get_filename_component(
|
||||
EXCLUDE
|
||||
${EXCLUDE}
|
||||
ABSOLUTE
|
||||
BASE_DIR
|
||||
${BASEDIR})
|
||||
endif()
|
||||
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
|
|
|
|||
|
|
@ -228,7 +228,12 @@ macro(configure_xorg_libs)
|
|||
|
||||
# Xtxt depends on X11.
|
||||
set(HAVE_X11)
|
||||
list(APPEND libs Xtst X11 xkbfile)
|
||||
list(
|
||||
APPEND
|
||||
libs
|
||||
Xtst
|
||||
X11
|
||||
xkbfile)
|
||||
|
||||
else()
|
||||
|
||||
|
|
@ -280,8 +285,12 @@ macro(configure_windows_libs)
|
|||
comsuppw
|
||||
Shlwapi)
|
||||
|
||||
add_definitions(/DWIN32 /D_WINDOWS /D_CRT_SECURE_NO_WARNINGS
|
||||
/DSYNERGY_VERSION=\"${SYNERGY_VERSION}\" /D_XKEYCHECK_H)
|
||||
add_definitions(
|
||||
/DWIN32
|
||||
/D_WINDOWS
|
||||
/D_CRT_SECURE_NO_WARNINGS
|
||||
/DSYNERGY_VERSION=\"${SYNERGY_VERSION}\"
|
||||
/D_XKEYCHECK_H)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/res/win/version.rc.in
|
||||
${CMAKE_BINARY_DIR}/src/version.rc @ONLY)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ config:
|
|||
libxkbfile-dev \
|
||||
qt6-base-dev \
|
||||
qt6-tools-dev \
|
||||
libqt6core5compat6-dev \
|
||||
libgtk-3-dev \
|
||||
file
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,7 @@ include_files = [
|
|||
"CMakeLists.txt",
|
||||
]
|
||||
|
||||
exclude_dirs = [
|
||||
"ext",
|
||||
"build",
|
||||
]
|
||||
exclude_dirs = ["ext", "build", "deps"]
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
|||
47
scripts/tests.py
Executable file
47
scripts/tests.py
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse, os, sys
|
||||
import lib.cmd_utils as cmd_utils
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--unit-tests", action="store_true")
|
||||
parser.add_argument("--integ-tests", action="store_true")
|
||||
parser.add_argument(
|
||||
"--filter-file",
|
||||
type=str,
|
||||
help="Takes the base filename without extension and uses it as a filter",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ignore-return-code",
|
||||
action="store_true",
|
||||
help="Ignore the return code of the test command",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
binary = get_binary_path(args)
|
||||
if args.filter_file:
|
||||
file_base = os.path.basename(args.filter_file)
|
||||
without_ext = os.path.splitext(file_base)[0]
|
||||
command = [binary, f"--gtest_filter={without_ext}*"]
|
||||
else:
|
||||
command = [binary]
|
||||
|
||||
result = cmd_utils.run(command, print_cmd=True, check=False)
|
||||
if not args.ignore_return_code:
|
||||
sys.exit(result.returncode)
|
||||
|
||||
|
||||
def get_binary_path(args):
|
||||
base_dir = "./build/bin"
|
||||
if args.unit_tests:
|
||||
return f"{base_dir}/unittests"
|
||||
elif args.integ_tests:
|
||||
return f"{base_dir}/integtests"
|
||||
else:
|
||||
raise RuntimeError("No test type specified")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -8,7 +8,13 @@ set(CMAKE_AUTORCC ON)
|
|||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
file(GLOB GUI_SOURCE_FILES src/*.cpp src/*.h src/validators/* src/widgets/*)
|
||||
file(
|
||||
GLOB
|
||||
GUI_SOURCE_FILES
|
||||
src/*.cpp
|
||||
src/*.h
|
||||
src/validators/*
|
||||
src/widgets/*)
|
||||
file(GLOB GUI_UI_FILES src/*.ui)
|
||||
file(GLOB ACTIVATION_FILES src/*Activation* src/*License*)
|
||||
|
||||
|
|
@ -26,8 +32,13 @@ if(WIN32)
|
|||
set(GUI_RC_FILES res/win/Synergy.rc ${CMAKE_BINARY_DIR}/src/version.rc)
|
||||
endif()
|
||||
|
||||
add_executable(synergy WIN32 ${GUI_SOURCE_FILES} ${GUI_UI_FILES}
|
||||
${GUI_RC_FILES} res/Synergy.qrc ${QM_FILES})
|
||||
add_executable(
|
||||
synergy WIN32
|
||||
${GUI_SOURCE_FILES}
|
||||
${GUI_UI_FILES}
|
||||
${GUI_RC_FILES}
|
||||
res/Synergy.qrc
|
||||
${QM_FILES})
|
||||
|
||||
include_directories(./src)
|
||||
target_link_libraries(synergy shared)
|
||||
|
|
|
|||
|
|
@ -17,33 +17,31 @@
|
|||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include "QSynergyApplication.h"
|
||||
#include "QUtility.h"
|
||||
|
||||
#include "ConfigWriter.h"
|
||||
#include "SslCertificate.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include "ConfigWriter.h"
|
||||
#include "SslCertificate.h"
|
||||
|
||||
using GUI::Config::ConfigWriter;
|
||||
#if defined(Q_OS_WIN)
|
||||
const char AppConfig::m_SynergysName[] = "synergys.exe";
|
||||
const char AppConfig::m_SynergycName[] = "synergyc.exe";
|
||||
const char AppConfig::m_SynergyLogDir[] = "log/";
|
||||
const char AppConfig::synergyConfigName[] = "synergy.sgc";
|
||||
#define DEFAULT_PROCESS_MODE Service
|
||||
const char AppConfig::m_SynergyConfigName[] = "synergy.sgc";
|
||||
const ProcessMode kDefaultProcessMode = ProcessMode::kService;
|
||||
#else
|
||||
const char AppConfig::m_SynergysName[] = "synergys";
|
||||
const char AppConfig::m_SynergycName[] = "synergyc";
|
||||
const char AppConfig::m_SynergyLogDir[] = "/var/log/";
|
||||
const char AppConfig::synergyConfigName[] = "synergy.conf";
|
||||
#define DEFAULT_PROCESS_MODE Desktop
|
||||
const char AppConfig::m_SynergyConfigName[] = "synergy.conf";
|
||||
const ProcessMode kDefaultProcessMode = ProcessMode::kDesktop;
|
||||
#endif
|
||||
|
||||
const ElevateMode defaultElevateMode = ElevateAsNeeded;
|
||||
const ElevateMode kDefaultElevateMode = ElevateAsNeeded;
|
||||
|
||||
const char *AppConfig::m_SynergySettingsName[] = {
|
||||
"screenName",
|
||||
|
|
@ -86,10 +84,10 @@ const char *AppConfig::m_SynergySettingsName[] = {
|
|||
|
||||
static const char *logLevelNames[] = {"INFO", "DEBUG", "DEBUG1", "DEBUG2"};
|
||||
|
||||
AppConfig::AppConfig()
|
||||
AppConfig::AppConfig(bool globalLoad)
|
||||
: m_ScreenName(), m_Port(24800), m_Interface(), m_LogLevel(0),
|
||||
m_LogToFile(), m_WizardLastRun(0), m_ProcessMode(DEFAULT_PROCESS_MODE),
|
||||
m_StartedBefore(), m_ElevateMode(defaultElevateMode),
|
||||
m_LogToFile(), m_WizardLastRun(0), m_ProcessMode(kDefaultProcessMode),
|
||||
m_StartedBefore(), m_ElevateMode(kDefaultElevateMode),
|
||||
m_Edition(kUnregistered), m_CryptoEnabled(false), m_AutoHide(false),
|
||||
m_LastExpiringWarningTime(0), m_ActivationHasRun(),
|
||||
m_MinimizeToTray(false), m_ServerGroupChecked(), m_UseExternalConfig(),
|
||||
|
|
@ -99,15 +97,20 @@ AppConfig::AppConfig()
|
|||
|
||||
// Register this class to receive global load and saves
|
||||
writer->registerClass(this);
|
||||
writer->globalLoad();
|
||||
|
||||
// HACK: enable global load by default but allow it to be disabled for tests.
|
||||
// when run in a test environment, this function causes a segfault.
|
||||
if (globalLoad) {
|
||||
writer->globalLoad();
|
||||
}
|
||||
|
||||
// User settings exist and the load from system scope variable is true
|
||||
if (writer->hasSetting(settingName(kLoadSystemSettings),
|
||||
if (writer->hasSetting(settingName(Setting::kLoadSystemSettings),
|
||||
ConfigWriter::kUser)) {
|
||||
setLoadFromSystemScope(m_LoadFromSystemScope);
|
||||
}
|
||||
// If user setting don't exist but system ones do, load the system settings
|
||||
else if (writer->hasSetting(settingName(kScreenName),
|
||||
else if (writer->hasSetting(settingName(Setting::kScreenName),
|
||||
ConfigWriter::kSystem)) {
|
||||
setLoadFromSystemScope(true);
|
||||
}
|
||||
|
|
@ -165,72 +168,82 @@ bool AppConfig::startedBefore() const { return m_StartedBefore; }
|
|||
|
||||
void AppConfig::loadSettings() {
|
||||
m_ScreenName =
|
||||
loadSetting(kScreenName, QHostInfo::localHostName()).toString();
|
||||
loadSetting(Setting::kScreenName, QHostInfo::localHostName()).toString();
|
||||
if (m_ScreenName.isEmpty()) {
|
||||
m_ScreenName = QHostInfo::localHostName();
|
||||
}
|
||||
|
||||
m_Port = loadSetting(kPort, 24800).toInt();
|
||||
m_Interface = loadSetting(kInterfaceSetting).toString();
|
||||
m_LogLevel = loadSetting(kLogLevel, 0).toInt();
|
||||
m_LogToFile = loadSetting(kLogToFile, false).toBool();
|
||||
m_Port = loadSetting(Setting::kPort, 24800).toInt();
|
||||
m_Interface = loadSetting(Setting::kInterfaceSetting).toString();
|
||||
m_LogLevel = loadSetting(Setting::kLogLevel, 0).toInt();
|
||||
m_LogToFile = loadSetting(Setting::kLogToFile, false).toBool();
|
||||
m_LogFilename =
|
||||
loadSetting(kLogFilename, synergyLogDir() + "synergy.log").toString();
|
||||
m_WizardLastRun = loadCommonSetting(kWizardLastRun, 0).toInt();
|
||||
m_StartedBefore = loadSetting(kStartedBefore, false).toBool();
|
||||
loadSetting(Setting::kLogFilename, synergyLogDir() + "synergy.log")
|
||||
.toString();
|
||||
m_WizardLastRun = loadCommonSetting(Setting::kWizardLastRun, 0).toInt();
|
||||
m_StartedBefore = loadSetting(Setting::kStartedBefore, false).toBool();
|
||||
|
||||
{ // Scope related code together
|
||||
// TODO Investigate why kElevateModeEnum isn't loaded fully
|
||||
QVariant elevateMode = loadSetting(kElevateModeEnum);
|
||||
QVariant elevateMode = loadSetting(Setting::kElevateModeEnum);
|
||||
if (!elevateMode.isValid()) {
|
||||
elevateMode = loadSetting(kElevateModeSetting,
|
||||
QVariant(static_cast<int>(defaultElevateMode)));
|
||||
elevateMode =
|
||||
loadSetting(Setting::kElevateModeSetting,
|
||||
QVariant(static_cast<int>(kDefaultElevateMode)));
|
||||
}
|
||||
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
|
||||
}
|
||||
|
||||
m_ActivateEmail = loadSetting(kActivateEmail, "").toString();
|
||||
m_CryptoEnabled = loadSetting(kCryptoEnabled, true).toBool();
|
||||
m_AutoHide = loadSetting(kAutoHide, false).toBool();
|
||||
m_lastVersion = loadSetting(kLastVersion, "Unknown").toString();
|
||||
m_LastExpiringWarningTime = loadSetting(kLastExpireWarningTime, 0).toInt();
|
||||
m_ActivationHasRun = loadSetting(kActivationHasRun, false).toBool();
|
||||
m_MinimizeToTray = loadSetting(kMinimizeToTray, false).toBool();
|
||||
m_ActivateEmail = loadSetting(Setting::kActivateEmail, "").toString();
|
||||
m_CryptoEnabled = loadSetting(Setting::kCryptoEnabled, true).toBool();
|
||||
m_AutoHide = loadSetting(Setting::kAutoHide, false).toBool();
|
||||
m_lastVersion = loadSetting(Setting::kLastVersion, "Unknown").toString();
|
||||
m_LastExpiringWarningTime =
|
||||
loadSetting(Setting::kLastExpireWarningTime, 0).toInt();
|
||||
m_ActivationHasRun = loadSetting(Setting::kActivationHasRun, false).toBool();
|
||||
m_MinimizeToTray = loadSetting(Setting::kMinimizeToTray, false).toBool();
|
||||
m_LoadFromSystemScope =
|
||||
loadCommonSetting(kLoadSystemSettings, false).toBool();
|
||||
m_ServerGroupChecked = loadSetting(kGroupServerCheck, false).toBool();
|
||||
m_UseExternalConfig = loadSetting(kUseExternalConfig, false).toBool();
|
||||
m_ConfigFile =
|
||||
loadSetting(kConfigFile, QDir::homePath() + "/" + synergyConfigName)
|
||||
.toString();
|
||||
m_UseInternalConfig = loadSetting(kUseInternalConfig, false).toBool();
|
||||
m_ClientGroupChecked = loadSetting(kGroupClientCheck, false).toBool();
|
||||
m_ServerHostname = loadSetting(kServerHostname).toString();
|
||||
m_PreventSleep = loadSetting(kPreventSleep, false).toBool();
|
||||
m_LanguageSync = loadSetting(kLanguageSync, false).toBool();
|
||||
m_InvertScrollDirection = loadSetting(kInvertScrollDirection, false).toBool();
|
||||
m_guid = loadCommonSetting(kGuid, QUuid::createUuid()).toString();
|
||||
loadCommonSetting(Setting::kLoadSystemSettings, false).toBool();
|
||||
m_ServerGroupChecked =
|
||||
loadSetting(Setting::kGroupServerCheck, false).toBool();
|
||||
m_UseExternalConfig =
|
||||
loadSetting(Setting::kUseExternalConfig, false).toBool();
|
||||
m_ConfigFile = loadSetting(Setting::kConfigFile,
|
||||
QDir::homePath() + "/" + m_SynergyConfigName)
|
||||
.toString();
|
||||
m_UseInternalConfig =
|
||||
loadSetting(Setting::kUseInternalConfig, false).toBool();
|
||||
m_ClientGroupChecked =
|
||||
loadSetting(Setting::kGroupClientCheck, false).toBool();
|
||||
m_ServerHostname = loadSetting(Setting::kServerHostname).toString();
|
||||
m_PreventSleep = loadSetting(Setting::kPreventSleep, false).toBool();
|
||||
m_LanguageSync = loadSetting(Setting::kLanguageSync, false).toBool();
|
||||
m_InvertScrollDirection =
|
||||
loadSetting(Setting::kInvertScrollDirection, false).toBool();
|
||||
m_guid = loadCommonSetting(Setting::kGuid, QUuid::createUuid()).toString();
|
||||
m_licenseRegistryUrl =
|
||||
loadCommonSetting(kLicenseRegistryUrl,
|
||||
loadCommonSetting(Setting::kLicenseRegistryUrl,
|
||||
"https://api2.prod.symless.com/license/register")
|
||||
.toString();
|
||||
m_licenseNextCheck = loadCommonSetting(kLicenseNextCheck, 0).toULongLong();
|
||||
m_ClientHostMode = loadSetting(kClientHostMode, true).toBool();
|
||||
m_ServerClientMode = loadSetting(kServerClientMode, true).toBool();
|
||||
m_licenseNextCheck =
|
||||
loadCommonSetting(Setting::kLicenseNextCheck, 0).toULongLong();
|
||||
m_ClientHostMode = loadSetting(Setting::kClientHostMode, true).toBool();
|
||||
m_ServerClientMode = loadSetting(Setting::kServerClientMode, true).toBool();
|
||||
m_InitiateConnectionFromServer =
|
||||
loadSetting(kInitiateConnectionFromServer, false).toBool();
|
||||
loadSetting(Setting::kInitiateConnectionFromServer, false).toBool();
|
||||
|
||||
// only change the serial key if the settings being loaded contains a key
|
||||
bool updateSerial = ConfigWriter::make()->hasSetting(
|
||||
settingName(kLoadSystemSettings), ConfigWriter::kCurrent);
|
||||
settingName(Setting::kLoadSystemSettings), ConfigWriter::kCurrent);
|
||||
// if the setting exists and is not empty
|
||||
updateSerial = updateSerial &&
|
||||
!loadSetting(kSerialKey, "").toString().trimmed().isEmpty();
|
||||
updateSerial =
|
||||
updateSerial &&
|
||||
!loadSetting(Setting::kSerialKey, "").toString().trimmed().isEmpty();
|
||||
|
||||
if (updateSerial) {
|
||||
m_Serialkey = loadSetting(kSerialKey, "").toString().trimmed();
|
||||
m_Serialkey = loadSetting(Setting::kSerialKey, "").toString().trimmed();
|
||||
m_Edition = static_cast<Edition>(
|
||||
loadSetting(kEditionSetting, kUnregistered).toInt());
|
||||
loadSetting(Setting::kEditionSetting, kUnregistered).toInt());
|
||||
}
|
||||
|
||||
// Set the default path of the TLS certificate file in the users DIR
|
||||
|
|
@ -239,8 +252,8 @@ void AppConfig::loadSettings() {
|
|||
.arg(m_CoreInterface.getProfileDir(), "SSL", "Synergy.pem");
|
||||
|
||||
m_TLSCertificatePath =
|
||||
loadSetting(kTLSCertPath, certificateFilename).toString();
|
||||
m_TLSKeyLength = loadSetting(kTLSKeyLength, "2048").toString();
|
||||
loadSetting(Setting::kTLSCertPath, certificateFilename).toString();
|
||||
m_TLSKeyLength = loadSetting(Setting::kTLSKeyLength, "2048").toString();
|
||||
|
||||
if (getCryptoEnabled()) {
|
||||
generateCertificate();
|
||||
|
|
@ -248,43 +261,43 @@ void AppConfig::loadSettings() {
|
|||
}
|
||||
|
||||
void AppConfig::saveSettings() {
|
||||
setCommonSetting(kWizardLastRun, m_WizardLastRun);
|
||||
setCommonSetting(kLoadSystemSettings, m_LoadFromSystemScope);
|
||||
setCommonSetting(kGroupClientCheck, m_ClientGroupChecked);
|
||||
setCommonSetting(kGroupServerCheck, m_ServerGroupChecked);
|
||||
setCommonSetting(kGuid, m_guid);
|
||||
setCommonSetting(kLicenseRegistryUrl, m_licenseRegistryUrl);
|
||||
setCommonSetting(kLicenseNextCheck, m_licenseNextCheck);
|
||||
setCommonSetting(Setting::kWizardLastRun, m_WizardLastRun);
|
||||
setCommonSetting(Setting::kLoadSystemSettings, m_LoadFromSystemScope);
|
||||
setCommonSetting(Setting::kGroupClientCheck, m_ClientGroupChecked);
|
||||
setCommonSetting(Setting::kGroupServerCheck, m_ServerGroupChecked);
|
||||
setCommonSetting(Setting::kGuid, m_guid);
|
||||
setCommonSetting(Setting::kLicenseRegistryUrl, m_licenseRegistryUrl);
|
||||
setCommonSetting(Setting::kLicenseNextCheck, m_licenseNextCheck);
|
||||
|
||||
if (isWritable()) {
|
||||
setSetting(kScreenName, m_ScreenName);
|
||||
setSetting(kPort, m_Port);
|
||||
setSetting(kInterfaceSetting, m_Interface);
|
||||
setSetting(kLogLevel, m_LogLevel);
|
||||
setSetting(kLogToFile, m_LogToFile);
|
||||
setSetting(kLogFilename, m_LogFilename);
|
||||
setSetting(kStartedBefore, m_StartedBefore);
|
||||
setSetting(Setting::kScreenName, m_ScreenName);
|
||||
setSetting(Setting::kPort, m_Port);
|
||||
setSetting(Setting::kInterfaceSetting, m_Interface);
|
||||
setSetting(Setting::kLogLevel, m_LogLevel);
|
||||
setSetting(Setting::kLogToFile, m_LogToFile);
|
||||
setSetting(Setting::kLogFilename, m_LogFilename);
|
||||
setSetting(Setting::kStartedBefore, m_StartedBefore);
|
||||
// Refer to enum ElevateMode declaration for insight in to why this
|
||||
// flag is mapped this way
|
||||
setSetting(kElevateModeSetting, m_ElevateMode == ElevateAlways);
|
||||
setSetting(kElevateModeEnum, static_cast<int>(m_ElevateMode));
|
||||
setSetting(kEditionSetting, m_Edition);
|
||||
setSetting(kCryptoEnabled, m_CryptoEnabled);
|
||||
setSetting(kAutoHide, m_AutoHide);
|
||||
setSetting(kSerialKey, m_Serialkey);
|
||||
setSetting(kLastVersion, m_lastVersion);
|
||||
setSetting(kLastExpireWarningTime, m_LastExpiringWarningTime);
|
||||
setSetting(kActivationHasRun, m_ActivationHasRun);
|
||||
setSetting(kMinimizeToTray, m_MinimizeToTray);
|
||||
setSetting(kUseExternalConfig, m_UseExternalConfig);
|
||||
setSetting(kConfigFile, m_ConfigFile);
|
||||
setSetting(kUseInternalConfig, m_UseInternalConfig);
|
||||
setSetting(kServerHostname, m_ServerHostname);
|
||||
setSetting(kPreventSleep, m_PreventSleep);
|
||||
setSetting(kLanguageSync, m_LanguageSync);
|
||||
setSetting(kInvertScrollDirection, m_InvertScrollDirection);
|
||||
setSetting(kClientHostMode, m_ClientHostMode);
|
||||
setSetting(kServerClientMode, m_ServerClientMode);
|
||||
setSetting(Setting::kElevateModeSetting, m_ElevateMode == ElevateAlways);
|
||||
setSetting(Setting::kElevateModeEnum, static_cast<int>(m_ElevateMode));
|
||||
setSetting(Setting::kEditionSetting, m_Edition);
|
||||
setSetting(Setting::kCryptoEnabled, m_CryptoEnabled);
|
||||
setSetting(Setting::kAutoHide, m_AutoHide);
|
||||
setSetting(Setting::kSerialKey, m_Serialkey);
|
||||
setSetting(Setting::kLastVersion, m_lastVersion);
|
||||
setSetting(Setting::kLastExpireWarningTime, m_LastExpiringWarningTime);
|
||||
setSetting(Setting::kActivationHasRun, m_ActivationHasRun);
|
||||
setSetting(Setting::kMinimizeToTray, m_MinimizeToTray);
|
||||
setSetting(Setting::kUseExternalConfig, m_UseExternalConfig);
|
||||
setSetting(Setting::kConfigFile, m_ConfigFile);
|
||||
setSetting(Setting::kUseInternalConfig, m_UseInternalConfig);
|
||||
setSetting(Setting::kServerHostname, m_ServerHostname);
|
||||
setSetting(Setting::kPreventSleep, m_PreventSleep);
|
||||
setSetting(Setting::kLanguageSync, m_LanguageSync);
|
||||
setSetting(Setting::kInvertScrollDirection, m_InvertScrollDirection);
|
||||
setSetting(Setting::kClientHostMode, m_ClientHostMode);
|
||||
setSetting(Setting::kServerClientMode, m_ServerClientMode);
|
||||
}
|
||||
|
||||
m_unsavedChanges = false;
|
||||
|
|
@ -339,14 +352,14 @@ void AppConfig::setElevateMode(ElevateMode em) {
|
|||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
void AppConfig::setEdition(Edition e) {
|
||||
setSettingModified(m_Edition, e);
|
||||
setCommonSetting(kEditionSetting, m_Edition);
|
||||
setCommonSetting(Setting::kEditionSetting, m_Edition);
|
||||
}
|
||||
|
||||
Edition AppConfig::edition() const { return m_Edition; }
|
||||
|
||||
void AppConfig::setSerialKey(const QString &serial) {
|
||||
setSettingModified(m_Serialkey, serial);
|
||||
setCommonSetting(kSerialKey, m_Serialkey);
|
||||
setCommonSetting(Setting::kSerialKey, m_Serialkey);
|
||||
}
|
||||
|
||||
void AppConfig::clearSerialKey() { m_Serialkey.clear(); }
|
||||
|
|
@ -448,29 +461,27 @@ void AppConfig::setPreventSleep(bool newValue) {
|
|||
|
||||
bool AppConfig::getMinimizeToTray() { return m_MinimizeToTray; }
|
||||
|
||||
QString AppConfig::settingName(AppConfig::Setting name) {
|
||||
return m_SynergySettingsName[name];
|
||||
QString AppConfig::settingName(Setting name) {
|
||||
auto index = static_cast<int>(name);
|
||||
return m_SynergySettingsName[index];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AppConfig::setSetting(AppConfig::Setting name, T value) {
|
||||
template <typename T> void AppConfig::setSetting(Setting name, T value) {
|
||||
ConfigWriter::make()->setSetting(settingName(name), value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AppConfig::setCommonSetting(AppConfig::Setting name, T value) {
|
||||
template <typename T> void AppConfig::setCommonSetting(Setting name, T value) {
|
||||
ConfigWriter::make()->setSetting(settingName(name), value,
|
||||
ConfigWriter::kUser);
|
||||
ConfigWriter::make()->setSetting(settingName(name), value,
|
||||
ConfigWriter::kSystem);
|
||||
}
|
||||
|
||||
QVariant AppConfig::loadSetting(AppConfig::Setting name,
|
||||
const QVariant &defaultValue) {
|
||||
QVariant AppConfig::loadSetting(Setting name, const QVariant &defaultValue) {
|
||||
return ConfigWriter::make()->loadSetting(settingName(name), defaultValue);
|
||||
}
|
||||
|
||||
QVariant AppConfig::loadCommonSetting(AppConfig::Setting name,
|
||||
QVariant AppConfig::loadCommonSetting(Setting name,
|
||||
const QVariant &defaultValue) const {
|
||||
QVariant result(defaultValue);
|
||||
QString setting(settingName(name));
|
||||
|
|
@ -495,7 +506,8 @@ void AppConfig::loadScope(ConfigWriter::Scope scope) {
|
|||
if (writer->getScope() != scope) {
|
||||
setDefaultValues();
|
||||
writer->setScope(scope);
|
||||
if (writer->hasSetting(settingName(kScreenName), writer->getScope())) {
|
||||
if (writer->hasSetting(settingName(Setting::kScreenName),
|
||||
writer->getScope())) {
|
||||
// If the user already has settings, then load them up now.
|
||||
writer->globalLoad();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class SettingsDialog;
|
|||
class ServerConfig;
|
||||
class LicenseRegister;
|
||||
|
||||
enum ProcessMode { Service, Desktop };
|
||||
enum class ProcessMode { kService, kDesktop };
|
||||
|
||||
class AppConfig : public QObject, public GUI::Config::ConfigBase {
|
||||
Q_OBJECT
|
||||
|
|
@ -63,9 +63,8 @@ class AppConfig : public QObject, public GUI::Config::ConfigBase {
|
|||
friend class ServerConfig;
|
||||
|
||||
public:
|
||||
AppConfig();
|
||||
explicit AppConfig(bool globalLoad = true);
|
||||
|
||||
public:
|
||||
bool isWritable() const;
|
||||
bool isSystemScoped() const;
|
||||
|
||||
|
|
@ -176,7 +175,7 @@ public:
|
|||
protected:
|
||||
/// @brief The enumeration to easily access the names of the setting inside
|
||||
/// m_SynergySettingsName
|
||||
enum Setting {
|
||||
enum class Setting {
|
||||
kScreenName,
|
||||
kPort,
|
||||
kInterfaceSetting,
|
||||
|
|
@ -288,7 +287,7 @@ private:
|
|||
static const char *m_SynergySettingsName[];
|
||||
|
||||
/// @brief Contains the name of the default configuration filename
|
||||
static const char synergyConfigName[];
|
||||
static const char m_SynergyConfigName[];
|
||||
|
||||
/// @brief Sets the value of a setting
|
||||
/// @param [in] name The Setting to be saved
|
||||
|
|
|
|||
|
|
@ -34,4 +34,4 @@
|
|||
//
|
||||
enum ElevateMode { ElevateAsNeeded = 0, ElevateAlways = 1, ElevateNever = 2 };
|
||||
|
||||
extern const ElevateMode defaultElevateMode;
|
||||
extern const ElevateMode kDefaultElevateMode;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
* Copyright (C) 2008 Volker Lanz (vl@fidra.de)
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
|
|
@ -25,15 +25,10 @@
|
|||
|
||||
#include "AboutDialog.h"
|
||||
#include "ActivationDialog.h"
|
||||
#include "CommandProcess.h"
|
||||
#include "DataDownloader.h"
|
||||
#include "Fingerprint.h"
|
||||
#include "LicenseManager.h"
|
||||
#include "ProcessorArch.h"
|
||||
#include "QUtility.h"
|
||||
#include "ServerConfigDialog.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include "SslCertificate.h"
|
||||
#include <QPushButton>
|
||||
#include <shared/EditionType.h>
|
||||
|
||||
|
|
@ -56,8 +51,6 @@
|
|||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
static const char *tlsCheckString = "network encryption protocol: ";
|
||||
|
||||
static const int debugLogLevel = 1;
|
||||
|
||||
static const char *synergyLightIconFiles[] = {
|
||||
|
|
@ -181,7 +174,7 @@ MainWindow::MainWindow(AppConfig &appConfig)
|
|||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
if (appConfig().processMode() == Desktop) {
|
||||
if (appConfig().processMode() == ProcessMode::kDesktop) {
|
||||
m_ExpectedRunningState = kStopped;
|
||||
try {
|
||||
stopDesktop();
|
||||
|
|
@ -216,7 +209,7 @@ void MainWindow::open() {
|
|||
// auto hiding before the user has configured synergy (which of course
|
||||
// confuses first time users, who think synergy has crashed).
|
||||
if (appConfig().startedBefore() &&
|
||||
appConfig().processMode() == ProcessMode::Desktop) {
|
||||
appConfig().processMode() == ProcessMode::kDesktop) {
|
||||
startSynergy();
|
||||
}
|
||||
}
|
||||
|
|
@ -486,20 +479,16 @@ void MainWindow::checkFingerprint(const QString &line) {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::checkSecureSocket(const QString &line) {
|
||||
// obviously not very secure, since this can be tricked by injecting something
|
||||
// into the log. however, since we don't have IPC between core and GUI...
|
||||
// patches welcome.
|
||||
const int index = line.indexOf(tlsCheckString, 0, Qt::CaseInsensitive);
|
||||
if (index > 0) {
|
||||
secureSocket(true);
|
||||
|
||||
// Get the protocol version from the line
|
||||
m_SecureSocketVersion = line.mid(
|
||||
index + strlen(tlsCheckString)); // Compliant: we made sure that
|
||||
// tlsCheckString variable ended with
|
||||
// null(static const char* declaration)
|
||||
bool MainWindow::checkSecureSocket(const QString &line) {
|
||||
static const QString tlsCheckString = "network encryption protocol: ";
|
||||
const auto index = line.indexOf(tlsCheckString, 0, Qt::CaseInsensitive);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
secureSocket(true);
|
||||
m_SecureSocketVersion = line.mid(index + tlsCheckString.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
|
@ -554,8 +543,8 @@ void MainWindow::startSynergy() {
|
|||
}
|
||||
m_LicenseManager->registerLicense();
|
||||
#endif
|
||||
bool desktopMode = appConfig().processMode() == Desktop;
|
||||
bool serviceMode = appConfig().processMode() == Service;
|
||||
bool desktopMode = appConfig().processMode() == ProcessMode::kDesktop;
|
||||
bool serviceMode = appConfig().processMode() == ProcessMode::kService;
|
||||
|
||||
appendLogDebug("starting process");
|
||||
m_ExpectedRunningState = kStarted;
|
||||
|
|
@ -859,9 +848,9 @@ void MainWindow::stopSynergy() {
|
|||
|
||||
m_ExpectedRunningState = kStopped;
|
||||
|
||||
if (appConfig().processMode() == Service) {
|
||||
if (appConfig().processMode() == ProcessMode::kService) {
|
||||
stopService();
|
||||
} else if (appConfig().processMode() == Desktop) {
|
||||
} else if (appConfig().processMode() == ProcessMode::kDesktop) {
|
||||
stopDesktop();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
#include "ClientConnection.h"
|
||||
#include "ConfigWriter.h"
|
||||
#include "Ipc.h"
|
||||
#include "IpcClient.h"
|
||||
#include "QIpcClient.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "ServerConnection.h"
|
||||
#include "VersionChecker.h"
|
||||
|
|
@ -188,7 +188,7 @@ protected:
|
|||
QString getProfileRootForArg();
|
||||
void checkConnected(const QString &line);
|
||||
void checkFingerprint(const QString &line);
|
||||
void checkSecureSocket(const QString &line);
|
||||
bool checkSecureSocket(const QString &line);
|
||||
#ifdef Q_OS_MAC
|
||||
void checkOSXNotification(const QString &line);
|
||||
#endif
|
||||
|
|
@ -215,7 +215,7 @@ private:
|
|||
ServerConfig m_ServerConfig;
|
||||
bool m_AlreadyHidden;
|
||||
VersionChecker m_VersionChecker;
|
||||
IpcClient m_IpcClient;
|
||||
QIpcClient m_IpcClient;
|
||||
QMenuBar *m_pMenuBar;
|
||||
QMenu *m_pMenuFile;
|
||||
QMenu *m_pMenuEdit;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -16,17 +15,26 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "IpcClient.h"
|
||||
#include "QIpcClient.h"
|
||||
#include "Ipc.h"
|
||||
#include "IpcReader.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QHostAddress>
|
||||
#include <QTcpSocket>
|
||||
#include <QTimer>
|
||||
#include <iostream>
|
||||
|
||||
IpcClient::IpcClient() : m_ReaderStarted(false), m_Enabled(false) {
|
||||
QIpcClient::QIpcClient(const StreamProvider &streamProvider)
|
||||
: m_ReaderStarted(false), m_Enabled(false),
|
||||
m_StreamProvider(streamProvider) {
|
||||
|
||||
m_Socket = new QTcpSocket(this);
|
||||
|
||||
if (!m_StreamProvider) {
|
||||
m_StreamProvider = [this]() {
|
||||
return std::make_shared<QDataStreamProxy>(m_Socket);
|
||||
};
|
||||
}
|
||||
|
||||
connect(m_Socket, SIGNAL(connected()), this, SLOT(connected()));
|
||||
connect(m_Socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this,
|
||||
SLOT(error(QAbstractSocket::SocketError)));
|
||||
|
|
@ -36,14 +44,17 @@ IpcClient::IpcClient() : m_ReaderStarted(false), m_Enabled(false) {
|
|||
SLOT(handleReadLogLine(const QString &)));
|
||||
}
|
||||
|
||||
IpcClient::~IpcClient() {}
|
||||
QIpcClient::~QIpcClient() {
|
||||
delete m_Reader;
|
||||
delete m_Socket;
|
||||
}
|
||||
|
||||
void IpcClient::connected() {
|
||||
void QIpcClient::connected() {
|
||||
sendHello();
|
||||
infoMessage("connection established");
|
||||
}
|
||||
|
||||
void IpcClient::connectToHost() {
|
||||
void QIpcClient::connectToHost() {
|
||||
m_Enabled = true;
|
||||
|
||||
infoMessage("connecting to service...");
|
||||
|
|
@ -55,13 +66,13 @@ void IpcClient::connectToHost() {
|
|||
}
|
||||
}
|
||||
|
||||
void IpcClient::disconnectFromHost() {
|
||||
void QIpcClient::disconnectFromHost() {
|
||||
infoMessage("service disconnect");
|
||||
m_Reader->stop();
|
||||
m_Socket->close();
|
||||
}
|
||||
|
||||
void IpcClient::error(QAbstractSocket::SocketError error) {
|
||||
void QIpcClient::error(QAbstractSocket::SocketError error) {
|
||||
QString text;
|
||||
switch (error) {
|
||||
case 0:
|
||||
|
|
@ -80,48 +91,46 @@ void IpcClient::error(QAbstractSocket::SocketError error) {
|
|||
QTimer::singleShot(1000, this, SLOT(retryConnect()));
|
||||
}
|
||||
|
||||
void IpcClient::retryConnect() {
|
||||
void QIpcClient::retryConnect() {
|
||||
if (m_Enabled) {
|
||||
connectToHost();
|
||||
}
|
||||
}
|
||||
|
||||
void IpcClient::sendHello() {
|
||||
QDataStream stream(m_Socket);
|
||||
stream.writeRawData(kIpcMsgHello, 4);
|
||||
void QIpcClient::sendHello() {
|
||||
auto stream = m_StreamProvider();
|
||||
stream->writeRawData(kIpcMsgHello, 4);
|
||||
|
||||
char typeBuf[1];
|
||||
typeBuf[0] = kIpcClientGui;
|
||||
stream.writeRawData(typeBuf, 1);
|
||||
stream->writeRawData(typeBuf, 1);
|
||||
}
|
||||
|
||||
void IpcClient::sendCommand(const QString &command, ElevateMode const elevate) {
|
||||
QDataStream stream(m_Socket);
|
||||
|
||||
stream.writeRawData(kIpcMsgCommand, 4);
|
||||
void QIpcClient::sendCommand(const QString &command,
|
||||
ElevateMode const elevate) {
|
||||
auto stream = m_StreamProvider();
|
||||
stream->writeRawData(kIpcMsgCommand, 4);
|
||||
|
||||
std::string stdStringCommand = command.toStdString();
|
||||
const char *charCommand = stdStringCommand.c_str();
|
||||
int length = static_cast<int>(
|
||||
strlen(charCommand)); // Compliant: we made sure that charCommand variable
|
||||
// ended with null(String type is safe)
|
||||
auto length = static_cast<int>(stdStringCommand.length());
|
||||
|
||||
char lenBuf[4];
|
||||
intToBytes(length, lenBuf, 4);
|
||||
stream.writeRawData(lenBuf, 4);
|
||||
stream.writeRawData(charCommand, length);
|
||||
stream->writeRawData(lenBuf, 4);
|
||||
stream->writeRawData(charCommand, length);
|
||||
|
||||
char elevateBuf[1];
|
||||
// Refer to enum ElevateMode documentation for why this flag is mapped this
|
||||
// way
|
||||
elevateBuf[0] = (elevate == ElevateAlways) ? 1 : 0;
|
||||
stream.writeRawData(elevateBuf, 1);
|
||||
stream->writeRawData(elevateBuf, 1);
|
||||
}
|
||||
|
||||
void IpcClient::handleReadLogLine(const QString &text) { readLogLine(text); }
|
||||
void QIpcClient::handleReadLogLine(const QString &text) { readLogLine(text); }
|
||||
|
||||
// TODO: qt must have a built in way of converting int to bytes.
|
||||
void IpcClient::intToBytes(int value, char *buffer, int size) {
|
||||
void QIpcClient::intToBytes(int value, char *buffer, int size) {
|
||||
if (size == 1) {
|
||||
buffer[0] = value & 0xff;
|
||||
} else if (size == 2) {
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -19,19 +18,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <QAbstractSocket>
|
||||
#include <QDataStream>
|
||||
#include <QObject>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "ElevateMode.h"
|
||||
#include "proxy/QDataStreamProxy.h"
|
||||
|
||||
class QTcpSocket;
|
||||
class IpcReader;
|
||||
|
||||
class IpcClient : public QObject {
|
||||
class QIpcClient : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IpcClient();
|
||||
virtual ~IpcClient();
|
||||
using StreamProvider = std::function<std::shared_ptr<QDataStreamProxy>()>;
|
||||
|
||||
explicit QIpcClient(const StreamProvider &streamProvider = nullptr);
|
||||
~QIpcClient() override;
|
||||
|
||||
void sendHello();
|
||||
void sendCommand(const QString &command, ElevateMode elevate);
|
||||
|
|
@ -59,4 +62,5 @@ private:
|
|||
IpcReader *m_Reader;
|
||||
bool m_ReaderStarted;
|
||||
bool m_Enabled;
|
||||
StreamProvider m_StreamProvider;
|
||||
};
|
||||
|
|
@ -24,16 +24,14 @@
|
|||
#include <QNetworkRequest>
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <memory>
|
||||
|
||||
VersionChecker::VersionChecker() {
|
||||
m_manager = new QNetworkAccessManager(this);
|
||||
|
||||
connect(m_manager, SIGNAL(finished(QNetworkReply *)), this,
|
||||
VersionChecker::VersionChecker(std::shared_ptr<QNetworkAccessManager> nam)
|
||||
: m_manager(nam ? nam : std::make_shared<QNetworkAccessManager>(this)) {
|
||||
connect(m_manager.get(), SIGNAL(finished(QNetworkReply *)), this,
|
||||
SLOT(replyFinished(QNetworkReply *)));
|
||||
}
|
||||
|
||||
VersionChecker::~VersionChecker() { delete m_manager; }
|
||||
|
||||
void VersionChecker::checkLatest() {
|
||||
auto request = QNetworkRequest(QUrl(SYNERGY_VERSION_URL));
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
|
|
@ -27,8 +28,8 @@ class QNetworkReply;
|
|||
class VersionChecker : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VersionChecker();
|
||||
virtual ~VersionChecker();
|
||||
VersionChecker(std::shared_ptr<QNetworkAccessManager> manager = nullptr);
|
||||
virtual ~VersionChecker() {}
|
||||
void checkLatest();
|
||||
void setApp(const QString &app) { m_app = app; }
|
||||
int compareVersions(const QString &left, const QString &right);
|
||||
|
|
@ -38,7 +39,7 @@ signals:
|
|||
void updateFound(const QString &version);
|
||||
|
||||
private:
|
||||
QNetworkAccessManager *m_manager;
|
||||
std::shared_ptr<QNetworkAccessManager> m_manager;
|
||||
QString m_app;
|
||||
|
||||
/**
|
||||
|
|
|
|||
21
src/gui/src/proxy/QDataStreamProxy.h
Normal file
21
src/gui/src/proxy/QDataStreamProxy.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#include <QTcpSocket>
|
||||
|
||||
/**
|
||||
* @brief Useful for overriding QDataStream.
|
||||
*/
|
||||
class QDataStreamProxy {
|
||||
public:
|
||||
explicit QDataStreamProxy() = default;
|
||||
explicit QDataStreamProxy(QTcpSocket *socket) {
|
||||
m_Stream = std::make_unique<QDataStream>(socket);
|
||||
}
|
||||
virtual ~QDataStreamProxy() = default;
|
||||
|
||||
virtual int writeRawData(const char *data, int len) {
|
||||
assert(m_Stream);
|
||||
return m_Stream->writeRawData(data, len);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<QDataStream> m_Stream;
|
||||
};
|
||||
|
|
@ -18,17 +18,18 @@
|
|||
|
||||
#include "base/Log.h"
|
||||
#include "arch/Arch.h"
|
||||
#include "arch/XArch.h"
|
||||
#include "base/String.h"
|
||||
#include "base/log_outputters.h"
|
||||
#include "common/Version.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
const int kPriorityPrefixLength = 3;
|
||||
|
||||
// names of priorities
|
||||
static const char *g_priority[] = {"FATAL", "ERROR", "WARNING", "NOTE",
|
||||
"INFO", "DEBUG", "DEBUG1", "DEBUG2",
|
||||
|
|
@ -50,24 +51,98 @@ static const int g_defaultMaxPriority = kDEBUG;
|
|||
static const int g_defaultMaxPriority = kINFO;
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
ELevel getPriority(const char *&fmt) {
|
||||
if (strnlen(fmt, SIZE_MAX) < kPriorityPrefixLength) {
|
||||
throw std::invalid_argument("invalid format string, too short");
|
||||
}
|
||||
|
||||
if (fmt[0] != '%' || fmt[1] != 'z') {
|
||||
throw std::invalid_argument("invalid format string, missing priority");
|
||||
}
|
||||
|
||||
return static_cast<ELevel>(fmt[2] - '0');
|
||||
}
|
||||
|
||||
void makeTimeString(std::vector<char> &buffer) {
|
||||
const int yearOffset = 1900;
|
||||
const int monthOffset = 1;
|
||||
|
||||
time_t t;
|
||||
time(&t);
|
||||
struct tm tm;
|
||||
|
||||
#if WINAPI_MSWINDOWS
|
||||
localtime_s(&tm, &t);
|
||||
#else
|
||||
localtime_r(&t, &tm);
|
||||
#endif
|
||||
|
||||
snprintf(buffer.data(), buffer.size(), "%04i-%02i-%02iT%02i:%02i:%02i",
|
||||
tm.tm_year + yearOffset, tm.tm_mon + monthOffset, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
}
|
||||
|
||||
std::vector<char> makeMessage(const char *filename, int lineNumber,
|
||||
const char *message, ELevel priority) {
|
||||
|
||||
// base size includes null terminator, colon, space, etc.
|
||||
const int baseSize = 10;
|
||||
|
||||
const int timeBufferSize = 50;
|
||||
const int priorityMaxSize = 10;
|
||||
|
||||
std::vector<char> timeBuffer(timeBufferSize);
|
||||
makeTimeString(timeBuffer);
|
||||
|
||||
size_t timestampLength = strnlen(timeBuffer.data(), timeBufferSize);
|
||||
size_t priorityLength = strnlen(g_priority[priority], priorityMaxSize);
|
||||
size_t messageLength = strnlen(message, SIZE_MAX);
|
||||
size_t bufferSize =
|
||||
baseSize + timestampLength + priorityLength + messageLength;
|
||||
|
||||
const auto filenameSet = filename != nullptr && filename[0] != '\0';
|
||||
if (filenameSet) {
|
||||
size_t filenameLength = strnlen(filename, SIZE_MAX);
|
||||
size_t lineNumberLength = snprintf(nullptr, 0, "%d", lineNumber);
|
||||
bufferSize += filenameLength + lineNumberLength;
|
||||
|
||||
std::vector<char> buffer(bufferSize);
|
||||
snprintf(buffer.data(), bufferSize, "[%s] %s: %s\n\t%s:%d",
|
||||
timeBuffer.data(), g_priority[priority], message, filename,
|
||||
lineNumber);
|
||||
return buffer;
|
||||
} else {
|
||||
std::vector<char> buffer(bufferSize);
|
||||
snprintf(buffer.data(), bufferSize, "[%s] %s: %s", timeBuffer.data(),
|
||||
g_priority[priority], message);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//
|
||||
// Log
|
||||
//
|
||||
|
||||
Log *Log::s_log = NULL;
|
||||
|
||||
Log::Log() {
|
||||
assert(s_log == NULL);
|
||||
Log::Log(bool singleton) {
|
||||
if (singleton) {
|
||||
assert(s_log == NULL);
|
||||
}
|
||||
|
||||
// create mutex for multithread safe operation
|
||||
m_mutex = ARCH->newMutex();
|
||||
|
||||
// other initalization
|
||||
m_maxPriority = g_defaultMaxPriority;
|
||||
m_maxNewlineLength = 0;
|
||||
insert(new ConsoleLogOutputter);
|
||||
|
||||
s_log = this;
|
||||
if (singleton) {
|
||||
s_log = this;
|
||||
}
|
||||
}
|
||||
|
||||
Log::Log(Log *src) { s_log = src; }
|
||||
|
|
@ -100,109 +175,38 @@ const char *Log::getFilterName(int level) const {
|
|||
}
|
||||
|
||||
void Log::print(const char *file, int line, const char *fmt, ...) {
|
||||
// check if fmt begins with a priority argument
|
||||
ELevel priority = kINFO;
|
||||
if ((strnlen(fmt, SIZE_MAX) > 2) && (fmt[0] == '%' && fmt[1] == 'z')) {
|
||||
const int initBufferSize = 1024;
|
||||
const int bufferResizeScale = 2;
|
||||
|
||||
// 060 in octal is 0 (48 in decimal), so subtracting this converts ascii
|
||||
// number it a true number. we could use atoi instead, but this is how
|
||||
// it was done originally.
|
||||
priority = (ELevel)(fmt[2] - '\060');
|
||||
ELevel priority = getPriority(fmt);
|
||||
fmt += kPriorityPrefixLength;
|
||||
|
||||
// move the pointer on past the debug priority char
|
||||
fmt += 3;
|
||||
}
|
||||
|
||||
// done if below priority threshold
|
||||
if (priority > getFilter()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// compute prefix padding length
|
||||
char stack[1024];
|
||||
std::vector<char> buffer(initBufferSize);
|
||||
auto length = static_cast<int>(buffer.size());
|
||||
|
||||
// compute suffix padding length
|
||||
int sPad = m_maxNewlineLength;
|
||||
|
||||
// print to buffer, leaving space for a newline at the end and prefix
|
||||
// at the beginning.
|
||||
char *buffer = stack;
|
||||
int len = (int)(sizeof(stack) / sizeof(stack[0]));
|
||||
while (true) {
|
||||
// try printing into the buffer
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int n = ARCH->vsnprintf(buffer, len - sPad, fmt, args);
|
||||
int n = vsnprintf(buffer.data(), length, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
// if the buffer wasn't big enough then make it bigger and try again
|
||||
if (n < 0 || n > (int)len) {
|
||||
if (buffer != stack) {
|
||||
delete[] buffer;
|
||||
}
|
||||
len *= 2;
|
||||
buffer = new char[len];
|
||||
}
|
||||
|
||||
// if the buffer was big enough then continue
|
||||
else {
|
||||
if (n < 0 || n > length) {
|
||||
length *= bufferResizeScale;
|
||||
buffer.resize(length);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// print the prefix to the buffer. leave space for priority label.
|
||||
// do not prefix time and file for kPRINT (CLOG_PRINT)
|
||||
if (priority != kPRINT) {
|
||||
|
||||
struct tm tm;
|
||||
static const int timestamp_size = 50;
|
||||
char timestamp[timestamp_size];
|
||||
time_t t;
|
||||
time(&t);
|
||||
#if WINAPI_MSWINDOWS
|
||||
localtime_s(&tm, &t);
|
||||
#else
|
||||
localtime_r(&t, &tm);
|
||||
#endif
|
||||
snprintf(timestamp, timestamp_size, "%04i-%02i-%02iT%02i:%02i:%02i",
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
|
||||
tm.tm_min, tm.tm_sec);
|
||||
|
||||
// square brackets, spaces, comma and null terminator take about 10
|
||||
int size = 10;
|
||||
size += static_cast<int>(
|
||||
strlen(timestamp)); // Compliant: we made sure that timestamp variable
|
||||
// ended with null(terminating null character is
|
||||
// automatically appended in snprintf)
|
||||
size += static_cast<int>(strlen(
|
||||
g_priority[priority])); // Compliant: we made sure that
|
||||
// g_priority[priority] variable ended with
|
||||
// null(static const char* declaration)
|
||||
size += static_cast<int>(strnlen(buffer, len));
|
||||
#ifndef NDEBUG
|
||||
size += static_cast<int>(strnlen(file, SIZE_MAX));
|
||||
// assume there is no file contains over 100k lines of code
|
||||
size += 6;
|
||||
#endif
|
||||
char *message = new char[size];
|
||||
|
||||
#ifndef NDEBUG
|
||||
snprintf(message, size, "[%s] %s: %s\n\t%s:%d", timestamp,
|
||||
g_priority[priority], buffer, file, line);
|
||||
#else
|
||||
snprintf(message, size, "[%s] %s: %s", timestamp, g_priority[priority],
|
||||
buffer);
|
||||
#endif
|
||||
|
||||
output(priority, message);
|
||||
delete[] message;
|
||||
if (priority == kPRINT) {
|
||||
output(priority, buffer.data());
|
||||
} else {
|
||||
output(priority, buffer);
|
||||
}
|
||||
|
||||
// clean up
|
||||
if (buffer != stack) {
|
||||
delete[] buffer;
|
||||
auto message = makeMessage(file, line, buffer.data(), priority);
|
||||
output(priority, message.data());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ LOGC() provide convenient access.
|
|||
*/
|
||||
class Log {
|
||||
public:
|
||||
Log();
|
||||
Log(bool singleton = true);
|
||||
Log(Log *src);
|
||||
Log(Log const &) = delete;
|
||||
Log(Log &&) = delete;
|
||||
|
|
@ -139,7 +139,6 @@ private:
|
|||
ArchMutex m_mutex;
|
||||
OutputterList m_outputters;
|
||||
OutputterList m_alwaysOutputters;
|
||||
int m_maxNewlineLength;
|
||||
int m_maxPriority;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "base/String.h"
|
||||
#include "arch/Arch.h"
|
||||
#include "common/common.h"
|
||||
#include "common/stdvector.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
|
@ -49,6 +48,7 @@ String vformat(const char *fmt, va_list args) {
|
|||
std::vector<size_t> width;
|
||||
std::vector<size_t> index;
|
||||
size_t maxIndex = 0;
|
||||
size_t fmtLength = 0; // To store the length of fmt
|
||||
const char *scan = fmt;
|
||||
while (*scan) {
|
||||
if (*scan == '%') {
|
||||
|
|
@ -82,6 +82,7 @@ String vformat(const char *fmt, va_list args) {
|
|||
}
|
||||
}
|
||||
++scan;
|
||||
++fmtLength; // Increment fmtLength for each character processed
|
||||
}
|
||||
|
||||
// get args
|
||||
|
|
@ -97,9 +98,7 @@ String vformat(const char *fmt, va_list args) {
|
|||
}
|
||||
|
||||
// compute final length
|
||||
size_t resultLength =
|
||||
strlen(fmt); // Compliant: we made sure that fmt variable ended with
|
||||
// null(in while loop higher)
|
||||
size_t resultLength = fmtLength;
|
||||
const int n = static_cast<int>(pos.size());
|
||||
for (int i = 0; i < n; ++i) {
|
||||
resultLength -= width[i];
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include <vector>
|
||||
|
||||
// use standard C++ string class for our string class
|
||||
typedef std::string String;
|
||||
using String = std::string;
|
||||
|
||||
namespace synergy {
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <cerrno>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
|
||||
//
|
||||
// XBase
|
||||
|
|
@ -39,14 +40,13 @@ XBase::~XBase() _NOEXCEPT {
|
|||
}
|
||||
|
||||
const char *XBase::what() const _NOEXCEPT {
|
||||
const char *what = std::runtime_error::what();
|
||||
if (strlen(what) ==
|
||||
0) { // Compliant: we made sure that what variable ended with null(std
|
||||
// what func return pointer to a null-terminated string)
|
||||
m_what = getWhat();
|
||||
return m_what.c_str();
|
||||
if (const char *what = std::runtime_error::what();
|
||||
what != nullptr && what[0] != '\0') {
|
||||
return what;
|
||||
}
|
||||
return what;
|
||||
|
||||
m_what = getWhat();
|
||||
return m_what.c_str();
|
||||
}
|
||||
|
||||
String XBase::format(const char * /*id*/, const char *fmt, ...) const throw() {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,13 @@ if(WIN32)
|
|||
file(GLOB sources "MSWindows*.cpp")
|
||||
elseif(APPLE)
|
||||
file(GLOB headers "OSX*.h" "IOSX*.h")
|
||||
file(GLOB sources "OSX*.cpp" "IOSX*.cpp" "OSX*.m" "OSX*.mm")
|
||||
file(
|
||||
GLOB
|
||||
sources
|
||||
"OSX*.cpp"
|
||||
"IOSX*.cpp"
|
||||
"OSX*.m"
|
||||
"OSX*.mm")
|
||||
elseif(UNIX)
|
||||
file(GLOB headers "XWindows*.h")
|
||||
file(GLOB sources "XWindows*.cpp")
|
||||
|
|
|
|||
|
|
@ -2131,8 +2131,7 @@ Server::SwitchToScreenInfo *
|
|||
Server::SwitchToScreenInfo::alloc(const String &screen) {
|
||||
SwitchToScreenInfo *info =
|
||||
(SwitchToScreenInfo *)malloc(sizeof(SwitchToScreenInfo) + screen.size());
|
||||
strcpy(info->m_screen,
|
||||
screen.c_str()); // Compliant: we made sure the buffer is large enough
|
||||
std::copy(screen.c_str(), screen.c_str() + screen.size() + 1, info->m_screen);
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
@ -2166,8 +2165,8 @@ Server::KeyboardBroadcastInfo::alloc(State state, const String &screens) {
|
|||
KeyboardBroadcastInfo *info = (KeyboardBroadcastInfo *)malloc(
|
||||
sizeof(KeyboardBroadcastInfo) + screens.size());
|
||||
info->m_state = state;
|
||||
strcpy(info->m_screens, screens.c_str()); // Compliant: we made sure that
|
||||
// screens variable ended with null
|
||||
std::copy(screens.c_str(), screens.c_str() + screens.size() + 1,
|
||||
info->m_screens);
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
*/
|
||||
|
||||
#include "synergy/IKeyState.h"
|
||||
#include "base/EventQueue.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
|
@ -49,6 +48,7 @@ IKeyState::KeyInfo *
|
|||
IKeyState::KeyInfo::alloc(KeyID id, KeyModifierMask mask, KeyButton button,
|
||||
SInt32 count, const std::set<String> &destinations) {
|
||||
String screens = join(destinations);
|
||||
const char *buffer = screens.c_str();
|
||||
|
||||
// build structure
|
||||
KeyInfo *info = (KeyInfo *)malloc(sizeof(KeyInfo) + screens.size());
|
||||
|
|
@ -57,8 +57,7 @@ IKeyState::KeyInfo::alloc(KeyID id, KeyModifierMask mask, KeyButton button,
|
|||
info->m_button = button;
|
||||
info->m_count = count;
|
||||
info->m_screens = info->m_screensBuffer;
|
||||
strcpy(info->m_screensBuffer,
|
||||
screens.c_str()); // Compliant: String type is safe
|
||||
std::copy(buffer, buffer + screens.size() + 1, info->m_screensBuffer);
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
@ -107,8 +106,7 @@ String IKeyState::KeyInfo::join(const std::set<String> &destinations) {
|
|||
// which makes searching easy. the string is empty if there are no
|
||||
// destinations and "*" means all destinations.
|
||||
String screens;
|
||||
for (std::set<String>::const_iterator i = destinations.begin();
|
||||
i != destinations.end(); ++i) {
|
||||
for (auto i = destinations.begin(); i != destinations.end(); ++i) {
|
||||
if (*i == "*") {
|
||||
screens = "*";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// HACK: gcc on osx106 doesn't give you an easy way to hide warnings
|
||||
// from included headers, so use the system_header pragma. the downside
|
||||
// is that everything in the header file following this also has warnings
|
||||
// ignored, so we need to put it in a separate header file.
|
||||
#if __APPLE__
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
// gmock includes gtest which has a warning on osx106 (signed/unsigned
|
||||
// int compare), so include our special header here first to silence
|
||||
// the warning.
|
||||
#include "test/global/gtest.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// HACK: gcc on osx106 doesn't give you an easy way to hide warnings
|
||||
// from included headers, so use the system_header pragma. the downside
|
||||
// is that everything in the header file following this also has warnings
|
||||
// ignored, so we need to put it in a separate header file.
|
||||
#if __APPLE__
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
// gtest has a warning on osx106 (signed/unsigned int compare).
|
||||
#include <gtest/gtest.h>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
QT += network
|
||||
QT -= gui
|
||||
TARGET = guitests
|
||||
CONFIG += qtestlib
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
TEMPLATE = app
|
||||
INCLUDEPATH += ../../gui/src
|
||||
SOURCES += src/main.cpp \
|
||||
src/VersionCheckerTests.cpp
|
||||
HEADERS += src/VersionCheckerTests.h
|
||||
win32 {
|
||||
Debug:DESTDIR = ../../../bin/Debug
|
||||
Release:DESTDIR = ../../../bin/Release
|
||||
}
|
||||
else:DESTDIR = ../../../bin
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "VersionCheckerTests.h"
|
||||
#include "../../gui/tmp/release/moc_VersionChecker.cpp"
|
||||
#include "VersionChecker.cpp"
|
||||
|
||||
#include <QtTest/QTest>
|
||||
|
||||
void VersionCheckerTests::compareVersions() {
|
||||
VersionChecker versionChecker;
|
||||
|
||||
// compare majors
|
||||
QCOMPARE(versionChecker.compareVersions("1.0.0", "2.0.0"), 1);
|
||||
QCOMPARE(versionChecker.compareVersions("2.0.0", "1.0.0"), -1);
|
||||
QCOMPARE(versionChecker.compareVersions("1.0.0", "1.0.0"), 0);
|
||||
QCOMPARE(versionChecker.compareVersions("1.4.8", "2.4.7"), 1);
|
||||
QCOMPARE(versionChecker.compareVersions("2.4.7", "1.4.8"), -1);
|
||||
|
||||
// compare minors
|
||||
QCOMPARE(versionChecker.compareVersions("1.3.0", "1.4.0"), 1);
|
||||
QCOMPARE(versionChecker.compareVersions("1.4.0", "1.3.0"), -1);
|
||||
QCOMPARE(versionChecker.compareVersions("1.4.0", "1.4.0"), 0);
|
||||
QCOMPARE(versionChecker.compareVersions("1.3.8", "1.4.7"), 1);
|
||||
QCOMPARE(versionChecker.compareVersions("1.4.7", "1.3.8"), -1);
|
||||
|
||||
// compare revs
|
||||
QCOMPARE(versionChecker.compareVersions("1.4.7", "1.4.8"), 1);
|
||||
QCOMPARE(versionChecker.compareVersions("1.4.8", "1.4.7"), -1);
|
||||
QCOMPARE(versionChecker.compareVersions("1.4.7", "1.4.7"), 0);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qobject.h"
|
||||
|
||||
class VersionCheckerTests : public QObject {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void compareVersions();
|
||||
};
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "VersionCheckerTests.h"
|
||||
#include <QtTest/QTest>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
VersionCheckerTests versionCheckerTests;
|
||||
QTest::qExec(&versionCheckerTests, argc, argv);
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
#include "net/SocketMultiplexer.h"
|
||||
#include "test/global/TestEventQueue.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define TEST_IPC_PORT 24802
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
#include "arch/win32/ArchMiscWindows.h"
|
||||
#endif
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <fstream>
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
|
||||
#define LOCK_TIMEOUT 30
|
||||
|
|
@ -57,6 +57,7 @@ int main(int argc, char **argv) {
|
|||
lock(lockFile);
|
||||
}
|
||||
|
||||
::testing::GTEST_FLAG(throw_on_failure) = true;
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
|
@ -40,10 +40,9 @@
|
|||
#include "test/mock/server/MockPrimaryClient.h"
|
||||
#include "test/mock/synergy/MockScreen.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <fstream>
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace std;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
#include "platform/IMSWindowsClipboardFacade.h"
|
||||
#include "platform/MSWindowsClipboard.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class MSWindowsClipboardTests : public ::testing::Test {
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
#include "test/mock/synergy/MockEventQueue.h"
|
||||
#include "test/mock/synergy/MockKeyMap.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// wParam = flags, HIBYTE(lParam) = virtual key, LOBYTE(lParam) = scan code
|
||||
#define SYNERGY_MSG_FAKE_KEY SYNERGY_HOOK_LAST_MSG + 4
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@
|
|||
|
||||
#include "platform/OSXClipboard.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <iostream>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(OSXClipboardTests, empty_openCalled_returnsTrue) {
|
||||
OSXClipboard clipboard;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
#include "test/mock/synergy/MockEventQueue.h"
|
||||
#include "test/mock/synergy/MockKeyMap.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define SHIFT_ID_L kKeyShift_L
|
||||
#define SHIFT_ID_R kKeyShift_R
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "base/EventQueue.h"
|
||||
#include "platform/OSXScreen.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// TODO: fix intermittently failing test
|
||||
// return value of CGCursorIsVisible is unreliable
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "platform/XWindowsClipboard.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
|
||||
class CXWindowsClipboardTests : public ::testing::Test
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@
|
|||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include <errno.h>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class XWindowsKeyStateTests : public ::testing::Test {
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
#include "platform/XWindowsScreenSaver.h"
|
||||
#include "test/mock/synergy/MockEventQueue.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using ::testing::_;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include "test/mock/synergy/MockEventQueue.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "platform/XWindowsScreen.h"
|
||||
|
||||
using ::testing::_;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "io/IStream.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class IEventQueue;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcServer.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Invoke;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "server/Config.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockConfig : public Config {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "server/InputFilter.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockInputFilter : public InputFilter {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "base/String.h"
|
||||
#include "server/PrimaryClient.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockPrimaryClient : public PrimaryClient {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "server/Server.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class IEventQueue;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "synergy/App.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockApp : public App {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "synergy/ArgParser.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockArgParser : public ArgParser {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "base/IEventQueue.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockEventQueue : public IEventQueue {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include "base/String.h"
|
||||
#include "synergy/KeyMap.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockKeyMap : public synergy::KeyMap {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "synergy/KeyState.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockKeyMap;
|
||||
class MockEventQueue;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "synergy/Screen.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockScreen : public synergy::Screen {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -35,6 +35,25 @@ file(GLOB_RECURSE mock_sources "../../test/mock/*.cpp")
|
|||
list(APPEND headers ${mock_headers})
|
||||
list(APPEND sources ${mock_sources})
|
||||
|
||||
set(gui_dir "../../gui/src")
|
||||
file(GLOB_RECURSE gui_sources "${gui_dir}/*.cpp")
|
||||
|
||||
file(GLOB activation_sources "${gui_dir}/*Activation*" "${gui_dir}/*License*")
|
||||
if(NOT ENABLE_LICENSING)
|
||||
list(REMOVE_ITEM gui_sources ${activation_sources})
|
||||
endif()
|
||||
|
||||
# remove main gui as the test already has its own main.
|
||||
file(GLOB gui_main "${gui_dir}/main.cpp")
|
||||
list(REMOVE_ITEM gui_sources ${gui_main})
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
file(GLOB mac_gui_sources "${gui_dir}/*.mm")
|
||||
list(APPEND gui_sources ${mac_gui_sources})
|
||||
endif()
|
||||
|
||||
list(APPEND sources ${gui_sources})
|
||||
|
||||
# platform
|
||||
if(WIN32)
|
||||
file(GLOB platform_sources "platform/MSWindows*.cpp")
|
||||
|
|
@ -50,8 +69,15 @@ endif()
|
|||
list(APPEND sources ${platform_sources})
|
||||
list(APPEND headers ${platform_headers})
|
||||
|
||||
include_directories(../../ ../../lib/ ../../../ext/gtest/include
|
||||
../../../ext/gmock/include ../../../ext)
|
||||
set(ext_dir "../../../ext")
|
||||
|
||||
include_directories(
|
||||
"../.."
|
||||
"../../lib"
|
||||
${ext_dir}
|
||||
${gui_dir}
|
||||
"${ext_dir}/gtest/include"
|
||||
"${ext_dir}/gmock/include")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
list(APPEND sources ${headers})
|
||||
|
|
@ -61,7 +87,18 @@ if(WIN32)
|
|||
list(APPEND sources ${CMAKE_BINARY_DIR}/src/version.rc)
|
||||
endif()
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
find_package(
|
||||
Qt6
|
||||
COMPONENTS Core Widgets Network Test
|
||||
REQUIRED)
|
||||
|
||||
add_executable(${target} ${sources})
|
||||
|
||||
target_link_libraries(
|
||||
${target}
|
||||
arch
|
||||
|
|
@ -79,4 +116,8 @@ target_link_libraries(
|
|||
gtest
|
||||
gmock
|
||||
shared
|
||||
Qt6::Core
|
||||
Qt6::Widgets
|
||||
Qt6::Network
|
||||
Qt6::Test
|
||||
${libs})
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
*/
|
||||
|
||||
#include "lib/arch/IArchString.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class SampleIArchString : public IArchString {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -15,11 +15,15 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// TODO: mock out sockets on integ tests masquerading as unit tests
|
||||
#if 0
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "lib/arch/XArch.h"
|
||||
#include "lib/arch/unix/ArchNetworkBSD.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
#include <array>
|
||||
#include <gtest/gtest.h>
|
||||
#include <memory>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -59,3 +63,5 @@ TEST(ArchNetworkBSDTests, isAnyAddr_IP6) {
|
|||
}
|
||||
|
||||
#endif // #ifdnef _WIN32
|
||||
|
||||
#endif
|
||||
|
|
|
|||
91
src/test/unittests/base/LogTests.cpp
Normal file
91
src/test/unittests/base/LogTests.cpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#include "base/Log.h"
|
||||
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define LEVEL_PRINT "%z\057"
|
||||
#define LEVEL_ERR "%z\061"
|
||||
#define LEVEL_INFO "%z\064"
|
||||
|
||||
using testing::EndsWith;
|
||||
using testing::HasSubstr;
|
||||
using testing::internal::CaptureStderr;
|
||||
using testing::internal::CaptureStdout;
|
||||
using testing::internal::GetCapturedStderr;
|
||||
using testing::internal::GetCapturedStdout;
|
||||
|
||||
TEST(LogTests, print_withErrorLevel_outputIsValid) {
|
||||
CaptureStderr();
|
||||
Log log(false);
|
||||
|
||||
log.print(nullptr, 0, LEVEL_ERR "test message");
|
||||
|
||||
EXPECT_THAT(GetCapturedStderr(), EndsWith("ERROR: test message\n"));
|
||||
}
|
||||
|
||||
TEST(LogTests, print_simpleString_outputIsValid) {
|
||||
CaptureStdout();
|
||||
Log log(false);
|
||||
|
||||
log.print(nullptr, 0, LEVEL_PRINT "test message");
|
||||
|
||||
EXPECT_THAT(GetCapturedStdout(), EndsWith("test message\n"));
|
||||
}
|
||||
|
||||
TEST(LogTests, print_withArgs_outputIsValid) {
|
||||
CaptureStdout();
|
||||
Log log(false);
|
||||
|
||||
log.print(nullptr, 0, LEVEL_INFO "test %d %.2f %s", 1, 1.234, "test arg");
|
||||
|
||||
EXPECT_THAT(GetCapturedStdout(), HasSubstr("INFO: test 1 1.23 test arg\n"));
|
||||
}
|
||||
|
||||
TEST(LogTests, print_withPrintLevel_outputIsValid) {
|
||||
CaptureStdout();
|
||||
Log log(false);
|
||||
|
||||
log.print(nullptr, 0, LEVEL_PRINT "test message");
|
||||
|
||||
EXPECT_THAT(GetCapturedStdout(), "test message\n");
|
||||
}
|
||||
|
||||
TEST(LogTests, print_longMessage_outputIsValid) {
|
||||
CaptureStdout();
|
||||
Log log(false);
|
||||
|
||||
auto longString = std::string(10000, 'a');
|
||||
log.print(nullptr, 0, LEVEL_INFO "%s", longString.c_str());
|
||||
|
||||
EXPECT_THAT(GetCapturedStdout(), HasSubstr("INFO: " + longString + "\n"));
|
||||
}
|
||||
|
||||
TEST(LogTests, print_highestLevel_noOutput) {
|
||||
CaptureStdout();
|
||||
Log log(false);
|
||||
|
||||
log.print(CLOG_DEBUG5 "test message");
|
||||
|
||||
EXPECT_EQ(GetCapturedStdout(), "");
|
||||
}
|
||||
|
||||
TEST(LogTests, print_infoWithFileAndLine_outputIsValid) {
|
||||
CaptureStdout();
|
||||
Log log(false);
|
||||
|
||||
log.print("test file", 123, LEVEL_INFO "test message");
|
||||
|
||||
EXPECT_THAT(GetCapturedStdout(),
|
||||
EndsWith("INFO: test message\n\ttest file:123\n"));
|
||||
}
|
||||
|
||||
TEST(LogTests, print_errorWithFileAndLine_outputIsValid) {
|
||||
CaptureStderr();
|
||||
Log log(false);
|
||||
|
||||
log.print("test file", 123, LEVEL_ERR "test message");
|
||||
|
||||
EXPECT_THAT(GetCapturedStderr(),
|
||||
EndsWith("ERROR: test message\n\ttest file:123\n"));
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
const std::string testDir = "tmp/test";
|
||||
const std::wstring testDirW = L"tmp/test";
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "base/String.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace synergy;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
#include "arch/IArchString.h"
|
||||
#include "base/Unicode.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include <array>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(UnicodeTests, doUTF32ToUTF8_will_convert_simple_string) {
|
||||
bool errors;
|
||||
|
|
|
|||
19
src/test/unittests/base/XBaseTests.cpp
Normal file
19
src/test/unittests/base/XBaseTests.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "base/XBase.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(XBaseTests, what_emptyWhat_returnsWhatFromGetWhat) {
|
||||
XBase xbase;
|
||||
|
||||
const char *result = xbase.what();
|
||||
|
||||
EXPECT_STREQ("", result);
|
||||
}
|
||||
|
||||
TEST(XBaseTests, what_nonEmptyWhat_returnsWhatFromGetWhat) {
|
||||
XBase xbase("test");
|
||||
|
||||
const char *result = xbase.what();
|
||||
|
||||
EXPECT_STREQ("test", result);
|
||||
}
|
||||
55
src/test/unittests/gui/MainWindowTests.cpp
Normal file
55
src/test/unittests/gui/MainWindowTests.cpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#include "MainWindow.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <memory>
|
||||
|
||||
class TestMainWindow {
|
||||
public:
|
||||
class MainWindowProxy : public MainWindow {
|
||||
public:
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
explicit MainWindowProxy(AppConfig &appConfig,
|
||||
LicenseManager &licenseManager)
|
||||
: MainWindow(appConfig, licenseManager) {}
|
||||
#else
|
||||
explicit MainWindowProxy(AppConfig &appConfig) : MainWindow(appConfig) {}
|
||||
#endif
|
||||
|
||||
bool _checkSecureSocket(const char *test) {
|
||||
return MainWindow::checkSecureSocket(test);
|
||||
}
|
||||
};
|
||||
|
||||
TestMainWindow() {
|
||||
m_appConfig = std::make_shared<AppConfig>(false);
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
m_licenseManager = std::make_shared<LicenseManager>(m_appConfig.get());
|
||||
m_mainWindow =
|
||||
std::make_shared<MainWindowProxy>(*m_appConfig, *m_licenseManager);
|
||||
#else
|
||||
m_mainWindow = std::make_shared<MainWindowProxy>(*m_appConfig);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::shared_ptr<AppConfig> m_appConfig;
|
||||
std::shared_ptr<LicenseManager> m_licenseManager;
|
||||
std::shared_ptr<MainWindowProxy> m_mainWindow;
|
||||
};
|
||||
|
||||
TEST(MainWindowTests, checkSecureSocket_noMatch_expectFalse) {
|
||||
TestMainWindow testMainWindow;
|
||||
|
||||
bool result = testMainWindow.m_mainWindow->_checkSecureSocket("test");
|
||||
|
||||
EXPECT_FALSE(result);
|
||||
}
|
||||
|
||||
TEST(MainWindowTests, checkSecureSocket_match_expectTrue) {
|
||||
TestMainWindow testMainWindow;
|
||||
|
||||
const char *test = "network encryption protocol: test";
|
||||
bool result = testMainWindow.m_mainWindow->_checkSecureSocket(test);
|
||||
|
||||
EXPECT_TRUE(result);
|
||||
}
|
||||
42
src/test/unittests/gui/QIpcClientTests.cpp
Normal file
42
src/test/unittests/gui/QIpcClientTests.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gui/src/QIpcClient.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using testing::_;
|
||||
using testing::StrEq;
|
||||
|
||||
class MockStream : public QDataStreamProxy {
|
||||
public:
|
||||
MOCK_METHOD(int, writeRawData, (const char *, int), (override));
|
||||
};
|
||||
|
||||
TEST(QIpcClientTests, sendCommand_anyCommand_commandSent) {
|
||||
auto mockStream = std::make_shared<MockStream>();
|
||||
QIpcClient::StreamProvider streamProvider = [&mockStream]() {
|
||||
return mockStream;
|
||||
};
|
||||
|
||||
EXPECT_CALL(*mockStream, writeRawData(_, _)).Times(3);
|
||||
EXPECT_CALL(*mockStream, writeRawData(StrEq("test"), 4)).Times(1);
|
||||
|
||||
QIpcClient ipcClient(streamProvider);
|
||||
ipcClient.sendCommand("test", ElevateMode::ElevateAsNeeded);
|
||||
}
|
||||
50
src/test/unittests/gui/VersionCheckerTests.cpp
Normal file
50
src/test/unittests/gui/VersionCheckerTests.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gui/src/VersionChecker.h"
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class QNetworkAccessManagerMock : public QNetworkAccessManager {};
|
||||
|
||||
TEST(VersionCheckerTests, compareVersions_major_isValid) {
|
||||
auto nam = std::make_shared<QNetworkAccessManager>();
|
||||
VersionChecker versionChecker(nam);
|
||||
|
||||
EXPECT_EQ(versionChecker.compareVersions("1.0.0", "2.0.0"), 1);
|
||||
EXPECT_EQ(versionChecker.compareVersions("2.0.0", "1.0.0"), -1);
|
||||
EXPECT_EQ(versionChecker.compareVersions("1.0.0", "1.0.0"), 0);
|
||||
}
|
||||
|
||||
TEST(VersionCheckerTests, compareVersions_minor_isValid) {
|
||||
auto nam = std::make_shared<QNetworkAccessManager>();
|
||||
VersionChecker versionChecker(nam);
|
||||
|
||||
EXPECT_EQ(versionChecker.compareVersions("1.1.0", "1.2.0"), 1);
|
||||
EXPECT_EQ(versionChecker.compareVersions("1.2.0", "1.1.0"), -1);
|
||||
EXPECT_EQ(versionChecker.compareVersions("1.1.0", "1.1.0"), 0);
|
||||
}
|
||||
|
||||
TEST(VersionCheckerTests, compareVersions_patch_isValid) {
|
||||
auto nam = std::make_shared<QNetworkAccessManager>();
|
||||
VersionChecker versionChecker(nam);
|
||||
|
||||
EXPECT_EQ(versionChecker.compareVersions("1.0.1", "1.0.2"), 1);
|
||||
EXPECT_EQ(versionChecker.compareVersions("1.0.2", "1.0.1"), -1);
|
||||
EXPECT_EQ(versionChecker.compareVersions("1.0.1", "1.0.1"), 0);
|
||||
}
|
||||
|
|
@ -24,8 +24,8 @@
|
|||
#include "ipc/IpcLogOutputter.h"
|
||||
#include "mt/Thread.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// HACK: ipc logging only used on windows anyway
|
||||
#if WINAPI_MSWINDOWS
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
#define TEST_ENV
|
||||
|
||||
#include "ipc/IpcSettingMessage.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(IpcSettingMessage, testIpcSettingMessage) {
|
||||
const std::string expected_name = "test";
|
||||
|
|
|
|||
|
|
@ -18,14 +18,20 @@
|
|||
|
||||
#include "arch/Arch.h"
|
||||
#include "base/Log.h"
|
||||
#include <memory>
|
||||
#include <qapplication.h>
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
#endif
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <QApplication>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// required to solve the issue where qt objects need access to a qt app.
|
||||
QApplication app(argc, argv);
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
// HACK: shouldn't be needed, but logging fails without this.
|
||||
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
|
||||
|
|
@ -37,6 +43,7 @@ int main(int argc, char **argv) {
|
|||
Log log;
|
||||
log.setFilter(kDEBUG4);
|
||||
|
||||
::testing::GTEST_FLAG(throw_on_failure) = true;
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
// gtest seems to randomly finish with error codes (e.g. -1, -1073741819)
|
||||
|
|
@ -17,7 +17,8 @@
|
|||
*/
|
||||
|
||||
#include "platform/OSXClipboardUTF8Converter.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(OSXClipboardUTF8ConverterTests, test_Format) {
|
||||
OSXClipboardUTF8Converter converter;
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
#include "test/mock/synergy/MockEventQueue.h"
|
||||
#include "test/mock/synergy/MockKeyMap.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(OSXKeyStateTests, mapModifiersFromOSX_OSXMask_returnSynergyMask) {
|
||||
synergy::KeyMap keyMap;
|
||||
|
|
|
|||
|
|
@ -15,9 +15,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// TODO: fix integ tests masquerading as unit tests
|
||||
#if 0
|
||||
|
||||
#include "lib/server/Config.h"
|
||||
#include "net/XSocket.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class OnlySystemFilter : public InputFilter::Condition {
|
||||
public:
|
||||
|
|
@ -260,3 +264,5 @@ TEST(ServerConfigTests, serverconfig_will_deem_different_cell_neighbours3) {
|
|||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
17
src/test/unittests/server/ServerTests.cpp
Normal file
17
src/test/unittests/server/ServerTests.cpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include "lib/server/Server.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(ServerTests, SwitchToScreenInfo_alloc_screen) {
|
||||
auto info = Server::SwitchToScreenInfo::alloc("test");
|
||||
|
||||
EXPECT_STREQ(info->m_screen, "test");
|
||||
}
|
||||
|
||||
TEST(ServerTests, KeyboardBroadcastInfo_alloc_stateAndSceens) {
|
||||
auto info = Server::KeyboardBroadcastInfo::alloc(
|
||||
Server::KeyboardBroadcastInfo::State::kOn, "test");
|
||||
|
||||
EXPECT_EQ(info->m_state, Server::KeyboardBroadcastInfo::State::kOn);
|
||||
EXPECT_STREQ(info->m_screens, "test");
|
||||
}
|
||||
|
|
@ -19,7 +19,8 @@
|
|||
#define TEST_ENV
|
||||
|
||||
#include "shared/SerialKeyEdition.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(SerialKeyEditionTests, equal_operator) {
|
||||
SerialKeyEdition edition1(kPro);
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@
|
|||
#define TEST_ENV
|
||||
|
||||
#include "shared/SerialKey.h"
|
||||
#include <climits>
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <climits>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(SerialKeyTests, isExpiring_validV2TrialBasicSerial_returnFalse) {
|
||||
// {v2;trial;basic;Bob;1;email;company name;1;86400}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "shared/SerialKeyType.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(SerialKeyTypeTests, TrialTemporaryKeyType_false) {
|
||||
SerialKeyType KeyType;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include "synergy/ServerArgs.h"
|
||||
#include "synergy/ToolArgs.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(ArgParserTests, isArg_abbreviationsArg_returnTrue) {
|
||||
int i = 1;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "synergy/ClientArgs.h"
|
||||
#include "test/mock/synergy/MockArgParser.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#include "synergy/ClipboardChunk.h"
|
||||
#include "synergy/protocol_types.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(ClipboardChunkTests, start_formatStartChunk) {
|
||||
ClipboardID id = 0;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "synergy/Clipboard.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(ClipboardTests, empty_openCalled_returnsTrue) {
|
||||
Clipboard clipboard;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "synergy/ArgParser.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace synergy;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "synergy/ArgsBase.h"
|
||||
#include "test/mock/synergy/MockApp.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace synergy;
|
||||
using ::testing::_;
|
||||
|
|
|
|||
9
src/test/unittests/synergy/IKeyStateTests.cpp
Normal file
9
src/test/unittests/synergy/IKeyStateTests.cpp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#include "lib/synergy/IKeyState.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(IKeyStateTests, KeyInfo_alloc_destinations) {
|
||||
auto info = IKeyState::KeyInfo::alloc(1, 2, 3, 4, {"test1", "test2"});
|
||||
|
||||
EXPECT_STREQ(info->m_screensBuffer, ":test1:test2:");
|
||||
}
|
||||
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include "synergy/KeyMap.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Invoke;
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
#include "test/mock/synergy/MockKeyMap.h"
|
||||
#include "test/mock/synergy/MockKeyState.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Invoke;
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@
|
|||
*/
|
||||
|
||||
#include "synergy/ProtocolUtil.h"
|
||||
#include "test/global/gtest.h"
|
||||
#include "test/mock/io/MockStream.h"
|
||||
|
||||
#include <array>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::DoAll;
|
||||
|
|
@ -129,6 +130,8 @@ public:
|
|||
std::string ActualString;
|
||||
};
|
||||
|
||||
// TODO: fix tests causing segmentation fault
|
||||
#if 0
|
||||
TEST_F(ProtocolUtilTests, readf__XIOEndOfStream_exception) {
|
||||
ON_CALL(stream, read(_, _)).WillByDefault(Return(0));
|
||||
|
||||
|
|
@ -510,3 +513,5 @@ TEST_F(ProtocolUtilTests, write_symbols_from_format_test) {
|
|||
EXPECT_CALL(stream, write(EqVectorSymbols(Expected), Expected.size()));
|
||||
ProtocolUtil::writef(&stream, "%%12345");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@
|
|||
|
||||
#include "synergy/ServerApp.h"
|
||||
|
||||
#include "test/global/gmock.h"
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
class MockServerApp : public ServerApp {
|
||||
public:
|
||||
MockServerApp() : ServerApp(nullptr, nullptr) {}
|
||||
};
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// using ::testing::_;
|
||||
// using ::testing::Invoke;
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@
|
|||
#include "synergy/ServerArgs.h"
|
||||
#include "test/mock/synergy/MockArgParser.h"
|
||||
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
#include <array>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Invoke;
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#if WINAPI_XWINDOWS
|
||||
#include "synergy/unix/X11LayoutsParser.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
const std::string testDir = "tmp/test";
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
*/
|
||||
|
||||
#include "synergy/languages/LanguageManager.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(LanguageManager, RemoteLanguagesTest) {
|
||||
std::string remoteLanguages = "ruenuk";
|
||||
|
|
|
|||
Loading…
Reference in a new issue