mirror of
https://github.com/weechat/weechat.git
synced 2026-06-25 12:26:40 +02:00
Compare commits
60 Commits
parse-integers
...
4.6
| Author | SHA1 | Date | |
|---|---|---|---|
| 6330ec76e0 | |||
| bc3f14eacb | |||
| f07a63755c | |||
| c6f30816dd | |||
| c55b5836f0 | |||
| e93db7f99d | |||
| 22ee76cdd6 | |||
| cf2d0733d3 | |||
| 75b72e7f69 | |||
| 03a6d9306a | |||
| 398cfc473a | |||
| e5df225d9f | |||
| f5fa814fa4 | |||
| 34cbe56a6f | |||
| a17a80f1d0 | |||
| 405707d544 | |||
| 2a272a7543 | |||
| d4b15ea432 | |||
| 3a954405d7 | |||
| 42ae480f0a | |||
| f4fe63c312 | |||
| 68b017935a | |||
| 97ceefd183 | |||
| 7a757d94c0 | |||
| f07d439cec | |||
| 3f670d31fe | |||
| 558087325d | |||
| 3766d52bd3 | |||
| 2df0b3e2c3 | |||
| c1115c04d5 | |||
| e6d850daa0 | |||
| a0ffb9e5dd | |||
| 95a940294e | |||
| d49c6515e4 | |||
| 2f375b652b | |||
| 8a024dddad | |||
| 951c030082 | |||
| 5def4f72fe | |||
| 3db2f71112 | |||
| 09917a807b | |||
| 334f88ae2c | |||
| 2e14645691 | |||
| 2c0bbdf9b9 | |||
| 5839df90e7 | |||
| 6082453002 | |||
| d0568dce79 | |||
| 00a873dda0 | |||
| 18e2badfbd | |||
| 120b048efb | |||
| 600e438b90 | |||
| bf3a8628ae | |||
| 1478ecd77d | |||
| 5c9d9bc8fc | |||
| ff00323363 | |||
| 1d2e5ce700 | |||
| 2eebe241ab | |||
| e93cebf02c | |||
| c3db4946b2 | |||
| 86d4da2fd1 | |||
| e39ef93903 |
@@ -92,7 +92,7 @@ env:
|
|||||||
ruby
|
ruby
|
||||||
rubygem-asciidoctor
|
rubygem-asciidoctor
|
||||||
sudo
|
sudo
|
||||||
tcl87
|
tcl86
|
||||||
zstd
|
zstd
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -163,7 +163,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
RELAY_PASSWORD: test
|
RELAY_PASSWORD: test
|
||||||
run: |
|
run: |
|
||||||
pipx install schemathesis
|
pipx install schemathesis==3.39.16
|
||||||
weechat-headless \
|
weechat-headless \
|
||||||
--dir /tmp/weechat-test-api \
|
--dir /tmp/weechat-test-api \
|
||||||
--run-command '/set relay.network.password "${{ env.RELAY_PASSWORD }}"' \
|
--run-command '/set relay.network.password "${{ env.RELAY_PASSWORD }}"' \
|
||||||
|
|||||||
@@ -1,5 +1,57 @@
|
|||||||
# WeeChat ChangeLog
|
# WeeChat ChangeLog
|
||||||
|
|
||||||
|
## Version 4.6.4 (under dev)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- core: add support of specifier `%@` for UTC time in function util_strftimeval
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- core: fix buffer overflow in connection to SOCKS5 proxy ([#2325](https://github.com/weechat/weechat/issues/2325))
|
||||||
|
- api: fix infinite loop in function string_replace when the search string is empty
|
||||||
|
- irc: limit size of data received from the server to prevent memory exhaustion
|
||||||
|
- irc: fix out-of-bounds read on incoming DCC command with a quoted filename ending the message ([#2322](https://github.com/weechat/weechat/issues/2322))
|
||||||
|
- relay: limit size of received websocket frame and HTTP body to prevent memory exhaustion
|
||||||
|
- relay: fix timing attack on password authentication ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc), [CVE-2026-53525](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53525))
|
||||||
|
- api, relay: fix timing attack on TOTP validation ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc), [CVE-2026-53525](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53525))
|
||||||
|
- relay: limit size of decompressed websocket frame with permessage-deflate to prevent memory exhaustion ([GHSA-v2v4-45wm-5cr3](https://github.com/weechat/weechat/security/advisories/GHSA-v2v4-45wm-5cr3), [CVE-2026-53524](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53524))
|
||||||
|
- relay/weechat: fix empty buffers in client when WeeChat is running on Solaris/illumos
|
||||||
|
- relay: limit size of partial message received while reading an HTTP request to prevent memory exhaustion
|
||||||
|
- relay: fix out-of-bounds read in dump of data ([#2324](https://github.com/weechat/weechat/issues/2324))
|
||||||
|
- xfer: replace directory separator in remote nick by underscore in download filename to prevent writing the file outside the download directory ([#2321](https://github.com/weechat/weechat/issues/2321))
|
||||||
|
- xfer: fix out-of-bounds read when receiving empty line in DCC chat ([#2323](https://github.com/weechat/weechat/issues/2323))
|
||||||
|
- xfer: fix out-of-bounds write in xfer file transfer resume ([#2326](https://github.com/weechat/weechat/issues/2326))
|
||||||
|
- build: fix build on Solaris/illumos (issue #2251)
|
||||||
|
|
||||||
|
## Version 4.6.3 (2025-05-11)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- core: fix integer overflow with decimal numbers in calculation of expression
|
||||||
|
- core: fix integer overflow in base32 encoding/decoding
|
||||||
|
- core: fix integer overflow in function util_version_number
|
||||||
|
- core: fix buffer overflow in function util_parse_time
|
||||||
|
- core: fix buffer overflow in function eval_syntax_highlight_colorize
|
||||||
|
- core: fix buffer overflow in function eval_string_base_encode
|
||||||
|
- core: fix buffer overflow in function eval_string_range_chars
|
||||||
|
- core: fix memory leak in function util_parse_delay
|
||||||
|
|
||||||
|
## Version 4.6.2 (2025-04-18)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- core: fix write of weechat.log to stdout with `weechat-headless --stdout` ([#2247](https://github.com/weechat/weechat/issues/2247))
|
||||||
|
- core: add refresh of window title on buffer switch, when option weechat.look.window_title is set
|
||||||
|
|
||||||
|
## Version 4.6.1 (2025-04-09)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- core: consider all keys are safe in cursor context ([#2244](https://github.com/weechat/weechat/issues/2244))
|
||||||
|
- irc: display nick changes and quit messages when option irc.look.ignore_tag_messages is enabled ([#2241](https://github.com/weechat/weechat/issues/2241))
|
||||||
|
- perl: fix build when multiplicity is not available ([#2243](https://github.com/weechat/weechat/issues/2243))
|
||||||
|
|
||||||
## Version 4.6.0 (2025-03-23)
|
## Version 4.6.0 (2025-03-23)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ include(FindPkgConfig)
|
|||||||
include(CheckIncludeFiles)
|
include(CheckIncludeFiles)
|
||||||
include(CheckFunctionExists)
|
include(CheckFunctionExists)
|
||||||
include(CheckSymbolExists)
|
include(CheckSymbolExists)
|
||||||
|
include(CheckLibraryExists)
|
||||||
|
|
||||||
check_include_files("langinfo.h" HAVE_LANGINFO_CODESET)
|
check_include_files("langinfo.h" HAVE_LANGINFO_CODESET)
|
||||||
check_include_files("sys/resource.h" HAVE_SYS_RESOURCE_H)
|
check_include_files("sys/resource.h" HAVE_SYS_RESOURCE_H)
|
||||||
@@ -208,13 +209,33 @@ check_symbol_exists("malloc_trim" "malloc.h" HAVE_MALLOC_TRIM)
|
|||||||
check_function_exists(mallinfo HAVE_MALLINFO)
|
check_function_exists(mallinfo HAVE_MALLINFO)
|
||||||
check_function_exists(mallinfo2 HAVE_MALLINFO2)
|
check_function_exists(mallinfo2 HAVE_MALLINFO2)
|
||||||
|
|
||||||
|
check_symbol_exists("htonll" "sys/types.h;netinet/in.h;inttypes.h" HAVE_HTONLL)
|
||||||
|
|
||||||
check_symbol_exists("eat_newline_glitch" "term.h" HAVE_EAT_NEWLINE_GLITCH)
|
check_symbol_exists("eat_newline_glitch" "term.h" HAVE_EAT_NEWLINE_GLITCH)
|
||||||
|
|
||||||
|
# Check if res_init requires libresolv
|
||||||
|
check_function_exists(res_init, LIBC_HAS_RES_INIT)
|
||||||
|
if(NOT LIBC_HAS_RES_INIT)
|
||||||
|
find_library(RESOLV_LIBRARY resolv)
|
||||||
|
if(RESOLV_LIBRARY)
|
||||||
|
check_library_exists("${RESOLV_LIBRARY}" res_init "" LIBRESOLV_HAS_RES_INIT)
|
||||||
|
if(LIBRESOLV_HAS_RES_INIT)
|
||||||
|
list(APPEND EXTRA_LIBS ${RESOLV_LIBRARY})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Check for Large File Support
|
# Check for Large File Support
|
||||||
if(ENABLE_LARGEFILE)
|
if(ENABLE_LARGEFILE)
|
||||||
add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D_LARGE_FILES)
|
add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D_LARGE_FILES)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# _XPG4_2 is needed for macros like CMSG_SPACE
|
||||||
|
# __EXTENSIONS__ is needed for constants like NI_MAXHOST and for struct timeval
|
||||||
|
if(CMAKE_HOST_SOLARIS)
|
||||||
|
add_definitions(-D_XPG4_2 -D__EXTENSIONS__)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Check for libgcrypt
|
# Check for libgcrypt
|
||||||
pkg_check_modules(LIBGCRYPT REQUIRED libgcrypt)
|
pkg_check_modules(LIBGCRYPT REQUIRED libgcrypt)
|
||||||
include_directories(${LIBGCRYPT_INCLUDE_DIRS})
|
include_directories(${LIBGCRYPT_INCLUDE_DIRS})
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ When upgrading from version X to Y, please read and apply all instructions from
|
|||||||
|
|
||||||
For a list of all changes in each version, please see [CHANGELOG.md](CHANGELOG.md).
|
For a list of all changes in each version, please see [CHANGELOG.md](CHANGELOG.md).
|
||||||
|
|
||||||
|
## Version 4.6.3
|
||||||
|
|
||||||
|
### API function util_version_number
|
||||||
|
|
||||||
|
An integer overflow has been fixed in the function
|
||||||
|
[util_version_number](https://weechat.org/doc/weechat/plugin/#_util_version_number)
|
||||||
|
which now returns a version up to "127.255.255.255" (0x7FFFFFFF).
|
||||||
|
|
||||||
## Version 4.6.0
|
## Version 4.6.0
|
||||||
|
|
||||||
### Relay remote commands
|
### Relay remote commands
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2003-2025 Sébastien Helleu <flashcode@flashtux.org>
|
|
||||||
# Copyright (C) 2009 Julien Louis <ptitlouis@sysif.net>
|
|
||||||
#
|
|
||||||
# This file is part of WeeChat, the extensible chat client.
|
|
||||||
#
|
|
||||||
# WeeChat is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
|
|
||||||
# - Find Python
|
|
||||||
# This module finds if Python is installed and determines where the include files
|
|
||||||
# and libraries are. It also determines what the name of the library is. This
|
|
||||||
# code sets the following variables:
|
|
||||||
#
|
|
||||||
# PYTHON_EXECUTABLE = full path to the python binary
|
|
||||||
# PYTHON_INCLUDE_DIRS = path to where python.h can be found
|
|
||||||
# PYTHON_LIBRARIES = path to where libpython.so* can be found
|
|
||||||
# PYTHON_LDFLAGS = python compiler options for linking
|
|
||||||
|
|
||||||
pkg_check_modules(PYTHON python3-embed IMPORTED_TARGET GLOBAL)
|
|
||||||
if(NOT PYTHON_FOUND)
|
|
||||||
pkg_check_modules(PYTHON python3 IMPORTED_TARGET GLOBAL)
|
|
||||||
endif()
|
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
#cmakedefine HAVE_MALLINFO2
|
#cmakedefine HAVE_MALLINFO2
|
||||||
#cmakedefine HAVE_MALLOC_H
|
#cmakedefine HAVE_MALLOC_H
|
||||||
#cmakedefine HAVE_MALLOC_TRIM
|
#cmakedefine HAVE_MALLOC_TRIM
|
||||||
|
#cmakedefine HAVE_HTONLL
|
||||||
#cmakedefine HAVE_EAT_NEWLINE_GLITCH
|
#cmakedefine HAVE_EAT_NEWLINE_GLITCH
|
||||||
#cmakedefine HAVE_ASPELL_VERSION_STRING
|
#cmakedefine HAVE_ASPELL_VERSION_STRING
|
||||||
#cmakedefine HAVE_ENCHANT_GET_VERSION
|
#cmakedefine HAVE_ENCHANT_GET_VERSION
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ Build-Depends:
|
|||||||
libzstd-dev,
|
libzstd-dev,
|
||||||
zlib1g-dev,
|
zlib1g-dev,
|
||||||
libcjson-dev
|
libcjson-dev
|
||||||
Standards-Version: 4.7.0
|
Standards-Version: 4.7.2
|
||||||
Homepage: https://weechat.org/
|
Homepage: https://weechat.org/
|
||||||
Vcs-Git: https://salsa.debian.org/kolter/weechat.git
|
Vcs-Git: https://salsa.debian.org/kolter/weechat.git
|
||||||
Vcs-Browser: https://salsa.debian.org/kolter/weechat
|
Vcs-Browser: https://salsa.debian.org/kolter/weechat
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
weechat (4.6.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release (Closes: #1102450, #1098090)
|
||||||
|
|
||||||
|
-- Emmanuel Bouthenot <kolter@debian.org> Wed, 16 Apr 2025 20:31:07 +0000
|
||||||
|
|
||||||
weechat (4.5.1-1) unstable; urgency=medium
|
weechat (4.5.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
* New upstream release
|
* New upstream release
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ Build-Depends:
|
|||||||
libzstd-dev,
|
libzstd-dev,
|
||||||
zlib1g-dev,
|
zlib1g-dev,
|
||||||
libcjson-dev
|
libcjson-dev
|
||||||
Standards-Version: 4.7.0
|
Standards-Version: 4.7.2
|
||||||
Homepage: https://weechat.org/
|
Homepage: https://weechat.org/
|
||||||
Vcs-Git: https://salsa.debian.org/kolter/weechat.git
|
Vcs-Git: https://salsa.debian.org/kolter/weechat.git
|
||||||
Vcs-Browser: https://salsa.debian.org/kolter/weechat
|
Vcs-Browser: https://salsa.debian.org/kolter/weechat
|
||||||
|
|||||||
@@ -4762,7 +4762,7 @@ This function is not available in scripting API.
|
|||||||
|
|
||||||
==== util_strftimeval
|
==== util_strftimeval
|
||||||
|
|
||||||
_WeeChat ≥ 4.2.0, updated in 4.3.0._
|
_WeeChat ≥ 4.2.0, updated in 4.3.0, 4.6.4._
|
||||||
|
|
||||||
Format date and time like function `strftime` in C library, using `struct timeval`
|
Format date and time like function `strftime` in C library, using `struct timeval`
|
||||||
as input, and supporting extra specifiers.
|
as input, and supporting extra specifiers.
|
||||||
@@ -4779,6 +4779,8 @@ Arguments:
|
|||||||
* _string_: buffer where the formatted string is stored
|
* _string_: buffer where the formatted string is stored
|
||||||
* _max_: string size
|
* _max_: string size
|
||||||
* _format_: format, the same as _strftime_ function, with these extra specifiers:
|
* _format_: format, the same as _strftime_ function, with these extra specifiers:
|
||||||
|
** `%@`: return the date expressed in Coordinated Universal Time (UTC)
|
||||||
|
instead of date relative to the user's specified timezone _(WeeChat ≥ 4.7.0)_
|
||||||
** `%.N` where `N` is between 1 and 6: zero-padded microseconds on N digits
|
** `%.N` where `N` is between 1 and 6: zero-padded microseconds on N digits
|
||||||
(for example `%.3` for milliseconds)
|
(for example `%.3` for milliseconds)
|
||||||
** `%f`: alias of `%.6`
|
** `%f`: alias of `%.6`
|
||||||
@@ -4795,8 +4797,8 @@ C example:
|
|||||||
char time[256];
|
char time[256];
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday (&tv, NULL);
|
gettimeofday (&tv, NULL);
|
||||||
weechat_util_strftimeval (time, sizeof (time), "%FT%T.%f", &tv);
|
weechat_util_strftimeval (time, sizeof (time), "%@%FT%T.%fZ", &tv);
|
||||||
/* result: 2023-12-26T18:10:04.460509 */
|
/* result: 2023-12-26T18:10:04.460509Z */
|
||||||
----
|
----
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
@@ -15528,8 +15530,8 @@ void weechat_window_set_title (const char *title);
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
* _title_: new title for terminal (NULL to reset title); string is evaluated,
|
* _title_: new title for terminal; string is evaluated, so variables like
|
||||||
so variables like `${info:version}` can be used
|
`${info:version}` can be used
|
||||||
(see <<_string_eval_expression,string_eval_expression>>)
|
(see <<_string_eval_expression,string_eval_expression>>)
|
||||||
|
|
||||||
C example:
|
C example:
|
||||||
|
|||||||
@@ -4841,7 +4841,7 @@ Cette fonction n'est pas disponible dans l'API script.
|
|||||||
|
|
||||||
==== util_strftimeval
|
==== util_strftimeval
|
||||||
|
|
||||||
_WeeChat ≥ 4.2.0, mis à jour dans la 4.3.0._
|
_WeeChat ≥ 4.2.0, mis à jour dans la 4.3.0, 4.6.4._
|
||||||
|
|
||||||
Formatter la date et l'heure comme la fonction `strftime` de la bibliothèque C,
|
Formatter la date et l'heure comme la fonction `strftime` de la bibliothèque C,
|
||||||
en utilisant un `struct timeval` en entrée et en supportant des caractères de
|
en utilisant un `struct timeval` en entrée et en supportant des caractères de
|
||||||
@@ -4860,6 +4860,8 @@ Paramètres :
|
|||||||
* _max_ : taille de la chaîne
|
* _max_ : taille de la chaîne
|
||||||
* _format_ : format, le même que celui de la fonction _strftime_, avec des
|
* _format_ : format, le même que celui de la fonction _strftime_, avec des
|
||||||
caractères de conversion supplémentaires :
|
caractères de conversion supplémentaires :
|
||||||
|
** `%@` : retourner la date exprimée en Temps Universel Coordonné (UTC)
|
||||||
|
au lieu de la date relative au fuseau horaire de l'utilisateur _(WeeChat ≥ 4.7.0)_
|
||||||
** `%.N` où `N` est entre 1 and 6: microsecondes remplies avec des zéros sur
|
** `%.N` où `N` est entre 1 and 6: microsecondes remplies avec des zéros sur
|
||||||
N chiffres (par exemple `%.3` pour les millisecondes)
|
N chiffres (par exemple `%.3` pour les millisecondes)
|
||||||
** `%f` : alias de `%.6`
|
** `%f` : alias de `%.6`
|
||||||
@@ -4876,8 +4878,8 @@ Exemple en C :
|
|||||||
char time[256];
|
char time[256];
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday (&tv, NULL);
|
gettimeofday (&tv, NULL);
|
||||||
weechat_util_strftimeval (time, sizeof (time), "%FT%T.%f", &tv);
|
weechat_util_strftimeval (time, sizeof (time), "%@%FT%T.%fZ", &tv);
|
||||||
/* résultat : 2023-12-26T18:10:04.460509 */
|
/* résultat : 2023-12-26T18:10:04.460509Z */
|
||||||
----
|
----
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
@@ -15869,9 +15871,9 @@ void weechat_window_set_title (const char *title);
|
|||||||
|
|
||||||
Paramètres :
|
Paramètres :
|
||||||
|
|
||||||
* _title_ : nouveau titre pour le terminal (NULL pour réinitialiser le titre) ;
|
* _title_ : nouveau titre pour le terminal ; la chaîne est évaluée, donc les variables
|
||||||
la chaîne est évaluée, donc les variables comme `${info:version}` peuvent
|
comme `${info:version}` peuvent être utilisées
|
||||||
être utilisées (voir <<_string_eval_expression,string_eval_expression>>)
|
(voir <<_string_eval_expression,string_eval_expression>>)
|
||||||
|
|
||||||
Exemple en C :
|
Exemple en C :
|
||||||
|
|
||||||
|
|||||||
@@ -4985,7 +4985,7 @@ Questa funzione non è disponibile nelle API per lo scripting.
|
|||||||
// TRANSLATION MISSING
|
// TRANSLATION MISSING
|
||||||
==== util_strftimeval
|
==== util_strftimeval
|
||||||
|
|
||||||
_WeeChat ≥ 4.2.0, updated in 4.3.0._
|
_WeeChat ≥ 4.2.0, updated in 4.3.0, 4.6.4._
|
||||||
|
|
||||||
Format date and time like function `strftime` in C library, using `struct timeval`
|
Format date and time like function `strftime` in C library, using `struct timeval`
|
||||||
as input, and supporting extra specifiers.
|
as input, and supporting extra specifiers.
|
||||||
@@ -5002,6 +5002,8 @@ Arguments:
|
|||||||
* _string_: buffer where the formatted string is stored
|
* _string_: buffer where the formatted string is stored
|
||||||
* _max_: string size
|
* _max_: string size
|
||||||
* _format_: format, the same as _strftime_ function, with these extra specifiers:
|
* _format_: format, the same as _strftime_ function, with these extra specifiers:
|
||||||
|
** `%@`: return the date expressed in Coordinated Universal Time (UTC)
|
||||||
|
instead of date relative to the user's specified timezone _(WeeChat ≥ 4.7.0)_
|
||||||
** `%.N` where `N` is between 1 and 6: zero-padded microseconds on N digits
|
** `%.N` where `N` is between 1 and 6: zero-padded microseconds on N digits
|
||||||
(for example `%.3` for milliseconds)
|
(for example `%.3` for milliseconds)
|
||||||
** `%f`: alias of `%.6`
|
** `%f`: alias of `%.6`
|
||||||
@@ -5018,8 +5020,8 @@ C example:
|
|||||||
char time[256];
|
char time[256];
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday (&tv, NULL);
|
gettimeofday (&tv, NULL);
|
||||||
weechat_util_strftimeval (time, sizeof (time), "%FT%T.%f", &tv);
|
weechat_util_strftimeval (time, sizeof (time), "%@%FT%T.%fZ", &tv);
|
||||||
/* result: 2023-12-26T18:10:04.460509 */
|
/* result: 2023-12-26T18:10:04.460509Z */
|
||||||
----
|
----
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
@@ -16302,8 +16304,8 @@ void weechat_window_set_title (const char *title);
|
|||||||
Argomenti:
|
Argomenti:
|
||||||
|
|
||||||
// TRANSLATION MISSING
|
// TRANSLATION MISSING
|
||||||
* _title_: nuovo titolo per il terminale (NULL per resettarlo);
|
* _title_: nuovo titolo per il terminale; string is evaluated, so variables
|
||||||
string is evaluated, so variables like `${info:version}` can be used
|
like `${info:version}` can be used
|
||||||
(see <<_string_eval_expression,string_eval_expression>>)
|
(see <<_string_eval_expression,string_eval_expression>>)
|
||||||
|
|
||||||
Esempio in C:
|
Esempio in C:
|
||||||
|
|||||||
@@ -4898,7 +4898,7 @@ weechat_printf (NULL, "date: %s",
|
|||||||
// TRANSLATION MISSING
|
// TRANSLATION MISSING
|
||||||
==== util_strftimeval
|
==== util_strftimeval
|
||||||
|
|
||||||
_WeeChat ≥ 4.2.0, updated in 4.3.0._
|
_WeeChat ≥ 4.2.0, updated in 4.3.0, 4.6.4._
|
||||||
|
|
||||||
Format date and time like function `strftime` in C library, using `struct timeval`
|
Format date and time like function `strftime` in C library, using `struct timeval`
|
||||||
as input, and supporting extra specifiers.
|
as input, and supporting extra specifiers.
|
||||||
@@ -4915,6 +4915,8 @@ Arguments:
|
|||||||
* _string_: buffer where the formatted string is stored
|
* _string_: buffer where the formatted string is stored
|
||||||
* _max_: string size
|
* _max_: string size
|
||||||
* _format_: format, the same as _strftime_ function, with these extra specifiers:
|
* _format_: format, the same as _strftime_ function, with these extra specifiers:
|
||||||
|
** `%@`: return the date expressed in Coordinated Universal Time (UTC)
|
||||||
|
instead of date relative to the user's specified timezone _(WeeChat ≥ 4.7.0)_
|
||||||
** `%.N` where `N` is between 1 and 6: zero-padded microseconds on N digits
|
** `%.N` where `N` is between 1 and 6: zero-padded microseconds on N digits
|
||||||
(for example `%.3` for milliseconds)
|
(for example `%.3` for milliseconds)
|
||||||
** `%f`: alias of `%.6`
|
** `%f`: alias of `%.6`
|
||||||
@@ -4931,8 +4933,8 @@ C example:
|
|||||||
char time[256];
|
char time[256];
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday (&tv, NULL);
|
gettimeofday (&tv, NULL);
|
||||||
weechat_util_strftimeval (time, sizeof (time), "%FT%T.%f", &tv);
|
weechat_util_strftimeval (time, sizeof (time), "%@%FT%T.%fZ", &tv);
|
||||||
/* result: 2023-12-26T18:10:04.460509 */
|
/* result: 2023-12-26T18:10:04.460509Z */
|
||||||
----
|
----
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
@@ -15797,8 +15799,8 @@ void weechat_window_set_title (const char *title);
|
|||||||
|
|
||||||
引数:
|
引数:
|
||||||
|
|
||||||
* _title_: 端末の新しいタイトル (タイトルをリセットする場合は NULL);
|
* _title_: 端末の新しいタイトル; この文字列は評価されるため、文字列内に
|
||||||
この文字列は評価されるため、文字列内に `${info:version}` などの変数を含めることが可能です
|
`${info:version}` などの変数を含めることが可能です
|
||||||
(<<_string_eval_expression,string_eval_expression>> を参照)
|
(<<_string_eval_expression,string_eval_expression>> を参照)
|
||||||
|
|
||||||
C 言語での使用例:
|
C 言語での使用例:
|
||||||
|
|||||||
@@ -4624,7 +4624,7 @@ weechat_printf (NULL, "date: %s",
|
|||||||
|
|
||||||
==== util_strftimeval
|
==== util_strftimeval
|
||||||
|
|
||||||
_WeeChat ≥ 4.2.0, ажурирано у 4.3.0._
|
_WeeChat ≥ 4.2.0, ажурирано у 4.3.0, 4.6.4._
|
||||||
|
|
||||||
Форматира датум и време као функција `strftime` из C библиотеке, користећи `struct timeval`
|
Форматира датум и време као функција `strftime` из C библиотеке, користећи `struct timeval`
|
||||||
као улаз уз подршку за додатне спецификаторе.
|
као улаз уз подршку за додатне спецификаторе.
|
||||||
@@ -4641,6 +4641,9 @@ int weechat_util_strftimeval (char *string, int max, const char *format, struct
|
|||||||
* _string_: бафер у који се смешта форматирани стринг
|
* _string_: бафер у који се смешта форматирани стринг
|
||||||
* _max_: величина стринга
|
* _max_: величина стринга
|
||||||
* _format_: формат, исто као за _strftime_ функцију, са следећим додатним спецификаторима:
|
* _format_: формат, исто као за _strftime_ функцију, са следећим додатним спецификаторима:
|
||||||
|
// TRANSLATION MISSING
|
||||||
|
** `%@`: return the date expressed in Coordinated Universal Time (UTC)
|
||||||
|
instead of date relative to the user's specified timezone _(WeeChat ≥ 4.7.0)_
|
||||||
** `%.N` где је `N` између 1 и 6: микросекунде допуњене нулама на N цифара
|
** `%.N` где је `N` између 1 и 6: микросекунде допуњене нулама на N цифара
|
||||||
(на пример `%.3` за милисекунде)
|
(на пример `%.3` за милисекунде)
|
||||||
** `%f`: алијас за `%.6`
|
** `%f`: алијас за `%.6`
|
||||||
@@ -4657,8 +4660,8 @@ C пример:
|
|||||||
char time[256];
|
char time[256];
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday (&tv, NULL);
|
gettimeofday (&tv, NULL);
|
||||||
weechat_util_strftimeval (time, sizeof (time), "%FT%T.%f", &tv);
|
weechat_util_strftimeval (time, sizeof (time), "%@%FT%T.%fZ", &tv);
|
||||||
/* резултат: 2023-12-26T18:10:04.460509 */
|
/* резултат: 2023-12-26T18:10:04.460509Z */
|
||||||
----
|
----
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
@@ -15104,7 +15107,9 @@ void weechat_window_set_title (const char *title);
|
|||||||
|
|
||||||
Аргументи:
|
Аргументи:
|
||||||
|
|
||||||
* _title_: нови наслов за терминал (NULL ако желите да ресетујете наслов); стринг се израчунава, тако да је могуће коришћење променљивих као што је `${info:version}` (погледајте <<_string_eval_expression,string_eval_expression>>)
|
* _title_: нови наслов за терминал; стринг се израчунава, тако да је могуће
|
||||||
|
коришћење променљивих као што је `${info:version}`
|
||||||
|
(погледајте <<_string_eval_expression,string_eval_expression>>)
|
||||||
|
|
||||||
C пример:
|
C пример:
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -79,8 +79,7 @@ foreach(pofile ${PO_FILES})
|
|||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT "${mofile}"
|
OUTPUT "${mofile}"
|
||||||
COMMAND "${MSGMERGE_EXECUTABLE}" ARGS --quiet -o "${CMAKE_CURRENT_BINARY_DIR}/${pofile}" "${CMAKE_CURRENT_SOURCE_DIR}/${pofile}" ${POT_FILE_PATH}
|
COMMAND "${MSGMERGE_EXECUTABLE}" ARGS --quiet -o "${CMAKE_CURRENT_BINARY_DIR}/${pofile}" "${CMAKE_CURRENT_SOURCE_DIR}/${pofile}" ${POT_FILE_PATH}
|
||||||
COMMAND "${MSGFMT_EXECUTABLE}" ARGS -o "${mofile}" "${CMAKE_CURRENT_BINARY_DIR}/${pofile}"
|
COMMAND "${MSGFMT_EXECUTABLE}" ARGS -c --statistics --verbose -o "${mofile}" "${CMAKE_CURRENT_BINARY_DIR}/${pofile}"
|
||||||
COMMAND "${MSGFMT_EXECUTABLE}" ARGS -c --statistics --verbose --output-file=/dev/null "${CMAKE_CURRENT_BINARY_DIR}/${pofile}"
|
|
||||||
DEPENDS "${POT_FILE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/${pofile}"
|
DEPENDS "${POT_FILE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/${pofile}"
|
||||||
COMMENT "Compiling ${polang}.po"
|
COMMENT "Compiling ${polang}.po"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -336,9 +336,9 @@ calc_expression (const char *expr)
|
|||||||
struct t_arraylist *list_values, *list_ops;
|
struct t_arraylist *list_values, *list_ops;
|
||||||
const char *ptr_expr, *ptr_expr2;
|
const char *ptr_expr, *ptr_expr2;
|
||||||
char str_result[64], *ptr_operator, *operator;
|
char str_result[64], *ptr_operator, *operator;
|
||||||
int index_op, decimals;
|
int index_op;
|
||||||
enum t_calc_symbol last_symbol;
|
enum t_calc_symbol last_symbol;
|
||||||
double value, factor, *ptr_value;
|
double value, factor, decimals, *ptr_value;
|
||||||
|
|
||||||
list_values = NULL;
|
list_values = NULL;
|
||||||
list_ops = NULL;
|
list_ops = NULL;
|
||||||
|
|||||||
@@ -498,12 +498,8 @@ config_change_window_title (const void *pointer, void *data,
|
|||||||
(void) data;
|
(void) data;
|
||||||
(void) option;
|
(void) option;
|
||||||
|
|
||||||
if (gui_init_ok
|
if (gui_init_ok)
|
||||||
|| (CONFIG_STRING(config_look_window_title)
|
|
||||||
&& CONFIG_STRING(config_look_window_title)[0]))
|
|
||||||
{
|
|
||||||
gui_window_set_title (CONFIG_STRING(config_look_window_title));
|
gui_window_set_title (CONFIG_STRING(config_look_window_title));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+17
-10
@@ -34,10 +34,18 @@
|
|||||||
/* Bring in htobe64 */
|
/* Bring in htobe64 */
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#define _BSD_SOURCE
|
#define _BSD_SOURCE
|
||||||
|
#define BE_INT64 htobe64
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
#include <libkern/OSByteOrder.h>
|
#include <libkern/OSByteOrder.h>
|
||||||
#define htobe64 OSSwapHostToBigInt64
|
#define BE_INT64 OSSwapHostToBigInt64
|
||||||
|
#elif defined(HAVE_HTONLL)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#define BE_INT64 htonll
|
||||||
|
#else
|
||||||
|
#define BE_INT64 htobe64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "weechat.h"
|
#include "weechat.h"
|
||||||
@@ -47,10 +55,6 @@
|
|||||||
#include "core-string.h"
|
#include "core-string.h"
|
||||||
#include "../plugins/plugin.h"
|
#include "../plugins/plugin.h"
|
||||||
|
|
||||||
#ifdef htonll
|
|
||||||
#define htobe64 htonll
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *weecrypto_hash_algo_string[] = {
|
char *weecrypto_hash_algo_string[] = {
|
||||||
"crc32",
|
"crc32",
|
||||||
"md5",
|
"md5",
|
||||||
@@ -533,7 +537,7 @@ weecrypto_totp_generate_internal (const char *secret, int length_secret,
|
|||||||
int rc, offset, length;
|
int rc, offset, length;
|
||||||
unsigned long bin_code;
|
unsigned long bin_code;
|
||||||
|
|
||||||
moving_factor_swapped = htobe64 (moving_factor);
|
moving_factor_swapped = BE_INT64 (moving_factor);
|
||||||
rc = weecrypto_hmac (secret, length_secret,
|
rc = weecrypto_hmac (secret, length_secret,
|
||||||
&moving_factor_swapped, sizeof (moving_factor_swapped),
|
&moving_factor_swapped, sizeof (moving_factor_swapped),
|
||||||
GCRY_MD_SHA1,
|
GCRY_MD_SHA1,
|
||||||
@@ -658,15 +662,18 @@ weecrypto_totp_validate (const char *secret_base32, time_t totp_time,
|
|||||||
|
|
||||||
otp_ok = 0;
|
otp_ok = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compare in constant time and never break early: a non-constant
|
||||||
|
* compare and an early exit on match would let an observer measure
|
||||||
|
* how many digits of the expected OTP they got right and which
|
||||||
|
* time-window offset matched.
|
||||||
|
*/
|
||||||
for (i = moving_factor - window; i <= moving_factor + window; i++)
|
for (i = moving_factor - window; i <= moving_factor + window; i++)
|
||||||
{
|
{
|
||||||
rc = weecrypto_totp_generate_internal (secret, length_secret,
|
rc = weecrypto_totp_generate_internal (secret, length_secret,
|
||||||
i, digits, str_otp);
|
i, digits, str_otp);
|
||||||
if (rc && (strcmp (str_otp, otp) == 0))
|
if (rc && (string_memcmp_constant_time (str_otp, otp, digits) == 0))
|
||||||
{
|
|
||||||
otp_ok = 1;
|
otp_ok = 1;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free (secret);
|
free (secret);
|
||||||
|
|||||||
+16
-4
@@ -300,6 +300,9 @@ eval_string_range_chars (const char *range)
|
|||||||
string = NULL;
|
string = NULL;
|
||||||
result = NULL;
|
result = NULL;
|
||||||
|
|
||||||
|
if (!range || !range[0])
|
||||||
|
goto end;
|
||||||
|
|
||||||
for (i = 0; eval_range_chars[i][0]; i++)
|
for (i = 0; eval_range_chars[i][0]; i++)
|
||||||
{
|
{
|
||||||
if (strcmp (range, eval_range_chars[i][0]) == 0)
|
if (strcmp (range, eval_range_chars[i][0]) == 0)
|
||||||
@@ -309,11 +312,15 @@ eval_string_range_chars (const char *range)
|
|||||||
char1 = utf8_char_int (range);
|
char1 = utf8_char_int (range);
|
||||||
|
|
||||||
/* next char must be '-' */
|
/* next char must be '-' */
|
||||||
|
if (!range[0])
|
||||||
|
goto end;
|
||||||
ptr_char = utf8_next_char (range);
|
ptr_char = utf8_next_char (range);
|
||||||
if (!ptr_char || !ptr_char[0] || (ptr_char[0] != '-'))
|
if (!ptr_char || !ptr_char[0] || (ptr_char[0] != '-'))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* next char is the char2 */
|
/* next char is the char2 */
|
||||||
|
if (!range[0])
|
||||||
|
goto end;
|
||||||
ptr_char = utf8_next_char (ptr_char);
|
ptr_char = utf8_next_char (ptr_char);
|
||||||
if (!ptr_char || !ptr_char[0])
|
if (!ptr_char || !ptr_char[0])
|
||||||
goto end;
|
goto end;
|
||||||
@@ -894,7 +901,7 @@ eval_string_base_encode (const char *text)
|
|||||||
|
|
||||||
ptr_string++;
|
ptr_string++;
|
||||||
length = strlen (ptr_string);
|
length = strlen (ptr_string);
|
||||||
result = malloc ((length * 4) + 1);
|
result = malloc ((length * 4) + 8 + 1);
|
||||||
if (!result)
|
if (!result)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
@@ -1144,6 +1151,7 @@ char *
|
|||||||
eval_hdata_count (const char *text, struct t_eval_context *eval_context)
|
eval_hdata_count (const char *text, struct t_eval_context *eval_context)
|
||||||
{
|
{
|
||||||
struct t_hdata *hdata;
|
struct t_hdata *hdata;
|
||||||
|
unsigned long ptr_value;
|
||||||
void *pointer;
|
void *pointer;
|
||||||
char *pos1, *pos2, *value, *hdata_name, *pointer_name, str_count[64];
|
char *pos1, *pos2, *value, *hdata_name, *pointer_name, str_count[64];
|
||||||
int rc, count;
|
int rc, count;
|
||||||
@@ -1174,9 +1182,10 @@ eval_hdata_count (const char *text, struct t_eval_context *eval_context)
|
|||||||
|
|
||||||
if (strncmp (pointer_name, "0x", 2) == 0)
|
if (strncmp (pointer_name, "0x", 2) == 0)
|
||||||
{
|
{
|
||||||
rc = sscanf (pointer_name, "%p", &pointer);
|
rc = sscanf (pointer_name, "%lx", &ptr_value);
|
||||||
if ((rc != EOF) && (rc != 0))
|
if ((rc != EOF) && (rc != 0))
|
||||||
{
|
{
|
||||||
|
pointer = (void *)ptr_value;
|
||||||
if (!hdata_check_pointer (hdata, NULL, pointer))
|
if (!hdata_check_pointer (hdata, NULL, pointer))
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -1413,6 +1422,7 @@ eval_string_hdata (const char *text, struct t_eval_context *eval_context)
|
|||||||
void *pointer;
|
void *pointer;
|
||||||
struct t_hdata *hdata;
|
struct t_hdata *hdata;
|
||||||
int rc;
|
int rc;
|
||||||
|
unsigned long ptr;
|
||||||
|
|
||||||
value = NULL;
|
value = NULL;
|
||||||
hdata_name = NULL;
|
hdata_name = NULL;
|
||||||
@@ -1464,9 +1474,10 @@ eval_string_hdata (const char *text, struct t_eval_context *eval_context)
|
|||||||
{
|
{
|
||||||
if (strncmp (pointer_name, "0x", 2) == 0)
|
if (strncmp (pointer_name, "0x", 2) == 0)
|
||||||
{
|
{
|
||||||
rc = sscanf (pointer_name, "%p", &pointer);
|
rc = sscanf (pointer_name, "%lx", &ptr);
|
||||||
if ((rc != EOF) && (rc != 0))
|
if ((rc != EOF) && (rc != 0))
|
||||||
{
|
{
|
||||||
|
pointer = (void *)ptr;
|
||||||
if (!hdata_check_pointer (hdata, NULL, pointer))
|
if (!hdata_check_pointer (hdata, NULL, pointer))
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -1572,7 +1583,8 @@ eval_syntax_highlight_colorize (const char *value)
|
|||||||
else if (ptr_value[0] == '-')
|
else if (ptr_value[0] == '-')
|
||||||
color--;
|
color--;
|
||||||
}
|
}
|
||||||
ptr_value++;
|
if (ptr_value[0])
|
||||||
|
ptr_value++;
|
||||||
if (config_num_eval_syntax_colors > 0)
|
if (config_num_eval_syntax_colors > 0)
|
||||||
{
|
{
|
||||||
string_dyn_concat (
|
string_dyn_concat (
|
||||||
|
|||||||
@@ -1244,10 +1244,10 @@ hdata_set (struct t_hdata *hdata, void *pointer, const char *name,
|
|||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
struct t_hdata_var *var;
|
struct t_hdata_var *var;
|
||||||
void *ptr;
|
|
||||||
char **ptr_string, *error;
|
char **ptr_string, *error;
|
||||||
long number;
|
long number;
|
||||||
long long number_longlong;
|
long long number_longlong;
|
||||||
|
unsigned long ptr;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!hdata->update_pending)
|
if (!hdata->update_pending)
|
||||||
@@ -1307,10 +1307,10 @@ hdata_set (struct t_hdata *hdata, void *pointer, const char *name,
|
|||||||
case WEECHAT_HDATA_POINTER:
|
case WEECHAT_HDATA_POINTER:
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
rc = sscanf (value, "%p", &ptr);
|
rc = sscanf (value, "%lx", &ptr);
|
||||||
if ((rc != EOF) && (rc != 0))
|
if ((rc != EOF) && (rc != 0))
|
||||||
{
|
{
|
||||||
*((void **)(pointer + var->offset)) = ptr;
|
*((void **)(pointer + var->offset)) = (void *)ptr;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-11
@@ -70,21 +70,22 @@ log_open (const char *filename, const char *mode)
|
|||||||
{
|
{
|
||||||
weechat_log_file = stdout;
|
weechat_log_file = stdout;
|
||||||
}
|
}
|
||||||
else if (filename)
|
|
||||||
{
|
|
||||||
weechat_log_filename = strdup (filename);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string_asprintf (&weechat_log_filename,
|
if (filename)
|
||||||
"%s/%s", weechat_state_dir, WEECHAT_LOG_NAME);
|
{
|
||||||
|
weechat_log_filename = strdup (filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string_asprintf (&weechat_log_filename,
|
||||||
|
"%s/%s", weechat_state_dir, WEECHAT_LOG_NAME);
|
||||||
|
}
|
||||||
|
if (!weechat_log_filename)
|
||||||
|
return 0;
|
||||||
|
weechat_log_file = fopen (weechat_log_filename, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!weechat_log_filename)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
weechat_log_file = fopen (weechat_log_filename, mode);
|
|
||||||
|
|
||||||
if (!weechat_log_file)
|
if (!weechat_log_file)
|
||||||
{
|
{
|
||||||
if (weechat_log_filename)
|
if (weechat_log_filename)
|
||||||
|
|||||||
+19
-8
@@ -26,13 +26,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* _XPG4_2 is needed on SunOS for macros like CMSG_SPACE */
|
|
||||||
/* __EXTENSIONS__ is needed on SunOS for constants like NI_MAXHOST */
|
|
||||||
#ifdef __sun
|
|
||||||
#define _XPG4_2
|
|
||||||
#define __EXTENSIONS__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -585,7 +578,13 @@ network_pass_socks5proxy (struct t_proxy *proxy, int sock, const char *address,
|
|||||||
int port)
|
int port)
|
||||||
{
|
{
|
||||||
struct t_network_socks5 socks5;
|
struct t_network_socks5 socks5;
|
||||||
unsigned char buffer[288];
|
/*
|
||||||
|
* buffer must be large enough for the username/password authentication
|
||||||
|
* request, which is the longest message sent/received here; according to
|
||||||
|
* RFC 1929 it is: version (1) + username length (1) + username (max 255)
|
||||||
|
* + password length (1) + password (max 255)
|
||||||
|
*/
|
||||||
|
unsigned char buffer[2 + 255 + 1 + 255];
|
||||||
int username_len, password_len, addr_len, addr_buffer_len;
|
int username_len, password_len, addr_len, addr_buffer_len;
|
||||||
unsigned char *addr_buffer;
|
unsigned char *addr_buffer;
|
||||||
char *username, *password;
|
char *username, *password;
|
||||||
@@ -634,6 +633,18 @@ network_pass_socks5proxy (struct t_proxy *proxy, int sock, const char *address,
|
|||||||
username_len = strlen (username);
|
username_len = strlen (username);
|
||||||
password_len = strlen (password);
|
password_len = strlen (password);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* username and password length are each stored on a single byte
|
||||||
|
* (RFC 1929), so they cannot exceed 255 bytes: reject longer values,
|
||||||
|
* otherwise the memcpy calls below would overflow the buffer
|
||||||
|
*/
|
||||||
|
if ((username_len > 255) || (password_len > 255))
|
||||||
|
{
|
||||||
|
free (username);
|
||||||
|
free (password);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* make username/password buffer */
|
/* make username/password buffer */
|
||||||
buffer[0] = 1;
|
buffer[0] = 1;
|
||||||
buffer[1] = (unsigned char) username_len;
|
buffer[1] = (unsigned char) username_len;
|
||||||
|
|||||||
+44
-2
@@ -916,6 +916,43 @@ string_strcmp_ignore_chars (const char *string1, const char *string2,
|
|||||||
string_charcasecmp (string1, string2);
|
string_charcasecmp (string1, string2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compares two memory areas of the same size in constant time.
|
||||||
|
*
|
||||||
|
* Use to compare secrets (e.g. password hashes, MACs) without leaking
|
||||||
|
* information through the comparison's running time. The loop always
|
||||||
|
* walks the full "size" bytes and uses only bitwise operations on the
|
||||||
|
* data, so the execution time depends on "size" alone, not on the
|
||||||
|
* position of the first differing byte.
|
||||||
|
*
|
||||||
|
* If either pointer is NULL, the areas are considered different (the
|
||||||
|
* NULL check itself is not constant time but does not look at any
|
||||||
|
* secret content).
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0: areas are equal
|
||||||
|
* 1: areas differ
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
string_memcmp_constant_time (const void *area1, const void *area2, size_t size)
|
||||||
|
{
|
||||||
|
const unsigned char *p1, *p2;
|
||||||
|
unsigned char diff;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!area1 || !area2)
|
||||||
|
return (area1 == area2) ? 0 : 1;
|
||||||
|
|
||||||
|
p1 = (const unsigned char *)area1;
|
||||||
|
p2 = (const unsigned char *)area2;
|
||||||
|
diff = 0;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
diff |= p1[i] ^ p2[i];
|
||||||
|
|
||||||
|
return (diff == 0) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Searches for a string in another string (locale and case independent).
|
* Searches for a string in another string (locale and case independent).
|
||||||
*
|
*
|
||||||
@@ -1922,6 +1959,9 @@ string_replace (const char *string, const char *search, const char *replace)
|
|||||||
if (!string || !search || !replace)
|
if (!string || !search || !replace)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (!search[0])
|
||||||
|
return strdup (string);
|
||||||
|
|
||||||
length1 = strlen (search);
|
length1 = strlen (search);
|
||||||
length2 = strlen (replace);
|
length2 = strlen (replace);
|
||||||
|
|
||||||
@@ -3570,7 +3610,8 @@ int
|
|||||||
string_base32_encode (const char *from, int length, char *to)
|
string_base32_encode (const char *from, int length, char *to)
|
||||||
{
|
{
|
||||||
unsigned char base32_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
unsigned char base32_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||||
int count, value, next, bits_left, pad, index;
|
unsigned int value;
|
||||||
|
int count, next, bits_left, pad, index;
|
||||||
int length_padding[8] = { 0, 0, 6, 0, 4, 3, 0, 2 };
|
int length_padding[8] = { 0, 0, 6, 0, 4, 3, 0, 2 };
|
||||||
|
|
||||||
if (!from || !to)
|
if (!from || !to)
|
||||||
@@ -3648,7 +3689,8 @@ int
|
|||||||
string_base32_decode (const char *from, char *to)
|
string_base32_decode (const char *from, char *to)
|
||||||
{
|
{
|
||||||
const char *ptr_from;
|
const char *ptr_from;
|
||||||
int value, bits_left, count;
|
int bits_left, count;
|
||||||
|
unsigned int value;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
|
||||||
if (!from || !to)
|
if (!from || !to)
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ extern int string_strcmp_ignore_chars (const char *string1,
|
|||||||
const char *string2,
|
const char *string2,
|
||||||
const char *chars_ignored,
|
const char *chars_ignored,
|
||||||
int case_sensitive);
|
int case_sensitive);
|
||||||
|
extern int string_memcmp_constant_time (const void *area1, const void *area2,
|
||||||
|
size_t size);
|
||||||
extern const char *string_strcasestr (const char *string, const char *search);
|
extern const char *string_strcasestr (const char *string, const char *search);
|
||||||
extern int string_match (const char *string, const char *mask,
|
extern int string_match (const char *string, const char *mask,
|
||||||
int case_sensitive);
|
int case_sensitive);
|
||||||
|
|||||||
@@ -88,12 +88,14 @@ struct t_url_constant url_protocols[] =
|
|||||||
URL_DEF_CONST(PROTO, SMTP),
|
URL_DEF_CONST(PROTO, SMTP),
|
||||||
URL_DEF_CONST(PROTO, SMTPS),
|
URL_DEF_CONST(PROTO, SMTPS),
|
||||||
URL_DEF_CONST(PROTO, RTSP),
|
URL_DEF_CONST(PROTO, RTSP),
|
||||||
|
#if LIBCURL_VERSION_NUM < 0x081400 /* < 8.20.0 */
|
||||||
URL_DEF_CONST(PROTO, RTMP),
|
URL_DEF_CONST(PROTO, RTMP),
|
||||||
URL_DEF_CONST(PROTO, RTMPT),
|
URL_DEF_CONST(PROTO, RTMPT),
|
||||||
URL_DEF_CONST(PROTO, RTMPE),
|
URL_DEF_CONST(PROTO, RTMPE),
|
||||||
URL_DEF_CONST(PROTO, RTMPTE),
|
URL_DEF_CONST(PROTO, RTMPTE),
|
||||||
URL_DEF_CONST(PROTO, RTMPS),
|
URL_DEF_CONST(PROTO, RTMPS),
|
||||||
URL_DEF_CONST(PROTO, RTMPTS),
|
URL_DEF_CONST(PROTO, RTMPTS),
|
||||||
|
#endif
|
||||||
URL_DEF_CONST(PROTO, GOPHER),
|
URL_DEF_CONST(PROTO, GOPHER),
|
||||||
URL_DEF_CONST(PROTO, SMB),
|
URL_DEF_CONST(PROTO, SMB),
|
||||||
URL_DEF_CONST(PROTO, SMBS),
|
URL_DEF_CONST(PROTO, SMBS),
|
||||||
@@ -122,7 +124,9 @@ struct t_url_constant url_auth[] =
|
|||||||
URL_DEF_CONST(AUTH, NTLM),
|
URL_DEF_CONST(AUTH, NTLM),
|
||||||
URL_DEF_CONST(AUTH, ANY),
|
URL_DEF_CONST(AUTH, ANY),
|
||||||
URL_DEF_CONST(AUTH, ANYSAFE),
|
URL_DEF_CONST(AUTH, ANYSAFE),
|
||||||
|
#if LIBCURL_VERSION_NUM < 0x081500 /* < 8.21.0 */
|
||||||
URL_DEF_CONST(AUTH, DIGEST_IE),
|
URL_DEF_CONST(AUTH, DIGEST_IE),
|
||||||
|
#endif
|
||||||
URL_DEF_CONST(AUTH, ONLY),
|
URL_DEF_CONST(AUTH, ONLY),
|
||||||
#if LIBCURL_VERSION_NUM < 0x080800 /* < 8.8.0 */
|
#if LIBCURL_VERSION_NUM < 0x080800 /* < 8.8.0 */
|
||||||
URL_DEF_CONST(AUTH, NTLM_WB),
|
URL_DEF_CONST(AUTH, NTLM_WB),
|
||||||
@@ -651,7 +655,9 @@ struct t_url_option url_options[] =
|
|||||||
URL_DEF_OPTION(SSLENGINE_DEFAULT, LONG, NULL),
|
URL_DEF_OPTION(SSLENGINE_DEFAULT, LONG, NULL),
|
||||||
URL_DEF_OPTION(CAPATH, STRING, NULL),
|
URL_DEF_OPTION(CAPATH, STRING, NULL),
|
||||||
URL_DEF_OPTION(SSL_SESSIONID_CACHE, LONG, NULL),
|
URL_DEF_OPTION(SSL_SESSIONID_CACHE, LONG, NULL),
|
||||||
|
#if LIBCURL_VERSION_NUM < 0x081100 /* < 8.17.0 */
|
||||||
URL_DEF_OPTION(KRBLEVEL, STRING, NULL),
|
URL_DEF_OPTION(KRBLEVEL, STRING, NULL),
|
||||||
|
#endif
|
||||||
URL_DEF_OPTION(KEYPASSWD, STRING, NULL),
|
URL_DEF_OPTION(KEYPASSWD, STRING, NULL),
|
||||||
URL_DEF_OPTION(ISSUERCERT, STRING, NULL),
|
URL_DEF_OPTION(ISSUERCERT, STRING, NULL),
|
||||||
URL_DEF_OPTION(CRLFILE, STRING, NULL),
|
URL_DEF_OPTION(CRLFILE, STRING, NULL),
|
||||||
@@ -664,7 +670,9 @@ struct t_url_option url_options[] =
|
|||||||
#endif
|
#endif
|
||||||
URL_DEF_OPTION(PINNEDPUBLICKEY, STRING, NULL),
|
URL_DEF_OPTION(PINNEDPUBLICKEY, STRING, NULL),
|
||||||
URL_DEF_OPTION(SSL_VERIFYSTATUS, LONG, NULL),
|
URL_DEF_OPTION(SSL_VERIFYSTATUS, LONG, NULL),
|
||||||
|
#if LIBCURL_VERSION_NUM < 0x080F00 /* < 8.15.0 */
|
||||||
URL_DEF_OPTION(SSL_FALSESTART, LONG, NULL),
|
URL_DEF_OPTION(SSL_FALSESTART, LONG, NULL),
|
||||||
|
#endif
|
||||||
#if LIBCURL_VERSION_NUM >= 0x073400 /* 7.52.0 */
|
#if LIBCURL_VERSION_NUM >= 0x073400 /* 7.52.0 */
|
||||||
URL_DEF_OPTION(PROXY_CAINFO, STRING, NULL),
|
URL_DEF_OPTION(PROXY_CAINFO, STRING, NULL),
|
||||||
URL_DEF_OPTION(PROXY_CAPATH, STRING, NULL),
|
URL_DEF_OPTION(PROXY_CAPATH, STRING, NULL),
|
||||||
|
|||||||
+24
-10
@@ -166,6 +166,8 @@ util_get_time_string (const time_t *date)
|
|||||||
/*
|
/*
|
||||||
* Formats date and time like strftime (but with timeval structure as input)
|
* Formats date and time like strftime (but with timeval structure as input)
|
||||||
* and adds extra specifiers:
|
* and adds extra specifiers:
|
||||||
|
* - "%@": return the date expressed in Coordinated Universal Time (UTC)
|
||||||
|
* instead of date relative to the user's specified timezone
|
||||||
* - "%.1" to "%.6": first N digits of microseconds, zero-padded
|
* - "%.1" to "%.6": first N digits of microseconds, zero-padded
|
||||||
* - "%f": alias of "%.6" (microseconds, zero-padded to 6 digits)
|
* - "%f": alias of "%.6" (microseconds, zero-padded to 6 digits)
|
||||||
* - "%!": timestamp as integer, in seconds (value of tv->tv_sec)
|
* - "%!": timestamp as integer, in seconds (value of tv->tv_sec)
|
||||||
@@ -176,14 +178,15 @@ util_strftimeval (char *string, int max, const char *format, struct timeval *tv)
|
|||||||
{
|
{
|
||||||
char **format2, str_temp[32];
|
char **format2, str_temp[32];
|
||||||
const char *ptr_format;
|
const char *ptr_format;
|
||||||
struct tm *local_time;
|
struct tm *date_time;
|
||||||
int length, bytes;
|
int length, bytes, local_time;
|
||||||
long usec;
|
long usec;
|
||||||
|
|
||||||
if (!string || (max <= 0) || !format || !tv)
|
if (!string || (max <= 0) || !format || !tv)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
string[0] = '\0';
|
string[0] = '\0';
|
||||||
|
local_time = 1;
|
||||||
|
|
||||||
if (!format[0])
|
if (!format[0])
|
||||||
return 0;
|
return 0;
|
||||||
@@ -206,6 +209,11 @@ util_strftimeval (char *string, int max, const char *format, struct timeval *tv)
|
|||||||
string_dyn_concat (format2, "%%", -1);
|
string_dyn_concat (format2, "%%", -1);
|
||||||
ptr_format += 2;
|
ptr_format += 2;
|
||||||
}
|
}
|
||||||
|
else if ((ptr_format[0] == '%') && (ptr_format[1] == '@'))
|
||||||
|
{
|
||||||
|
local_time = 0;
|
||||||
|
ptr_format += 2;
|
||||||
|
}
|
||||||
else if ((ptr_format[0] == '%') && (ptr_format[1] == '.'))
|
else if ((ptr_format[0] == '%') && (ptr_format[1] == '.'))
|
||||||
{
|
{
|
||||||
if ((ptr_format[2] >= '1') && (ptr_format[2] <= '6'))
|
if ((ptr_format[2] >= '1') && (ptr_format[2] <= '6'))
|
||||||
@@ -242,14 +250,17 @@ util_strftimeval (char *string, int max, const char *format, struct timeval *tv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
local_time = localtime (&(tv->tv_sec));
|
if (local_time)
|
||||||
if (!local_time)
|
date_time = localtime (&(tv->tv_sec));
|
||||||
|
else
|
||||||
|
date_time = gmtime (&(tv->tv_sec));
|
||||||
|
if (!date_time)
|
||||||
{
|
{
|
||||||
string_dyn_free (format2, 1);
|
string_dyn_free (format2, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = strftime (string, max, *format2, local_time);
|
bytes = strftime (string, max, *format2, date_time);
|
||||||
|
|
||||||
string_dyn_free (format2, 1);
|
string_dyn_free (format2, 1);
|
||||||
|
|
||||||
@@ -285,7 +296,8 @@ util_strftimeval (char *string, int max, const char *format, struct timeval *tv)
|
|||||||
int
|
int
|
||||||
util_parse_time (const char *datetime, struct timeval *tv)
|
util_parse_time (const char *datetime, struct timeval *tv)
|
||||||
{
|
{
|
||||||
char *string, *pos, *pos2, str_usec[16], *error, str_date[128];
|
char *string, *pos, *pos2, str_usec[16], *error;
|
||||||
|
char str_date[128], str_date2[256];
|
||||||
struct tm tm_date, tm_date_gm, tm_date_local, *local_time;
|
struct tm tm_date, tm_date_gm, tm_date_local, *local_time;
|
||||||
time_t time_now, time_gm, time_local;
|
time_t time_now, time_gm, time_local;
|
||||||
long long value;
|
long long value;
|
||||||
@@ -445,10 +457,10 @@ util_parse_time (const char *datetime, struct timeval *tv)
|
|||||||
local_time = localtime (&time_now);
|
local_time = localtime (&time_now);
|
||||||
strftime (str_date, sizeof (str_date),
|
strftime (str_date, sizeof (str_date),
|
||||||
"%Y-%m-%dT", local_time);
|
"%Y-%m-%dT", local_time);
|
||||||
strcat (str_date, string);
|
snprintf (str_date2, sizeof (str_date2), "%s%s", str_date, string);
|
||||||
/* initialize structure, because strptime does not do it */
|
/* initialize structure, because strptime does not do it */
|
||||||
memset (&tm_date, 0, sizeof (struct tm));
|
memset (&tm_date, 0, sizeof (struct tm));
|
||||||
pos = strptime (str_date, "%Y-%m-%dT%H:%M:%S", &tm_date);
|
pos = strptime (str_date2, "%Y-%m-%dT%H:%M:%S", &tm_date);
|
||||||
if (pos)
|
if (pos)
|
||||||
{
|
{
|
||||||
if (use_local_time)
|
if (use_local_time)
|
||||||
@@ -571,7 +583,6 @@ util_parse_delay (const char *string_delay, unsigned long long default_factor,
|
|||||||
|
|
||||||
if ((pos > string_delay) && pos[0])
|
if ((pos > string_delay) && pos[0])
|
||||||
{
|
{
|
||||||
str_number = string_strndup (string_delay, pos - string_delay);
|
|
||||||
if (strcmp (pos, "us") == 0)
|
if (strcmp (pos, "us") == 0)
|
||||||
factor = 1ULL;
|
factor = 1ULL;
|
||||||
else if (strcmp (pos, "ms") == 0)
|
else if (strcmp (pos, "ms") == 0)
|
||||||
@@ -584,6 +595,7 @@ util_parse_delay (const char *string_delay, unsigned long long default_factor,
|
|||||||
factor = 1000ULL * 1000ULL * 60ULL * 60ULL;
|
factor = 1000ULL * 1000ULL * 60ULL * 60ULL;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
str_number = string_strndup (string_delay, pos - string_delay);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -670,7 +682,9 @@ util_version_number (const char *version)
|
|||||||
{
|
{
|
||||||
if (number < 0)
|
if (number < 0)
|
||||||
number = 0;
|
number = 0;
|
||||||
else if (number > 0xFF)
|
else if ((i == 0) && (number > 0x7F))
|
||||||
|
number = 0x7F;
|
||||||
|
else if ((i > 0) && (number > 0xFF))
|
||||||
number = 0xFF;
|
number = 0xFF;
|
||||||
version_int[i] = number;
|
version_int[i] = number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#ifndef WEECHAT_HOOK_URL_H
|
#ifndef WEECHAT_HOOK_URL_H
|
||||||
#define WEECHAT_HOOK_URL_H
|
#define WEECHAT_HOOK_URL_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
struct t_weechat_plugin;
|
struct t_weechat_plugin;
|
||||||
struct t_infolist_item;
|
struct t_infolist_item;
|
||||||
struct t_hashtable;
|
struct t_hashtable;
|
||||||
|
|||||||
@@ -51,11 +51,6 @@ if(ENABLE_ZSTD)
|
|||||||
list(APPEND EXTRA_LIBS ${LIBZSTD_LDFLAGS})
|
list(APPEND EXTRA_LIBS ${LIBZSTD_LDFLAGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|
||||||
# link with resolv lib on macOS
|
|
||||||
list(APPEND EXTRA_LIBS "resolv")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_NCURSES)
|
if(ENABLE_NCURSES)
|
||||||
subdirs(normal)
|
subdirs(normal)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -231,12 +231,7 @@ gui_main_init (void)
|
|||||||
gui_term_cols, gui_term_lines, 100, 100))
|
gui_term_cols, gui_term_lines, 100, 100))
|
||||||
{
|
{
|
||||||
gui_current_window = gui_windows;
|
gui_current_window = gui_windows;
|
||||||
|
gui_window_set_title (CONFIG_STRING(config_look_window_title));
|
||||||
if (CONFIG_STRING(config_look_window_title)
|
|
||||||
&& CONFIG_STRING(config_look_window_title)[0])
|
|
||||||
{
|
|
||||||
gui_window_set_title (CONFIG_STRING(config_look_window_title));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* switch to buffer */
|
/* switch to buffer */
|
||||||
@@ -526,13 +521,6 @@ gui_main_end (int clean_exit)
|
|||||||
/* delete global history */
|
/* delete global history */
|
||||||
gui_history_global_free ();
|
gui_history_global_free ();
|
||||||
|
|
||||||
/* reset title */
|
|
||||||
if (CONFIG_STRING(config_look_window_title)
|
|
||||||
&& CONFIG_STRING(config_look_window_title)[0])
|
|
||||||
{
|
|
||||||
gui_window_set_title (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end color */
|
/* end color */
|
||||||
gui_color_end ();
|
gui_color_end ();
|
||||||
|
|
||||||
|
|||||||
@@ -2479,13 +2479,11 @@ gui_window_refresh_screen (int full_refresh)
|
|||||||
refresh ();
|
refresh ();
|
||||||
gui_window_read_terminal_size ();
|
gui_window_read_terminal_size ();
|
||||||
refresh ();
|
refresh ();
|
||||||
gui_window_set_title (
|
|
||||||
(CONFIG_STRING(config_look_window_title)
|
|
||||||
&& CONFIG_STRING(config_look_window_title)[0]) ?
|
|
||||||
CONFIG_STRING(config_look_window_title) : NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_window_refresh_windows ();
|
gui_window_refresh_windows ();
|
||||||
|
|
||||||
|
gui_window_set_title (CONFIG_STRING(config_look_window_title));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2573,15 +2571,17 @@ gui_window_set_title (const char *title)
|
|||||||
{
|
{
|
||||||
char *new_title, *envterm, *envshell, *shell, *shellname;
|
char *new_title, *envterm, *envshell, *shell, *shellname;
|
||||||
|
|
||||||
envterm = getenv ("TERM");
|
if (!title || !title[0])
|
||||||
if (!envterm)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
new_title = (title && title[0]) ?
|
new_title = eval_expression (title, NULL, NULL, NULL);
|
||||||
eval_expression (title, NULL, NULL, NULL) : NULL;
|
|
||||||
if (!new_title)
|
if (!new_title)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
envterm = getenv ("TERM");
|
||||||
|
if (!envterm)
|
||||||
|
return;
|
||||||
|
|
||||||
if (strcmp (envterm, "sun-cmd") == 0)
|
if (strcmp (envterm, "sun-cmd") == 0)
|
||||||
{
|
{
|
||||||
printf ("\033]l%s\033\\", new_title);
|
printf ("\033]l%s\033\\", new_title);
|
||||||
|
|||||||
@@ -47,23 +47,20 @@ daemonize (void)
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
int fd, i;
|
int fd, i;
|
||||||
|
|
||||||
printf (_("Running WeeChat in background..."));
|
printf ("%s ", _("Running WeeChat in background..."));
|
||||||
printf (" ");
|
|
||||||
|
|
||||||
pid = fork ();
|
pid = fork ();
|
||||||
|
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
{
|
{
|
||||||
printf (_("fork error"));
|
printf ("%s\n", _("fork error"));
|
||||||
printf ("\n");
|
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid > 0)
|
if (pid > 0)
|
||||||
{
|
{
|
||||||
/* parent process */
|
/* parent process */
|
||||||
printf (_("OK"));
|
printf ("%s\n", _("OK"));
|
||||||
printf ("\n");
|
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ set(LIB_GUI_CURSES_SRC
|
|||||||
|
|
||||||
find_package(Ncurses)
|
find_package(Ncurses)
|
||||||
if(NCURSES_FOUND)
|
if(NCURSES_FOUND)
|
||||||
|
add_definitions(${NCURSES_CFLAGS})
|
||||||
check_include_files(ncursesw/ncurses.h NCURSESW_HEADERS)
|
check_include_files(ncursesw/ncurses.h NCURSESW_HEADERS)
|
||||||
if(NCURSESW_HEADERS)
|
if(NCURSESW_HEADERS)
|
||||||
add_definitions(-DHAVE_NCURSESW_CURSES_H)
|
add_definitions(-DHAVE_NCURSESW_CURSES_H)
|
||||||
|
|||||||
@@ -2148,6 +2148,7 @@ gui_bar_item_focus_buffer_nicklist_cb (const void *pointer,
|
|||||||
struct t_gui_nick_group *ptr_group;
|
struct t_gui_nick_group *ptr_group;
|
||||||
struct t_gui_nick *ptr_nick;
|
struct t_gui_nick *ptr_nick;
|
||||||
int i, rc, bar_item_line;
|
int i, rc, bar_item_line;
|
||||||
|
unsigned long value;
|
||||||
const char *str_window, *str_buffer, *str_bar_item_line;
|
const char *str_window, *str_buffer, *str_bar_item_line;
|
||||||
struct t_gui_window *window;
|
struct t_gui_window *window;
|
||||||
struct t_gui_buffer *buffer;
|
struct t_gui_buffer *buffer;
|
||||||
@@ -2165,9 +2166,10 @@ gui_bar_item_focus_buffer_nicklist_cb (const void *pointer,
|
|||||||
str_window = hashtable_get (info, "_window");
|
str_window = hashtable_get (info, "_window");
|
||||||
if (str_window && str_window[0])
|
if (str_window && str_window[0])
|
||||||
{
|
{
|
||||||
rc = sscanf (str_window, "%p", &window);
|
rc = sscanf (str_window, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
window = (struct t_gui_window *)value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2182,9 +2184,10 @@ gui_bar_item_focus_buffer_nicklist_cb (const void *pointer,
|
|||||||
str_buffer = hashtable_get (info, "_buffer");
|
str_buffer = hashtable_get (info, "_buffer");
|
||||||
if (str_buffer && str_buffer[0])
|
if (str_buffer && str_buffer[0])
|
||||||
{
|
{
|
||||||
rc = sscanf (str_buffer, "%p", &buffer);
|
rc = sscanf (str_buffer, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
buffer = (struct t_gui_buffer *)value;
|
||||||
}
|
}
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
+3
-1
@@ -1396,6 +1396,7 @@ gui_chat_hsignal_quote_line_cb (const void *pointer, void *data,
|
|||||||
{
|
{
|
||||||
const char *ptr_date, *ptr_date_usec, *line, *prefix, *ptr_prefix, *message;
|
const char *ptr_date, *ptr_date_usec, *line, *prefix, *ptr_prefix, *message;
|
||||||
long long number;
|
long long number;
|
||||||
|
unsigned long value;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct t_gui_line *ptr_line;
|
struct t_gui_line *ptr_line;
|
||||||
int is_nick, rc;
|
int is_nick, rc;
|
||||||
@@ -1440,9 +1441,10 @@ gui_chat_hsignal_quote_line_cb (const void *pointer, void *data,
|
|||||||
line = hashtable_get (hashtable, "_chat_line");
|
line = hashtable_get (hashtable, "_chat_line");
|
||||||
if (line && line[0])
|
if (line && line[0])
|
||||||
{
|
{
|
||||||
rc = sscanf (line, "%p", &ptr_line);
|
rc = sscanf (line, "%lx", &value);
|
||||||
if ((rc != EOF) && (rc != 0))
|
if ((rc != EOF) && (rc != 0))
|
||||||
{
|
{
|
||||||
|
ptr_line = (struct t_gui_line *)value;
|
||||||
if (gui_line_search_tag_starting_with (ptr_line, "prefix_nick"))
|
if (gui_line_search_tag_starting_with (ptr_line, "prefix_nick"))
|
||||||
is_nick = 1;
|
is_nick = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -356,6 +356,7 @@ gui_history_hdata_history_update_cb (void *data,
|
|||||||
struct t_gui_history *ptr_history;
|
struct t_gui_history *ptr_history;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
const char *text, *buffer;
|
const char *text, *buffer;
|
||||||
|
unsigned long value;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* make C compiler happy */
|
/* make C compiler happy */
|
||||||
@@ -384,9 +385,9 @@ gui_history_hdata_history_update_cb (void *data,
|
|||||||
buffer = hashtable_get (hashtable, "buffer");
|
buffer = hashtable_get (hashtable, "buffer");
|
||||||
if (buffer)
|
if (buffer)
|
||||||
{
|
{
|
||||||
rc = sscanf (buffer, "%p", &ptr_buffer);
|
rc = sscanf (buffer, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc != EOF) && (rc != 0))
|
||||||
ptr_buffer = NULL;
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ptr_buffer)
|
if (ptr_buffer)
|
||||||
|
|||||||
+14
-13
@@ -1213,12 +1213,12 @@ gui_key_set_score (struct t_gui_key *key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Checks if a key is safe or not: a safe key begins always with the "meta" or
|
* Checks if a key is safe or not: a safe key should begin with the "meta" or
|
||||||
* "ctrl" code (except "@" allowed in cursor/mouse contexts).
|
* "ctrl" code (there are exceptions).
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* 1: key is safe
|
* 1: key is safe for the given context
|
||||||
* 0: key is NOT safe
|
* 0: key is NOT safe for the given context
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -1229,13 +1229,13 @@ gui_key_is_safe (int context, const char *key)
|
|||||||
if (!key || !key[0])
|
if (!key || !key[0])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* "@" is allowed at beginning for cursor/mouse contexts */
|
/* all keys are safe in cursor mode */
|
||||||
if ((key[0] == '@')
|
if (context == GUI_KEY_CONTEXT_CURSOR)
|
||||||
&& ((context == GUI_KEY_CONTEXT_CURSOR)
|
return 1;
|
||||||
|| (context == GUI_KEY_CONTEXT_MOUSE)))
|
|
||||||
{
|
/* "@" is allowed at beginning for mouse context */
|
||||||
|
if ((key[0] == '@') && (context == GUI_KEY_CONTEXT_MOUSE))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp (key, "comma", 5) == 0)
|
if (strncmp (key, "comma", 5) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2042,6 +2042,7 @@ gui_key_focus_command (const char *key, int context,
|
|||||||
{
|
{
|
||||||
struct t_gui_key *ptr_key;
|
struct t_gui_key *ptr_key;
|
||||||
int matching, debug, rc;
|
int matching, debug, rc;
|
||||||
|
unsigned long value;
|
||||||
char *command, **commands, **ptr_command;
|
char *command, **commands, **ptr_command;
|
||||||
const char *str_buffer;
|
const char *str_buffer;
|
||||||
struct t_hashtable *hashtable;
|
struct t_hashtable *hashtable;
|
||||||
@@ -2099,9 +2100,9 @@ gui_key_focus_command (const char *key, int context,
|
|||||||
str_buffer = hashtable_get (hashtable, "_buffer");
|
str_buffer = hashtable_get (hashtable, "_buffer");
|
||||||
if (str_buffer && str_buffer[0])
|
if (str_buffer && str_buffer[0])
|
||||||
{
|
{
|
||||||
rc = sscanf (str_buffer, "%p", &ptr_buffer);
|
rc = sscanf (str_buffer, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc != EOF) && (rc != 0))
|
||||||
ptr_buffer = gui_current_window->buffer;
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
}
|
}
|
||||||
if (!ptr_buffer)
|
if (!ptr_buffer)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
+3
-1
@@ -1671,6 +1671,7 @@ gui_line_hook_update (struct t_gui_line *line,
|
|||||||
{
|
{
|
||||||
const char *ptr_value, *ptr_value2;
|
const char *ptr_value, *ptr_value2;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
|
unsigned long value_pointer;
|
||||||
long value;
|
long value;
|
||||||
char *error, *new_message, *pos_newline;
|
char *error, *new_message, *pos_newline;
|
||||||
int rc, tags_updated, notify_level_updated, highlight_updated;
|
int rc, tags_updated, notify_level_updated, highlight_updated;
|
||||||
@@ -1704,7 +1705,8 @@ gui_line_hook_update (struct t_gui_line *line,
|
|||||||
{
|
{
|
||||||
if ((ptr_value2[0] == '0') && (ptr_value2[1] == 'x'))
|
if ((ptr_value2[0] == '0') && (ptr_value2[1] == 'x'))
|
||||||
{
|
{
|
||||||
rc = sscanf (ptr_value2, "%p", &ptr_buffer);
|
rc = sscanf (ptr_value2 + 2, "%lx", &value_pointer);
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value_pointer;
|
||||||
if ((rc != EOF) && (rc >= 1)
|
if ((rc != EOF) && (rc >= 1)
|
||||||
&& gui_chat_buffer_valid (ptr_buffer, line->data->buffer->type))
|
&& gui_chat_buffer_valid (ptr_buffer, line->data->buffer->type))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -122,8 +122,12 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENABLE_SCRIPTS AND ENABLE_PYTHON)
|
if(ENABLE_SCRIPTS AND ENABLE_PYTHON)
|
||||||
find_package(Python)
|
if(CMAKE_VERSION VERSION_LESS "3.18.0")
|
||||||
if(PYTHON_FOUND)
|
find_package(Python 3.0 COMPONENTS Development)
|
||||||
|
else()
|
||||||
|
find_package(Python 3.0 COMPONENTS Development.Embed)
|
||||||
|
endif()
|
||||||
|
if(Python_FOUND)
|
||||||
add_subdirectory(python)
|
add_subdirectory(python)
|
||||||
else()
|
else()
|
||||||
message(SEND_ERROR "Python not found")
|
message(SEND_ERROR "Python not found")
|
||||||
|
|||||||
@@ -333,6 +333,7 @@ buflist_hsignal_cb (const void *pointer, void *data, const char *signal,
|
|||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
char *error, str_command[1024];
|
char *error, str_command[1024];
|
||||||
long number, number2;
|
long number, number2;
|
||||||
|
unsigned long value;
|
||||||
int rc, current_buffer_number;
|
int rc, current_buffer_number;
|
||||||
|
|
||||||
/* make C compiler happy */
|
/* make C compiler happy */
|
||||||
@@ -352,9 +353,10 @@ buflist_hsignal_cb (const void *pointer, void *data, const char *signal,
|
|||||||
return WEECHAT_RC_OK;
|
return WEECHAT_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sscanf (ptr_pointer, "%p", &ptr_buffer);
|
rc = sscanf (ptr_pointer, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return WEECHAT_RC_OK;
|
return WEECHAT_RC_OK;
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
number = strtol (ptr_number, &error, 10);
|
number = strtol (ptr_number, &error, 10);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ fset_mouse_focus_cb (const void *pointer, void *data, struct t_hashtable *info)
|
|||||||
{
|
{
|
||||||
const char *buffer;
|
const char *buffer;
|
||||||
int rc, format_number;
|
int rc, format_number;
|
||||||
|
unsigned long value;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
long y, option_index;
|
long y, option_index;
|
||||||
char *error, str_value[128];
|
char *error, str_value[128];
|
||||||
@@ -57,10 +58,12 @@ fset_mouse_focus_cb (const void *pointer, void *data, struct t_hashtable *info)
|
|||||||
if (!buffer)
|
if (!buffer)
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
rc = sscanf (buffer, "%p", &ptr_buffer);
|
rc = sscanf (buffer, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
|
|
||||||
if (!ptr_buffer || (ptr_buffer != fset_buffer))
|
if (!ptr_buffer || (ptr_buffer != fset_buffer))
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
@@ -184,6 +187,7 @@ fset_mouse_hsignal_cb (const void *pointer, void *data, const char *signal,
|
|||||||
const char *ptr_key, *ptr_fset_option_pointer;
|
const char *ptr_key, *ptr_fset_option_pointer;
|
||||||
char str_command[1024];
|
char str_command[1024];
|
||||||
struct t_fset_option *ptr_fset_option;
|
struct t_fset_option *ptr_fset_option;
|
||||||
|
unsigned long value;
|
||||||
int rc, distance, num_options, min_y, max_y, i;
|
int rc, distance, num_options, min_y, max_y, i;
|
||||||
int chat_line_x, chat_line_x2, y, y2, chat_line_y, chat_line_y2;
|
int chat_line_x, chat_line_x2, y, y2, chat_line_y, chat_line_y2;
|
||||||
int option_index, option_index2, index1, index2;
|
int option_index, option_index2, index1, index2;
|
||||||
@@ -202,9 +206,10 @@ fset_mouse_hsignal_cb (const void *pointer, void *data, const char *signal,
|
|||||||
if (!ptr_key || !ptr_fset_option_pointer)
|
if (!ptr_key || !ptr_fset_option_pointer)
|
||||||
return WEECHAT_RC_OK;
|
return WEECHAT_RC_OK;
|
||||||
|
|
||||||
rc = sscanf (ptr_fset_option_pointer, "%p", &ptr_fset_option);
|
rc = sscanf (ptr_fset_option_pointer, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return WEECHAT_RC_OK;
|
return WEECHAT_RC_OK;
|
||||||
|
ptr_fset_option = (struct t_fset_option *)value;
|
||||||
if (!ptr_fset_option)
|
if (!ptr_fset_option)
|
||||||
return WEECHAT_RC_OK;
|
return WEECHAT_RC_OK;
|
||||||
|
|
||||||
|
|||||||
@@ -624,6 +624,7 @@ struct t_hashtable *
|
|||||||
irc_bar_item_focus_buffer_nicklist (const void *pointer, void *data,
|
irc_bar_item_focus_buffer_nicklist (const void *pointer, void *data,
|
||||||
struct t_hashtable *info)
|
struct t_hashtable *info)
|
||||||
{
|
{
|
||||||
|
unsigned long value;
|
||||||
int rc;
|
int rc;
|
||||||
struct t_gui_buffer *buffer;
|
struct t_gui_buffer *buffer;
|
||||||
struct t_irc_nick *ptr_nick;
|
struct t_irc_nick *ptr_nick;
|
||||||
@@ -634,10 +635,12 @@ irc_bar_item_focus_buffer_nicklist (const void *pointer, void *data,
|
|||||||
if (!str_buffer || !str_buffer[0])
|
if (!str_buffer || !str_buffer[0])
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rc = sscanf (str_buffer, "%p", &buffer);
|
rc = sscanf (str_buffer, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
buffer = (struct t_gui_buffer *)value;
|
||||||
|
|
||||||
IRC_BUFFER_GET_SERVER_CHANNEL(buffer);
|
IRC_BUFFER_GET_SERVER_CHANNEL(buffer);
|
||||||
|
|
||||||
/* make C compiler happy */
|
/* make C compiler happy */
|
||||||
|
|||||||
@@ -855,7 +855,7 @@ irc_ctcp_recv_dcc (struct t_irc_protocol_ctxt *ctxt, const char *arguments)
|
|||||||
* double-quote
|
* double-quote
|
||||||
*/
|
*/
|
||||||
pos = strrchr (pos_file, '"');
|
pos = strrchr (pos_file, '"');
|
||||||
if (!pos || (pos == pos_file))
|
if (!pos || (pos == pos_file) || !pos[1])
|
||||||
{
|
{
|
||||||
weechat_printf (
|
weechat_printf (
|
||||||
ctxt->server->buffer,
|
ctxt->server->buffer,
|
||||||
@@ -1030,7 +1030,7 @@ irc_ctcp_recv_dcc (struct t_irc_protocol_ctxt *ctxt, const char *arguments)
|
|||||||
* double-quote
|
* double-quote
|
||||||
*/
|
*/
|
||||||
pos = strrchr (pos_file, '"');
|
pos = strrchr (pos_file, '"');
|
||||||
if (!pos || (pos == pos_file))
|
if (!pos || (pos == pos_file) || !pos[1])
|
||||||
{
|
{
|
||||||
weechat_printf (
|
weechat_printf (
|
||||||
ctxt->server->buffer,
|
ctxt->server->buffer,
|
||||||
@@ -1174,7 +1174,7 @@ irc_ctcp_recv_dcc (struct t_irc_protocol_ctxt *ctxt, const char *arguments)
|
|||||||
* double-quote
|
* double-quote
|
||||||
*/
|
*/
|
||||||
pos = strrchr (pos_file, '"');
|
pos = strrchr (pos_file, '"');
|
||||||
if (!pos || (pos == pos_file))
|
if (!pos || (pos == pos_file) || !pos[1])
|
||||||
{
|
{
|
||||||
weechat_printf (
|
weechat_printf (
|
||||||
ctxt->server->buffer,
|
ctxt->server->buffer,
|
||||||
|
|||||||
@@ -1311,6 +1311,7 @@ irc_list_mouse_hsignal_cb (const void *pointer, void *data, const char *signal,
|
|||||||
{
|
{
|
||||||
const char *ptr_key, *ptr_chat_line_y, *ptr_buffer_pointer;
|
const char *ptr_key, *ptr_chat_line_y, *ptr_buffer_pointer;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
|
unsigned long value;
|
||||||
char str_command[1024];
|
char str_command[1024];
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -1326,9 +1327,10 @@ irc_list_mouse_hsignal_cb (const void *pointer, void *data, const char *signal,
|
|||||||
if (!ptr_key || !ptr_buffer_pointer || !ptr_chat_line_y)
|
if (!ptr_key || !ptr_buffer_pointer || !ptr_chat_line_y)
|
||||||
return WEECHAT_RC_OK;
|
return WEECHAT_RC_OK;
|
||||||
|
|
||||||
rc = sscanf (ptr_buffer_pointer, "%p", &ptr_buffer);
|
rc = sscanf (ptr_buffer_pointer, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return WEECHAT_RC_OK;
|
return WEECHAT_RC_OK;
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
if (!ptr_buffer)
|
if (!ptr_buffer)
|
||||||
return WEECHAT_RC_OK;
|
return WEECHAT_RC_OK;
|
||||||
|
|
||||||
|
|||||||
@@ -2393,8 +2393,7 @@ IRC_PROTOCOL_CALLBACK(nick)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!irc_ignore_check (ctxt->server, ptr_channel->name,
|
if (!ctxt->ignore_remove)
|
||||||
ctxt->nick, ctxt->host))
|
|
||||||
{
|
{
|
||||||
ptr_nick_speaking = ((weechat_config_boolean (irc_config_look_smart_filter))
|
ptr_nick_speaking = ((weechat_config_boolean (irc_config_look_smart_filter))
|
||||||
&& (weechat_config_boolean (irc_config_look_smart_filter_nick))) ?
|
&& (weechat_config_boolean (irc_config_look_smart_filter_nick))) ?
|
||||||
@@ -3401,7 +3400,7 @@ IRC_PROTOCOL_CALLBACK(quit)
|
|||||||
if (ptr_nick
|
if (ptr_nick
|
||||||
|| (irc_server_strcasecmp (ctxt->server, ptr_channel->name, ctxt->nick) == 0))
|
|| (irc_server_strcasecmp (ctxt->server, ptr_channel->name, ctxt->nick) == 0))
|
||||||
{
|
{
|
||||||
if (!irc_ignore_check (ctxt->server, ptr_channel->name, ctxt->nick, ctxt->host))
|
if (!ctxt->ignore_remove)
|
||||||
{
|
{
|
||||||
/* display quit message */
|
/* display quit message */
|
||||||
ptr_nick_speaking = NULL;
|
ptr_nick_speaking = NULL;
|
||||||
@@ -4144,16 +4143,25 @@ IRC_PROTOCOL_CALLBACK(005)
|
|||||||
if (ctxt->server->isupport)
|
if (ctxt->server->isupport)
|
||||||
{
|
{
|
||||||
length_isupport = strlen (ctxt->server->isupport);
|
length_isupport = strlen (ctxt->server->isupport);
|
||||||
isupport2 = realloc (ctxt->server->isupport,
|
/*
|
||||||
length_isupport + /* existing */
|
* limit the size of the accumulated ISUPPORT data: once the
|
||||||
1 + /* space */
|
* maximum is reached, ignore the extra data (protection against a
|
||||||
length + /* new */
|
* server flooding "005" messages, which would consume all the
|
||||||
1);
|
* memory)
|
||||||
if (isupport2)
|
*/
|
||||||
|
if (length_isupport + 1 + length < IRC_SERVER_ISUPPORT_MAX_LENGTH)
|
||||||
{
|
{
|
||||||
ctxt->server->isupport = isupport2;
|
isupport2 = realloc (ctxt->server->isupport,
|
||||||
strcat (ctxt->server->isupport, " ");
|
length_isupport + /* existing */
|
||||||
strcat (ctxt->server->isupport, str_info);
|
1 + /* space */
|
||||||
|
length + /* new */
|
||||||
|
1);
|
||||||
|
if (isupport2)
|
||||||
|
{
|
||||||
|
ctxt->server->isupport = isupport2;
|
||||||
|
strcat (ctxt->server->isupport, " ");
|
||||||
|
strcat (ctxt->server->isupport, str_info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -3409,6 +3409,14 @@ irc_server_msgq_add_unterminated (struct t_irc_server *server,
|
|||||||
|
|
||||||
if (server->unterminated_message)
|
if (server->unterminated_message)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* limit the size of the unterminated message: once the maximum is
|
||||||
|
* reached, ignore the extra data (protection against a server sending
|
||||||
|
* a very long line without end-of-line, which would consume all the
|
||||||
|
* memory)
|
||||||
|
*/
|
||||||
|
if (strlen (server->unterminated_message) >= IRC_SERVER_RECV_MSG_MAX_LENGTH)
|
||||||
|
return;
|
||||||
unterminated_message2 =
|
unterminated_message2 =
|
||||||
realloc (server->unterminated_message,
|
realloc (server->unterminated_message,
|
||||||
(strlen (server->unterminated_message) +
|
(strlen (server->unterminated_message) +
|
||||||
|
|||||||
@@ -142,6 +142,15 @@ enum t_irc_server_option
|
|||||||
#define IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES 4096
|
#define IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES 4096
|
||||||
#define IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES 24
|
#define IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES 24
|
||||||
|
|
||||||
|
/*
|
||||||
|
* maximum length of an unterminated message (a received line without
|
||||||
|
* end-of-line) and of the accumulated "005" (ISUPPORT) data; these limits
|
||||||
|
* protect against a server sending a huge amount of data without end-of-line
|
||||||
|
* (or a flood of "005" messages), which would consume all the memory
|
||||||
|
*/
|
||||||
|
#define IRC_SERVER_RECV_MSG_MAX_LENGTH (64 * 1024)
|
||||||
|
#define IRC_SERVER_ISUPPORT_MAX_LENGTH (64 * 1024)
|
||||||
|
|
||||||
/* casemapping (string comparisons for nicks/channels) */
|
/* casemapping (string comparisons for nicks/channels) */
|
||||||
enum t_irc_server_casemapping
|
enum t_irc_server_casemapping
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ logger_info_log_file_cb (const void *pointer, void *data,
|
|||||||
const char *arguments)
|
const char *arguments)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
unsigned long value;
|
||||||
struct t_gui_buffer *buffer;
|
struct t_gui_buffer *buffer;
|
||||||
struct t_logger_buffer *logger_buffer;
|
struct t_logger_buffer *logger_buffer;
|
||||||
|
|
||||||
@@ -52,20 +53,16 @@ logger_info_log_file_cb (const void *pointer, void *data,
|
|||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
if (strncmp (arguments, "0x", 2) == 0)
|
if (strncmp (arguments, "0x", 2) == 0)
|
||||||
{
|
{
|
||||||
rc = sscanf (arguments, "%p", &buffer);
|
rc = sscanf (arguments, "%lx", &value);
|
||||||
if ((rc != EOF) && (rc != 0) && buffer)
|
if ((rc != EOF) && (rc != 0) && value)
|
||||||
{
|
{
|
||||||
if (!weechat_hdata_check_pointer (weechat_hdata_get ("buffer"),
|
if (weechat_hdata_check_pointer (weechat_hdata_get ("buffer"),
|
||||||
NULL,
|
NULL,
|
||||||
buffer))
|
(struct t_gui_buffer *)value))
|
||||||
{
|
{
|
||||||
buffer = NULL;
|
buffer = (struct t_gui_buffer *)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
buffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ add_library(lua MODULE
|
|||||||
set_target_properties(lua PROPERTIES PREFIX "")
|
set_target_properties(lua PROPERTIES PREFIX "")
|
||||||
|
|
||||||
if(LUA_FOUND)
|
if(LUA_FOUND)
|
||||||
|
add_definitions(${LUA_CFLAGS})
|
||||||
include_directories(${LUA_INCLUDE_DIRS})
|
include_directories(${LUA_INCLUDE_DIRS})
|
||||||
target_link_libraries(lua ${LUA_LDFLAGS} weechat_plugins_scripts coverage_config)
|
target_link_libraries(lua ${LUA_LDFLAGS} weechat_plugins_scripts coverage_config)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ weechat_perl_exec (struct t_plugin_script *script,
|
|||||||
if (weechat_asprintf (
|
if (weechat_asprintf (
|
||||||
&func,
|
&func,
|
||||||
"%s::%s",
|
"%s::%s",
|
||||||
(char *) ((script->interpreter) ? script->interpreter : perl_main)
|
(char *) ((script->interpreter) ? script->interpreter : perl_main),
|
||||||
function) < 0)
|
function) < 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ plugin_script_str2ptr (struct t_weechat_plugin *weechat_plugin,
|
|||||||
const char *script_name, const char *function_name,
|
const char *script_name, const char *function_name,
|
||||||
const char *str_pointer)
|
const char *str_pointer)
|
||||||
{
|
{
|
||||||
void *pointer;
|
unsigned long value;
|
||||||
int rc;
|
int rc;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
|
|
||||||
@@ -415,9 +415,9 @@ plugin_script_str2ptr (struct t_weechat_plugin *weechat_plugin,
|
|||||||
if ((str_pointer[0] != '0') || (str_pointer[1] != 'x'))
|
if ((str_pointer[0] != '0') || (str_pointer[1] != 'x'))
|
||||||
goto invalid;
|
goto invalid;
|
||||||
|
|
||||||
rc = sscanf (str_pointer, "%p", &pointer);
|
rc = sscanf (str_pointer + 2, "%lx", &value);
|
||||||
if ((rc != EOF) && (rc >= 1))
|
if ((rc != EOF) && (rc >= 1))
|
||||||
return pointer;
|
return (void *)value;
|
||||||
|
|
||||||
invalid:
|
invalid:
|
||||||
if ((weechat_plugin->debug >= 1) && script_name && function_name)
|
if ((weechat_plugin->debug >= 1) && script_name && function_name)
|
||||||
|
|||||||
@@ -623,6 +623,7 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv)
|
|||||||
new_plugin->strncasecmp = &string_strncasecmp;
|
new_plugin->strncasecmp = &string_strncasecmp;
|
||||||
new_plugin->strncasecmp_range = &string_strncasecmp_range;
|
new_plugin->strncasecmp_range = &string_strncasecmp_range;
|
||||||
new_plugin->strcmp_ignore_chars = &string_strcmp_ignore_chars;
|
new_plugin->strcmp_ignore_chars = &string_strcmp_ignore_chars;
|
||||||
|
new_plugin->string_memcmp_constant_time = &string_memcmp_constant_time;
|
||||||
new_plugin->strcasestr = &string_strcasestr;
|
new_plugin->strcasestr = &string_strcasestr;
|
||||||
new_plugin->strlen_screen = &gui_chat_strlen_screen;
|
new_plugin->strlen_screen = &gui_chat_strlen_screen;
|
||||||
new_plugin->string_match = &string_match;
|
new_plugin->string_match = &string_match;
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ add_library(python MODULE
|
|||||||
)
|
)
|
||||||
set_target_properties(python PROPERTIES PREFIX "")
|
set_target_properties(python PROPERTIES PREFIX "")
|
||||||
|
|
||||||
if(PYTHON_FOUND)
|
if(Python_FOUND)
|
||||||
target_link_libraries(python PkgConfig::PYTHON weechat_plugins_scripts coverage_config)
|
include_directories(${Python_INCLUDE_DIRS})
|
||||||
|
add_definitions(${Python_DEFINITIONS})
|
||||||
|
target_link_libraries(python ${Python_LIBRARIES} weechat_plugins_scripts coverage_config)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(TARGETS python LIBRARY DESTINATION "${WEECHAT_LIBDIR}/plugins")
|
install(TARGETS python LIBRARY DESTINATION "${WEECHAT_LIBDIR}/plugins")
|
||||||
|
|||||||
@@ -57,15 +57,11 @@
|
|||||||
|
|
||||||
#define MSG_ADD_HDATA_TIME_USEC(__json_name, \
|
#define MSG_ADD_HDATA_TIME_USEC(__json_name, \
|
||||||
__var_name, __var_name_usec) \
|
__var_name, __var_name_usec) \
|
||||||
time_value = weechat_hdata_time (hdata, pointer, __var_name); \
|
tv.tv_sec = weechat_hdata_time (hdata, pointer, __var_name); \
|
||||||
local_time = localtime (&time_value); \
|
|
||||||
time_value -= local_time->tm_gmtoff; \
|
|
||||||
local_time = localtime (&time_value); \
|
|
||||||
tv.tv_sec = mktime (local_time); \
|
|
||||||
tv.tv_usec = weechat_hdata_integer (hdata, pointer, \
|
tv.tv_usec = weechat_hdata_integer (hdata, pointer, \
|
||||||
__var_name_usec); \
|
__var_name_usec); \
|
||||||
weechat_util_strftimeval (str_time, sizeof (str_time), \
|
weechat_util_strftimeval (str_time, sizeof (str_time), \
|
||||||
"%FT%T.%fZ", &tv); \
|
"%@%FT%T.%fZ", &tv); \
|
||||||
MSG_ADD_STR_BUF(__json_name, str_time);
|
MSG_ADD_STR_BUF(__json_name, str_time);
|
||||||
|
|
||||||
#define MSG_ADD_HDATA_STR(__json_name, __var_name) \
|
#define MSG_ADD_HDATA_STR(__json_name, __var_name) \
|
||||||
@@ -487,9 +483,7 @@ relay_api_msg_line_data_to_json (struct t_gui_line_data *line_data,
|
|||||||
const char *ptr_string;
|
const char *ptr_string;
|
||||||
char *string, str_time[256], str_var[64];
|
char *string, str_time[256], str_var[64];
|
||||||
int i, tags_count;
|
int i, tags_count;
|
||||||
time_t time_value;
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct tm *local_time;
|
|
||||||
|
|
||||||
hdata = relay_hdata_line_data;
|
hdata = relay_hdata_line_data;
|
||||||
pointer = line_data;
|
pointer = line_data;
|
||||||
@@ -792,9 +786,7 @@ relay_api_msg_hotlist_to_json (struct t_gui_hotlist *hotlist)
|
|||||||
struct t_gui_hotlist *pointer;
|
struct t_gui_hotlist *pointer;
|
||||||
struct t_gui_buffer *buffer;
|
struct t_gui_buffer *buffer;
|
||||||
cJSON *json, *json_count;
|
cJSON *json, *json_count;
|
||||||
time_t time_value;
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct tm *local_time;
|
|
||||||
char str_time[256], str_key[32];
|
char str_time[256], str_key[32];
|
||||||
int i, array_size;
|
int i, array_size;
|
||||||
long long buffer_id;
|
long long buffer_id;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "../../weechat-plugin.h"
|
#include "../../weechat-plugin.h"
|
||||||
#include "../relay.h"
|
#include "../relay.h"
|
||||||
#include "relay-irc.h"
|
#include "relay-irc.h"
|
||||||
|
#include "../relay-auth.h"
|
||||||
#include "../relay-buffer.h"
|
#include "../relay-buffer.h"
|
||||||
#include "../relay-client.h"
|
#include "../relay-client.h"
|
||||||
#include "../relay-config.h"
|
#include "../relay-config.h"
|
||||||
@@ -1699,7 +1700,7 @@ relay_irc_recv (struct t_relay_client *client, const char *data)
|
|||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
if (password)
|
if (password)
|
||||||
{
|
{
|
||||||
if (strcmp (password, pos_password) == 0)
|
if (relay_auth_password_equals (password, pos_password))
|
||||||
{
|
{
|
||||||
RELAY_IRC_DATA(client, password_ok) = 1;
|
RELAY_IRC_DATA(client, password_ok) = 1;
|
||||||
weechat_hook_signal_send ("relay_client_auth_ok",
|
weechat_hook_signal_send ("relay_client_auth_ok",
|
||||||
|
|||||||
@@ -100,6 +100,66 @@ relay_auth_generate_nonce (int size)
|
|||||||
return nonce_hexa;
|
return nonce_hexa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compare two passwords for equality in constant time.
|
||||||
|
*
|
||||||
|
* HMAC both sides with a fresh random key, then compare the fixed-size
|
||||||
|
* MACs. This hides both the per-byte comparison and the password length
|
||||||
|
* from a timing-side-channel observer.
|
||||||
|
*
|
||||||
|
* Both messages are prefixed with a zero byte so empty passwords still
|
||||||
|
* produce a valid HMAC (the underlying crypto API rejects zero-length
|
||||||
|
* messages); the prefix is identical on both sides so equal inputs
|
||||||
|
* still yield equal MACs.
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* 1: passwords are equal
|
||||||
|
* 0: passwords are not equal (or an error occurred)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
relay_auth_password_equals (const char *password1, const char *password2)
|
||||||
|
{
|
||||||
|
unsigned char key[32];
|
||||||
|
char hmac1[64], hmac2[64];
|
||||||
|
char *buf1, *buf2;
|
||||||
|
int buf1_size, buf2_size, hmac1_size, hmac2_size, rc;
|
||||||
|
|
||||||
|
if (!password1 || !password2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
buf1_size = strlen (password1) + 1;
|
||||||
|
buf2_size = strlen (password2) + 1;
|
||||||
|
buf1 = malloc (buf1_size);
|
||||||
|
buf2 = malloc (buf2_size);
|
||||||
|
if (buf1 && buf2)
|
||||||
|
{
|
||||||
|
buf1[0] = 0;
|
||||||
|
memcpy (buf1 + 1, password1, buf1_size - 1);
|
||||||
|
buf2[0] = 0;
|
||||||
|
memcpy (buf2 + 1, password2, buf2_size - 1);
|
||||||
|
gcry_create_nonce (key, sizeof (key));
|
||||||
|
if (weechat_crypto_hmac (key, sizeof (key),
|
||||||
|
buf1, buf1_size,
|
||||||
|
"sha256",
|
||||||
|
hmac1, &hmac1_size)
|
||||||
|
&& weechat_crypto_hmac (key, sizeof (key),
|
||||||
|
buf2, buf2_size,
|
||||||
|
"sha256",
|
||||||
|
hmac2, &hmac2_size)
|
||||||
|
&& (hmac1_size == hmac2_size)
|
||||||
|
&& (weechat_string_memcmp_constant_time (
|
||||||
|
hmac1, hmac2, hmac1_size) == 0))
|
||||||
|
{
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free (buf1);
|
||||||
|
free (buf2);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Checks if password received as plain text is valid.
|
* Checks if password received as plain text is valid.
|
||||||
*
|
*
|
||||||
@@ -125,7 +185,7 @@ relay_auth_check_password_plain (struct t_relay_client *client,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (strcmp (password, relay_password) == 0) ? 0 : -2;
|
return relay_auth_password_equals (password, relay_password) ? 0 : -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -345,8 +405,9 @@ relay_auth_check_hash_sha (const char *hash_algo,
|
|||||||
const char *hash_sha,
|
const char *hash_sha,
|
||||||
const char *relay_password)
|
const char *relay_password)
|
||||||
{
|
{
|
||||||
char *salt_password, hash[512 / 8], hash_hexa[((512 / 8) * 2) + 1];
|
char *salt_password, *hash_sha_upper, hash[512 / 8];
|
||||||
int rc, length, hash_size;
|
char hash_hexa[((512 / 8) * 2) + 1];
|
||||||
|
int rc, length, hash_size, hash_hexa_len;
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
@@ -364,10 +425,23 @@ relay_auth_check_hash_sha (const char *hash_algo,
|
|||||||
hash_algo,
|
hash_algo,
|
||||||
hash, &hash_size))
|
hash, &hash_size))
|
||||||
{
|
{
|
||||||
weechat_string_base_encode ("16", hash, hash_size,
|
hash_hexa_len = weechat_string_base_encode ("16", hash, hash_size,
|
||||||
hash_hexa);
|
hash_hexa);
|
||||||
if (weechat_strcasecmp (hash_hexa, hash_sha) == 0)
|
/*
|
||||||
|
* Compare in constant time to defeat timing attacks: the
|
||||||
|
* client-supplied hash is normalized to uppercase to match
|
||||||
|
* the output of base16 encoding, then compared byte-for-byte
|
||||||
|
* with no early exit.
|
||||||
|
*/
|
||||||
|
hash_sha_upper = weechat_string_toupper (hash_sha);
|
||||||
|
if (hash_sha_upper
|
||||||
|
&& ((int)strlen (hash_sha_upper) == hash_hexa_len)
|
||||||
|
&& (weechat_string_memcmp_constant_time (
|
||||||
|
hash_hexa, hash_sha_upper, hash_hexa_len) == 0))
|
||||||
|
{
|
||||||
rc = 1;
|
rc = 1;
|
||||||
|
}
|
||||||
|
free (hash_sha_upper);
|
||||||
}
|
}
|
||||||
free (salt_password);
|
free (salt_password);
|
||||||
}
|
}
|
||||||
@@ -391,8 +465,8 @@ relay_auth_check_hash_pbkdf2 (const char *hash_pbkdf2_algo,
|
|||||||
const char *hash_pbkdf2,
|
const char *hash_pbkdf2,
|
||||||
const char *relay_password)
|
const char *relay_password)
|
||||||
{
|
{
|
||||||
char hash[512 / 8], hash_hexa[((512 / 8) * 2) + 1];
|
char *hash_pbkdf2_upper, hash[512 / 8], hash_hexa[((512 / 8) * 2) + 1];
|
||||||
int rc, hash_size;
|
int rc, hash_size, hash_hexa_len;
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
@@ -405,9 +479,18 @@ relay_auth_check_hash_pbkdf2 (const char *hash_pbkdf2_algo,
|
|||||||
iterations,
|
iterations,
|
||||||
hash, &hash_size))
|
hash, &hash_size))
|
||||||
{
|
{
|
||||||
weechat_string_base_encode ("16", hash, hash_size, hash_hexa);
|
hash_hexa_len = weechat_string_base_encode ("16", hash, hash_size,
|
||||||
if (weechat_strcasecmp (hash_hexa, hash_pbkdf2) == 0)
|
hash_hexa);
|
||||||
|
/* see relay_auth_check_hash_sha for rationale */
|
||||||
|
hash_pbkdf2_upper = weechat_string_toupper (hash_pbkdf2);
|
||||||
|
if (hash_pbkdf2_upper
|
||||||
|
&& ((int)strlen (hash_pbkdf2_upper) == hash_hexa_len)
|
||||||
|
&& (weechat_string_memcmp_constant_time (
|
||||||
|
hash_hexa, hash_pbkdf2_upper, hash_hexa_len) == 0))
|
||||||
|
{
|
||||||
rc = 1;
|
rc = 1;
|
||||||
|
}
|
||||||
|
free (hash_pbkdf2_upper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ extern char *relay_auth_password_hash_algo_name[];
|
|||||||
|
|
||||||
extern int relay_auth_password_hash_algo_search (const char *name);
|
extern int relay_auth_password_hash_algo_search (const char *name);
|
||||||
extern char *relay_auth_generate_nonce (int size);
|
extern char *relay_auth_generate_nonce (int size);
|
||||||
|
extern int relay_auth_password_equals (const char *password1,
|
||||||
|
const char *password2);
|
||||||
extern int relay_auth_check_password_plain (struct t_relay_client *client,
|
extern int relay_auth_check_password_plain (struct t_relay_client *client,
|
||||||
const char *password,
|
const char *password,
|
||||||
const char *relay_password);
|
const char *relay_password);
|
||||||
|
|||||||
@@ -487,6 +487,19 @@ relay_http_add_to_body (struct t_relay_http_request *request,
|
|||||||
if (!partial_message || !*partial_message)
|
if (!partial_message || !*partial_message)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reject the body if its announced length is too big: this prevents a
|
||||||
|
* client from forcing an unbounded allocation by announcing a huge
|
||||||
|
* "Content-Length"
|
||||||
|
*/
|
||||||
|
if (request->content_length > RELAY_HTTP_BODY_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
free (*partial_message);
|
||||||
|
*partial_message = NULL;
|
||||||
|
request->status = RELAY_HTTP_END;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
num_bytes_missing = request->content_length
|
num_bytes_missing = request->content_length
|
||||||
- request->body_size;
|
- request->body_size;
|
||||||
if (num_bytes_missing <= 0)
|
if (num_bytes_missing <= 0)
|
||||||
@@ -940,6 +953,14 @@ relay_http_recv (struct t_relay_client *client, const char *data)
|
|||||||
|
|
||||||
if (client->partial_message)
|
if (client->partial_message)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* limit the size of the partial message: once the maximum is reached,
|
||||||
|
* ignore the extra data (protection against a client sending a huge
|
||||||
|
* amount of data without any end-of-line and dribbling it, which would
|
||||||
|
* consume all the memory)
|
||||||
|
*/
|
||||||
|
if (strlen (client->partial_message) >= RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH)
|
||||||
|
return;
|
||||||
new_partial = realloc (client->partial_message,
|
new_partial = realloc (client->partial_message,
|
||||||
strlen (client->partial_message) +
|
strlen (client->partial_message) +
|
||||||
strlen (data) + 1);
|
strlen (data) + 1);
|
||||||
@@ -1639,7 +1660,7 @@ relay_http_print_log_request (struct t_relay_http_request *request)
|
|||||||
weechat_log_printf (" path_items. . . . . . . : %p", request->path_items);
|
weechat_log_printf (" path_items. . . . . . . : %p", request->path_items);
|
||||||
if (request->path_items)
|
if (request->path_items)
|
||||||
{
|
{
|
||||||
for (i = 0; request->path_items[0]; i++)
|
for (i = 0; request->path_items[i]; i++)
|
||||||
{
|
{
|
||||||
weechat_log_printf (" '%s'", request->path_items[i]);
|
weechat_log_printf (" '%s'", request->path_items[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,22 @@ enum t_relay_client_http_status
|
|||||||
#define RELAY_HTTP_ERROR_NOT_FOUND "Resource not found"
|
#define RELAY_HTTP_ERROR_NOT_FOUND "Resource not found"
|
||||||
#define RELAY_HTTP_ERROR_OUT_OF_MEMORY "Out of memory"
|
#define RELAY_HTTP_ERROR_OUT_OF_MEMORY "Out of memory"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* maximum length of an HTTP request body: used as an upper bound on the
|
||||||
|
* "Content-Length" accepted from a client, to prevent a client from forcing
|
||||||
|
* an unbounded allocation by announcing a huge body
|
||||||
|
*/
|
||||||
|
#define RELAY_HTTP_BODY_MAX_LENGTH (8 * 1024 * 1024)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* maximum length of the partial message accumulated while reading an HTTP
|
||||||
|
* request: once this limit is reached, the extra data is ignored; this
|
||||||
|
* protects against a client sending a huge amount of data without any
|
||||||
|
* end-of-line (an unterminated method or header line), which would consume
|
||||||
|
* all the memory
|
||||||
|
*/
|
||||||
|
#define RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH (8 * 1024 * 1024)
|
||||||
|
|
||||||
struct t_relay_http_request
|
struct t_relay_http_request
|
||||||
{
|
{
|
||||||
enum t_relay_client_http_status status; /* HTTP status */
|
enum t_relay_client_http_status status; /* HTTP status */
|
||||||
|
|||||||
@@ -530,7 +530,7 @@ relay_websocket_inflate (const void *data, size_t size, z_stream *strm,
|
|||||||
int rc;
|
int rc;
|
||||||
unsigned char append_bytes[4] = { 0x00, 0x00, 0xFF, 0xFF };
|
unsigned char append_bytes[4] = { 0x00, 0x00, 0xFF, 0xFF };
|
||||||
Bytef *data2, *dest, *dest2;
|
Bytef *data2, *dest, *dest2;
|
||||||
uLongf size2, dest_size;
|
uLongf size2, dest_size, new_size;
|
||||||
|
|
||||||
if (!data || (size == 0) || !strm || !size_decompressed)
|
if (!data || (size == 0) || !strm || !size_decompressed)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -547,8 +547,13 @@ relay_websocket_inflate (const void *data, size_t size, z_stream *strm,
|
|||||||
memcpy (data2, data, size);
|
memcpy (data2, data, size);
|
||||||
memcpy (data2 + size, append_bytes, sizeof (append_bytes));
|
memcpy (data2 + size, append_bytes, sizeof (append_bytes));
|
||||||
|
|
||||||
/* estimate the decompressed size, by default 10 * size */
|
/*
|
||||||
dest_size = 10 * size2;
|
* estimate the decompressed size, by default 10 * size, capped to the
|
||||||
|
* maximum allowed size (also prevents an integer overflow on the
|
||||||
|
* multiplication)
|
||||||
|
*/
|
||||||
|
dest_size = (size2 > WEBSOCKET_INFLATE_MAX_SIZE / 10) ?
|
||||||
|
WEBSOCKET_INFLATE_MAX_SIZE : 10 * size2;
|
||||||
dest = malloc (dest_size);
|
dest = malloc (dest_size);
|
||||||
if (!dest)
|
if (!dest)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -577,8 +582,19 @@ relay_websocket_inflate (const void *data, size_t size, z_stream *strm,
|
|||||||
&& (strm->avail_in > 0)))
|
&& (strm->avail_in > 0)))
|
||||||
{
|
{
|
||||||
/* output buffer is not large enough */
|
/* output buffer is not large enough */
|
||||||
strm->avail_out += dest_size;
|
if (dest_size >= WEBSOCKET_INFLATE_MAX_SIZE)
|
||||||
dest_size *= 2;
|
{
|
||||||
|
/*
|
||||||
|
* decompressed data is too large: reject the frame
|
||||||
|
* (protection against a "deflate bomb")
|
||||||
|
*/
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
/* double the buffer, capped to the maximum allowed size */
|
||||||
|
new_size = (dest_size > WEBSOCKET_INFLATE_MAX_SIZE / 2) ?
|
||||||
|
WEBSOCKET_INFLATE_MAX_SIZE : dest_size * 2;
|
||||||
|
strm->avail_out += (uInt)(new_size - dest_size);
|
||||||
|
dest_size = new_size;
|
||||||
dest2 = realloc (dest, dest_size);
|
dest2 = realloc (dest, dest_size);
|
||||||
if (!dest2)
|
if (!dest2)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -685,6 +701,14 @@ relay_websocket_decode_frame (const unsigned char *buffer,
|
|||||||
index_buffer += length_frame_size;
|
index_buffer += length_frame_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reject the frame if its announced length is too big: this prevents
|
||||||
|
* a client from forcing an unbounded allocation (and unbounded
|
||||||
|
* accumulation of partial frames) by announcing a huge frame
|
||||||
|
*/
|
||||||
|
if (length_frame > WEBSOCKET_FRAME_MAX_LENGTH)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (masked_frame)
|
if (masked_frame)
|
||||||
{
|
{
|
||||||
/* read mask (4 bytes) */
|
/* read mask (4 bytes) */
|
||||||
|
|||||||
@@ -39,6 +39,21 @@
|
|||||||
|
|
||||||
#define WEBSOCKET_SUB_PROTOCOL_API_WEECHAT "api.weechat"
|
#define WEBSOCKET_SUB_PROTOCOL_API_WEECHAT "api.weechat"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* maximum length of a websocket frame received from a client (or a remote
|
||||||
|
* WeeChat): used as an upper bound on the announced frame payload length, to
|
||||||
|
* prevent a client from forcing an unbounded allocation by announcing a huge
|
||||||
|
* frame and dribbling its payload
|
||||||
|
*/
|
||||||
|
#define WEBSOCKET_FRAME_MAX_LENGTH (8 * 1024 * 1024)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* maximum size of a decompressed websocket frame (with "permessage-deflate"):
|
||||||
|
* used as an upper bound when inflating, to prevent a small compressed frame
|
||||||
|
* from decompressing to an unbounded amount of data ("deflate bomb")
|
||||||
|
*/
|
||||||
|
#define WEBSOCKET_INFLATE_MAX_SIZE (8 * 1024 * 1024)
|
||||||
|
|
||||||
struct t_relay_client;
|
struct t_relay_client;
|
||||||
struct t_relay_http_request;
|
struct t_relay_http_request;
|
||||||
|
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ relay_modifier_input_text_display_cb (const void *pointer,
|
|||||||
{
|
{
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
struct t_relay_remote *ptr_remote;
|
struct t_relay_remote *ptr_remote;
|
||||||
|
unsigned long value;
|
||||||
const char *ptr_input, *ptr_text_local, *ptr_text_remote;
|
const char *ptr_input, *ptr_text_local, *ptr_text_remote;
|
||||||
char *text, *new_input;
|
char *text, *new_input;
|
||||||
int rc, input_get_any_user_data;
|
int rc, input_get_any_user_data;
|
||||||
@@ -281,10 +282,12 @@ relay_modifier_input_text_display_cb (const void *pointer,
|
|||||||
if (!relay_remotes)
|
if (!relay_remotes)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rc = sscanf (modifier_data, "%p", &ptr_buffer);
|
rc = sscanf (modifier_data, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
|
|
||||||
if (weechat_buffer_get_pointer (ptr_buffer, "plugin") != weechat_plugin)
|
if (weechat_buffer_get_pointer (ptr_buffer, "plugin") != weechat_plugin)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -588,6 +588,7 @@ relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg,
|
|||||||
char *path_returned;
|
char *path_returned;
|
||||||
const char *hdata_name, *array_size;
|
const char *hdata_name, *array_size;
|
||||||
void *pointer, **path_pointers;
|
void *pointer, **path_pointers;
|
||||||
|
unsigned long value;
|
||||||
int rc, num_keys, num_path, i, type, pos_count, count, rc_sscanf;
|
int rc, num_keys, num_path, i, type, pos_count, count, rc_sscanf;
|
||||||
uint32_t count32;
|
uint32_t count32;
|
||||||
|
|
||||||
@@ -628,9 +629,10 @@ relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg,
|
|||||||
pos[0] = '\0';
|
pos[0] = '\0';
|
||||||
if (strncmp (list_path[0], "0x", 2) == 0)
|
if (strncmp (list_path[0], "0x", 2) == 0)
|
||||||
{
|
{
|
||||||
rc_sscanf = sscanf (list_path[0], "%p", &pointer);
|
rc_sscanf = sscanf (list_path[0], "%lx", &value);
|
||||||
if ((rc_sscanf != EOF) && (rc_sscanf != 0))
|
if ((rc_sscanf != EOF) && (rc_sscanf != 0))
|
||||||
{
|
{
|
||||||
|
pointer = (void *)value;
|
||||||
if (!weechat_hdata_check_pointer (ptr_hdata_head, NULL, pointer))
|
if (!weechat_hdata_check_pointer (ptr_hdata_head, NULL, pointer))
|
||||||
{
|
{
|
||||||
if (weechat_relay_plugin->debug >= 1)
|
if (weechat_relay_plugin->debug >= 1)
|
||||||
@@ -644,10 +646,6 @@ relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
pointer = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pointer = weechat_hdata_get_list (ptr_hdata_head, list_path[0]);
|
pointer = weechat_hdata_get_list (ptr_hdata_head, list_path[0]);
|
||||||
|
|||||||
@@ -49,14 +49,17 @@ struct t_gui_buffer *
|
|||||||
relay_weechat_protocol_get_buffer (const char *arg)
|
relay_weechat_protocol_get_buffer (const char *arg)
|
||||||
{
|
{
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
|
unsigned long value;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
ptr_buffer = NULL;
|
ptr_buffer = NULL;
|
||||||
|
|
||||||
if (strncmp (arg, "0x", 2) == 0)
|
if (strncmp (arg, "0x", 2) == 0)
|
||||||
{
|
{
|
||||||
rc = sscanf (arg, "%p", &ptr_buffer);
|
rc = sscanf (arg, "%lx", &value);
|
||||||
if ((rc != EOF) && (rc != 0) && ptr_buffer)
|
if ((rc != EOF) && (rc != 0))
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
|
if (ptr_buffer)
|
||||||
{
|
{
|
||||||
if (!weechat_hdata_check_pointer (
|
if (!weechat_hdata_check_pointer (
|
||||||
relay_hdata_buffer,
|
relay_hdata_buffer,
|
||||||
@@ -67,10 +70,6 @@ relay_weechat_protocol_get_buffer (const char *arg)
|
|||||||
ptr_buffer = NULL;
|
ptr_buffer = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr_buffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ptr_buffer = weechat_buffer_search ("==", arg);
|
ptr_buffer = weechat_buffer_search ("==", arg);
|
||||||
@@ -527,7 +526,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(info)
|
|||||||
RELAY_WEECHAT_PROTOCOL_CALLBACK(infolist)
|
RELAY_WEECHAT_PROTOCOL_CALLBACK(infolist)
|
||||||
{
|
{
|
||||||
struct t_relay_weechat_msg *msg;
|
struct t_relay_weechat_msg *msg;
|
||||||
void *pointer;
|
unsigned long value;
|
||||||
char *args;
|
char *args;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -536,17 +535,17 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(infolist)
|
|||||||
msg = relay_weechat_msg_new (id);
|
msg = relay_weechat_msg_new (id);
|
||||||
if (msg)
|
if (msg)
|
||||||
{
|
{
|
||||||
pointer = NULL;
|
value = 0;
|
||||||
args = NULL;
|
args = NULL;
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
{
|
{
|
||||||
rc = sscanf (argv[1], "%p", &pointer);
|
rc = sscanf (argv[1], "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
pointer = NULL;
|
value = 0;
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
args = argv_eol[2];
|
args = argv_eol[2];
|
||||||
}
|
}
|
||||||
relay_weechat_msg_add_infolist (msg, argv[0], pointer, args);
|
relay_weechat_msg_add_infolist (msg, argv[0], (void *)value, args);
|
||||||
relay_weechat_msg_send (client, msg);
|
relay_weechat_msg_send (client, msg);
|
||||||
relay_weechat_msg_free (msg);
|
relay_weechat_msg_free (msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ script_mouse_focus_chat_cb (const void *pointer, void *data,
|
|||||||
{
|
{
|
||||||
const char *buffer;
|
const char *buffer;
|
||||||
int rc;
|
int rc;
|
||||||
|
unsigned long value;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
long x;
|
long x;
|
||||||
char *error, str_date[64];
|
char *error, str_date[64];
|
||||||
@@ -56,10 +57,12 @@ script_mouse_focus_chat_cb (const void *pointer, void *data,
|
|||||||
if (!buffer)
|
if (!buffer)
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
rc = sscanf (buffer, "%p", &ptr_buffer);
|
rc = sscanf (buffer, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
|
|
||||||
if (!ptr_buffer || (ptr_buffer != script_buffer))
|
if (!ptr_buffer || (ptr_buffer != script_buffer))
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ spell_info_info_spell_dict_cb (const void *pointer, void *data,
|
|||||||
const char *arguments)
|
const char *arguments)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
unsigned long value;
|
||||||
struct t_gui_buffer *buffer;
|
struct t_gui_buffer *buffer;
|
||||||
const char *buffer_full_name, *ptr_dict;
|
const char *buffer_full_name, *ptr_dict;
|
||||||
|
|
||||||
@@ -53,9 +54,10 @@ spell_info_info_spell_dict_cb (const void *pointer, void *data,
|
|||||||
buffer_full_name = NULL;
|
buffer_full_name = NULL;
|
||||||
if (strncmp (arguments, "0x", 2) == 0)
|
if (strncmp (arguments, "0x", 2) == 0)
|
||||||
{
|
{
|
||||||
rc = sscanf (arguments, "%p", &buffer);
|
rc = sscanf (arguments, "%lx", &value);
|
||||||
if ((rc != EOF) && (rc != 0) && buffer)
|
if ((rc != EOF) && (rc != 0) && value)
|
||||||
{
|
{
|
||||||
|
buffer = (struct t_gui_buffer *)value;
|
||||||
if (weechat_hdata_check_pointer (weechat_hdata_get ("buffer"),
|
if (weechat_hdata_check_pointer (weechat_hdata_get ("buffer"),
|
||||||
NULL, buffer))
|
NULL, buffer))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -713,6 +713,7 @@ spell_modifier_cb (const void *pointer, void *data,
|
|||||||
const char *modifier,
|
const char *modifier,
|
||||||
const char *modifier_data, const char *string)
|
const char *modifier_data, const char *string)
|
||||||
{
|
{
|
||||||
|
unsigned long value;
|
||||||
struct t_gui_buffer *buffer;
|
struct t_gui_buffer *buffer;
|
||||||
struct t_spell_speller_buffer *ptr_speller_buffer;
|
struct t_spell_speller_buffer *ptr_speller_buffer;
|
||||||
char **result, *ptr_string, *ptr_string_orig, *pos_space;
|
char **result, *ptr_string, *ptr_string_orig, *pos_space;
|
||||||
@@ -735,10 +736,12 @@ spell_modifier_cb (const void *pointer, void *data,
|
|||||||
if (!string)
|
if (!string)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rc = sscanf (modifier_data, "%p", &buffer);
|
rc = sscanf (modifier_data, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
buffer = (struct t_gui_buffer *)value;
|
||||||
|
|
||||||
/* check text during search only if option is enabled */
|
/* check text during search only if option is enabled */
|
||||||
if (weechat_buffer_get_integer (buffer, "text_search")
|
if (weechat_buffer_get_integer (buffer, "text_search")
|
||||||
&& !weechat_config_boolean (spell_config_check_during_search))
|
&& !weechat_config_boolean (spell_config_check_during_search))
|
||||||
|
|||||||
@@ -811,9 +811,9 @@ trigger_callback_modifier_cb (const void *pointer, void *data,
|
|||||||
const char *ptr_string;
|
const char *ptr_string;
|
||||||
char *string_modified, *pos, *buffer_pointer;
|
char *string_modified, *pos, *buffer_pointer;
|
||||||
char *str_tags, **tags, *prefix, *string_no_color;
|
char *str_tags, **tags, *prefix, *string_no_color;
|
||||||
|
unsigned long value;
|
||||||
int num_tags, rc;
|
int num_tags, rc;
|
||||||
void *ptr_irc_server, *ptr_irc_channel;
|
void *ptr_irc_server, *ptr_irc_channel;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
|
||||||
|
|
||||||
TRIGGER_CALLBACK_CB_INIT(NULL);
|
TRIGGER_CALLBACK_CB_INIT(NULL);
|
||||||
|
|
||||||
@@ -926,10 +926,10 @@ trigger_callback_modifier_cb (const void *pointer, void *data,
|
|||||||
pos - modifier_data);
|
pos - modifier_data);
|
||||||
if (buffer_pointer)
|
if (buffer_pointer)
|
||||||
{
|
{
|
||||||
rc = sscanf (buffer_pointer, "%p", &ptr_buffer);
|
rc = sscanf (buffer_pointer, "%lx", &value);
|
||||||
if ((rc != EOF) && (rc != 0))
|
if ((rc != EOF) && (rc != 0))
|
||||||
{
|
{
|
||||||
ctx.buffer = ptr_buffer;
|
ctx.buffer = (struct t_gui_buffer *)value;
|
||||||
weechat_hashtable_set (
|
weechat_hashtable_set (
|
||||||
ctx.extra_vars,
|
ctx.extra_vars,
|
||||||
"tg_plugin",
|
"tg_plugin",
|
||||||
@@ -997,7 +997,7 @@ trigger_callback_line_cb (const void *pointer, void *data,
|
|||||||
{
|
{
|
||||||
struct t_hashtable *hashtable;
|
struct t_hashtable *hashtable;
|
||||||
struct t_weelist_item *ptr_item;
|
struct t_weelist_item *ptr_item;
|
||||||
void *ptr;
|
unsigned long value;
|
||||||
const char *ptr_key, *ptr_value;
|
const char *ptr_key, *ptr_value;
|
||||||
char **tags, *str_tags, *string_no_color;
|
char **tags, *str_tags, *string_no_color;
|
||||||
int rc, num_tags;
|
int rc, num_tags;
|
||||||
@@ -1021,10 +1021,10 @@ trigger_callback_line_cb (const void *pointer, void *data,
|
|||||||
ptr_value = weechat_hashtable_get (line, "buffer");
|
ptr_value = weechat_hashtable_get (line, "buffer");
|
||||||
if (!ptr_value || (ptr_value[0] != '0') || (ptr_value[1] != 'x'))
|
if (!ptr_value || (ptr_value[0] != '0') || (ptr_value[1] != 'x'))
|
||||||
goto end;
|
goto end;
|
||||||
rc = sscanf (ptr_value, "%p", &ptr);
|
rc = sscanf (ptr_value + 2, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc < 1))
|
if ((rc == EOF) || (rc < 1))
|
||||||
goto end;
|
goto end;
|
||||||
ctx.buffer = ptr;
|
ctx.buffer = (void *)value;
|
||||||
|
|
||||||
weechat_hashtable_set (ctx.pointers, "buffer", ctx.buffer);
|
weechat_hashtable_set (ctx.pointers, "buffer", ctx.buffer);
|
||||||
ptr_value = weechat_hashtable_get (line, "tags");
|
ptr_value = weechat_hashtable_get (line, "tags");
|
||||||
@@ -1361,7 +1361,7 @@ trigger_callback_focus_cb (const void *pointer, void *data,
|
|||||||
struct t_hashtable *info)
|
struct t_hashtable *info)
|
||||||
{
|
{
|
||||||
const char *ptr_value;
|
const char *ptr_value;
|
||||||
void *ptr;
|
unsigned long value;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
TRIGGER_CALLBACK_CB_INIT(info);
|
TRIGGER_CALLBACK_CB_INIT(info);
|
||||||
@@ -1375,16 +1375,16 @@ trigger_callback_focus_cb (const void *pointer, void *data,
|
|||||||
ptr_value = weechat_hashtable_get (info, "_window");
|
ptr_value = weechat_hashtable_get (info, "_window");
|
||||||
if (ptr_value && ptr_value[0] && (strncmp (ptr_value, "0x", 2) == 0))
|
if (ptr_value && ptr_value[0] && (strncmp (ptr_value, "0x", 2) == 0))
|
||||||
{
|
{
|
||||||
rc = sscanf (ptr_value, "%p", &ptr);
|
rc = sscanf (ptr_value + 2, "%lx", &value);
|
||||||
if ((rc != EOF) && (rc >= 1))
|
if ((rc != EOF) && (rc >= 1))
|
||||||
weechat_hashtable_set (ctx.pointers, "window", ptr);
|
weechat_hashtable_set (ctx.pointers, "window", (void *)value);
|
||||||
}
|
}
|
||||||
ptr_value = weechat_hashtable_get (info, "_buffer");
|
ptr_value = weechat_hashtable_get (info, "_buffer");
|
||||||
if (ptr_value && ptr_value[0] && (strncmp (ptr_value, "0x", 2) == 0))
|
if (ptr_value && ptr_value[0] && (strncmp (ptr_value, "0x", 2) == 0))
|
||||||
{
|
{
|
||||||
rc = sscanf (ptr_value, "%p", &ptr);
|
rc = sscanf (ptr_value + 2, "%lx", &value);
|
||||||
if ((rc != EOF) && (rc >= 1))
|
if ((rc != EOF) && (rc >= 1))
|
||||||
weechat_hashtable_set (ctx.pointers, "buffer", ptr);
|
weechat_hashtable_set (ctx.pointers, "buffer", (void *)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* execute the trigger (conditions, regex, command) */
|
/* execute the trigger (conditions, regex, command) */
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ typing_input_text_for_buffer_modifier_cb (const void *pointer,
|
|||||||
const char *string)
|
const char *string)
|
||||||
{
|
{
|
||||||
int rc, text_search;
|
int rc, text_search;
|
||||||
|
unsigned long value;
|
||||||
const char *ptr_input_for_buffer;
|
const char *ptr_input_for_buffer;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
struct t_typing_status *ptr_typing_status;
|
struct t_typing_status *ptr_typing_status;
|
||||||
@@ -191,9 +192,10 @@ typing_input_text_for_buffer_modifier_cb (const void *pointer,
|
|||||||
(void) modifier;
|
(void) modifier;
|
||||||
(void) string;
|
(void) string;
|
||||||
|
|
||||||
rc = sscanf (modifier_data, "%p", &ptr_buffer);
|
rc = sscanf (modifier_data, "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
|
|
||||||
/* ignore any change in input if the user is searching text in the buffer */
|
/* ignore any change in input if the user is searching text in the buffer */
|
||||||
text_search = weechat_buffer_get_integer (ptr_buffer, "text_search");
|
text_search = weechat_buffer_get_integer (ptr_buffer, "text_search");
|
||||||
@@ -380,6 +382,7 @@ typing_typing_set_nick_signal_cb (const void *pointer, void *data,
|
|||||||
{
|
{
|
||||||
char **items;
|
char **items;
|
||||||
int num_items, rc, state, updated;
|
int num_items, rc, state, updated;
|
||||||
|
unsigned long value;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
struct t_typing_status *ptr_typing_status;
|
struct t_typing_status *ptr_typing_status;
|
||||||
|
|
||||||
@@ -394,9 +397,10 @@ typing_typing_set_nick_signal_cb (const void *pointer, void *data,
|
|||||||
if (!items || (num_items != 3))
|
if (!items || (num_items != 3))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
rc = sscanf (items[0], "%p", &ptr_buffer);
|
rc = sscanf (items[0], "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
goto end;
|
goto end;
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
if (!ptr_buffer)
|
if (!ptr_buffer)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ struct t_weelist_item;
|
|||||||
* please change the date with current one; for a second change at same
|
* please change the date with current one; for a second change at same
|
||||||
* date, increment the 01, otherwise please keep 01.
|
* date, increment the 01, otherwise please keep 01.
|
||||||
*/
|
*/
|
||||||
#define WEECHAT_PLUGIN_API_VERSION "20250215-01"
|
#define WEECHAT_PLUGIN_API_VERSION "20260530-01"
|
||||||
|
|
||||||
/* macros for defining plugin infos */
|
/* macros for defining plugin infos */
|
||||||
#define WEECHAT_PLUGIN_NAME(__name) \
|
#define WEECHAT_PLUGIN_NAME(__name) \
|
||||||
@@ -346,6 +346,8 @@ struct t_weechat_plugin
|
|||||||
int max, int range);
|
int max, int range);
|
||||||
int (*strcmp_ignore_chars) (const char *string1, const char *string2,
|
int (*strcmp_ignore_chars) (const char *string1, const char *string2,
|
||||||
const char *chars_ignored, int case_sensitive);
|
const char *chars_ignored, int case_sensitive);
|
||||||
|
int (*string_memcmp_constant_time) (const void *area1, const void *area2,
|
||||||
|
size_t size);
|
||||||
const char *(*strcasestr) (const char *string, const char *search);
|
const char *(*strcasestr) (const char *string, const char *search);
|
||||||
int (*strlen_screen) (const char *string);
|
int (*strlen_screen) (const char *string);
|
||||||
int (*string_match) (const char *string, const char *mask,
|
int (*string_match) (const char *string, const char *mask,
|
||||||
@@ -1342,6 +1344,9 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
|
|||||||
(weechat_plugin->strcmp_ignore_chars)(__string1, __string2, \
|
(weechat_plugin->strcmp_ignore_chars)(__string1, __string2, \
|
||||||
__chars_ignored, \
|
__chars_ignored, \
|
||||||
__case_sensitive)
|
__case_sensitive)
|
||||||
|
#define weechat_string_memcmp_constant_time(__area1, __area2, __size) \
|
||||||
|
(weechat_plugin->string_memcmp_constant_time)(__area1, __area2, \
|
||||||
|
__size)
|
||||||
#define weechat_strcasestr(__string, __search) \
|
#define weechat_strcasestr(__string, __search) \
|
||||||
(weechat_plugin->strcasestr)(__string, __search)
|
(weechat_plugin->strcasestr)(__string, __search)
|
||||||
#define weechat_strlen_screen(__string) \
|
#define weechat_strlen_screen(__string) \
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ xfer_chat_recv_cb (const void *pointer, void *data, int fd)
|
|||||||
{
|
{
|
||||||
ctcp_action = 0;
|
ctcp_action = 0;
|
||||||
length = strlen (ptr_buf);
|
length = strlen (ptr_buf);
|
||||||
if (ptr_buf[length - 1] == '\r')
|
if ((length > 0) && (ptr_buf[length - 1] == '\r'))
|
||||||
{
|
{
|
||||||
ptr_buf[length - 1] = '\0';
|
ptr_buf[length - 1] = '\0';
|
||||||
length--;
|
length--;
|
||||||
|
|||||||
@@ -240,8 +240,8 @@ int
|
|||||||
xfer_dcc_resume_hash (struct t_xfer *xfer)
|
xfer_dcc_resume_hash (struct t_xfer *xfer)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
unsigned long long total_read;
|
unsigned long long total_read, length_buf, to_read;
|
||||||
ssize_t length_buf, to_read, num_read;
|
ssize_t num_read;
|
||||||
int ret, fd;
|
int ret, fd;
|
||||||
|
|
||||||
total_read = 0;
|
total_read = 0;
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ xfer_file_find_suffix (struct t_xfer *xfer)
|
|||||||
void
|
void
|
||||||
xfer_file_find_filename (struct t_xfer *xfer)
|
xfer_file_find_filename (struct t_xfer *xfer)
|
||||||
{
|
{
|
||||||
char *dir_separator, *path;
|
char *dir_separator, *path, *nick;
|
||||||
struct t_hashtable *options;
|
struct t_hashtable *options;
|
||||||
|
|
||||||
if (!XFER_IS_FILE(xfer->type))
|
if (!XFER_IS_FILE(xfer->type))
|
||||||
@@ -285,12 +285,20 @@ xfer_file_find_filename (struct t_xfer *xfer)
|
|||||||
{
|
{
|
||||||
strcat (xfer->local_filename, dir_separator);
|
strcat (xfer->local_filename, dir_separator);
|
||||||
}
|
}
|
||||||
free (dir_separator);
|
|
||||||
if (weechat_config_boolean (xfer_config_file_use_nick_in_filename))
|
if (weechat_config_boolean (xfer_config_file_use_nick_in_filename))
|
||||||
{
|
{
|
||||||
strcat (xfer->local_filename, xfer->remote_nick);
|
/*
|
||||||
|
* the remote nick comes from the server and can contain a directory
|
||||||
|
* separator: replace it so the nick cannot make the file be written
|
||||||
|
* outside the download directory
|
||||||
|
*/
|
||||||
|
nick = (dir_separator) ?
|
||||||
|
weechat_string_replace (xfer->remote_nick, dir_separator, "_") : NULL;
|
||||||
|
strcat (xfer->local_filename, (nick) ? nick : xfer->remote_nick);
|
||||||
|
free (nick);
|
||||||
strcat (xfer->local_filename, ".");
|
strcat (xfer->local_filename, ".");
|
||||||
}
|
}
|
||||||
|
free (dir_separator);
|
||||||
strcat (xfer->local_filename, xfer->filename);
|
strcat (xfer->local_filename, xfer->filename);
|
||||||
|
|
||||||
free (path);
|
free (path);
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ test_modifier_cb (const void *pointer, void *data,
|
|||||||
char **items, *new_string;
|
char **items, *new_string;
|
||||||
const char *ptr_plugin, *ptr_tags, *ptr_msg;
|
const char *ptr_plugin, *ptr_tags, *ptr_msg;
|
||||||
int num_items, length, rc;
|
int num_items, length, rc;
|
||||||
|
unsigned long value;
|
||||||
struct t_gui_buffer *ptr_buffer;
|
struct t_gui_buffer *ptr_buffer;
|
||||||
|
|
||||||
/* make C++ compiler happy */
|
/* make C++ compiler happy */
|
||||||
@@ -81,10 +82,12 @@ test_modifier_cb (const void *pointer, void *data,
|
|||||||
|
|
||||||
ptr_tags = (num_items >= 2) ? items[1] : NULL;
|
ptr_tags = (num_items >= 2) ? items[1] : NULL;
|
||||||
|
|
||||||
rc = sscanf (items[0], "%p", &ptr_buffer);
|
rc = sscanf (items[0], "%lx", &value);
|
||||||
if ((rc == EOF) || (rc == 0))
|
if ((rc == EOF) || (rc == 0))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
ptr_buffer = (struct t_gui_buffer *)value;
|
||||||
|
|
||||||
ptr_plugin = gui_buffer_get_plugin_name (ptr_buffer);
|
ptr_plugin = gui_buffer_get_plugin_name (ptr_buffer);
|
||||||
if (!ptr_plugin)
|
if (!ptr_plugin)
|
||||||
goto error;
|
goto error;
|
||||||
|
|||||||
@@ -342,6 +342,7 @@ TEST(CoreCalc, Expression)
|
|||||||
WEE_CHECK_CALC("0.0000000008", "1/1234567890");
|
WEE_CHECK_CALC("0.0000000008", "1/1234567890");
|
||||||
WEE_CHECK_CALC("0.0000000001", "1/12345678901");
|
WEE_CHECK_CALC("0.0000000001", "1/12345678901");
|
||||||
WEE_CHECK_CALC("0", "1/123456789012");
|
WEE_CHECK_CALC("0", "1/123456789012");
|
||||||
|
WEE_CHECK_CALC("1.2222222222", "1+0.22222222222222222222222222222222222");
|
||||||
|
|
||||||
/* expressions with parentheses */
|
/* expressions with parentheses */
|
||||||
WEE_CHECK_CALC("6", "((6))");
|
WEE_CHECK_CALC("6", "((6))");
|
||||||
|
|||||||
@@ -1035,7 +1035,6 @@ TEST(CoreEval, EvalExpression)
|
|||||||
WEE_CHECK_EVAL("", "${buffer[].full_name}");
|
WEE_CHECK_EVAL("", "${buffer[].full_name}");
|
||||||
WEE_CHECK_EVAL("", "${buffer[0x0].full_name}");
|
WEE_CHECK_EVAL("", "${buffer[0x0].full_name}");
|
||||||
WEE_CHECK_EVAL("", "${buffer[0x1].full_name}");
|
WEE_CHECK_EVAL("", "${buffer[0x1].full_name}");
|
||||||
WEE_CHECK_EVAL("", "${buffer[0xZ].full_name}");
|
|
||||||
WEE_CHECK_EVAL("", "${buffer[unknown_list].full_name}");
|
WEE_CHECK_EVAL("", "${buffer[unknown_list].full_name}");
|
||||||
WEE_CHECK_EVAL("", "${unknown_pointer}");
|
WEE_CHECK_EVAL("", "${unknown_pointer}");
|
||||||
WEE_CHECK_EVAL("", "${my_null_pointer}");
|
WEE_CHECK_EVAL("", "${my_null_pointer}");
|
||||||
|
|||||||
@@ -798,6 +798,38 @@ TEST(CoreString, StringComparison)
|
|||||||
LONGS_EQUAL(-2, string_strcmp_ignore_chars ("è", "ê", "", 1));
|
LONGS_EQUAL(-2, string_strcmp_ignore_chars ("è", "ê", "", 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests functions:
|
||||||
|
* string_memcmp_constant_time
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(CoreString, MemcmpConstantTime)
|
||||||
|
{
|
||||||
|
/* NULL handling */
|
||||||
|
LONGS_EQUAL(0, string_memcmp_constant_time (NULL, NULL, 0));
|
||||||
|
LONGS_EQUAL(0, string_memcmp_constant_time (NULL, NULL, 4));
|
||||||
|
LONGS_EQUAL(1, string_memcmp_constant_time (NULL, "abcd", 4));
|
||||||
|
LONGS_EQUAL(1, string_memcmp_constant_time ("abcd", NULL, 4));
|
||||||
|
|
||||||
|
/* zero-size compare always equal */
|
||||||
|
LONGS_EQUAL(0, string_memcmp_constant_time ("", "", 0));
|
||||||
|
LONGS_EQUAL(0, string_memcmp_constant_time ("abc", "xyz", 0));
|
||||||
|
|
||||||
|
/* equal areas */
|
||||||
|
LONGS_EQUAL(0, string_memcmp_constant_time ("abcd", "abcd", 4));
|
||||||
|
LONGS_EQUAL(0, string_memcmp_constant_time ("\x00\x01\x02\xff",
|
||||||
|
"\x00\x01\x02\xff", 4));
|
||||||
|
|
||||||
|
/* differing areas (first / middle / last byte) */
|
||||||
|
LONGS_EQUAL(1, string_memcmp_constant_time ("Xbcd", "abcd", 4));
|
||||||
|
LONGS_EQUAL(1, string_memcmp_constant_time ("aXcd", "abcd", 4));
|
||||||
|
LONGS_EQUAL(1, string_memcmp_constant_time ("abcX", "abcd", 4));
|
||||||
|
LONGS_EQUAL(1, string_memcmp_constant_time ("abcd", "abce", 4));
|
||||||
|
|
||||||
|
/* only compares "size" bytes, ignores trailing content */
|
||||||
|
LONGS_EQUAL(0, string_memcmp_constant_time ("abcd", "abcz", 3));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tests functions:
|
* Tests functions:
|
||||||
* string_strcasestr
|
* string_strcasestr
|
||||||
@@ -1420,6 +1452,8 @@ TEST(CoreString, Replace)
|
|||||||
WEE_TEST_STR(NULL, string_replace ("string", NULL, "replace"));
|
WEE_TEST_STR(NULL, string_replace ("string", NULL, "replace"));
|
||||||
WEE_TEST_STR(NULL, string_replace (NULL, "search", "replace"));
|
WEE_TEST_STR(NULL, string_replace (NULL, "search", "replace"));
|
||||||
|
|
||||||
|
WEE_TEST_STR("test abc def", string_replace("test abc def", "", "xxx"));
|
||||||
|
|
||||||
WEE_TEST_STR("test abc def", string_replace("test abc def", "xyz", "xxx"));
|
WEE_TEST_STR("test abc def", string_replace("test abc def", "xyz", "xxx"));
|
||||||
WEE_TEST_STR("test xxx def", string_replace("test abc def", "abc", "xxx"));
|
WEE_TEST_STR("test xxx def", string_replace("test abc def", "abc", "xxx"));
|
||||||
WEE_TEST_STR("xxx test xxx def xxx",
|
WEE_TEST_STR("xxx test xxx def xxx",
|
||||||
|
|||||||
@@ -185,6 +185,11 @@ TEST(CoreUtil, Strftimeval)
|
|||||||
"%H:%M:%S", &tv));
|
"%H:%M:%S", &tv));
|
||||||
STRCMP_EQUAL("10:29:09", str_time);
|
STRCMP_EQUAL("10:29:09", str_time);
|
||||||
|
|
||||||
|
strcpy (str_time, "test");
|
||||||
|
LONGS_EQUAL(8, util_strftimeval (str_time, sizeof (str_time),
|
||||||
|
"%@%H:%M:%S", &tv));
|
||||||
|
STRCMP_EQUAL("10:29:09", str_time);
|
||||||
|
|
||||||
strcpy (str_time, "test");
|
strcpy (str_time, "test");
|
||||||
LONGS_EQUAL(19, util_strftimeval (str_time, sizeof (str_time),
|
LONGS_EQUAL(19, util_strftimeval (str_time, sizeof (str_time),
|
||||||
"%Y-%m-%d %H:%M:%S", &tv));
|
"%Y-%m-%d %H:%M:%S", &tv));
|
||||||
@@ -537,4 +542,9 @@ TEST(CoreUtil, VersionNumber)
|
|||||||
LONGS_EQUAL(0x01010100, util_version_number ("1.1.1"));
|
LONGS_EQUAL(0x01010100, util_version_number ("1.1.1"));
|
||||||
LONGS_EQUAL(0x01010200, util_version_number ("1.1.2"));
|
LONGS_EQUAL(0x01010200, util_version_number ("1.1.2"));
|
||||||
LONGS_EQUAL(0x01020304, util_version_number ("1.2.3.4"));
|
LONGS_EQUAL(0x01020304, util_version_number ("1.2.3.4"));
|
||||||
|
LONGS_EQUAL(0x7EFFFFFF, util_version_number ("126.255.255.255"));
|
||||||
|
LONGS_EQUAL(0x7FFFFFFF, util_version_number ("127.255.255.255"));
|
||||||
|
LONGS_EQUAL(0x7FFFFFFF, util_version_number ("128.255.255.255"));
|
||||||
|
LONGS_EQUAL(0x7FFFFFFF, util_version_number ("255.255.255.255"));
|
||||||
|
LONGS_EQUAL(0x7FFFFFFF, util_version_number ("999999999.999999999.999999999.999999999"));;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ TEST_GROUP(IrcProtocolWithServer)
|
|||||||
|
|
||||||
void server_recv (const char *command)
|
void server_recv (const char *command)
|
||||||
{
|
{
|
||||||
char str_command[4096];
|
char str_command[8192];
|
||||||
|
|
||||||
record_start ();
|
record_start ();
|
||||||
arraylist_clear (sent_messages);
|
arraylist_clear (sent_messages);
|
||||||
@@ -3845,6 +3845,44 @@ TEST(IrcProtocolWithServer, 005_full)
|
|||||||
STRCMP_EQUAL(IRC_MSG_005 " " IRC_MSG_005, ptr_server->isupport);
|
STRCMP_EQUAL(IRC_MSG_005 " " IRC_MSG_005, ptr_server->isupport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests functions:
|
||||||
|
* irc_protocol_cb_005 (accumulated ISUPPORT is bounded)
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(IrcProtocolWithServer, 005_limit)
|
||||||
|
{
|
||||||
|
char str_msg[4096], str_value[3500];
|
||||||
|
size_t length1, length2;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
SRV_INIT;
|
||||||
|
|
||||||
|
memset (str_value, 'X', sizeof (str_value) - 1);
|
||||||
|
str_value[sizeof (str_value) - 1] = '\0';
|
||||||
|
snprintf (str_msg, sizeof (str_msg),
|
||||||
|
":server 005 alice TEST=%s :are supported", str_value);
|
||||||
|
|
||||||
|
/* flood the server with "005" messages */
|
||||||
|
for (i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
server_recv (str_msg);
|
||||||
|
}
|
||||||
|
CHECK(ptr_server->isupport);
|
||||||
|
length1 = strlen (ptr_server->isupport);
|
||||||
|
|
||||||
|
/* the accumulated ISUPPORT data must be bounded */
|
||||||
|
CHECK(length1 <= IRC_SERVER_ISUPPORT_MAX_LENGTH + sizeof (str_value));
|
||||||
|
|
||||||
|
/* receiving more "005" messages must not grow it any further */
|
||||||
|
for (i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
server_recv (str_msg);
|
||||||
|
}
|
||||||
|
length2 = strlen (ptr_server->isupport);
|
||||||
|
LONGS_EQUAL(length1, length2);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tests functions:
|
* Tests functions:
|
||||||
* irc_protocol_cb_005 (infos from server, multiple messages)
|
* irc_protocol_cb_005 (infos from server, multiple messages)
|
||||||
|
|||||||
@@ -63,6 +63,49 @@ TEST(IrcServer, Valid)
|
|||||||
irc_server_free (server);
|
irc_server_free (server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests functions:
|
||||||
|
* irc_server_msgq_add_unterminated (via irc_server_msgq_add_buffer)
|
||||||
|
*
|
||||||
|
* Check that data received without any end-of-line does not grow the
|
||||||
|
* unterminated message buffer without limit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(IrcServer, MsgqAddBufferLimit)
|
||||||
|
{
|
||||||
|
struct t_irc_server *server;
|
||||||
|
char chunk[4097];
|
||||||
|
int i;
|
||||||
|
size_t length1, length2;
|
||||||
|
|
||||||
|
server = irc_server_alloc ("server_msgq");
|
||||||
|
CHECK(server);
|
||||||
|
|
||||||
|
memset (chunk, 'a', sizeof (chunk) - 1);
|
||||||
|
chunk[sizeof (chunk) - 1] = '\0';
|
||||||
|
|
||||||
|
/* feed a lot of data with no end-of-line */
|
||||||
|
for (i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
irc_server_msgq_add_buffer (server, chunk);
|
||||||
|
}
|
||||||
|
CHECK(server->unterminated_message);
|
||||||
|
length1 = strlen (server->unterminated_message);
|
||||||
|
|
||||||
|
/* the buffer must be bounded (not ~400 KB) */
|
||||||
|
CHECK(length1 <= IRC_SERVER_RECV_MSG_MAX_LENGTH + sizeof (chunk));
|
||||||
|
|
||||||
|
/* feeding more data must not grow the buffer any further */
|
||||||
|
for (i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
irc_server_msgq_add_buffer (server, chunk);
|
||||||
|
}
|
||||||
|
length2 = strlen (server->unterminated_message);
|
||||||
|
LONGS_EQUAL(length1, length2);
|
||||||
|
|
||||||
|
irc_server_free (server);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tests functions:
|
* Tests functions:
|
||||||
* irc_server_search
|
* irc_server_search
|
||||||
|
|||||||
@@ -417,12 +417,12 @@ TEST(RelayApiMsg, LinesToJson)
|
|||||||
gmtime_r (&(gui_buffers->own_lines->last_line->prev_line->data->date), &gm_time);
|
gmtime_r (&(gui_buffers->own_lines->last_line->prev_line->data->date), &gm_time);
|
||||||
tv.tv_sec = mktime (&gm_time);
|
tv.tv_sec = mktime (&gm_time);
|
||||||
tv.tv_usec = gui_buffers->own_lines->last_line->prev_line->data->date_usec;
|
tv.tv_usec = gui_buffers->own_lines->last_line->prev_line->data->date_usec;
|
||||||
util_strftimeval (str_date, sizeof (str_date), "%FT%T.%fZ", &tv);
|
util_strftimeval (str_date, sizeof (str_date), "%@%FT%T.%fZ", &tv);
|
||||||
WEE_CHECK_OBJ_STR(str_date, json_line, "date");
|
WEE_CHECK_OBJ_STR(str_date, json_line, "date");
|
||||||
gmtime_r (&(gui_buffers->own_lines->last_line->prev_line->data->date_printed), &gm_time);
|
gmtime_r (&(gui_buffers->own_lines->last_line->prev_line->data->date_printed), &gm_time);
|
||||||
tv.tv_sec = mktime (&gm_time);
|
tv.tv_sec = mktime (&gm_time);
|
||||||
tv.tv_usec = gui_buffers->own_lines->last_line->prev_line->data->date_usec_printed;
|
tv.tv_usec = gui_buffers->own_lines->last_line->prev_line->data->date_usec_printed;
|
||||||
util_strftimeval (str_date, sizeof (str_date), "%FT%T.%fZ", &tv);
|
util_strftimeval (str_date, sizeof (str_date), "%@%FT%T.%fZ", &tv);
|
||||||
WEE_CHECK_OBJ_STR(str_date, json_line, "date_printed");
|
WEE_CHECK_OBJ_STR(str_date, json_line, "date_printed");
|
||||||
WEE_CHECK_OBJ_BOOL(0, json_line, "highlight");
|
WEE_CHECK_OBJ_BOOL(0, json_line, "highlight");
|
||||||
WEE_CHECK_OBJ_STR("nick1", json_line, "prefix");
|
WEE_CHECK_OBJ_STR("nick1", json_line, "prefix");
|
||||||
@@ -453,12 +453,12 @@ TEST(RelayApiMsg, LinesToJson)
|
|||||||
gmtime_r (&(gui_buffers->own_lines->last_line->data->date), &gm_time);
|
gmtime_r (&(gui_buffers->own_lines->last_line->data->date), &gm_time);
|
||||||
tv.tv_sec = mktime (&gm_time);
|
tv.tv_sec = mktime (&gm_time);
|
||||||
tv.tv_usec = gui_buffers->own_lines->last_line->data->date_usec;
|
tv.tv_usec = gui_buffers->own_lines->last_line->data->date_usec;
|
||||||
util_strftimeval (str_date, sizeof (str_date), "%FT%T.%fZ", &tv);
|
util_strftimeval (str_date, sizeof (str_date), "%@%FT%T.%fZ", &tv);
|
||||||
WEE_CHECK_OBJ_STR(str_date, json_line, "date");
|
WEE_CHECK_OBJ_STR(str_date, json_line, "date");
|
||||||
gmtime_r (&(gui_buffers->own_lines->last_line->data->date_printed), &gm_time);
|
gmtime_r (&(gui_buffers->own_lines->last_line->data->date_printed), &gm_time);
|
||||||
tv.tv_sec = mktime (&gm_time);
|
tv.tv_sec = mktime (&gm_time);
|
||||||
tv.tv_usec = gui_buffers->own_lines->last_line->data->date_usec_printed;
|
tv.tv_usec = gui_buffers->own_lines->last_line->data->date_usec_printed;
|
||||||
util_strftimeval (str_date, sizeof (str_date), "%FT%T.%fZ", &tv);
|
util_strftimeval (str_date, sizeof (str_date), "%@%FT%T.%fZ", &tv);
|
||||||
WEE_CHECK_OBJ_STR(str_date, json_line, "date_printed");
|
WEE_CHECK_OBJ_STR(str_date, json_line, "date_printed");
|
||||||
WEE_CHECK_OBJ_BOOL(0, json_line, "highlight");
|
WEE_CHECK_OBJ_BOOL(0, json_line, "highlight");
|
||||||
WEE_CHECK_OBJ_STR("", json_line, "prefix");
|
WEE_CHECK_OBJ_STR("", json_line, "prefix");
|
||||||
@@ -624,7 +624,7 @@ TEST(RelayApiMsg, HotlistToJson)
|
|||||||
gmtime_r (&time_value, &gm_time);
|
gmtime_r (&time_value, &gm_time);
|
||||||
tv.tv_sec = mktime (&gm_time);
|
tv.tv_sec = mktime (&gm_time);
|
||||||
tv.tv_usec = hdata_integer (relay_hdata_hotlist, gui_hotlist, "time_usec");
|
tv.tv_usec = hdata_integer (relay_hdata_hotlist, gui_hotlist, "time_usec");
|
||||||
util_strftimeval (str_date, sizeof (str_date), "%FT%T.%fZ", &tv);
|
util_strftimeval (str_date, sizeof (str_date), "%@%FT%T.%fZ", &tv);
|
||||||
WEE_CHECK_OBJ_STR(str_date, json, "date");
|
WEE_CHECK_OBJ_STR(str_date, json, "date");
|
||||||
WEE_CHECK_OBJ_NUM(gui_buffers->id, json, "buffer_id");
|
WEE_CHECK_OBJ_NUM(gui_buffers->id, json, "buffer_id");
|
||||||
json_count = cJSON_GetObjectItem (json, "count");
|
json_count = cJSON_GetObjectItem (json, "count");
|
||||||
|
|||||||
@@ -107,6 +107,31 @@ TEST(RelayAuth, GenerateNonce)
|
|||||||
free (nonce);
|
free (nonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests functions:
|
||||||
|
* relay_auth_password_equals
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(RelayAuth, PasswordEquals)
|
||||||
|
{
|
||||||
|
/* invalid arguments */
|
||||||
|
LONGS_EQUAL(0, relay_auth_password_equals (NULL, NULL));
|
||||||
|
LONGS_EQUAL(0, relay_auth_password_equals ("abcd", NULL));
|
||||||
|
LONGS_EQUAL(0, relay_auth_password_equals (NULL, "abcd"));
|
||||||
|
|
||||||
|
/* different passwords */
|
||||||
|
LONGS_EQUAL(0, relay_auth_password_equals ("test", "password"));
|
||||||
|
LONGS_EQUAL(0, relay_auth_password_equals ("Password", "password"));
|
||||||
|
LONGS_EQUAL(0, relay_auth_password_equals ("", "password"));
|
||||||
|
LONGS_EQUAL(0, relay_auth_password_equals ("password", ""));
|
||||||
|
|
||||||
|
/* equal passwords */
|
||||||
|
LONGS_EQUAL(1, relay_auth_password_equals ("", ""));
|
||||||
|
LONGS_EQUAL(1, relay_auth_password_equals ("password", "password"));
|
||||||
|
LONGS_EQUAL(1, relay_auth_password_equals ("a really long password with spaces",
|
||||||
|
"a really long password with spaces"));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tests functions:
|
* Tests functions:
|
||||||
* relay_auth_check_password_plain
|
* relay_auth_check_password_plain
|
||||||
|
|||||||
@@ -159,6 +159,35 @@ TEST(RelayHttp, RequestAllocReinitFree)
|
|||||||
relay_http_request_free (request);
|
relay_http_request_free (request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests functions:
|
||||||
|
* relay_http_add_to_body (body too large is rejected)
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(RelayHttp, AddToBodyLimit)
|
||||||
|
{
|
||||||
|
struct t_relay_http_request *request;
|
||||||
|
char *partial;
|
||||||
|
|
||||||
|
request = relay_http_request_alloc ();
|
||||||
|
CHECK(request);
|
||||||
|
|
||||||
|
/* announce a body larger than the maximum allowed */
|
||||||
|
request->status = RELAY_HTTP_BODY;
|
||||||
|
request->content_length = RELAY_HTTP_BODY_MAX_LENGTH + 1;
|
||||||
|
partial = strdup ("some body data");
|
||||||
|
|
||||||
|
relay_http_add_to_body (request, &partial);
|
||||||
|
|
||||||
|
/* the body must be rejected: nothing allocated, request ended */
|
||||||
|
POINTERS_EQUAL(NULL, request->body);
|
||||||
|
LONGS_EQUAL(0, request->body_size);
|
||||||
|
POINTERS_EQUAL(NULL, partial);
|
||||||
|
LONGS_EQUAL(RELAY_HTTP_END, request->status);
|
||||||
|
|
||||||
|
relay_http_request_free (request);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tests functions:
|
* Tests functions:
|
||||||
* relay_http_url_decode
|
* relay_http_url_decode
|
||||||
|
|||||||
@@ -464,6 +464,41 @@ TEST(RelayWebsocket, Inflate)
|
|||||||
free (payload_comp);
|
free (payload_comp);
|
||||||
|
|
||||||
relay_websocket_deflate_free (ws_deflate);
|
relay_websocket_deflate_free (ws_deflate);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* protection against "deflate bomb": a small compressed frame that
|
||||||
|
* decompresses to more than WEBSOCKET_INFLATE_MAX_SIZE must be rejected
|
||||||
|
* (relay_websocket_inflate returns NULL)
|
||||||
|
*/
|
||||||
|
ws_deflate = relay_websocket_deflate_alloc ();
|
||||||
|
CHECK(ws_deflate);
|
||||||
|
ws_deflate->window_bits_deflate = 15;
|
||||||
|
ws_deflate->window_bits_inflate = 15;
|
||||||
|
ws_deflate->strm_deflate = (z_stream *)calloc (1, sizeof (*ws_deflate->strm_deflate));
|
||||||
|
CHECK(ws_deflate->strm_deflate);
|
||||||
|
LONGS_EQUAL(1, relay_websocket_deflate_init_stream_deflate (ws_deflate));
|
||||||
|
ws_deflate->strm_inflate = (z_stream *)calloc (1, sizeof (*ws_deflate->strm_inflate));
|
||||||
|
CHECK(ws_deflate->strm_inflate);
|
||||||
|
LONGS_EQUAL(1, relay_websocket_deflate_init_stream_inflate (ws_deflate));
|
||||||
|
|
||||||
|
/* highly compressible payload that decompresses past the maximum size */
|
||||||
|
size_t bomb_size = WEBSOCKET_INFLATE_MAX_SIZE + (1024 * 1024);
|
||||||
|
char *bomb = (char *)calloc (1, bomb_size);
|
||||||
|
CHECK(bomb);
|
||||||
|
|
||||||
|
payload_comp = (char *)relay_websocket_deflate (bomb, bomb_size,
|
||||||
|
ws_deflate->strm_deflate, &size_comp);
|
||||||
|
CHECK(payload_comp);
|
||||||
|
CHECK(size_comp < bomb_size);
|
||||||
|
|
||||||
|
payload_decomp = (char *)relay_websocket_inflate (payload_comp, size_comp,
|
||||||
|
ws_deflate->strm_inflate, &size_decomp);
|
||||||
|
POINTERS_EQUAL(NULL, payload_decomp);
|
||||||
|
|
||||||
|
free (payload_comp);
|
||||||
|
free (bomb);
|
||||||
|
|
||||||
|
relay_websocket_deflate_free (ws_deflate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -473,7 +508,44 @@ TEST(RelayWebsocket, Inflate)
|
|||||||
|
|
||||||
TEST(RelayWebsocket, DecodeFrame)
|
TEST(RelayWebsocket, DecodeFrame)
|
||||||
{
|
{
|
||||||
/* TODO: write tests */
|
struct t_relay_websocket_frame *frames;
|
||||||
|
char *partial_ws_frame;
|
||||||
|
int num_frames, partial_ws_frame_size;
|
||||||
|
/* small unmasked binary frame with payload "hello" */
|
||||||
|
unsigned char frame_ok[7] = { 0x82, 0x05, 'h', 'e', 'l', 'l', 'o' };
|
||||||
|
/* masked frame announcing a 1 GB payload (64-bit length field) */
|
||||||
|
unsigned char frame_too_big[10] = {
|
||||||
|
0x82, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* a valid small frame is decoded */
|
||||||
|
frames = NULL;
|
||||||
|
num_frames = 0;
|
||||||
|
partial_ws_frame = NULL;
|
||||||
|
partial_ws_frame_size = 0;
|
||||||
|
LONGS_EQUAL(1, relay_websocket_decode_frame (
|
||||||
|
frame_ok, sizeof (frame_ok), 0, NULL,
|
||||||
|
&frames, &num_frames, &partial_ws_frame,
|
||||||
|
&partial_ws_frame_size));
|
||||||
|
LONGS_EQUAL(1, num_frames);
|
||||||
|
CHECK(frames);
|
||||||
|
LONGS_EQUAL(5, frames[0].payload_size);
|
||||||
|
MEMCMP_EQUAL("hello", frames[0].payload, 5);
|
||||||
|
free (frames[0].payload);
|
||||||
|
free (frames);
|
||||||
|
free (partial_ws_frame);
|
||||||
|
|
||||||
|
/* a frame announcing an oversized payload is rejected (return 0) */
|
||||||
|
frames = NULL;
|
||||||
|
num_frames = 0;
|
||||||
|
partial_ws_frame = NULL;
|
||||||
|
partial_ws_frame_size = 0;
|
||||||
|
LONGS_EQUAL(0, relay_websocket_decode_frame (
|
||||||
|
frame_too_big, sizeof (frame_too_big), 1, NULL,
|
||||||
|
&frames, &num_frames, &partial_ws_frame,
|
||||||
|
&partial_ws_frame_size));
|
||||||
|
free (frames);
|
||||||
|
free (partial_ws_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+2
-2
@@ -39,8 +39,8 @@
|
|||||||
# devel-number the devel version as hex number ("0x04010000" for "4.1.0-dev")
|
# devel-number the devel version as hex number ("0x04010000" for "4.1.0-dev")
|
||||||
#
|
#
|
||||||
|
|
||||||
weechat_stable="4.6.0"
|
weechat_stable="4.6.3"
|
||||||
weechat_devel="4.6.0"
|
weechat_devel="4.6.4-dev"
|
||||||
|
|
||||||
stable_major=$(echo "${weechat_stable}" | cut -d"." -f1)
|
stable_major=$(echo "${weechat_stable}" | cut -d"." -f1)
|
||||||
stable_minor=$(echo "${weechat_stable}" | cut -d"." -f2)
|
stable_minor=$(echo "${weechat_stable}" | cut -d"." -f2)
|
||||||
|
|||||||
Reference in New Issue
Block a user