mirror of
				https://github.com/Tha14/toxic.git
				synced 2025-10-31 18:56:51 +01:00 
			
		
		
		
	Compare commits
	
		
			9 Commits
		
	
	
		
			v0.11.3
			...
			widechar_c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 6a203fd7bf | ||
|  | 93b3bbd5f6 | ||
|  | e122c5dbca | ||
|  | f6f41a510b | ||
|  | 05dbc626e2 | ||
|  | ceb175e3f1 | ||
|  | 4bd1d9bfee | ||
|  | 55944aa5a9 | ||
|  | b71c6a3792 | 
| @@ -1,7 +1,7 @@ | |||||||
| --- | --- | ||||||
| cirrus-ci_task: | bazel-opt_task: | ||||||
|   container: |   container: | ||||||
|     image: toxchat/toktok-stack:0.0.31-third_party |     image: toxchat/toktok-stack:latest-release | ||||||
|     cpu: 2 |     cpu: 2 | ||||||
|     memory: 2G |     memory: 2G | ||||||
|   configure_script: |   configure_script: | ||||||
| @@ -9,5 +9,4 @@ cirrus-ci_task: | |||||||
|   test_all_script: |   test_all_script: | ||||||
|     - cd /src/workspace && bazel test -k |     - cd /src/workspace && bazel test -k | ||||||
|         --remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST |         --remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST | ||||||
|         --config=release |  | ||||||
|         //toxic/... |         //toxic/... | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								.github/settings.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/settings.yml
									
									
									
									
										vendored
									
									
								
							| @@ -12,7 +12,8 @@ branches: | |||||||
