[Libreoffice-commits] online.git: Branch 'feature/parallel_cypress' - 86 commits - android/app android/lib common/Log.hpp common/Message.hpp common/MessageQueue.cpp common/Protocol.cpp common/Protocol.hpp common/Seccomp.cpp common/Seccomp.hpp common/Session.cpp common/Session.hpp common/StringVector.cpp common/StringVector.hpp common/Unit.cpp common/Util.cpp common/Util.hpp configure.ac cypress_test/data cypress_test/integration_tests cypress_test/Makefile.am docker/l10n-docker-nightly.sh docker/README fuzzer/ClientSession.cpp fuzzer/data ios/Mobile.xcodeproj kit/ChildSession.cpp kit/ChildSession.hpp kit/ForKit.cpp kit/Kit.cpp loleaflet/admin loleaflet/build loleaflet/css loleaflet/images loleaflet/Makefile.am loleaflet/po loleaflet/src loolkitconfig-mobile.xcu Makefile.am test/data test/helpers.hpp test/Makefile.am test/test.cpp test/TileCacheTests.cpp test/UnitAdmin.cpp test/UnitBadDocLoad.cpp test/UnitClose.cpp test/UnitCursor.cpp test/UnitHTTP.cpp test/UnitInsertDelete.cpp test/UnitLoad.cpp t est/UnitPasswordProtected.cpp test/UnitRenderingOptions.cpp test/UnitRenderShape.cpp test/UnitSession.cpp test/UnitWOPIWatermark.cpp test/WhiteBoxTests.cpp tools/Connect.cpp tools/KitClient.cpp tools/WebSocketDump.cpp wsd/Admin.cpp wsd/AdminModel.hpp wsd/Auth.cpp wsd/ClientSession.cpp wsd/ClientSession.hpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/FileServer.cpp wsd/LOOLWSD.cpp wsd/LOOLWSD.hpp wsd/Storage.cpp wsd/TileCache.cpp wsd/TileDesc.hpp wsd/TraceFile.hpp
Tamás Zolnai (via logerrit)
logerrit at kemper.freedesktop.org
Mon Mar 2 19:15:25 UTC 2020
Rebased ref, commits from common ancestor:
commit 90f46a600699d90d71b2fb708807f90660ba0e33
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon Mar 2 20:03:15 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
remove this
Change-Id: If697f1399ab97d709025181380b279b27c5daea8
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index a0e9476df..13a769f08 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -92,13 +92,6 @@ $(DESKTOP_TEST_FILES_DONE): $(PID_FILE)
@$(foreach done_file,$(DESKTOP_TEST_FILES_DONE),mkdir -p $(dir $(done_file)) && touch $(done_file) &&) true\
)
-check-seq: @JAILS_PATH@ $(NODE_BINS)
- $(call run_JS_error_check)
- $(call start_loolwsd)
- $(call run_desktop_tests)
- $(call run_mobile_tests)
- @$(KILL_COMMAND) || true
-
check-desktop: @JAILS_PATH@ $(NODE_BINS)
$(call run_JS_error_check)
$(call start_loolwsd)
commit 8ae816b96ff9f6f813d89d3a56daed72e0b1ae36
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon Mar 2 17:15:38 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
parallel-cypress: improve console output of parallel test run.
Change-Id: I29440bafdba101c3f4e86de7d587330b972289de
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index 29285e3f3..a0e9476df 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -8,6 +8,7 @@ GET_PORT_BINARY = $(abs_builddir)/node_modules/get-port-cli/cli.js
NPM_INSTALLED = $(abs_builddir)/workdir/npm_installed
PID_FILE=$(abs_builddir)/workdir/loolwsd.pid
+ERROR_LOG=$(abs_builddir)/workdir/error.log
DESKTOP_USER_AGENT = "cypress"
DESKTOP_TEST_FOLDER = $(abs_srcdir)/integration_tests/desktop
@@ -57,18 +58,23 @@ MOBILE_TEST_FILES_DONE= \
DESKTOP_TEST_FILES_DONE= \
$(foreach test_file,$(DEKSTOP_TEST_FILES),$(DESKTOP_TRACK_FOLDER)/$(test_file).done)
-check-local: $(DESKTOP_TEST_FILES_DONE) $(MOBILE_TEST_FILES_DONE)
+check-local: do-check
+ $(if $(wildcard $(ERROR_LOG)),$(error Cypress test failure!))
+
+do-check: $(DESKTOP_TEST_FILES_DONE) $(MOBILE_TEST_FILES_DONE)
@$(KILL_COMMAND) || true
$(if $(HEADLESS_BUILD), at pkill Xvfb,)
+ $(if $(wildcard $(ERROR_LOG)), at cat $(ERROR_LOG))
$(PID_FILE): @JAILS_PATH@ $(NODE_BINS)
+ @rm -f $(ERROR_LOG)
$(call run_JS_error_check)
$(if $(HEADLESS_BUILD),$(call start_Xvfb),)
$(call start_loolwsd)
$(MOBILE_TEST_FILES_DONE): $(PID_FILE)
$(if $(PARALLEL_BUILD),\
- $(call run_mobile_tests,$(subst $(MOBILE_TRACK_FOLDER)/,,$(basename $@))),\
+ $(call run_mobile_tests,$(subst $(MOBILE_TRACK_FOLDER)/,,$(basename $@)),$(basename $@).log),\
$(call run_mobile_tests))
$(if $(PARALLEL_BUILD),\
@mkdir -p $(dir $@) && touch $@\
@@ -78,7 +84,7 @@ $(MOBILE_TEST_FILES_DONE): $(PID_FILE)
$(DESKTOP_TEST_FILES_DONE): $(PID_FILE)
$(if $(PARALLEL_BUILD),\
- $(call run_desktop_tests,$(subst $(DESKTOP_TRACK_FOLDER)/,,$(basename $@))),\
+ $(call run_desktop_tests,$(subst $(DESKTOP_TRACK_FOLDER)/,,$(basename $@)),$(basename $@).log),\
$(call run_desktop_tests))
$(if $(PARALLEL_BUILD),\
@mkdir -p $(dir $@) && touch $@\
@@ -169,8 +175,12 @@ define run_desktop_tests
--headless \
--env DATA_FOLDER=$(DESKTOP_DATA_FOLDER),WORKDIR=$(DESKTOP_WORKDIR),WSD_VERSION_HASH=$(LOOLWSD_VERSION_HASH),SERVER_PORT=$(FREE_PORT) \
$(if $(1), --spec=$(abs_dir)/integration_tests/desktop/$(1)) \
- || ($(KILL_COMMAND) && false))
- $(if $(PARALLEL_BUILD), at echo "`echo $(RUN_COMMAND) && $(RUN_COMMAND)`",$(RUN_COMMAND))
+ $(if $(PARALLEL_BUILD),,|| ($(KILL_COMMAND) && false)))
+ $(if $(PARALLEL_BUILD),\
+ $(call execute_run_parallel,$(RUN_COMMAND),$(2))\
+ ,\
+ $(RUN_COMMAND)\
+ )
endef
define run_mobile_tests
@@ -182,8 +192,21 @@ define run_mobile_tests
--headless \
--env DATA_FOLDER=$(MOBILE_DATA_FOLDER),WORKDIR=$(MOBILE_WORKDIR),WSD_VERSION_HASH=$(LOOLWSD_VERSION_HASH),SERVER_PORT=$(FREE_PORT) \
$(if $(1), --spec=$(abs_dir)/integration_tests/mobile/$(1)) \
- || ($(KILL_COMMAND) && false))
- $(if $(PARALLEL_BUILD), at echo "`echo $(RUN_COMMAND) && $(RUN_COMMAND)`",$(RUN_COMMAND))
+ $(if $(PARALLEL_BUILD),,|| ($(KILL_COMMAND) && false)))
+ $(if $(PARALLEL_BUILD),\
+ $(call execute_run_parallel,$(RUN_COMMAND),$(2))\
+ ,\
+ $(RUN_COMMAND)\
+ )
+endef
+
+define execute_run_parallel
+ @mkdir -p $(dir $(2)) && touch $(2) && \
+ echo "`echo $(1) && $(1)`" > $(2) 2>&1 && \
+ if [ `grep -o "CypressError" $(2)` ];\
+ then cat $(2) >> $(ERROR_LOG);\
+ else cat $(2);\
+ fi;
endef
NODE_BINS = \
commit ffe8d495f8569842780ba28375d60aea0c8af87e
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sat Feb 29 14:19:25 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
simplify this
Change-Id: I49d68b486e83bb0d0afaedb16860474c4d7eebe8
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89757
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index db4d87731..29285e3f3 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -71,11 +71,9 @@ $(MOBILE_TEST_FILES_DONE): $(PID_FILE)
$(call run_mobile_tests,$(subst $(MOBILE_TRACK_FOLDER)/,,$(basename $@))),\
$(call run_mobile_tests))
$(if $(PARALLEL_BUILD),\
- @mkdir -p $(dir $@) &&\
- touch $@\
+ @mkdir -p $(dir $@) && touch $@\
,\
- @$(foreach done_file,$(MOBILE_TEST_FILES_DONE),mkdir -p $(dir $(done_file)) &&)\
- $(foreach done_file,$(MOBILE_TEST_FILES_DONE),touch $(done_file) &&) true\
+ @$(foreach done_file,$(MOBILE_TEST_FILES_DONE),mkdir -p $(dir $(done_file)) && touch $(done_file) &&) true\
)
$(DESKTOP_TEST_FILES_DONE): $(PID_FILE)
@@ -83,11 +81,9 @@ $(DESKTOP_TEST_FILES_DONE): $(PID_FILE)
$(call run_desktop_tests,$(subst $(DESKTOP_TRACK_FOLDER)/,,$(basename $@))),\
$(call run_desktop_tests))
$(if $(PARALLEL_BUILD),\
- @mkdir -p $(dir $@) &&\
- touch $@\
+ @mkdir -p $(dir $@) && touch $@\
,\
- @$(foreach done_file,$(DESKTOP_TEST_FILES_DONE),mkdir -p $(dir $(done_file)) &&)\
- $(foreach done_file,$(DESKTOP_TEST_FILES_DONE),touch $(done_file) &&) true\
+ @$(foreach done_file,$(DESKTOP_TEST_FILES_DONE),mkdir -p $(dir $(done_file)) && touch $(done_file) &&) true\
)
check-seq: @JAILS_PATH@ $(NODE_BINS)
commit ed0217bdfe00ef8b2d91ea9c70f825c66172b9f9
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sat Feb 29 11:16:18 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
fix up test name
Change-Id: I45b65bd96812dddb3d7c48949f82fc5588d88bdb
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89752
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index ae3df12ad..db4d87731 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -68,7 +68,7 @@ $(PID_FILE): @JAILS_PATH@ $(NODE_BINS)
$(MOBILE_TEST_FILES_DONE): $(PID_FILE)
$(if $(PARALLEL_BUILD),\
- $(call run_mobile_tests,$(subst $(MOBILE_TRACK_FOLDER),,$(basename $@))),\
+ $(call run_mobile_tests,$(subst $(MOBILE_TRACK_FOLDER)/,,$(basename $@))),\
$(call run_mobile_tests))
$(if $(PARALLEL_BUILD),\
@mkdir -p $(dir $@) &&\
@@ -80,7 +80,7 @@ $(MOBILE_TEST_FILES_DONE): $(PID_FILE)
$(DESKTOP_TEST_FILES_DONE): $(PID_FILE)
$(if $(PARALLEL_BUILD),\
- $(call run_desktop_tests,$(subst $(DESKTOP_TRACK_FOLDER),,$(basename $@))),\
+ $(call run_desktop_tests,$(subst $(DESKTOP_TRACK_FOLDER)/,,$(basename $@))),\
$(call run_desktop_tests))
$(if $(PARALLEL_BUILD),\
@mkdir -p $(dir $@) &&\
commit 0d83848b1381f15ed534e35ab4f422b5202bc26f
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Feb 28 21:02:09 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
fix sequential build
Change-Id: I09d92458109c279380b1425b323b52c55b8f348b
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89749
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index 6be7830eb..ae3df12ad 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -70,19 +70,25 @@ $(MOBILE_TEST_FILES_DONE): $(PID_FILE)
$(if $(PARALLEL_BUILD),\
$(call run_mobile_tests,$(subst $(MOBILE_TRACK_FOLDER),,$(basename $@))),\
$(call run_mobile_tests))
- @mkdir -p $(dir $@)
$(if $(PARALLEL_BUILD),\
- @touch $@,\
- $(foreach done_file,$(MOBILE_TEST_FILES_DONE),touch $(done_file) &&) true)
+ @mkdir -p $(dir $@) &&\
+ touch $@\
+ ,\
+ @$(foreach done_file,$(MOBILE_TEST_FILES_DONE),mkdir -p $(dir $(done_file)) &&)\
+ $(foreach done_file,$(MOBILE_TEST_FILES_DONE),touch $(done_file) &&) true\
+ )
$(DESKTOP_TEST_FILES_DONE): $(PID_FILE)
$(if $(PARALLEL_BUILD),\
$(call run_desktop_tests,$(subst $(DESKTOP_TRACK_FOLDER),,$(basename $@))),\
$(call run_desktop_tests))
- @mkdir -p $(dir $@)
$(if $(PARALLEL_BUILD),\
- @touch $@,\
- $(foreach done_file,$(DESKTOP_TEST_FILES_DONE),touch $(done_file) &&) true)
+ @mkdir -p $(dir $@) &&\
+ touch $@\
+ ,\
+ @$(foreach done_file,$(DESKTOP_TEST_FILES_DONE),mkdir -p $(dir $(done_file)) &&)\
+ $(foreach done_file,$(DESKTOP_TEST_FILES_DONE),touch $(done_file) &&) true\
+ )
check-seq: @JAILS_PATH@ $(NODE_BINS)
$(call run_JS_error_check)
commit 30661de76de328419e5f893da2274765ba919540
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Feb 28 14:37:56 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
parallel-cypress: restore original sequential build.
Running all tests in one command will display a better output
and also might be faster.
Change-Id: Ib061fad28eeb1246c774bfb7fd958c3f5b9c317b
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89731
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index 8caf63453..6be7830eb 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -57,7 +57,7 @@ MOBILE_TEST_FILES_DONE= \
DESKTOP_TEST_FILES_DONE= \
$(foreach test_file,$(DEKSTOP_TEST_FILES),$(DESKTOP_TRACK_FOLDER)/$(test_file).done)
-check-local: $(MOBILE_TEST_FILES_DONE) $(DESKTOP_TEST_FILES_DONE)
+check-local: $(DESKTOP_TEST_FILES_DONE) $(MOBILE_TEST_FILES_DONE)
@$(KILL_COMMAND) || true
$(if $(HEADLESS_BUILD), at pkill Xvfb,)
@@ -67,14 +67,22 @@ $(PID_FILE): @JAILS_PATH@ $(NODE_BINS)
$(call start_loolwsd)
$(MOBILE_TEST_FILES_DONE): $(PID_FILE)
- $(call run_mobile_tests,$(subst $(MOBILE_TRACK_FOLDER),,$(basename $@)))
+ $(if $(PARALLEL_BUILD),\
+ $(call run_mobile_tests,$(subst $(MOBILE_TRACK_FOLDER),,$(basename $@))),\
+ $(call run_mobile_tests))
@mkdir -p $(dir $@)
- @touch $@
+ $(if $(PARALLEL_BUILD),\
+ @touch $@,\
+ $(foreach done_file,$(MOBILE_TEST_FILES_DONE),touch $(done_file) &&) true)
$(DESKTOP_TEST_FILES_DONE): $(PID_FILE)
- $(call run_desktop_tests,$(subst $(DESKTOP_TRACK_FOLDER),,$(basename $@)))
+ $(if $(PARALLEL_BUILD),\
+ $(call run_desktop_tests,$(subst $(DESKTOP_TRACK_FOLDER),,$(basename $@))),\
+ $(call run_desktop_tests))
@mkdir -p $(dir $@)
- @touch $@
+ $(if $(PARALLEL_BUILD),\
+ @touch $@,\
+ $(foreach done_file,$(DESKTOP_TEST_FILES_DONE),touch $(done_file) &&) true)
check-seq: @JAILS_PATH@ $(NODE_BINS)
$(call run_JS_error_check)
commit da976fed14b16ff49ecd2d3796492225d77e0b75
Author: Yunusemre Şentürk <yunusemre at collabora.com>
AuthorDate: Fri Feb 28 19:17:08 2020 +0300
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
Wait until Xvfb says it is ready
Change-Id: I3af4428802d6e0ee380536e8dbad1de8aa6d9337
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89727
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index 92d40a364..8caf63453 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -146,7 +146,7 @@ endef
define start_Xvfb
@echo "Launching Xvfb..."
Xvfb :$(DISPLAY_NUMBER) &
- sleep 10
+ while [ ! -f /tmp/.X$(DISPLAY_NUMBER)-lock ] ; do sleep 1; done
@echo
endef
commit ede8d4ea7035226c59ccb68cf5de1d64e8c31ee8
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Feb 28 14:37:56 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
parallel-cypress: restore original check rule as check-seq.
It can be used to run tests sequentially with a better
output on the console.
Change-Id: Ib061fad28eeb1246c774bfb7fd958c3f5b9c317b
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index 701fcf093..92d40a364 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -76,6 +76,13 @@ $(DESKTOP_TEST_FILES_DONE): $(PID_FILE)
@mkdir -p $(dir $@)
@touch $@
+check-seq: @JAILS_PATH@ $(NODE_BINS)
+ $(call run_JS_error_check)
+ $(call start_loolwsd)
+ $(call run_desktop_tests)
+ $(call run_mobile_tests)
+ @$(KILL_COMMAND) || true
+
check-desktop: @JAILS_PATH@ $(NODE_BINS)
$(call run_JS_error_check)
$(call start_loolwsd)
commit 6d5c60bb13760dc798a1795116d72b423560fa4b
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Tue Feb 25 13:09:31 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
parallel-cypress: Start own Xvfb in CI environment.
It's not necessary when we build with one job, but when
there are more jobs they try to start their own Xvfb
and they might use the same DISPLAY number for that
which leads to a failure or a freeze.
See also:
https://docs.cypress.io/guides/guides/continuous-integration.html#Xvfb
Change-Id: I2fb301b1d8e889b2898d6792fb38cece303129a6
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index 22c1e0271..701fcf093 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -24,6 +24,9 @@ MOBILE_TRACK_FOLDER=$(abs_builddir)/workdir/track/mobile
ALLOWED_PORTS = $(shell seq 9900 1 9980)
KILL_COMMAND=pkill -F $(PID_FILE) || pkill --signal SIGKILL -F $(PID_FILE)
PARALLEL_BUILD = $(findstring jobserver,$(MAKEFLAGS))
+DISPLAY_NUMBER = 100
+HEADLESS_BUILD := $(findstring Command failed,$(shell xhost > /dev/null 2>&1 || echo "Command failed, so we are in a headless environment."))
+export DISPLAY=$(if $(HEADLESS_BUILD),:$(DISPLAY_NUMBER),$(shell echo $$DISPLAY))
if HAVE_LO_PATH
MOBILE_TEST_FILES= \
@@ -56,9 +59,11 @@ DESKTOP_TEST_FILES_DONE= \
check-local: $(MOBILE_TEST_FILES_DONE) $(DESKTOP_TEST_FILES_DONE)
@$(KILL_COMMAND) || true
+ $(if $(HEADLESS_BUILD), at pkill Xvfb,)
$(PID_FILE): @JAILS_PATH@ $(NODE_BINS)
$(call run_JS_error_check)
+ $(if $(HEADLESS_BUILD),$(call start_Xvfb),)
$(call start_loolwsd)
$(MOBILE_TEST_FILES_DONE): $(PID_FILE)
@@ -130,6 +135,14 @@ define start_loolwsd
@echo
endef
+#https://docs.cypress.io/guides/guides/continuous-integration.html#Xvfb
+define start_Xvfb
+ @echo "Launching Xvfb..."
+ Xvfb :$(DISPLAY_NUMBER) &
+ sleep 10
+ @echo
+endef
+
define run_desktop_tests
@echo $(if $(1),"Running cypress desktop test: $(1)","Running cypress desktop tests...")
@echo
commit 63b55f9a7a25444f04caf1f89765aaf0745408cf
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Tue Feb 25 12:56:42 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
[DONT PUSH TO MASTER]: Don't run C++ unit tests.
Change-Id: I7a8a10187e63668f04c9af18fa6352fbbe958251
diff --git a/Makefile.am b/Makefile.am
index bf5725b92..60654c841 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,7 +14,7 @@ endif
else
-SUBDIRS = . test loleaflet cypress_test
+SUBDIRS = . loleaflet cypress_test
export ENABLE_DEBUG
commit ffdb88a589e43ab11937281ba80484fdffc1241c
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sat Feb 22 11:48:33 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
parallel-cypress: during parallel build don't write out execution line-by-line
Because in this case, the output of the different threads will be
mixed in the command line.
For sequential build keep the original behavior.
Change-Id: Ibf9bf7c6111f8b5b0cf188fab66b97dedd613c65
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index 0984e5248..22c1e0271 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -23,6 +23,7 @@ MOBILE_TRACK_FOLDER=$(abs_builddir)/workdir/track/mobile
ALLOWED_PORTS = $(shell seq 9900 1 9980)
KILL_COMMAND=pkill -F $(PID_FILE) || pkill --signal SIGKILL -F $(PID_FILE)
+PARALLEL_BUILD = $(findstring jobserver,$(MAKEFLAGS))
if HAVE_LO_PATH
MOBILE_TEST_FILES= \
@@ -130,27 +131,29 @@ define start_loolwsd
endef
define run_desktop_tests
+ @echo $(if $(1),"Running cypress desktop test: $(1)","Running cypress desktop tests...")
@echo
- @echo "Running cypress desktop tests..."
- @echo
- $(CYPRESS_BINARY) run --browser $(CHROME) \
+ $(eval RUN_COMMAND = \
+ $(CYPRESS_BINARY) run --browser $(CHROME) \
--config integrationFolder=$(DESKTOP_TEST_FOLDER),userAgent=$(DESKTOP_USER_AGENT) \
--headless \
--env DATA_FOLDER=$(DESKTOP_DATA_FOLDER),WORKDIR=$(DESKTOP_WORKDIR),WSD_VERSION_HASH=$(LOOLWSD_VERSION_HASH),SERVER_PORT=$(FREE_PORT) \
$(if $(1), --spec=$(abs_dir)/integration_tests/desktop/$(1)) \
- || ($(KILL_COMMAND) && false)
+ || ($(KILL_COMMAND) && false))
+ $(if $(PARALLEL_BUILD), at echo "`echo $(RUN_COMMAND) && $(RUN_COMMAND)`",$(RUN_COMMAND))
endef
define run_mobile_tests
+ @echo $(if $(1),"Running cypress mobile test: $(1)","Running cypress mobile tests...")
@echo
- @echo "Running cypress mobile tests..."
- @echo
- $(CYPRESS_BINARY) run --browser $(CHROME) \
+ $(eval RUN_COMMAND = \
+ $(CYPRESS_BINARY) run --browser $(CHROME) \
--config integrationFolder=$(MOBILE_TEST_FOLDER),userAgent=$(MOBILE_USER_AGENT) \
--headless \
--env DATA_FOLDER=$(MOBILE_DATA_FOLDER),WORKDIR=$(MOBILE_WORKDIR),WSD_VERSION_HASH=$(LOOLWSD_VERSION_HASH),SERVER_PORT=$(FREE_PORT) \
$(if $(1), --spec=$(abs_dir)/integration_tests/mobile/$(1)) \
- || ($(KILL_COMMAND) && false)
+ || ($(KILL_COMMAND) && false))
+ $(if $(PARALLEL_BUILD), at echo "`echo $(RUN_COMMAND) && $(RUN_COMMAND)`",$(RUN_COMMAND))
endef
NODE_BINS = \
commit 673b6a4aeee6f88ae3bf94b573c49a55e8ab3ece
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sat Feb 22 10:42:49 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
parallel-cypress: some cleanup around loolwsd server starting
Change-Id: Ia762d9ae73a40ea9debf0b847bc93e8e9171284d
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index 0e71f1fe2..0984e5248 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -58,7 +58,6 @@ check-local: $(MOBILE_TEST_FILES_DONE) $(DESKTOP_TEST_FILES_DONE)
$(PID_FILE): @JAILS_PATH@ $(NODE_BINS)
$(call run_JS_error_check)
- $(eval FREE_PORT:=$(shell $(GET_PORT_BINARY) --host=127.0.0.1 $(ALLOWED_PORTS)))
$(call start_loolwsd)
$(MOBILE_TEST_FILES_DONE): $(PID_FILE)
@@ -112,6 +111,7 @@ define run_JS_error_check
endef
define start_loolwsd
+ $(eval FREE_PORT:=$(shell $(GET_PORT_BINARY) --host=127.0.0.1 $(ALLOWED_PORTS)))
@echo "Found available port for testing: $(FREE_PORT)"
@echo
@echo "Launching loolwsd..."
@@ -121,9 +121,10 @@ define start_loolwsd
--o:child_root_path="@JAILS_PATH@" --o:storage.filesystem[@allow]=true \
--disable-ssl \
--o:admin_console.username=admin --o:admin_console.password=admin \
- --o:logging.file[@enable]=true --o:logging.level=trace > /dev/null 2>&1 \
+ --o:logging.file[@enable]=true --o:logging.level=trace \
--port=$(FREE_PORT) \
- --pidfile=$(PID_FILE) &
+ --pidfile=$(PID_FILE) \
+ > /dev/null 2>&1 &
@$(WAIT_ON_BINARY) http://localhost:$(FREE_PORT) --timeout 60000
@echo
endef
commit ca2f60a8932188ae71fc9038a94981a47807751d
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Feb 20 22:01:27 2020 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Mar 2 20:11:43 2020 +0100
parallel-cypress: initial parallelization
- Run all spec files separately so we can run them
parallel.
- Use separate test files for all spec files.
- Disable two tests which are failing while running in parallel.
Change-Id: I521feeac6e1ac4c3d2c87e989c11d4231945e569
diff --git a/cypress_test/Makefile.am b/cypress_test/Makefile.am
index e05ddbb82..0e71f1fe2 100644
--- a/cypress_test/Makefile.am
+++ b/cypress_test/Makefile.am
@@ -13,24 +13,63 @@ DESKTOP_USER_AGENT = "cypress"
DESKTOP_TEST_FOLDER = $(abs_srcdir)/integration_tests/desktop
DESKTOP_DATA_FOLDER = $(abs_srcdir)/data/desktop/
DESKTOP_WORKDIR = $(abs_builddir)/workdir/desktop/
+DESKTOP_TRACK_FOLDER=$(abs_builddir)/workdir/track/desktop
MOBILE_USER_AGENT = "cypress mobile"
MOBILE_TEST_FOLDER = $(abs_srcdir)/integration_tests/mobile
MOBILE_DATA_FOLDER = $(abs_srcdir)/data/mobile/
MOBILE_WORKDIR = $(abs_builddir)/workdir/mobile/
+MOBILE_TRACK_FOLDER=$(abs_builddir)/workdir/track/mobile
ALLOWED_PORTS = $(shell seq 9900 1 9980)
-FREE_PORT=$(shell $(GET_PORT_BINARY) --host=127.0.0.1 $(ALLOWED_PORTS))
-
KILL_COMMAND=pkill -F $(PID_FILE) || pkill --signal SIGKILL -F $(PID_FILE)
if HAVE_LO_PATH
-check-local: @JAILS_PATH@ $(NODE_BINS)
+MOBILE_TEST_FILES= \
+ calc/calc_focus_spec.js \
+ impress/impress_focus_spec.js \
+ writer/apply_font_spec.js \
+ writer/apply_paragraph_properties_spec.js \
+ writer/bottom_toolbar_spec.js \
+ writer/focus_spec.js \
+ writer/insert_field_spec.js \
+ writer/insert_formatting_mark_spec.js \
+ writer/insert_object_spec.js \
+ writer/mobile_wizard_state_spec.js \
+ writer/shape_properties_spec.js \
+ writer/spellchecking_spec.js \
+ writer/styles_spec.js \
+ writer/table_properties_spec.js \
+ writer/toolbar_spec.js
+
+DEKSTOP_TEST_FILES= \
+ copy_paste_spec.js \
+ example_desktop_test_spec.js \
+ shape_operations_spec.js
+
+MOBILE_TEST_FILES_DONE= \
+ $(foreach test_file,$(MOBILE_TEST_FILES),$(MOBILE_TRACK_FOLDER)/$(test_file).done)
+
+DESKTOP_TEST_FILES_DONE= \
+ $(foreach test_file,$(DEKSTOP_TEST_FILES),$(DESKTOP_TRACK_FOLDER)/$(test_file).done)
+
+check-local: $(MOBILE_TEST_FILES_DONE) $(DESKTOP_TEST_FILES_DONE)
+ @$(KILL_COMMAND) || true
+
+$(PID_FILE): @JAILS_PATH@ $(NODE_BINS)
$(call run_JS_error_check)
+ $(eval FREE_PORT:=$(shell $(GET_PORT_BINARY) --host=127.0.0.1 $(ALLOWED_PORTS)))
$(call start_loolwsd)
- $(call run_desktop_tests)
- $(call run_mobile_tests)
- @$(KILL_COMMAND) || true
+
+$(MOBILE_TEST_FILES_DONE): $(PID_FILE)
+ $(call run_mobile_tests,$(subst $(MOBILE_TRACK_FOLDER),,$(basename $@)))
+ @mkdir -p $(dir $@)
+ @touch $@
+
+$(DESKTOP_TEST_FILES_DONE): $(PID_FILE)
+ $(call run_desktop_tests,$(subst $(DESKTOP_TRACK_FOLDER),,$(basename $@)))
+ @mkdir -p $(dir $@)
+ @touch $@
check-desktop: @JAILS_PATH@ $(NODE_BINS)
$(call run_JS_error_check)
commit 11c12a2729dcaccdcc84bc94a1a250fa124159c2
Author: Marco Marinello <marinello at libreoffice.org>
AuthorDate: Tue Feb 25 21:46:04 2020 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Mar 2 01:53:29 2020 +0100
Variabilize online git source
Signed-off-by: Marco Marinello <marinello at libreoffice.org>
Change-Id: If8f9103972952b98193ca6d1501844422b8aae54
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89483
Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/docker/l10n-docker-nightly.sh b/docker/l10n-docker-nightly.sh
index 598282e94..96d5a9be8 100755
--- a/docker/l10n-docker-nightly.sh
+++ b/docker/l10n-docker-nightly.sh
@@ -9,6 +9,7 @@
# * DOCKER_HUB_REPO - which Docker Hub repo to use
# * DOCKER_HUB_TAG - which Docker Hub tag to create
# * LIBREOFFICE_BRANCH - which branch to build in core
+# * LIBREOFFICE_ONLINE_REPO - which git repo to clone online from
# * LIBREOFFICE_ONLINE_BRANCH - which branch to build in online
# * LIBREOFFICE_BUILD_TARGET - which make target to run (in core repo)
# * ONLINE_EXTRA_BUILD_OPTIONS - extra build options for online
@@ -47,6 +48,11 @@ if [ -z "$LIBREOFFICE_BUILD_TARGET" ]; then
fi;
echo "LibreOffice build target: '$LIBREOFFICE_BUILD_TARGET'"
+if [ -z "$LIBREOFFICE_ONLINE_REPO" ]; then
+ LIBREOFFICE_ONLINE_REPO="https://git.libreoffice.org/online"
+fi;
+echo "LibreOffice build target: '$LIBREOFFICE_BUILD_TARGET'"
+
# do everything in the builddir
SRCDIR=$(realpath `dirname $0`)
INSTDIR="$SRCDIR/instdir"
@@ -69,7 +75,7 @@ fi
# online repo
if test ! -d online ; then
- git clone https://git.libreoffice.org/online online || exit 1
+ git clone "$LIBREOFFICE_ONLINE_REPO" online || exit 1
fi
( cd online && git fetch --all && git checkout -f $LIBREOFFICE_ONLINE_BRANCH && git clean -f -d && git pull -r ) || exit 1
commit 0acb00fc24bbdc15f63bc36d619cd7cb2cbb9b04
Author: Jan Holesovsky <kendy at collabora.com>
AuthorDate: Fri Feb 28 18:30:52 2020 +0100
Commit: Michael Meeks <michael.meeks at collabora.com>
CommitDate: Sat Feb 29 11:03:42 2020 +0100
android: Handle the loading progress directly in the app.
This way we can easily extend the "preparing for the 1st start" to the
follow-up "loading..."
It should also look better while the webview is being initialized etc.
Change-Id: I8de2dd96a726fa8302df558f691b1db82c9c8e71
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89733
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java
index 4a7c23151..ef8aa9bf3 100644
--- a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java
+++ b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java
@@ -43,7 +43,6 @@ import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
-import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
@@ -114,6 +113,8 @@ public class LOActivity extends AppCompatActivity {
private Looper nativeLooper;
private Bundle savedInstanceState;
+ private ProgressDialog mProgressDialog = null;
+
/** In case the mobile-wizard is visible, we have to intercept the Android's Back button. */
private boolean mMobileWizardVisible = false;
@@ -251,7 +252,10 @@ public class LOActivity extends AppCompatActivity {
this.savedInstanceState = savedInstanceState;
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
sPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+
setContentView(R.layout.lolib_activity_main);
+ mProgressDialog = new ProgressDialog(this);
+
init();
}
@@ -263,8 +267,7 @@ public class LOActivity extends AppCompatActivity {
return;
}
- final AlertDialog assetsProgress = createProgressDialog(R.string.preparing_for_the_first_start_after_an_update);
- assetsProgress.show();
+ mProgressDialog.indeterminate(R.string.preparing_for_the_first_start_after_an_update);
new AsyncTask<Void, Void, Void>() {
@Override
@@ -278,7 +281,6 @@ public class LOActivity extends AppCompatActivity {
@Override
protected void onPostExecute(Void aVoid) {
- assetsProgress.dismiss();
initUI();
}
}.execute();
@@ -507,18 +509,16 @@ public class LOActivity extends AppCompatActivity {
@Override
protected void onPause() {
- super.onPause();
- Log.d(TAG, "onPause() - hinting to save, we might need to return to the doc");
-
// A Save similar to an autosave
if (documentLoaded)
postMobileMessageNative("save dontTerminateEdit=true dontSaveIfUnmodified=true");
+
+ super.onPause();
+ Log.d(TAG, "onPause() - hinting to save, we might need to return to the doc");
}
@Override
protected void onDestroy() {
- super.onDestroy();
- Log.i(TAG, "onDestroy() - we know we are leaving the document");
nativeLooper.quit();
// Remove the webview from the hierarchy & destroy
@@ -532,6 +532,11 @@ public class LOActivity extends AppCompatActivity {
// than never, so let's call it from here too anyway
documentLoaded = false;
postMobileMessageNative("BYE");
+
+ mProgressDialog.dismiss();
+
+ super.onDestroy();
+ Log.i(TAG, "onDestroy() - we know we are leaving the document");
}
@Override
@@ -601,24 +606,9 @@ public class LOActivity extends AppCompatActivity {
return null;
}
- /** Create the progress dialog. */
- private AlertDialog createProgressDialog(int id) {
- LayoutInflater inflater = this.getLayoutInflater();
-
- View loadingView = inflater.inflate(R.layout.lolib_dialog_loading, null);
- TextView loadingText = loadingView.findViewById(R.id.lolib_loading_dialog_text);
- loadingText.setText(getText(id));
-
- return new AlertDialog.Builder(LOActivity.this)
- .setView(loadingView)
- .setCancelable(true)
- .create();
- }
-
/** Show the Saving progress and finish the app. */
private void finishWithProgress() {
- final AlertDialog savingProgress = createProgressDialog(R.string.saving);
- savingProgress.show();
+ mProgressDialog.indeterminate(R.string.saving);
// The 'BYE' takes a considerable amount of time, we need to post it
// so that it starts after the saving progress is actually shown
@@ -629,12 +619,12 @@ public class LOActivity extends AppCompatActivity {
postMobileMessageNative("BYE");
copyTempBackToIntent();
- runOnUiThread(new Runnable() {
+ /*runOnUiThread(new Runnable() {
@Override
public void run() {
- savingProgress.dismiss();
+ mProgressDialog.dismiss();
}
- });
+ });*/
finish();
}
@@ -654,6 +644,8 @@ public class LOActivity extends AppCompatActivity {
}
private void loadDocument() {
+ mProgressDialog.determinate(R.string.loading);
+
// setup the LOOLWSD
ApplicationInfo applicationInfo = getApplicationInfo();
String dataDir = applicationInfo.dataDir;
@@ -752,6 +744,31 @@ public class LOActivity extends AppCompatActivity {
mWebView.loadUrl("javascript:window.TheFakeWebSocket.onmessage({'data':" + message + "});");
}
});
+
+ // update progress bar when loading
+ if (message.startsWith("'statusindicator")) {
+ runOnUiThread(new Runnable() {
+ public void run() {
+ // update progress bar if it exists
+ final String statusIndicatorSetValue = "'statusindicatorsetvalue: ";
+ if (message.startsWith(statusIndicatorSetValue)) {
+ int start = statusIndicatorSetValue.length();
+ int end = message.indexOf("'", start);
+
+ int progress = 0;
+ try {
+ progress = Integer.parseInt(message.substring(start, end));
+ } catch (Exception e) {
+ }
+
+ mProgressDialog.determinateProgress(progress);
+ }
+ else if (message.startsWith("'statusindicatorfinish:")) {
+ mProgressDialog.dismiss();
+ }
+ }
+ });
+ }
}
/**
@@ -912,8 +929,7 @@ public class LOActivity extends AppCompatActivity {
}
private void initiateSlideShow() {
- final AlertDialog slideShowProgress = createProgressDialog(R.string.loading);
- slideShowProgress.show();
+ mProgressDialog.indeterminate(R.string.loading);
nativeHandler.post(new Runnable() {
@Override
@@ -924,7 +940,7 @@ public class LOActivity extends AppCompatActivity {
LOActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
- slideShowProgress.dismiss();
+ mProgressDialog.dismiss();
Intent slideShowActIntent = new Intent(LOActivity.this, SlideShowActivity.class);
slideShowActIntent.putExtra(SlideShowActivity.SVG_URI_KEY, slideShowFileUri);
LOActivity.this.startActivity(slideShowActIntent);
diff --git a/android/lib/src/main/java/org/libreoffice/androidlib/ProgressDialog.java b/android/lib/src/main/java/org/libreoffice/androidlib/ProgressDialog.java
new file mode 100644
index 000000000..39115fc29
--- /dev/null
+++ b/android/lib/src/main/java/org/libreoffice/androidlib/ProgressDialog.java
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.libreoffice.androidlib;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+/** Class to handle progress when loading, saving, or handling other time intensive operations. */
+public class ProgressDialog {
+ /** For the inflater. */
+ Activity mActivity;
+
+ /** The underlying dialog. */
+ AlertDialog mProgressDialog = null;
+
+ /** Various elements of the dialog. */
+ TextView mTextView;
+ ProgressBar mIndeterminateProgress;
+ ProgressBar mDeterminateProgress;
+
+ /** Current progress of the determinate progress bar. */
+ int mProgress = 0;
+
+ public ProgressDialog(Activity activity) {
+ mActivity = activity;
+ }
+
+ /** Set up the dialog if it does not exist; but don't show it yet. */
+ private void create() {
+ if (mProgressDialog != null)
+ return;
+
+ LayoutInflater inflater = mActivity.getLayoutInflater();
+
+ View loadingView = inflater.inflate(R.layout.lolib_dialog_loading, null);
+
+ mTextView = loadingView.findViewById(R.id.progress_dialog_text);
+ mIndeterminateProgress = loadingView.findViewById(R.id.progress_indeterminate);
+ mDeterminateProgress = loadingView.findViewById(R.id.progress_determinate);
+
+ mProgressDialog = new AlertDialog.Builder(mActivity)
+ .setView(loadingView)
+ .setCancelable(false)
+ .create();
+ }
+
+ /** Set the progress to indereterminate state. */
+ public void indeterminate(int messageId) {
+ create();
+
+ mIndeterminateProgress.setVisibility(View.VISIBLE);
+ mDeterminateProgress.setVisibility(View.INVISIBLE);
+ mTextView.setText(mActivity.getText(messageId));
+
+ mProgressDialog.show();
+ }
+
+ /** Set the progress to indereterminate state. */
+ public void determinate(int messageId) {
+ create();
+
+ mIndeterminateProgress.setVisibility(View.INVISIBLE);
+ mDeterminateProgress.setVisibility(View.VISIBLE);
+ mTextView.setText(mActivity.getText(messageId));
+
+ mProgress = 0;
+ mDeterminateProgress.setProgress(mProgress);
+
+ mProgressDialog.show();
+ }
+
+ /** Update the progress value. */
+ public void determinateProgress(int progress) {
+ if (mProgressDialog == null)
+ return;
+
+ if (mProgress > progress)
+ return;
+
+ mProgress = progress;
+ mDeterminateProgress.setProgress(mProgress);
+ }
+
+ /** Kill the dialog. */
+ public void dismiss() {
+ if (mProgressDialog == null)
+ return;
+
+ mProgressDialog.dismiss();
+ mProgressDialog = null;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/android/lib/src/main/res/layout/lolib_dialog_loading.xml b/android/lib/src/main/res/layout/lolib_dialog_loading.xml
index db4825bb7..b0fef6554 100644
--- a/android/lib/src/main/res/layout/lolib_dialog_loading.xml
+++ b/android/lib/src/main/res/layout/lolib_dialog_loading.xml
@@ -4,16 +4,31 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="20dp">
- <ProgressBar
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" />
+
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ProgressBar
+ android:id="@+id/progress_indeterminate"
+ android:layout_width="50dp"
+ android:layout_height="50dp" />
+
+ <ProgressBar
+ android:id="@+id/progress_determinate"
+ style="?android:attr/progressBarStyleHorizontal"
+ android:layout_width="50dp"
+ android:layout_height="50dp"
+ android:indeterminate="false"
+ android:min="0"
+ android:max="100"
+ android:visibility="invisible" />
+ </FrameLayout>
<TextView
- android:id="@+id/lolib_loading_dialog_text"
+ android:id="@+id/progress_dialog_text"
android:layout_width="0dp"
android:layout_height="match_parent"
- android:layout_weight="4"
- android:gravity="center"
- android:text="@string/loading" />
+ android:layout_weight="1"
+ android:gravity="center"/>
</LinearLayout>
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 4aa7fd7c7..a4804775d 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -441,6 +441,9 @@ L.Map = L.Evented.extend({
},
showBusy: function(label, bar) {
+ if (window.ThisIsTheAndroidApp)
+ return;
+
// If document is already loaded, ask the toolbar widget to show busy
// status on the bottom statusbar
if (this._docLayer) {
@@ -451,6 +454,9 @@ L.Map = L.Evented.extend({
},
hideBusy: function () {
+ if (window.ThisIsTheAndroidApp)
+ return;
+
this.fire('hidebusy');
this._progressBar.end(this);
},
commit a5410a126f283f28b583ef7916e8d55cc077101b
Author: Jan Holesovsky <kendy at collabora.com>
AuthorDate: Fri Feb 28 15:45:34 2020 +0100
Commit: Michael Meeks <michael.meeks at collabora.com>
CommitDate: Sat Feb 29 11:03:14 2020 +0100
android: No need for a USB device attached/detached receiver any more.
This was needed before we switched to using the Content provider
framework.
Change-Id: I3906069ad3dc04a957f768b9ed02463aeaa4470f
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89732
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/android/app/src/main/java/org/libreoffice/androidapp/ui/LibreOfficeUIActivity.java b/android/app/src/main/java/org/libreoffice/androidapp/ui/LibreOfficeUIActivity.java
index 4651a85bb..10652f005 100644
--- a/android/app/src/main/java/org/libreoffice/androidapp/ui/LibreOfficeUIActivity.java
+++ b/android/app/src/main/java/org/libreoffice/androidapp/ui/LibreOfficeUIActivity.java
@@ -164,12 +164,6 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
SettingsListenerModel.getInstance().setListener(this);
- // Registering the USB detect broadcast receiver
- IntentFilter filter = new IntentFilter();
- filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
- filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
- registerReceiver(mUSBReceiver, filter);
-
// Register the LOActivity events broadcast receiver
LocalBroadcastManager.getInstance(this).registerReceiver(mLOActivityReceiver,
new IntentFilter(LOActivity.LO_ACTIVITY_BROADCAST));
@@ -820,19 +814,6 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
//Log.d(LOGTAG, currentDirectory.toString() + Integer.toString(filterMode));
}
- private final BroadcastReceiver mUSBReceiver = new BroadcastReceiver() {
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
- Toast.makeText(context, R.string.usb_connected_configure, Toast.LENGTH_SHORT).show();
- //startActivity(new Intent(context, DocumentProviderSettingsActivity.class));
- Log.d(LOGTAG, "USB device attached");
- } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
- Log.d(LOGTAG, "USB device detached");
- }
- }
- };
-
/** Receiver for receiving messages from LOActivity - like that Save was performed and similar. */
private final BroadcastReceiver mLOActivityReceiver = new BroadcastReceiver() {
@Override
@@ -925,7 +906,6 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
@Override
protected void onDestroy() {
super.onDestroy();
- unregisterReceiver(mUSBReceiver);
LocalBroadcastManager.getInstance(this).unregisterReceiver(mLOActivityReceiver);
Log.d(LOGTAG, "onDestroy");
}
commit 48283deca56d3ddad90025fb1eb6f38473b92f04
Author: Jan Holesovsky <kendy at collabora.com>
AuthorDate: Fri Feb 28 14:58:32 2020 +0100
Commit: Michael Meeks <michael.meeks at collabora.com>
CommitDate: Sat Feb 29 11:02:52 2020 +0100
Just try to catch everything in the getSafeConfig().
Poco::Exception is derived from std::exception, yet there were cases
where it was not caught - no idea why:
I/DEBUG (24700): #00 pc 000371e4 /system/lib/libc.so (tgkill+12)
I/DEBUG (24700): #01 pc 00013fb9 /system/lib/libc.so (pthread_kill+52)
I/DEBUG (24700): #02 pc 00014bd7 /system/lib/libc.so (raise+10)
I/DEBUG (24700): #03 pc 00011519 /system/lib/libc.so (__libc_android_abort+36)
I/DEBUG (24700): #04 pc 0000fca4 /system/lib/libc.so (abort+4)
I/DEBUG (24700): #05 pc 000126e9 /system/lib/libc.so (__libc_fatal+16)
I/DEBUG (24700): #06 pc 0001159d /system/lib/libc.so (__assert2+20)
I/DEBUG (24700): #07 pc 00064fed /data/app/com.collabora.libreoffice-1/lib/arm/libc++_shared.so
I/DEBUG (24700): #08 pc 00065183 /data/app/com.collabora.libreoffice-1/lib/arm/libc++_shared.so
I/DEBUG (24700): #09 pc 0006cb79 /data/app/com.collabora.libreoffice-1/lib/arm/libc++_shared.so
I/DEBUG (24700): #10 pc 0006c527 /data/app/com.collabora.libreoffice-1/lib/arm/libc++_shared.so
I/DEBUG (24700): #11 pc 0006c4ef /data/app/com.collabora.libreoffice-1/lib/arm/libc++_shared.so (__cxa_throw+74)
I/DEBUG (24700): #12 pc 001be25c /data/app/com.collabora.libreoffice-1/lib/arm/libandroidapp.so (_ZNK4Poco4Util21AbstractConfiguration7getBoolERKNSt6__ndk112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE+208)
I/DEBUG (24700): #13 pc 001847fd /data/app/com.collabora.libreoffice-1/lib/arm/libandroidapp.so (_ZN7LOOLWSD17ConfigValueGetterclERb+12)
I/DEBUG (24700): #14 pc 001847c3 /data/app/com.collabora.libreoffice-1/lib/arm/libandroidapp.so (_ZN7LOOLWSD13getSafeConfigIbEEbRN4Poco4Util20LayeredConfigurationERKNSt6__ndk112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEERT_+22)
I/DEBUG (24700): #15 pc 00184747 /data/app/com.collabora.libreoffice-1/lib/arm/libandroidapp.so (_ZN7LOOLWSD14getConfigValueIbEET_RN4Poco4Util20LayeredConfigurationERKNSt6__ndk112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEES1_+38)
I/DEBUG (24700): #16 pc 0018748b /data/app/com.collabora.libreoffice-1/lib/arm/libandroidapp.so (_ZN7LOOLWSD10initializeERN4Poco4Util11ApplicationE+1334)
I/DEBUG (24700): #17 pc 001c7274 /data/app/com.collabora.libreoffice-1/lib/arm/libandroidapp.so (_ZN4Poco4Util11Application3runEv+28)
I/DEBUG (24700): #18 pc 00134fbf /data/app/com.collabora.libreoffice-1/lib/arm/libandroidapp.so
I/DEBUG (24700): #19 pc 00134df7 /data/app/com.collabora.libreoffice-1/lib/arm/libandroidapp.so
I/DEBUG (24700): #20 pc 00134dc5 /data/app/com.collabora.libreoffice-1/lib/arm/libandroidapp.so
I/DEBUG (24700): #21 pc 000137a3 /system/lib/libc.so (_ZL15__pthread_startPv+30)
I/DEBUG (24700): #22 pc 00011883 /system/lib/libc.so (__start_thread+6)
Change-Id: Ica643f88d572b239b9a124e31cb4552f86439bf6
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89715
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp
index 204129d77..b4e2b4306 100644
--- a/wsd/LOOLWSD.hpp
+++ b/wsd/LOOLWSD.hpp
@@ -262,7 +262,7 @@ private:
ConfigValueGetter(config, name)(value);
return true;
}
- catch (const std::exception&)
+ catch (...)
{
}
commit 09005eb1cf67b12dd0be7623646c2e900c81b241
Author: Jan Holesovsky <kendy at collabora.com>
AuthorDate: Fri Feb 28 14:55:42 2020 +0100
Commit: Michael Meeks <michael.meeks at collabora.com>
CommitDate: Sat Feb 29 11:01:00 2020 +0100
android: Don't even try to read these values, seem to trigger an exception.
All the code that is using them is compiled out on Android anyway.
Change-Id: Ica349135202211ecdcb095bb82aa677f2dee19ba
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89714
Tested-by: Michael Meeks <michael.meeks at collabora.com>
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 5611edba5..61b9d8f09 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -213,7 +213,6 @@ static int careerSpanMs = 0;
/// The timeout for a child to spawn, initially high, then reset to the default.
int ChildSpawnTimeoutMs = CHILD_TIMEOUT_MS * 4;
-bool LOOLWSD::NoCapsForKit = false;
std::atomic<unsigned> LOOLWSD::NumConnections;
std::set<std::string> LOOLWSD::EditFileExtensions;
@@ -699,8 +698,11 @@ std::atomic<uint64_t> LOOLWSD::NextConnectionId(1);
std::atomic<int> LOOLWSD::ForKitWritePipe(-1);
std::atomic<int> LOOLWSD::ForKitProcId(-1);
#endif
+#if !MOBILEAPP
+bool LOOLWSD::NoCapsForKit = false;
bool LOOLWSD::NoSeccomp = false;
bool LOOLWSD::AdminEnabled = true;
+#endif
#ifdef FUZZER
bool LOOLWSD::DummyLOK = false;
std::string LOOLWSD::FuzzFileName;
@@ -1100,9 +1102,11 @@ void LOOLWSD::initialize(Application& self)
LOOLWSD::MaxConnections = MAX_CONNECTIONS;
LOOLWSD::MaxDocuments = MAX_DOCUMENTS;
+#if !MOBILEAPP
NoSeccomp = !getConfigValue<bool>(conf, "security.seccomp", true);
NoCapsForKit = !getConfigValue<bool>(conf, "security.capabilities", true);
AdminEnabled = getConfigValue<bool>(conf, "admin_console.enable", true);
+#endif
#if ENABLE_SUPPORT_KEY
const std::string supportKeyString = getConfigValue<std::string>(conf, "support_key", "");
diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp
index d14b77ae5..204129d77 100644
--- a/wsd/LOOLWSD.hpp
+++ b/wsd/LOOLWSD.hpp
@@ -49,9 +49,11 @@ public:
// so just keep these as statics.
static std::atomic<uint64_t> NextConnectionId;
static unsigned int NumPreSpawnedChildren;
+#if !MOBILEAPP
static bool NoCapsForKit;
static bool NoSeccomp;
static bool AdminEnabled;
+#endif
static std::atomic<int> ForKitWritePipe;
static std::atomic<int> ForKitProcId;
static bool DummyLOK;
commit 7193699742a48c347b8b6a694c8f4aa0218735c9
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Feb 28 16:02:38 2020 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Feb 28 18:31:53 2020 +0100
libfuzzer: don't require a core.git installation set
The fuzzer focuses on catching protocol parsing problems, it's not an
end-to-end test.
Change-Id: I1edc308134f365749339790f242614332b54dce4
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89720
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
diff --git a/configure.ac b/configure.ac
index 1a038efaf..3c34c153d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -679,7 +679,7 @@ AS_IF([test -n "$LOKIT_PATH"],
[CPPFLAGS="$CPPFLAGS -I${LOKIT_PATH}"])
lokit_msg="$LOKIT_PATH"
-AS_IF([test "$ENABLE_IOSAPP" != "true" -a "$ENABLE_ANDROIDAPP" != "true"],
+AS_IF([test "$ENABLE_IOSAPP" != "true" -a "$ENABLE_ANDROIDAPP" != "true" -a "$enable_fuzzers" != "yes"],
[AC_MSG_CHECKING([for LibreOffice path])
if test -n "$with_lo_path"; then
# strip trailing '/' from LO_PATH, 'ln -s' with such path will otherwise fail
commit 547f9ea73186d274d512a9fa1f01e6edcad66bab
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Feb 28 14:51:22 2020 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Feb 28 18:31:37 2020 +0100
Rework StringVector to have a single underlying string
This is meant to reduce lots of small allocations and instead have
pointers into the single string for the various tokens instead.
This has a few requirements, though:
1) It's no longer OK to modify the tokens, changing their length would
invalidate the start/length of other tokens. Rework
DocumentBroker::load() to avoid such mutation.
2) The iterators no longer expose zero-terminated strings, so
Poco::cat() doesn't work anymore: add an own cat() instead and use that
in e.g. ChildSession. The own cat() has the benefit that it won't read
past the end of the array if the begin index is out of bounds to add
more safety.
(This nicely works towards killing Poco usage in general.)
3) If zero-terminated strings for all individual tokens is needed, a
copy has to be made, as done in spawnProcess().
(For all of these requirements, the build fails if there are problems.)
Change-Id: Iea40e4400e630b2d669f5c72aea85cb40edf9a2c
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89711
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
diff --git a/common/Protocol.hpp b/common/Protocol.hpp
index 787be3706..3574d2027 100644
--- a/common/Protocol.hpp
+++ b/common/Protocol.hpp
@@ -85,7 +85,7 @@ namespace LOOLProtocol
{
for (const auto& token : tokens)
{
- if (getTokenString(token, name, value))
+ if (getTokenString(tokens.getParam(token), name, value))
{
return true;
}
@@ -101,10 +101,10 @@ namespace LOOLProtocol
inline
StringVector tokenize(const char* data, const size_t size, const char delimiter = ' ')
{
- std::vector<std::string> tokens;
+ std::vector<StringToken> tokens;
if (size == 0 || data == nullptr)
{
- return StringVector(tokens);
+ return StringVector(std::string(), {});
}
tokens.reserve(8);
@@ -116,7 +116,7 @@ namespace LOOLProtocol
{
if (start != end && *start != delimiter)
{
- tokens.emplace_back(start, end);
+ tokens.emplace_back(start - data, end - start);
}
start = end;
@@ -129,10 +129,10 @@ namespace LOOLProtocol
if (start != end && *start != delimiter && *start != '\n')
{
- tokens.emplace_back(start, end);
+ tokens.emplace_back(start - data, end - start);
}
- return StringVector(tokens);
+ return StringVector(std::string(data, size), tokens);
}
inline
diff --git a/common/Session.cpp b/common/Session.cpp
index 815fd5391..a0cdabe41 100644
--- a/common/Session.cpp
+++ b/common/Session.cpp
@@ -182,7 +182,7 @@ void Session::parseDocOptions(const StringVector& tokens, int& part, std::string
if (getTokenString(tokens[offset], "options", _docOptions))
{
if (tokens.size() > offset + 1)
- _docOptions += Poco::cat(std::string(" "), tokens.begin() + offset + 1, tokens.end());
+ _docOptions += tokens.cat(std::string(" "), offset + 1);
}
}
}
diff --git a/common/StringVector.cpp b/common/StringVector.cpp
index a4bf78109..89777166b 100644
--- a/common/StringVector.cpp
+++ b/common/StringVector.cpp
@@ -11,35 +11,79 @@
StringVector::StringVector() = default;
-StringVector::StringVector(const std::vector<std::string>& vector) { _vector = vector; }
+StringVector::StringVector(const std::string& string, const std::vector<StringToken>& tokens)
+ : _string(string),
+ _tokens(tokens)
+{
+}
std::string StringVector::operator[](size_t index) const
{
- if (index >= _vector.size())
+ if (index >= _tokens.size())
{
return std::string();
}
- return _vector[index];
+ const StringToken& token = _tokens[index];
+ return _string.substr(token._index, token._length);
}
-size_t StringVector::size() const { return _vector.size(); }
+size_t StringVector::size() const { return _tokens.size(); }
+
+bool StringVector::empty() const { return _tokens.empty(); }
-bool StringVector::empty() const { return _vector.empty(); }
+std::vector<StringToken>::const_iterator StringVector::begin() const { return _tokens.begin(); }
-std::vector<std::string>::const_iterator StringVector::begin() const { return _vector.begin(); }
+std::vector<StringToken>::iterator StringVector::begin() { return _tokens.begin(); }
-std::vector<std::string>::iterator StringVector::begin() { return _vector.begin(); }
+std::vector<StringToken>::const_iterator StringVector::end() const { return _tokens.end(); }
-std::vector<std::string>::const_iterator StringVector::end() const { return _vector.end(); }
+std::vector<StringToken>::iterator StringVector::end() { return _tokens.end(); }
-std::vector<std::string>::iterator StringVector::end() { return _vector.end(); }
+std::vector<StringToken>::iterator StringVector::erase(std::vector<StringToken>::const_iterator it)
+{
+ return _tokens.erase(it);
+}
-std::vector<std::string>::iterator StringVector::erase(std::vector<std::string>::const_iterator it)
+void StringVector::push_back(const std::string& string)
{
- return _vector.erase(it);
+ StringToken token;
+ token._index = _string.length();
+ token._length = string.length();
+ _tokens.push_back(token);
+ _string += string;
}
-void StringVector::push_back(const std::string& string) { _vector.push_back(string); }
+std::string StringVector::getParam(const StringToken& token) const
+{
+ return _string.substr(token._index, token._length);
+}
+
+std::string StringVector::cat(const std::string& separator, size_t begin) const
+{
+ std::string ret;
+ bool first = true;
+
+ if (begin >= _tokens.size())
+ {
+ return ret;
+ }
+
+ for (auto it = _tokens.begin() + begin; it != _tokens.end(); ++it)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ ret += separator;
+ }
+
+ ret += getParam(*it);
+ }
+
+ return ret;
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/common/StringVector.hpp b/common/StringVector.hpp
index 346bfabff..4255e9d54 100644
--- a/common/StringVector.hpp
+++ b/common/StringVector.hpp
@@ -13,18 +13,37 @@
#include <string>
#include <vector>
+/**
+ * Stores an offset and a length into the single underlying string of StringVector.
+ */
+struct StringToken
+{
+ size_t _index;
+ size_t _length;
+
+ StringToken() = default;
+
+ StringToken(size_t index, size_t length)
+ : _index(index),
+ _length(length)
+ {
+ }
+};
+
/**
* Safe wrapper around an std::vector<std::string>. Gives you an empty string if you would read past
* the ends of the vector.
*/
class StringVector
{
- std::vector<std::string> _vector;
+ /// All tokens are substrings of this string.
+ std::string _string;
+ std::vector<StringToken> _tokens;
public:
explicit StringVector();
- explicit StringVector(const std::vector<std::string>& vector);
+ explicit StringVector(const std::string& string, const std::vector<StringToken>& tokens);
/// Unlike std::vector, gives an empty string if index is unexpected.
std::string operator[](size_t index) const;
@@ -33,17 +52,23 @@ public:
bool empty() const;
- std::vector<std::string>::const_iterator begin() const;
+ std::vector<StringToken>::const_iterator begin() const;
- std::vector<std::string>::iterator begin();
+ std::vector<StringToken>::iterator begin();
- std::vector<std::string>::const_iterator end() const;
+ std::vector<StringToken>::const_iterator end() const;
- std::vector<std::string>::iterator end();
+ std::vector<StringToken>::iterator end();
- std::vector<std::string>::iterator erase(std::vector<std::string>::const_iterator it);
+ std::vector<StringToken>::iterator erase(std::vector<StringToken>::const_iterator it);
void push_back(const std::string& string);
+
+ /// Gets the underlying string of a single token.
+ std::string getParam(const StringToken& token) const;
+
+ /// Concats tokens starting from begin, using separator as separator.
+ std::string cat(const std::string& separator, size_t begin) const;
};
#endif
diff --git a/common/Util.cpp b/common/Util.cpp
index 9a2273eaf..137ec3897 100644
--- a/common/Util.cpp
+++ b/common/Util.cpp
@@ -257,9 +257,16 @@ namespace Util
}
}
+ // Create a vector of zero-terminated strings.
+ std::vector<std::string> argStrings(args.size());
+ for (const auto& arg : args)
+ {
+ argStrings.emplace_back(args.getParam(arg));
+ }
+
std::vector<char *> params;
params.push_back(const_cast<char *>(cmd.c_str()));
- for (const auto& i : args)
+ for (const auto& i : argStrings)
params.push_back(const_cast<char *>(i.c_str()));
params.push_back(nullptr);
diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index 13bc1d8e4..3cd8642bd 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -365,10 +365,10 @@ bool ChildSession::_handleInput(const char *buffer, int length)
if (tokens[1].find(".uno:SpellCheckApplySuggestion") != std::string::npos ||
tokens[1].find(".uno:LanguageStatus") != std::string::npos)
{
- std::vector<std::string> newTokens;
+ StringVector newTokens;
newTokens.push_back(tokens[0]);
newTokens.push_back(firstLine.substr(4)); // Copy the remaining part.
- return unoCommand(buffer, length, StringVector(newTokens));
+ return unoCommand(buffer, length, newTokens);
}
return unoCommand(buffer, length, tokens);
}
@@ -686,7 +686,7 @@ bool ChildSession::sendFontRendering(const char* /*buffer*/, int /*length*/, con
return false;
}
- const std::string response = "renderfont: " + Poco::cat(std::string(" "), tokens.begin() + 1, tokens.end()) + "\n";
+ const std::string response = "renderfont: " + tokens.cat(std::string(" "), 1) + "\n";
std::vector<char> output;
output.resize(response.size());
@@ -903,7 +903,7 @@ bool ChildSession::downloadAs(const char* /*buffer*/, int /*length*/, const Stri
{
if (tokens.size() > 5)
{
- filterOptions += Poco::cat(std::string(" "), tokens.begin() + 5, tokens.end());
+ filterOptions += tokens.cat(std::string(" "), 5);
}
}
@@ -1413,7 +1413,7 @@ bool ChildSession::dialogEvent(const char* /*buffer*/, int /*length*/, const Str
unsigned nLOKWindowId = std::stoi(tokens[1].c_str());
getLOKitDocument()->sendDialogEvent(nLOKWindowId,
- Poco::cat(std::string(" "), tokens.begin() + 2, tokens.end()).c_str());
+ tokens.cat(std::string(" "), 2).c_str());
return true;
}
@@ -1468,7 +1468,7 @@ bool ChildSession::unoCommand(const char* /*buffer*/, int /*length*/, const Stri
else
{
getLOKitDocument()->postUnoCommand(tokens[1].c_str(),
- Poco::cat(std::string(" "), tokens.begin() + 2, tokens.end()).c_str(),
+ tokens.cat(std::string(" "), 2).c_str(),
bNotify);
}
@@ -2002,7 +2002,7 @@ bool ChildSession::saveAs(const char* /*buffer*/, int /*length*/, const StringVe
{
if (tokens.size() > 4)
{
- filterOptions += Poco::cat(std::string(" "), tokens.begin() + 4, tokens.end());
+ filterOptions += tokens.cat(std::string(" "), 4);
}
}
diff --git a/kit/ForKit.cpp b/kit/ForKit.cpp
index 90a7947fd..3af723a99 100644
--- a/kit/ForKit.cpp
+++ b/kit/ForKit.cpp
@@ -442,13 +442,16 @@ int main(int argc, char** argv)
eq = std::strchr(cmd, '=');
const std::string rlimits = std::string(eq+1);
StringVector tokens = LOOLProtocol::tokenize(rlimits, ';');
- for (const std::string& cmdLimit : tokens)
+ for (const auto& cmdLimit : tokens)
{
- const std::pair<std::string, std::string> pair = Util::split(cmdLimit, ':');
- StringVector tokensLimit({ "setconfig", pair.first, pair.second });
+ const std::pair<std::string, std::string> pair = Util::split(tokens.getParam(cmdLimit), ':');
+ StringVector tokensLimit;
+ tokensLimit.push_back("setconfig");
+ tokensLimit.push_back(pair.first);
+ tokensLimit.push_back(pair.second);
if (!Rlimit::handleSetrlimitCommand(tokensLimit))
{
- LOG_ERR("Unknown rlimits command: " << cmdLimit);
+ LOG_ERR("Unknown rlimits command: " << tokens.getParam(cmdLimit));
}
}
}
diff --git a/kit/Kit.cpp b/kit/Kit.cpp
index 201628c54..883efa6fc 100644
--- a/kit/Kit.cpp
+++ b/kit/Kit.cpp
@@ -2106,16 +2106,16 @@ protected:
if (logger.enabled())
{
logger << _socketName << ": recv [";
- for (const std::string& token : tokens)
+ for (const auto& token : tokens)
{
// Don't log user-data, there are anonymized versions that get logged instead.
- if (Util::startsWith(token, "jail") ||
- Util::startsWith(token, "author") ||
- Util::startsWith(token, "name") ||
- Util::startsWith(token, "url"))
+ if (Util::startsWith(tokens.getParam(token), "jail") ||
+ Util::startsWith(tokens.getParam(token), "author") ||
+ Util::startsWith(tokens.getParam(token), "name") ||
+ Util::startsWith(tokens.getParam(token), "url"))
continue;
- logger << token << ' ';
+ logger << tokens.getParam(token) << ' ';
}
LOG_END(logger, true);
diff --git a/test/WhiteBoxTests.cpp b/test/WhiteBoxTests.cpp
index 67dd8644a..5c843adea 100644
--- a/test/WhiteBoxTests.cpp
+++ b/test/WhiteBoxTests.cpp
@@ -41,6 +41,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(testJson);
CPPUNIT_TEST(testAnonymization);
CPPUNIT_TEST(testTime);
+ CPPUNIT_TEST(testStringVector);
CPPUNIT_TEST_SUITE_END();
@@ -57,6 +58,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture
void testJson();
void testAnonymization();
void testTime();
+ void testStringVector();
};
void WhiteBoxTests::testLOOLProtocolFunctions()
@@ -795,6 +797,28 @@ void WhiteBoxTests::testTime()
}
}
+void WhiteBoxTests::testStringVector()
+{
+ // Test push_back() and getParam().
+ StringVector vector;
+ vector.push_back("a");
+ vector.push_back("b");
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), vector.size());
+ auto it = vector.begin();
+ CPPUNIT_ASSERT_EQUAL(std::string("a"), vector.getParam(*it));
+ ++it;
+ CPPUNIT_ASSERT_EQUAL(std::string("b"), vector.getParam(*it));
+
+ // Test cat().
+ CPPUNIT_ASSERT_EQUAL(std::string("a b"), vector.cat(" ", 0));
+ CPPUNIT_ASSERT_EQUAL(std::string(), vector.cat(" ", 3));
+ CPPUNIT_ASSERT_EQUAL(std::string(), vector.cat(" ", 42));
+
+ // Test operator []().
+ CPPUNIT_ASSERT_EQUAL(std::string("a"), vector[0]);
+ CPPUNIT_ASSERT_EQUAL(std::string(""), vector[2]);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(WhiteBoxTests);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index fedbf422e..8a79d46bb 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -878,7 +878,7 @@ bool ClientSession::sendFontRendering(const char *buffer, int length, const Stri
TileCache::Tile cachedTile = docBroker->tileCache().lookupCachedStream(TileCache::StreamType::Font, font+text);
if (cachedTile)
{
- const std::string response = "renderfont: " + Poco::cat(std::string(" "), tokens.begin() + 1, tokens.end()) + "\n";
+ const std::string response = "renderfont: " + tokens.cat(std::string(" "), 1) + "\n";
return sendTile(response, cachedTile);
}
@@ -1410,7 +1410,7 @@ bool ClientSession::handleKitToClientMessage(const char* buffer, const int lengt
{
// Need to get the initial part id from status message
int part = -1;
- if(getTokenInteger(token, "current", part))
+ if(getTokenInteger(tokens.getParam(token), "current", part))
{
_clientSelectedPart = part;
resetWireIdMap();
@@ -1418,14 +1418,14 @@ bool ClientSession::handleKitToClientMessage(const char* buffer, const int lengt
// Get document type too
std::string docType;
- if(getTokenString(token, "type", docType))
+ if(getTokenString(tokens.getParam(token), "type", docType))
{
_isTextDocument = docType.find("text") != std::string::npos;
}
// Store our Kit ViewId
int viewId = -1;
- if(getTokenInteger(token, "viewid", viewId))
+ if(getTokenInteger(tokens.getParam(token), "viewid", viewId))
_kitViewId = viewId;
}
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index bdb3d61ed..74b827678 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -767,7 +767,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
{
const std::string extension(plugin->getString("prefilter.extension"));
const std::string newExtension(plugin->getString("prefilter.newextension"));
- const std::string commandLine(plugin->getString("prefilter.commandline"));
+ std::string commandLine(plugin->getString("prefilter.commandline"));
if (localPath.length() > extension.length()+1 &&
strcasecmp(localPath.substr(localPath.length() - extension.length() -1).data(), (std::string(".") + extension).data()) == 0)
@@ -777,27 +777,30 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
const std::string newRootPath = _storage->getRootFilePath() + "." + newExtension;
- StringVector args(LOOLProtocol::tokenize(commandLine, ' '));
- std::string command(args[0]);
- args.erase(args.begin()); // strip the command
-
// The commandline must contain the space-separated substring @INPUT@ that is
// replaced with the input file name, and @OUTPUT@ for the output file name.
int inputs(0), outputs(0);
- for (auto it = args.begin(); it != args.end(); ++it)
+
+ std::string input("@INPUT");
+ size_t pos = commandLine.find(input);
+ if (pos != std::string::npos)
+ {
+ commandLine.replace(pos, input.length(), _storage->getRootFilePath());
+ ++inputs;
+ }
+
+ std::string output("@OUTPUT@");
+ pos = commandLine.find(output);
+ if (pos != std::string::npos)
{
- if (*it == "@INPUT@")
- {
- *it = _storage->getRootFilePath();
- ++inputs;
- }
- else if (*it == "@OUTPUT@")
- {
- *it = newRootPath;
- ++outputs;
- }
+ commandLine.replace(pos, output.length(), newRootPath);
+ ++outputs;
}
+ StringVector args(LOOLProtocol::tokenize(commandLine, ' '));
+ std::string command(args[0]);
+ args.erase(args.begin()); // strip the command
+
if (inputs != 1 || outputs != 1)
throw std::exception();
@@ -2019,7 +2022,7 @@ bool DocumentBroker::forwardToChild(const std::string& viewId, const std::string
msg = tokens[0] + ' ' + tokens[1] + ' ' + tokens[2];
msg += " jail=" + _uriJailed;
msg += " xjail=" + _uriJailedAnonym;
- msg += ' ' + Poco::cat(std::string(" "), tokens.begin() + 3, tokens.end());
+ msg += ' ' + tokens.cat(std::string(" "), 3);
}
_childProcess->sendTextFrame(msg);
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index d84f77b91..5611edba5 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1666,7 +1666,7 @@ bool LOOLWSD::createForKit()
++OutstandingForks;
LOG_INF("Launching forkit process: " << forKitPath << ' ' <<
- Poco::cat(std::string(" "), args.begin(), args.end()));
+ args.cat(std::string(" "), 0));
LastForkRequestTime = std::chrono::steady_clock::now();
int childStdin = -1;
@@ -2063,9 +2063,10 @@ public:
{
const std::string fowardedData = request.get("X-Forwarded-For");
StringVector tokens = LOOLProtocol::tokenize(fowardedData, ',');
- for(std::string& token : tokens)
+ for (const auto& token : tokens)
{
- addressToCheck = Util::trim(token);
+ std::string param = tokens.getParam(token);
+ addressToCheck = Util::trim(param);
try
{
hostToCheck = Poco::Net::DNS::resolve(addressToCheck).name();
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index a9caad8bb..9adc57656 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -439,7 +439,7 @@ static void addStorageReuseCookie(Poco::Net::HTTPRequest& request, const std::st
StringVector cookies = LOOLProtocol::tokenize(reuseStorageCookies, ':');
for (auto cookie : cookies)
{
- StringVector cookieTokens = LOOLProtocol::tokenize(cookie, '=');
+ StringVector cookieTokens = LOOLProtocol::tokenize(cookies.getParam(cookie), '=');
if (cookieTokens.size() == 2)
{
nvcCookies.add(cookieTokens[0], cookieTokens[1]);
diff --git a/wsd/TileDesc.hpp b/wsd/TileDesc.hpp
index d1296f0c8..e8eebdcf2 100644
--- a/wsd/TileDesc.hpp
+++ b/wsd/TileDesc.hpp
@@ -472,7 +472,7 @@ public:
{
std::string name;
std::string value;
- if (LOOLProtocol::parseNameValuePair(token, name, value))
+ if (LOOLProtocol::parseNameValuePair(tokens.getParam(token), name, value))
{
if (name == "tileposx")
{
diff --git a/wsd/TraceFile.hpp b/wsd/TraceFile.hpp
index 466e06fbc..8ef7eb201 100644
--- a/wsd/TraceFile.hpp
+++ b/wsd/TraceFile.hpp
@@ -222,7 +222,7 @@ public:
std::string newData;
for (const auto& token : tokens)
{
- newData += token + ' ';
+ newData += tokens.getParam(token) + ' ';
}
writeLocked(id, sessionId, newData, static_cast<char>(TraceFileRecord::Direction::Incoming));
commit b8bd1990aaa1b063ca21b78ffec629b5d5ae7697
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Feb 28 10:50:58 2020 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Feb 28 16:07:56 2020 +0100
Rework LOOLProtocol::tokenize() to return a StringVector object
The bulk of this commit just changes std::vector<std::string> to
StringVector when we deal with tokens from a websocket message.
The less boring part of it is the new StringVector class, which is a
wrapper around std::vector<std::string>, and provides the same API,
except that operator[] returns a string, not a string&, and this allows
returning an empty string in case that prevents reading past the end of
the underlying array.
This means in case client code forgets to check size() before invoking
operator[], we don't crash. (See the ~3 previous commits which fixed
such crashes.)
Later the ctor could be changed to take a single underlying string to
avoid lots of tiny allocations, that's not yet done in this commit.
Change-Id: I8a6082143a8ac0b65824f574b32104d7889c184f
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89687
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
diff --git a/Makefile.am b/Makefile.am
index 1ee125b1f..bf5725b92 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -92,6 +92,7 @@ shared_sources = common/FileUtil.cpp \
common/IoUtil.cpp \
common/Log.cpp \
common/Protocol.cpp \
+ common/StringVector.cpp \
common/Session.cpp \
common/Seccomp.cpp \
common/MessageQueue.cpp \
@@ -138,12 +139,14 @@ endif
connect_SOURCES = tools/Connect.cpp \
common/Log.cpp \
common/Protocol.cpp \
+ common/StringVector.cpp \
common/Util.cpp
lokitclient_SOURCES = common/IoUtil.cpp \
common/Log.cpp \
tools/KitClient.cpp \
common/Protocol.cpp \
+ common/StringVector.cpp \
common/Util.cpp
loolforkit_sources = kit/ChildSession.cpp \
@@ -170,6 +173,7 @@ clientsession_fuzzer_LDFLAGS = -fsanitize=fuzzer $(AM_LDFLAGS)
clientnb_SOURCES = net/clientnb.cpp \
common/Log.cpp \
+ common/StringVector.cpp \
common/Util.cpp
loolmount_SOURCES = tools/mount.cpp
@@ -181,12 +185,14 @@ loolconvert_SOURCES = tools/Tool.cpp
loolstress_CPPFLAGS = -DTDOC=\"$(abs_top_srcdir)/test/data\" ${include_paths}
loolstress_SOURCES = tools/Stress.cpp \
common/Protocol.cpp \
+ common/StringVector.cpp \
common/Log.cpp \
common/Util.cpp
loolconfig_SOURCES = tools/Config.cpp \
common/Crypto.cpp \
common/Log.cpp \
+ common/StringVector.cpp \
common/Util.cpp
loolsocketdump_SOURCES = tools/WebSocketDump.cpp \
@@ -218,6 +224,7 @@ shared_headers = common/Common.hpp \
common/Log.hpp \
common/LOOLWebSocket.hpp \
common/Protocol.hpp \
+ common/StringVector.hpp \
common/Seccomp.hpp \
common/Session.hpp \
common/Unit.hpp \
diff --git a/android/lib/src/main/cpp/CMakeLists.txt.in b/android/lib/src/main/cpp/CMakeLists.txt.in
index 29abef905..7b5b5323f 100644
--- a/android/lib/src/main/cpp/CMakeLists.txt.in
+++ b/android/lib/src/main/cpp/CMakeLists.txt.in
@@ -6,6 +6,7 @@ add_library(androidapp SHARED
../../../../../common/Log.cpp
../../../../../common/MessageQueue.cpp
../../../../../common/Protocol.cpp
+ ../../../../../common/StringVector.cpp
../../../../../common/Session.cpp
../../../../../common/SigUtil.cpp
../../../../../common/SpookyV2.cpp
diff --git a/common/Message.hpp b/common/Message.hpp
index 3fdbc5d36..9320037c7 100644
--- a/common/Message.hpp
+++ b/common/Message.hpp
@@ -80,11 +80,11 @@ public:
size_t size() const { return _data.size(); }
const std::vector<char>& data() const { return _data; }
- const std::vector<std::string>& tokens() const { return _tokens; }
+ const StringVector& tokens() const { return _tokens; }
const std::string& forwardToken() const { return _forwardToken; }
- const std::string& firstToken() const { return _tokens[0]; }
+ std::string firstToken() const { return _tokens[0]; }
const std::string& firstLine() const { return _firstLine; }
- const std::string& operator[](size_t index) const { return _tokens[index]; }
+ std::string operator[](size_t index) const { return _tokens[index]; }
bool getTokenInteger(const std::string& name, int& value)
{
@@ -177,7 +177,7 @@ private:
private:
const std::string _forwardToken;
std::vector<char> _data;
- const std::vector<std::string> _tokens;
+ const StringVector _tokens;
const std::string _id;
const std::string _firstLine;
const std::string _abbr;
diff --git a/common/MessageQueue.cpp b/common/MessageQueue.cpp
index dd8ea33b3..84987b278 100644
--- a/common/MessageQueue.cpp
+++ b/common/MessageQueue.cpp
@@ -30,7 +30,7 @@ void TileQueue::put_impl(const Payload& value)
{
LOG_TRC("Processing [" << LOOLProtocol::getAbbreviatedMessage(msg) << "]. Before canceltiles have " << getQueue().size() << " in queue.");
const std::string seqs = msg.substr(12);
- std::vector<std::string> tokens(LOOLProtocol::tokenize(seqs, ','));
+ StringVector tokens(LOOLProtocol::tokenize(seqs, ','));
getQueue().erase(std::remove_if(getQueue().begin(), getQueue().end(),
[&tokens](const Payload& v)
{
@@ -126,7 +126,7 @@ void TileQueue::removeTileDuplicate(const std::string& tileMsg)
namespace {
/// Read the viewId from the tokens.
-std::string extractViewId(const std::string& origMsg, const std::vector<std::string>& tokens)
+std::string extractViewId(const std::string& origMsg, const StringVector& tokens)
{
size_t nonJson = tokens[0].size() + tokens[1].size() + tokens[2].size() + 3; // including spaces
std::string jsonString(origMsg.data() + nonJson, origMsg.size() - nonJson);
@@ -151,7 +151,7 @@ std::string extractUnoCommand(const std::string& command)
}
/// Extract rectangle from the invalidation callback
-bool extractRectangle(const std::vector<std::string>& tokens, int& x, int& y, int& w, int& h, int& part)
+bool extractRectangle(const StringVector& tokens, int& x, int& y, int& w, int& h, int& part)
{
x = 0;
y = 0;
@@ -186,7 +186,7 @@ std::string TileQueue::removeCallbackDuplicate(const std::string& callbackMsg)
{
assert(LOOLProtocol::matchPrefix("callback", callbackMsg, /*ignoreWhitespace*/ true));
- std::vector<std::string> tokens = LOOLProtocol::tokenize(callbackMsg);
+ StringVector tokens = LOOLProtocol::tokenize(callbackMsg);
if (tokens.size() < 3)
return std::string();
@@ -211,7 +211,7 @@ std::string TileQueue::removeCallbackDuplicate(const std::string& callbackMsg)
{
auto& it = getQueue()[i];
- std::vector<std::string> queuedTokens = LOOLProtocol::tokenize(it.data(), it.size());
+ StringVector queuedTokens = LOOLProtocol::tokenize(it.data(), it.size());
if (queuedTokens.size() < 3)
{
++i;
@@ -316,7 +316,7 @@ std::string TileQueue::removeCallbackDuplicate(const std::string& callbackMsg)
{
auto& it = getQueue()[i];
- std::vector<std::string> queuedTokens = LOOLProtocol::tokenize(it.data(), it.size());
+ StringVector queuedTokens = LOOLProtocol::tokenize(it.data(), it.size());
if (queuedTokens.size() < 4)
continue;
@@ -362,7 +362,7 @@ std::string TileQueue::removeCallbackDuplicate(const std::string& callbackMsg)
if (!LOOLProtocol::matchPrefix("callback", it))
continue;
- std::vector<std::string> queuedTokens = LOOLProtocol::tokenize(it.data(), it.size());
+ StringVector queuedTokens = LOOLProtocol::tokenize(it.data(), it.size());
if (queuedTokens.size() < 3)
continue;
diff --git a/common/Protocol.cpp b/common/Protocol.cpp
index 4d8f51c50..7e5208774 100644
--- a/common/Protocol.cpp
+++ b/common/Protocol.cpp
@@ -27,12 +27,12 @@ namespace LOOLProtocol
int minor = -1;
std::string patch;
- std::vector<std::string> firstTokens(tokenize(version, '.'));
+ StringVector firstTokens(tokenize(version, '.'));
if (firstTokens.size() > 0)
{
major = std::stoi(firstTokens[0]);
- std::vector<std::string> secondTokens;
+ StringVector secondTokens;
if (firstTokens.size() > 1)
{
secondTokens = tokenize(firstTokens[1], '-');
@@ -170,7 +170,7 @@ namespace LOOLProtocol
return false;
}
- bool getTokenInteger(const std::vector<std::string>& tokens, const std::string& name, int& value)
+ bool getTokenInteger(const StringVector& tokens, const std::string& name, int& value)
{
for (size_t i = 0; i < tokens.size(); i++)
{
@@ -180,7 +180,7 @@ namespace LOOLProtocol
return false;
}
- bool getTokenKeyword(const std::vector<std::string>& tokens, const std::string& name, const std::map<std::string, int>& map, int& value)
+ bool getTokenKeyword(const StringVector& tokens, const std::string& name, const std::map<std::string, int>& map, int& value)
{
for (size_t i = 0; i < tokens.size(); i++)
{
diff --git a/common/Protocol.hpp b/common/Protocol.hpp
index e1a5d426e..787be3706 100644
--- a/common/Protocol.hpp
+++ b/common/Protocol.hpp
@@ -75,11 +75,11 @@ namespace LOOLProtocol
bool getTokenString(const std::string& token, const std::string& name, std::string& value);
bool getTokenKeyword(const std::string& token, const std::string& name, const std::map<std::string, int>& map, int& value);
- bool getTokenKeyword(const std::vector<std::string>& tokens, const std::string& name, const std::map<std::string, int>& map, int& value);
+ bool getTokenKeyword(const StringVector& tokens, const std::string& name, const std::map<std::string, int>& map, int& value);
- bool getTokenInteger(const std::vector<std::string>& tokens, const std::string& name, int& value);
+ bool getTokenInteger(const StringVector& tokens, const std::string& name, int& value);
- inline bool getTokenString(const std::vector<std::string>& tokens,
+ inline bool getTokenString(const StringVector& tokens,
const std::string& name,
std::string& value)
{
@@ -99,12 +99,12 @@ namespace LOOLProtocol
/// Tokenize space-delimited values until we hit new-line or the end.
inline
- std::vector<std::string> tokenize(const char* data, const size_t size, const char delimiter = ' ')
+ StringVector tokenize(const char* data, const size_t size, const char delimiter = ' ')
{
std::vector<std::string> tokens;
if (size == 0 || data == nullptr)
{
- return tokens;
+ return StringVector(tokens);
}
tokens.reserve(8);
@@ -132,11 +132,11 @@ namespace LOOLProtocol
tokens.emplace_back(start, end);
}
- return tokens;
+ return StringVector(tokens);
}
inline
- std::vector<std::string> tokenize(const std::string& s, const char delimiter = ' ')
+ StringVector tokenize(const std::string& s, const char delimiter = ' ')
{
return tokenize(s.data(), s.size(), delimiter);
}
diff --git a/common/Seccomp.cpp b/common/Seccomp.cpp
index c22937f9f..116056892 100644
--- a/common/Seccomp.cpp
+++ b/common/Seccomp.cpp
@@ -269,7 +269,7 @@ void setRLimit(rlim_t confLim, int resource, const std::string &resourceText, co
LOG_INF("Ignored setting " << resourceText << " to " << limTextWithUnit << ".");
}
-bool handleSetrlimitCommand(const std::vector<std::string>& tokens)
+bool handleSetrlimitCommand(const StringVector& tokens)
{
if (tokens.size() == 3 && tokens[0] == "setconfig")
{
diff --git a/common/Seccomp.hpp b/common/Seccomp.hpp
index 5a09de772..400745bfa 100644
--- a/common/Seccomp.hpp
+++ b/common/Seccomp.hpp
@@ -9,8 +9,7 @@
#ifndef INCLUDED_SECCOMP_HPP
#define INCLUDED_SECCOMP_HPP
-#include <string>
-#include <vector>
+#include <Protocol.hpp>
namespace Seccomp {
enum Type { KIT, WSD };
@@ -22,7 +21,7 @@ namespace Seccomp {
namespace Rlimit {
/// Handles setconfig command with limit_... subcommands.
/// Returns true iff it handled the command, regardless of success/failure.
- bool handleSetrlimitCommand(const std::vector<std::string>& tokens);
+ bool handleSetrlimitCommand(const StringVector& tokens);
};
#endif
diff --git a/common/Session.cpp b/common/Session.cpp
index 2a51b0e89..815fd5391 100644
--- a/common/Session.cpp
+++ b/common/Session.cpp
@@ -75,7 +75,7 @@ bool Session::sendBinaryFrame(const char *buffer, int length)
return sendMessage(buffer, length, WSOpCode::Binary) >= length;
}
-void Session::parseDocOptions(const std::vector<std::string>& tokens, int& part, std::string& timestamp, std::string& doctemplate)
+void Session::parseDocOptions(const StringVector& tokens, int& part, std::string& timestamp, std::string& doctemplate)
{
// First token is the "load" command itself.
size_t offset = 1;
diff --git a/common/Session.hpp b/common/Session.hpp
index aa585a559..8171fef64 100644
--- a/common/Session.hpp
+++ b/common/Session.hpp
@@ -168,7 +168,7 @@ protected:
/// Parses the options of the "load" command,
/// shared between MasterProcessSession::loadDocument() and ChildProcessSession::loadDocument().
- void parseDocOptions(const std::vector<std::string>& tokens, int& part, std::string& timestamp, std::string& doctemplate);
+ void parseDocOptions(const StringVector& tokens, int& part, std::string& timestamp, std::string& doctemplate);
void updateLastActivityTime()
{
diff --git a/common/StringVector.cpp b/common/StringVector.cpp
new file mode 100644
index 000000000..a4bf78109
--- /dev/null
+++ b/common/StringVector.cpp
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "StringVector.hpp"
+
+StringVector::StringVector() = default;
+
+StringVector::StringVector(const std::vector<std::string>& vector) { _vector = vector; }
+
+std::string StringVector::operator[](size_t index) const
+{
+ if (index >= _vector.size())
+ {
+ return std::string();
+ }
+
+ return _vector[index];
+}
+
+size_t StringVector::size() const { return _vector.size(); }
+
+bool StringVector::empty() const { return _vector.empty(); }
+
+std::vector<std::string>::const_iterator StringVector::begin() const { return _vector.begin(); }
+
+std::vector<std::string>::iterator StringVector::begin() { return _vector.begin(); }
+
+std::vector<std::string>::const_iterator StringVector::end() const { return _vector.end(); }
+
+std::vector<std::string>::iterator StringVector::end() { return _vector.end(); }
+
+std::vector<std::string>::iterator StringVector::erase(std::vector<std::string>::const_iterator it)
+{
+ return _vector.erase(it);
+}
+
+void StringVector::push_back(const std::string& string) { _vector.push_back(string); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/common/StringVector.hpp b/common/StringVector.hpp
new file mode 100644
index 000000000..346bfabff
--- /dev/null
+++ b/common/StringVector.hpp
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_STRINGVECTOR_HPP
+#define INCLUDED_STRINGVECTOR_HPP
+
+#include <string>
+#include <vector>
+
+/**
+ * Safe wrapper around an std::vector<std::string>. Gives you an empty string if you would read past
+ * the ends of the vector.
+ */
+class StringVector
+{
+ std::vector<std::string> _vector;
+
+public:
+ explicit StringVector();
+
+ explicit StringVector(const std::vector<std::string>& vector);
+
+ /// Unlike std::vector, gives an empty string if index is unexpected.
+ std::string operator[](size_t index) const;
+
+ size_t size() const;
+
+ bool empty() const;
+
+ std::vector<std::string>::const_iterator begin() const;
+
+ std::vector<std::string>::iterator begin();
+
+ std::vector<std::string>::const_iterator end() const;
+
+ std::vector<std::string>::iterator end();
+
+ std::vector<std::string>::iterator erase(std::vector<std::string>::const_iterator it);
+
+ void push_back(const std::string& string);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/common/Util.cpp b/common/Util.cpp
index f9df08f2f..9a2273eaf 100644
--- a/common/Util.cpp
+++ b/common/Util.cpp
@@ -245,7 +245,7 @@ namespace Util
}
}
- int spawnProcess(const std::string &cmd, const std::vector<std::string> &args, const std::vector<int>* fdsToKeep, int *stdInput)
+ int spawnProcess(const std::string &cmd, const StringVector &args, const std::vector<int>* fdsToKeep, int *stdInput)
{
int pipeFds[2] = { -1, -1 };
if (stdInput)
diff --git a/common/Util.hpp b/common/Util.hpp
index 991b548ef..52043692f 100644
--- a/common/Util.hpp
+++ b/common/Util.hpp
@@ -38,6 +38,8 @@
#define LOK_USE_UNSTABLE_API
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <StringVector.hpp>
+
namespace Util
{
namespace rng
@@ -68,7 +70,7 @@ namespace Util
/// Spawn a process if stdInput is non-NULL it contains a writable descriptor
/// to send data to the child.
- int spawnProcess(const std::string &cmd, const std::vector<std::string> &args,
+ int spawnProcess(const std::string &cmd, const StringVector &args,
const std::vector<int>* fdsToKeep = nullptr, int *stdInput = nullptr);
#endif
diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index 83acd082f..13bc1d8e4 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -106,7 +106,7 @@ bool ChildSession::_handleInput(const char *buffer, int length)
{
LOG_TRC(getName() << ": handling [" << getAbbreviatedMessage(buffer, length) << "].");
const std::string firstLine = getFirstLine(buffer, length);
- const std::vector<std::string> tokens = LOOLProtocol::tokenize(firstLine.data(), firstLine.size());
+ const StringVector tokens = LOOLProtocol::tokenize(firstLine.data(), firstLine.size());
if (LOOLProtocol::tokenIndicatesUserInteraction(tokens[0]))
{
@@ -368,7 +368,7 @@ bool ChildSession::_handleInput(const char *buffer, int length)
std::vector<std::string> newTokens;
newTokens.push_back(tokens[0]);
newTokens.push_back(firstLine.substr(4)); // Copy the remaining part.
- return unoCommand(buffer, length, newTokens);
+ return unoCommand(buffer, length, StringVector(newTokens));
}
return unoCommand(buffer, length, tokens);
}
@@ -467,7 +467,7 @@ std::string getMimeFromFileType(const std::string & fileType)
return std::string();
}
-bool ChildSession::uploadSignedDocument(const char* buffer, int length, const std::vector<std::string>& /*tokens*/)
+bool ChildSession::uploadSignedDocument(const char* buffer, int length, const StringVector& /*tokens*/)
{
std::string filename;
std::string wopiUrl;
@@ -578,7 +578,7 @@ bool ChildSession::uploadSignedDocument(const char* buffer, int length, const st
#endif
-bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, const StringVector& tokens)
{
int part = -1;
if (tokens.size() < 2)
@@ -660,7 +660,7 @@ bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, const s
return true;
}
-bool ChildSession::sendFontRendering(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::sendFontRendering(const char* /*buffer*/, int /*length*/, const StringVector& tokens)
{
std::string font, text, decodedFont, decodedChar;
bool bSuccess;
@@ -774,7 +774,7 @@ void insertUserNames(const std::map<int, UserInfo>& viewInfo, std::string& json)
}
-bool ChildSession::getCommandValues(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::getCommandValues(const char* /*buffer*/, int /*length*/, const StringVector& tokens)
{
bool success;
char* values;
@@ -813,7 +813,7 @@ bool ChildSession::getCommandValues(const char* /*buffer*/, int /*length*/, cons
return success;
}
-bool ChildSession::clientZoom(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::clientZoom(const char* /*buffer*/, int /*length*/, const StringVector& tokens)
{
int tilePixelWidth, tilePixelHeight, tileTwipWidth, tileTwipHeight;
@@ -833,7 +833,7 @@ bool ChildSession::clientZoom(const char* /*buffer*/, int /*length*/, const std:
return true;
}
-bool ChildSession::clientVisibleArea(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::clientVisibleArea(const char* /*buffer*/, int /*length*/, const StringVector& tokens)
{
int x;
int y;
@@ -856,7 +856,7 @@ bool ChildSession::clientVisibleArea(const char* /*buffer*/, int /*length*/, con
return true;
}
-bool ChildSession::outlineState(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::outlineState(const char* /*buffer*/, int /*length*/, const StringVector& tokens)
{
std::string type, state;
int level, index;
@@ -882,7 +882,7 @@ bool ChildSession::outlineState(const char* /*buffer*/, int /*length*/, const st
return true;
}
-bool ChildSession::downloadAs(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::downloadAs(const char* /*buffer*/, int /*length*/, const StringVector& tokens)
{
std::string name, id, format, filterOptions;
@@ -966,7 +966,7 @@ std::string ChildSession::getTextSelectionInternal(const std::string& mimeType)
return str;
}
-bool ChildSession::getTextSelection(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::getTextSelection(const char* /*buffer*/, int /*length*/, const StringVector& tokens)
{
std::string mimeType;
@@ -1006,7 +1006,7 @@ bool ChildSession::getTextSelection(const char* /*buffer*/, int /*length*/, cons
return true;
}
-bool ChildSession::getClipboard(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::getClipboard(const char* /*buffer*/, int /*length*/, const StringVector& tokens)
{
const char **pMimeTypes = nullptr; // fetch all for now.
const char *pOneType[2];
@@ -1068,7 +1068,7 @@ bool ChildSession::getClipboard(const char* /*buffer*/, int /*length*/, const st
return true;
}
-bool ChildSession::setClipboard(const char* buffer, int length, const std::vector<std::string>& /* tokens */)
+bool ChildSession::setClipboard(const char* buffer, int length, const StringVector& /* tokens */)
{
try {
ClipboardData data;
@@ -1107,7 +1107,7 @@ bool ChildSession::setClipboard(const char* buffer, int length, const std::vecto
return false;
}
-bool ChildSession::paste(const char* buffer, int length, const std::vector<std::string>& tokens)
+bool ChildSession::paste(const char* buffer, int length, const StringVector& tokens)
{
std::string mimeType;
if (tokens.size() < 2 || !getTokenString(tokens[1], "mimetype", mimeType) ||
@@ -1151,7 +1151,7 @@ bool ChildSession::paste(const char* buffer, int length, const std::vector<std::
return true;
}
-bool ChildSession::insertFile(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list