|       required_status_checks: |       required_status_checks: | ||||||
|         contexts: |         contexts: | ||||||
|           - build |           - build | ||||||
|           - cirrus-ci |           - build-static | ||||||
|  |           - bazel-opt | ||||||
|           - Codacy Static Code Analysis |           - Codacy Static Code Analysis | ||||||
|           - code-review/reviewable |           - code-review/reviewable | ||||||
|           - infer |           - infer | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -37,6 +37,22 @@ jobs: | |||||||
|       - name: Build toxic |       - name: Build toxic | ||||||
|         run: make -j4 |         run: make -j4 | ||||||
|  |  | ||||||
|  |   build-static: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout code | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - name: Build minimal static toxic binary | ||||||
|  |         run: docker run --rm | ||||||
|  |           -v /tmp/artifact:/artifact | ||||||
|  |           -v $PWD:/toxic | ||||||
|  |           amd64/alpine:latest | ||||||
|  |           sh -c 'yes | /toxic/script/build-minimal-static-toxic.sh' | ||||||
|  |       - name: Display binary checksum | ||||||
|  |         run: | | ||||||
|  |           tar Jxf /tmp/artifact/toxic-minimal-static-musl_linux_x86-64.tar.xz | ||||||
|  |           sha256sum toxic-minimal-static-musl_linux_x86-64/toxic | ||||||
|  |  | ||||||
|   infer: |   infer: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     container: toxchat/infer |     container: toxchat/infer | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| load("@rules_cc//cc:defs.bzl", "cc_binary") | load("@rules_cc//cc:defs.bzl", "cc_binary") | ||||||
| load("//tools/project:build_defs.bzl", "project") | load("//tools/project:build_defs.bzl", "project") | ||||||
|  |  | ||||||
|  | package(features = ["layering_check"]) | ||||||
|  |  | ||||||
| project() | project() | ||||||
|  |  | ||||||
| cc_binary( | cc_binary( | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| # MIT License | # MIT License | ||||||
| # | # | ||||||
| # Copyright (c) 2021 Maxim Biro <nurupo.contributions@gmail.com> | # Copyright (c) 2021-2022 Maxim Biro <nurupo.contributions@gmail.com> | ||||||
| # | # | ||||||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | # Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
| # of this software and associated documentation files (the "Software"), to deal | # of this software and associated documentation files (the "Software"), to deal | ||||||
| @@ -36,8 +36,19 @@ | |||||||
| # | # | ||||||
| # that would use Toxic code from /home/jfreegman/git/toxic and place the build | # that would use Toxic code from /home/jfreegman/git/toxic and place the build | ||||||
| # artifact at /tmp/artifact. | # artifact at /tmp/artifact. | ||||||
| # You can change between amd64/alpine:latest and i386/alpine:latest, for 64-bit | # | ||||||
| # and 32-bit builds. | # You can change between: | ||||||
|  | #   amd64/alpine:latest, | ||||||
|  | #   i386/alpine:latest, | ||||||
|  | #   arm64v8/alpine:latest, | ||||||
|  | #   arm32v7/alpine:latest, | ||||||
|  | #   arm32v6/alpine:latest, | ||||||
|  | #   ppc64le/alpine:latest, | ||||||
|  | #   s390x/alpine:latest, | ||||||
|  | #   etc. | ||||||
|  | # as long as your system can run foreign architecture binaries, e.g. via qemu | ||||||
|  | # static bins and binfmt (install qemu-user-static package on Debian/Ubuntu). | ||||||
|  | # | ||||||
| # | # | ||||||
| # To debug, run: | # To debug, run: | ||||||
| # | # | ||||||
| @@ -53,12 +64,6 @@ set -eu | |||||||
| ARTIFACT_DIR="/artifact" | ARTIFACT_DIR="/artifact" | ||||||
| TOXIC_SRC_DIR="/toxic" | TOXIC_SRC_DIR="/toxic" | ||||||
|  |  | ||||||
| # Make sure we run in the expected environment |  | ||||||
| if ! grep -q 'docker' /proc/1/cgroup |  | ||||||
| then |  | ||||||
|   echo "Error: This script should be run inside a disposable Docker container as it might modify system files in ways that would break a real system." |  | ||||||
|   exit 1 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| if [ ! -f /etc/os-release ] || ! grep -qi 'Alpine Linux' /etc/os-release | if [ ! -f /etc/os-release ] || ! grep -qi 'Alpine Linux' /etc/os-release | ||||||
| then | then | ||||||
| @@ -186,7 +191,8 @@ cd curl* | |||||||
|   --with-openssl |   --with-openssl | ||||||
| make | make | ||||||
| make install | make install | ||||||
| sed -i 's|-lbrotlidec |-lbrotlidec-static -lbrotlicommon-static |g' $BUILD_DIR/prefix-curl/lib/pkgconfig/libcurl.pc | sed -i 's|-lbrotlidec |-lbrotlidec -lbrotlicommon |g' $BUILD_DIR/prefix-curl/lib/pkgconfig/libcurl.pc | ||||||
|  |  | ||||||
|  |  | ||||||
| # Build Toxic | # Build Toxic | ||||||
| cd "$BUILD_DIR" | cd "$BUILD_DIR" | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								src/chat.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/chat.c
									
									
									
									
									
								
							| @@ -676,8 +676,10 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_ | |||||||
|     FILE *filecheck = NULL; |     FILE *filecheck = NULL; | ||||||
|     int count = 1; |     int count = 1; | ||||||
|  |  | ||||||
|     while ((filecheck = fopen(file_path, "r"))) { |     while ((filecheck = fopen(file_path, "r")) || file_transfer_recv_path_exists(file_path)) { | ||||||
|  |         if (filecheck) { | ||||||
|             fclose(filecheck); |             fclose(filecheck); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         file_path[path_len] = '\0'; |         file_path[path_len] = '\0'; | ||||||
|         char d[5]; |         char d[5]; | ||||||
| @@ -1383,7 +1385,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m) | |||||||
|     self->x = x2; |     self->x = x2; | ||||||
|  |  | ||||||
|     /* Truncate note if it doesn't fit in statusbar */ |     /* Truncate note if it doesn't fit in statusbar */ | ||||||
|     size_t maxlen = x2 - getcurx(statusbar->topline) - (KEY_IDENT_DIGITS * 2) - 6; |     size_t maxlen = x2 - getcurx(statusbar->topline) - KEY_IDENT_BYTES - 6; | ||||||
|  |  | ||||||
|     pthread_mutex_lock(&Winthread.lock); |     pthread_mutex_lock(&Winthread.lock); | ||||||
|     size_t statusmsg_len = statusbar->statusmsg_len; |     size_t statusmsg_len = statusbar->statusmsg_len; | ||||||
| @@ -1414,10 +1416,10 @@ static void chat_onDraw(ToxWindow *self, Tox *m) | |||||||
|     int s_x; |     int s_x; | ||||||
|     getyx(statusbar->topline, s_y, s_x); |     getyx(statusbar->topline, s_y, s_x); | ||||||
|  |  | ||||||
|     mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - (KEY_IDENT_DIGITS * 2) - 3); |     mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - KEY_IDENT_BYTES  - 3); | ||||||
|     wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT)); |     wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT)); | ||||||
|  |  | ||||||
|     wmove(statusbar->topline, 0, x2 - (KEY_IDENT_DIGITS * 2) - 3); |     wmove(statusbar->topline, 0, x2 - KEY_IDENT_BYTES  - 3); | ||||||
|  |  | ||||||
|     wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT)); |     wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT)); | ||||||
|     wprintw(statusbar->topline, "{"); |     wprintw(statusbar->topline, "{"); | ||||||
| @@ -1425,7 +1427,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m) | |||||||
|  |  | ||||||
|     wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT)); |     wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT)); | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < KEY_IDENT_DIGITS; ++i) { |     for (size_t i = 0; i < KEY_IDENT_BYTES / 2; ++i) { | ||||||
|         wprintw(statusbar->topline, "%02X", Friends.list[self->num].pub_key[i] & 0xff); |         wprintw(statusbar->topline, "%02X", Friends.list[self->num].pub_key[i] & 0xff); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -45,9 +45,8 @@ extern FriendsList Friends; | |||||||
| void init_progress_bar(char *progline) | void init_progress_bar(char *progline) | ||||||
| { | { | ||||||
|     strcpy(progline, "0% ["); |     strcpy(progline, "0% ["); | ||||||
|     int i; |  | ||||||
|  |  | ||||||
|     for (i = 0; i < NUM_PROG_MARKS; ++i) { |     for (size_t i = 0; i < NUM_PROG_MARKS; ++i) { | ||||||
|         strcat(progline, "-"); |         strcat(progline, "-"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -397,3 +396,26 @@ void kill_all_file_transfers(Tox *m) | |||||||
|         kill_all_file_transfers_friend(m, Friends.list[i].num); |         kill_all_file_transfers_friend(m, Friends.list[i].num); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool file_transfer_recv_path_exists(const char *path) | ||||||
|  | { | ||||||
|  |     for (size_t friendnumber = 0; friendnumber < Friends.max_idx; ++friendnumber) { | ||||||
|  |         if (!Friends.list[friendnumber].active) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         for (size_t i = 0; i < MAX_FILES; ++i) { | ||||||
|  |             FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i]; | ||||||
|  |  | ||||||
|  |             if (ft->state == FILE_TRANSFER_INACTIVE) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (strcmp(path, ft->file_path) == 0) { | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -145,4 +145,7 @@ void kill_all_file_transfers_friend(Tox *m, uint32_t friendnumber); | |||||||
|  |  | ||||||
| void kill_all_file_transfers(Tox *m); | void kill_all_file_transfers(Tox *m); | ||||||
|  |  | ||||||
|  | /* Return true if any pending or active file receiver has the path `path`. */ | ||||||
|  | bool file_transfer_recv_path_exists(const char *path); | ||||||
|  |  | ||||||
| #endif /* FILE_TRANSFERS_H */ | #endif /* FILE_TRANSFERS_H */ | ||||||
|   | |||||||
							
								
								
									
										125
									
								
								src/line_info.c
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								src/line_info.c
									
									
									
									
									
								
							| @@ -20,6 +20,10 @@ | |||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | #ifndef _GNU_SOURCE | ||||||
|  | #define _GNU_SOURCE    /* needed for wcswidth() */ | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| @@ -137,13 +141,13 @@ static struct line_info *line_info_ret_queue(struct history *hst) | |||||||
|  * Return 0 if string does not contain a newline byte. |  * Return 0 if string does not contain a newline byte. | ||||||
|  * Return -1 if printing was aborted. |  * Return -1 if printing was aborted. | ||||||
|  */ |  */ | ||||||
| static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y) | static int print_n_chars(WINDOW *win, const wchar_t *s, size_t n, int max_y) | ||||||
| { | { | ||||||
|     bool newline = false; |     bool newline = false; | ||||||
|     char ch; |     wchar_t ch; | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < n && (ch = s[i]); ++i) { |     for (size_t i = 0; i < n && (ch = s[i]); ++i) { | ||||||
|         if (ch == '\n') { |         if (ch == L'\n') { | ||||||
|             newline = true; |             newline = true; | ||||||
|  |  | ||||||
|             int x; |             int x; | ||||||
| @@ -159,7 +163,17 @@ static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y) | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (win) { |         if (win) { | ||||||
|             wprintw(win, "%c", ch); | #ifdef HAVE_WIDECHAR | ||||||
|  |             waddnwstr(win, &ch, 1); | ||||||
|  | #else | ||||||
|  |             char b; | ||||||
|  |  | ||||||
|  |             if (wcstombs(&b, &ch, sizeof(char)) != 1) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             wprintw(win, "%c", b); | ||||||
|  | #endif  // HAVE_WIDECHAR | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -169,10 +183,10 @@ static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y) | |||||||
| /* Returns the index of the last space character in `s` found before `limit`. | /* Returns the index of the last space character in `s` found before `limit`. | ||||||
|  * Returns -1 if no space is found. |  * Returns -1 if no space is found. | ||||||
|  */ |  */ | ||||||
| static int rspace_index(const char *s, int limit) | static int rspace_index(const wchar_t *s, int limit) | ||||||
| { | { | ||||||
|     for (int i = limit; i >= 0; --i) { |     for (int i = limit; i >= 0; --i) { | ||||||
|         if (s[i] == ' ') { |         if (s[i] == L' ') { | ||||||
|             return i; |             return i; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -183,12 +197,12 @@ static int rspace_index(const char *s, int limit) | |||||||
| /* Returns the first index in `s` containing a newline byte found before `limit`. | /* Returns the first index in `s` containing a newline byte found before `limit`. | ||||||
|  * Returns -1 if no newline  is found. |  * Returns -1 if no newline  is found. | ||||||
|  */ |  */ | ||||||
| static int newline_index(const char *s, int limit) | static int newline_index(const wchar_t *s, int limit) | ||||||
| { | { | ||||||
|     char ch; |     wchar_t ch; | ||||||
|  |  | ||||||
|     for (int i = 0; i < limit && (ch = s[i]); ++i) { |     for (int i = 0; i < limit && (ch = s[i]); ++i) { | ||||||
|         if (ch == '\n') { |         if (ch == L'\n') { | ||||||
|             return i; |             return i; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -197,13 +211,13 @@ static int newline_index(const char *s, int limit) | |||||||
| } | } | ||||||
|  |  | ||||||
| /* Returns the number of newline bytes in `s` */ | /* Returns the number of newline bytes in `s` */ | ||||||
| static unsigned int newline_count(const char *s) | static unsigned int newline_count(const wchar_t *s) | ||||||
| { | { | ||||||
|     char ch; |     wchar_t ch; | ||||||
|     unsigned int count = 0; |     unsigned int count = 0; | ||||||
|  |  | ||||||
|     for (size_t i = 0; (ch = s[i]); ++i) { |     for (size_t i = 0; (ch = s[i]); ++i) { | ||||||
|         if (ch == '\n') { |         if (ch == L'\n') { | ||||||
|             ++count; |             ++count; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -226,10 +240,10 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | |||||||
|     int y; |     int y; | ||||||
|     UNUSED_VAR(y); |     UNUSED_VAR(y); | ||||||
|  |  | ||||||
|     const char *msg = line->msg; |     const wchar_t *msg = line->msg; | ||||||
|     uint16_t length = line->msg_len; |     uint16_t length = line->msg_width; | ||||||
|     uint16_t lines = 0; |     uint16_t lines = 0; | ||||||
|     const int x_start = line->len - line->msg_len - 1;  // manually keep track of x position because ncurses sucks |     const int x_start = line->len - line->msg_width - 1;  // manually keep track of x position because ncurses sucks | ||||||
|     int x_limit = max_x - x_start; |     int x_limit = max_x - x_start; | ||||||
|  |  | ||||||
|     if (x_limit <= 1) { |     if (x_limit <= 1) { | ||||||
| @@ -246,7 +260,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (length < x_limit) { |         if (length < x_limit) { | ||||||
|             int p_ret = print_n_chars(win, msg, length, max_y); |             const int p_ret = print_n_chars(win, msg, length, max_y); | ||||||
|  |  | ||||||
|             if (p_ret == 1) { |             if (p_ret == 1) { | ||||||
|                 lines += newline_count(msg); |                 lines += newline_count(msg); | ||||||
| @@ -258,7 +272,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         int newline_idx = newline_index(msg, x_limit - 1); |         const int newline_idx = newline_index(msg, x_limit - 1); | ||||||
|  |  | ||||||
|         if (newline_idx >= 0) { |         if (newline_idx >= 0) { | ||||||
|             if (print_n_chars(win, msg, newline_idx + 1, max_y) == -1) { |             if (print_n_chars(win, msg, newline_idx + 1, max_y) == -1) { | ||||||
| @@ -272,7 +286,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | |||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         int space_idx = rspace_index(msg, x_limit - 1); |         const int space_idx = rspace_index(msg, x_limit - 1); | ||||||
|  |  | ||||||
|         if (space_idx >= 1) { |         if (space_idx >= 1) { | ||||||
|             if (print_n_chars(win, msg, space_idx, max_y) == -1) { |             if (print_n_chars(win, msg, space_idx, max_y) == -1) { | ||||||
| @@ -321,6 +335,34 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Converts `msg` into a widechar string and puts the result in `buf`. | ||||||
|  |  * | ||||||
|  |  * Returns the widechar width of the string. | ||||||
|  |  */ | ||||||
|  | static uint16_t line_info_add_msg(wchar_t *buf, size_t buf_size, const char *msg) | ||||||
|  | { | ||||||
|  |     if (msg == NULL || msg[0] == '\0') { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     uint16_t width = 0; | ||||||
|  |  | ||||||
|  |     const wint_t wc_msg_len = mbs_to_wcs_buf(buf, msg, buf_size); | ||||||
|  |  | ||||||
|  |     if (wc_msg_len > 0 && wc_msg_len < buf_size) { | ||||||
|  |         buf[wc_msg_len] = L'\0'; | ||||||
|  |         width = (uint16_t) wcswidth(buf, wc_msg_len); | ||||||
|  |     } else { | ||||||
|  |         fprintf(stderr, "Failed to convert string '%s' to widechar\n", msg); | ||||||
|  |         const wchar_t *err = L"Failed to parse message"; | ||||||
|  |         width = wcslen(err); | ||||||
|  |         wmemcpy(buf, err, width); | ||||||
|  |         buf[width] = L'\0'; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return width; | ||||||
|  | } | ||||||
|  |  | ||||||
| static void line_info_init_line(ToxWindow *self, struct line_info *line) | static void line_info_init_line(ToxWindow *self, struct line_info *line) | ||||||
| { | { | ||||||
|     int y2; |     int y2; | ||||||
| @@ -409,13 +451,8 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const | |||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     uint16_t msg_len = 0; |     const uint16_t msg_width = line_info_add_msg(new_line->msg, sizeof(new_line->msg), frmt_msg); | ||||||
|  |     len += msg_width; | ||||||
|     if (frmt_msg[0]) { |  | ||||||
|         snprintf(new_line->msg, sizeof(new_line->msg), "%s", frmt_msg); |  | ||||||
|         msg_len = strlen(new_line->msg); |  | ||||||
|         len += msg_len; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (show_timestamp) { |     if (show_timestamp) { | ||||||
|         get_time_str(new_line->timestr, sizeof(new_line->timestr)); |         get_time_str(new_line->timestr, sizeof(new_line->timestr)); | ||||||
| @@ -434,7 +471,7 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const | |||||||
|  |  | ||||||
|     new_line->id = (hst->line_end->id + 1 + hst->queue_size) % INT_MAX; |     new_line->id = (hst->line_end->id + 1 + hst->queue_size) % INT_MAX; | ||||||
|     new_line->len = len; |     new_line->len = len; | ||||||
|     new_line->msg_len = msg_len; |     new_line->msg_width = msg_width; | ||||||
|     new_line->type = type; |     new_line->type = type; | ||||||
|     new_line->bold = bold; |     new_line->bold = bold; | ||||||
|     new_line->colour = colour; |     new_line->colour = colour; | ||||||
| @@ -518,9 +555,8 @@ void line_info_print(ToxWindow *self) | |||||||
|     const int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT; |     const int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT; | ||||||
|     const int max_x = self->show_peerlist ? x2 - 1 - SIDEBAR_WIDTH : x2; |     const int max_x = self->show_peerlist ? x2 - 1 - SIDEBAR_WIDTH : x2; | ||||||
|     uint16_t numlines = line->format_lines; |     uint16_t numlines = line->format_lines; | ||||||
|     int print_ret = 0; |  | ||||||
|  |  | ||||||
|     while (line && numlines++ <= max_y && print_ret == 0) { |     while (line && numlines++ <= max_y) { | ||||||
|         int y; |         int y; | ||||||
|         int x; |         int x; | ||||||
|         getyx(win, y, x); |         getyx(win, y, x); | ||||||
| @@ -557,22 +593,22 @@ void line_info_print(ToxWindow *self) | |||||||
|                 wprintw(win, "%s %s: ", user_settings->line_normal, line->name1); |                 wprintw(win, "%s %s: ", user_settings->line_normal, line->name1); | ||||||
|                 wattroff(win, COLOR_PAIR(nameclr)); |                 wattroff(win, COLOR_PAIR(nameclr)); | ||||||
|  |  | ||||||
|                 if (line->msg[0] == 0) { |                 if (line->msg[0] == L'\0') { | ||||||
|                     waddch(win, '\n'); |                     waddch(win, '\n'); | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if (line->msg[0] == '>') { |                 if (line->msg[0] == L'>') { | ||||||
|                     wattron(win, COLOR_PAIR(GREEN)); |                     wattron(win, COLOR_PAIR(GREEN)); | ||||||
|                 } else if (line->msg[0] == '<') { |                 } else if (line->msg[0] == L'<') { | ||||||
|                     wattron(win, COLOR_PAIR(RED)); |                     wattron(win, COLOR_PAIR(RED)); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 print_ret = print_wrap(win, line, max_x, max_y); |                 print_wrap(win, line, max_x, max_y); | ||||||
|  |  | ||||||
|                 if (line->msg[0] == '>') { |                 if (line->msg[0] == L'>') { | ||||||
|                     wattroff(win, COLOR_PAIR(GREEN)); |                     wattroff(win, COLOR_PAIR(GREEN)); | ||||||
|                 } else if (line->msg[0] == '<') { |                 } else if (line->msg[0] == L'<') { | ||||||
|                     wattroff(win, COLOR_PAIR(RED)); |                     wattroff(win, COLOR_PAIR(RED)); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -592,7 +628,7 @@ void line_info_print(ToxWindow *self) | |||||||
|  |  | ||||||
|                 wattron(win, COLOR_PAIR(YELLOW)); |                 wattron(win, COLOR_PAIR(YELLOW)); | ||||||
|                 wprintw(win, "%s %s ", user_settings->line_normal, line->name1); |                 wprintw(win, "%s %s ", user_settings->line_normal, line->name1); | ||||||
|                 print_ret = print_wrap(win, line, max_x, max_y); |                 print_wrap(win, line, max_x, max_y); | ||||||
|                 wattroff(win, COLOR_PAIR(YELLOW)); |                 wattroff(win, COLOR_PAIR(YELLOW)); | ||||||
|  |  | ||||||
|                 waddch(win, '\n'); |                 waddch(win, '\n'); | ||||||
| @@ -613,7 +649,7 @@ void line_info_print(ToxWindow *self) | |||||||
|                     wattron(win, COLOR_PAIR(line->colour)); |                     wattron(win, COLOR_PAIR(line->colour)); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 print_ret = print_wrap(win, line, max_x, max_y); |                 print_wrap(win, line, max_x, max_y); | ||||||
|                 waddch(win, '\n'); |                 waddch(win, '\n'); | ||||||
|  |  | ||||||
|                 if (line->bold) { |                 if (line->bold) { | ||||||
| @@ -631,8 +667,8 @@ void line_info_print(ToxWindow *self) | |||||||
|                 wprintw(win, "$ "); |                 wprintw(win, "$ "); | ||||||
|                 wattroff(win, COLOR_PAIR(GREEN)); |                 wattroff(win, COLOR_PAIR(GREEN)); | ||||||
|  |  | ||||||
|                 if (line->msg[0]) { |                 if (line->msg[0] != L'\0') { | ||||||
|                     print_ret = print_wrap(win, line, max_x, max_y); |                     print_wrap(win, line, max_x, max_y); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 waddch(win, '\n'); |                 waddch(win, '\n'); | ||||||
| @@ -650,7 +686,7 @@ void line_info_print(ToxWindow *self) | |||||||
|                 wprintw(win, "%s ", line->name1); |                 wprintw(win, "%s ", line->name1); | ||||||
|                 wattroff(win, A_BOLD); |                 wattroff(win, A_BOLD); | ||||||
|  |  | ||||||
|                 print_ret = print_wrap(win, line, max_x, max_y); |                 print_wrap(win, line, max_x, max_y); | ||||||
|                 waddch(win, '\n'); |                 waddch(win, '\n'); | ||||||
|  |  | ||||||
|                 wattroff(win, COLOR_PAIR(line->colour)); |                 wattroff(win, COLOR_PAIR(line->colour)); | ||||||
| @@ -669,7 +705,7 @@ void line_info_print(ToxWindow *self) | |||||||
|                 wprintw(win, "%s ", line->name1); |                 wprintw(win, "%s ", line->name1); | ||||||
|                 wattroff(win, A_BOLD); |                 wattroff(win, A_BOLD); | ||||||
|  |  | ||||||
|                 print_ret = print_wrap(win, line, max_x, max_y); |                 print_wrap(win, line, max_x, max_y); | ||||||
|                 waddch(win, '\n'); |                 waddch(win, '\n'); | ||||||
|  |  | ||||||
|                 wattroff(win, COLOR_PAIR(line->colour)); |                 wattroff(win, COLOR_PAIR(line->colour)); | ||||||
| @@ -687,7 +723,7 @@ void line_info_print(ToxWindow *self) | |||||||
|                 wprintw(win, "%s", line->name1); |                 wprintw(win, "%s", line->name1); | ||||||
|                 wattroff(win, A_BOLD); |                 wattroff(win, A_BOLD); | ||||||
|  |  | ||||||
|                 print_ret = print_wrap(win, line, max_x, max_y); |                 print_wrap(win, line, max_x, max_y); | ||||||
|  |  | ||||||
|                 wattron(win, A_BOLD); |                 wattron(win, A_BOLD); | ||||||
|                 wprintw(win, "%s\n", line->name2); |                 wprintw(win, "%s\n", line->name2); | ||||||
| @@ -749,10 +785,9 @@ void line_info_set(ToxWindow *self, uint32_t id, char *msg) | |||||||
|  |  | ||||||
|     while (line) { |     while (line) { | ||||||
|         if (line->id == id) { |         if (line->id == id) { | ||||||
|             size_t new_len = strlen(msg); |             const uint16_t new_width = line_info_add_msg(line->msg, sizeof(line->msg), msg); | ||||||
|             line->len = line->len - line->msg_len + new_len; |             line->len = line->len - line->msg_width + new_width; | ||||||
|             line->msg_len = new_len; |             line->msg_width = new_width; | ||||||
|             snprintf(line->msg, sizeof(line->msg), "%s", msg); |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -49,7 +49,7 @@ struct line_info { | |||||||
|     char    timestr[TIME_STR_SIZE]; |     char    timestr[TIME_STR_SIZE]; | ||||||
|     char    name1[TOXIC_MAX_NAME_LENGTH + 1]; |     char    name1[TOXIC_MAX_NAME_LENGTH + 1]; | ||||||
|     char    name2[TOXIC_MAX_NAME_LENGTH + 1]; |     char    name2[TOXIC_MAX_NAME_LENGTH + 1]; | ||||||
|     char msg[MAX_LINE_INFO_MSG_SIZE]; |     wchar_t msg[MAX_LINE_INFO_MSG_SIZE]; | ||||||
|     time_t  timestamp; |     time_t  timestamp; | ||||||
|     uint8_t type; |     uint8_t type; | ||||||
|     uint8_t bold; |     uint8_t bold; | ||||||
| @@ -58,7 +58,7 @@ struct line_info { | |||||||
|     bool    read_flag;     /* true if a message has been flagged as read */ |     bool    read_flag;     /* true if a message has been flagged as read */ | ||||||
|     uint32_t id; |     uint32_t id; | ||||||
|     uint16_t len;        /* combined length of entire line */ |     uint16_t len;        /* combined length of entire line */ | ||||||
|     uint16_t msg_len;    /* length of the message */ |     uint16_t msg_width;    /* width of the message */ | ||||||
|     uint16_t format_lines;  /* number of lines the combined string takes up (dynamically set) */ |     uint16_t format_lines;  /* number of lines the combined string takes up (dynamically set) */ | ||||||
|  |  | ||||||
|     struct line_info *prev; |     struct line_info *prev; | ||||||
|   | |||||||
| @@ -62,21 +62,21 @@ static int get_log_path(char *dest, int destsize, const char *name, const char * | |||||||
|  |  | ||||||
|     /* first 6 bytes of selfkey */ |     /* first 6 bytes of selfkey */ | ||||||
|     char self_id[32] = {0}; |     char self_id[32] = {0}; | ||||||
|     path_len += KEY_IDENT_DIGITS * 2; |     path_len += KEY_IDENT_BYTES; | ||||||
|     sprintf(&self_id[0], "%02X", selfkey[0] & 0xff); |     sprintf(&self_id[0], "%02X", selfkey[0] & 0xff); | ||||||
|     sprintf(&self_id[2], "%02X", selfkey[1] & 0xff); |     sprintf(&self_id[2], "%02X", selfkey[1] & 0xff); | ||||||
|     sprintf(&self_id[4], "%02X", selfkey[2] & 0xff); |     sprintf(&self_id[4], "%02X", selfkey[2] & 0xff); | ||||||
|     self_id[KEY_IDENT_DIGITS * 2] = '\0'; |     self_id[KEY_IDENT_BYTES] = '\0'; | ||||||
|  |  | ||||||
|     char other_id[32] = {0}; |     char other_id[32] = {0}; | ||||||
|  |  | ||||||
|     if (otherkey) { |     if (otherkey) { | ||||||
|         /* first 6 bytes of otherkey */ |         /* first 6 bytes of otherkey */ | ||||||
|         path_len += KEY_IDENT_DIGITS * 2; |         path_len += KEY_IDENT_BYTES; | ||||||
|         sprintf(&other_id[0], "%02X", otherkey[0] & 0xff); |         sprintf(&other_id[0], "%02X", otherkey[0] & 0xff); | ||||||
|         sprintf(&other_id[2], "%02X", otherkey[1] & 0xff); |         sprintf(&other_id[2], "%02X", otherkey[1] & 0xff); | ||||||
|         sprintf(&other_id[4], "%02X", otherkey[2] & 0xff); |         sprintf(&other_id[4], "%02X", otherkey[2] & 0xff); | ||||||
|         other_id[KEY_IDENT_DIGITS * 2] = '\0'; |         other_id[KEY_IDENT_BYTES] = '\0'; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (path_len >= destsize) { |     if (path_len >= destsize) { | ||||||
|   | |||||||
							
								
								
									
										31
									
								
								src/prompt.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								src/prompt.c
									
									
									
									
									
								
							| @@ -175,9 +175,7 @@ static int add_friend_request(const char *public_key, const char *data) | |||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     int i; |     for (int i = 0; i <= FrndRequests.max_idx; ++i) { | ||||||
|  |  | ||||||
|     for (i = 0; i <= FrndRequests.max_idx; ++i) { |  | ||||||
|         if (!FrndRequests.request[i].active) { |         if (!FrndRequests.request[i].active) { | ||||||
|             FrndRequests.request[i].active = true; |             FrndRequests.request[i].active = true; | ||||||
|             memcpy(FrndRequests.request[i].key, public_key, TOX_PUBLIC_KEY_SIZE); |             memcpy(FrndRequests.request[i].key, public_key, TOX_PUBLIC_KEY_SIZE); | ||||||
| @@ -526,6 +524,26 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, uint32_t friendnu | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Return true is the first 3 bytes of `key` are identical to any other contact in the contact list. | ||||||
|  |  */ | ||||||
|  | static bool key_is_similar(const char *key) | ||||||
|  | { | ||||||
|  |     for (size_t i = 0; i < Friends.max_idx; ++i) { | ||||||
|  |         const ToxicFriend *friend = &Friends.list[i]; | ||||||
|  |  | ||||||
|  |         if (!friend->active) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (memcmp(friend->pub_key, key, KEY_IDENT_BYTES / 2) == 0) { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  |  | ||||||
| static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length) | static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length) | ||||||
| { | { | ||||||
|     UNUSED_VAR(m); |     UNUSED_VAR(m); | ||||||
| @@ -536,6 +554,13 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, con | |||||||
|     line_info_add(self, true, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data); |     line_info_add(self, true, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data); | ||||||
|     write_to_log("Friend request with the message '%s'", "", ctx->log, true); |     write_to_log("Friend request with the message '%s'", "", ctx->log, true); | ||||||
|  |  | ||||||
|  |     if (key_is_similar(key)) { | ||||||
|  |         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, | ||||||
|  |                       "WARNING: This contact's public key is suspiciously similar to that of another contact "); | ||||||
|  |         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, | ||||||
|  |                       "in your list. This may be an impersonation attempt, or it may have occurred by chance."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     int n = add_friend_request(key, data); |     int n = add_friend_request(key, data); | ||||||
|  |  | ||||||
|     if (n == -1) { |     if (n == -1) { | ||||||
|   | |||||||
| @@ -23,6 +23,10 @@ | |||||||
| #ifndef TOXIC_H | #ifndef TOXIC_H | ||||||
| #define TOXIC_H | #define TOXIC_H | ||||||
|  |  | ||||||
|  | #ifndef NCURSES_WIDECHAR | ||||||
|  | #define NCURSES_WIDECHAR 1 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #ifndef TOXICVER | #ifndef TOXICVER | ||||||
| #define TOXICVER "NOVERS"    /* Use the -D flag to set this */ | #define TOXICVER "NOVERS"    /* Use the -D flag to set this */ | ||||||
| #endif | #endif | ||||||
| @@ -46,7 +50,7 @@ | |||||||
| #define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH    /* must be >= TOX_MAX_MESSAGE_LENGTH */ | #define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH    /* must be >= TOX_MAX_MESSAGE_LENGTH */ | ||||||
| #define MAX_CMDNAME_SIZE 64 | #define MAX_CMDNAME_SIZE 64 | ||||||
| #define TOXIC_MAX_NAME_LENGTH 32   /* Must be <= TOX_MAX_NAME_LENGTH */ | #define TOXIC_MAX_NAME_LENGTH 32   /* Must be <= TOX_MAX_NAME_LENGTH */ | ||||||
| #define KEY_IDENT_DIGITS 3    /* number of hex digits to display for the pub-key based identifier */ | #define KEY_IDENT_BYTES 6    /* number of hex digits to display for the public key identifier */ | ||||||
| #define TIME_STR_SIZE 32 | #define TIME_STR_SIZE 32 | ||||||
| #define COLOR_STR_SIZE 10 /* should fit every color option */ | #define COLOR_STR_SIZE 10 /* should fit every color option */ | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user