From f1baa04e064631847cb065a0d3af53c51d21e008 Mon Sep 17 00:00:00 2001 From: Matthew Fernandez Date: Sun, 16 Jan 2022 10:47:37 -0800 Subject: [PATCH] expr: fix misinterpretation of shifts It is fairly clear from the surrounding code that these instances were writing to the wrong destination and, in some cases, reading from the wrong sources. The effect of this bug was a little slippery as the underlying storage is a union with `integer` and `floating` occupying the same storage, so this change does not alter which bytes are stored to. Additionally users rarely left or right shift within GVPR scripts, so it is unlikely this affected any real world code. Gitlab: Fixes #2103 --- CHANGELOG.md | 1 + lib/expr/exeval.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f095fdde..4ebfe7806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,6 +86,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - PNG format not available in CMake builds with MinGW - tclpkg Makefile corrupts CFLAGS #2177 - lneato -? sometimes fails with STATUS_STACK_BUFFER_OVERRUN on Windows #1934 +- expr misinterprets `<<` and `>>` #2103 ## [2.50.0] – 2021-12-04 diff --git a/lib/expr/exeval.c b/lib/expr/exeval.c index e2b8e8f81..0af282ee2 100644 --- a/lib/expr/exeval.c +++ b/lib/expr/exeval.c @@ -1754,10 +1754,10 @@ eval(Expr_t* ex, Exnode_t* expr, void* env) v.integer = v.floating > r.floating; return v; case LSH: - v.floating = (Sflong_t) ((Sfulong_t)v.floating << (Sflong_t)r.floating); + v.integer = (Sflong_t) ((Sfulong_t)v.floating << (Sflong_t)r.floating); return v; case RSH: - v.floating = (Sflong_t) ((Sfulong_t)v.floating >> (Sflong_t)r.floating); + v.integer = (Sflong_t) ((Sfulong_t)v.floating >> (Sflong_t)r.floating); return v; } break; @@ -1898,10 +1898,10 @@ eval(Expr_t* ex, Exnode_t* expr, void* env) v.integer = v.integer != r.integer; return v; case LSH: - v.floating = (double)((Sflong_t)v.floating << (Sflong_t)r.floating); + v.integer = (Sflong_t)v.integer << (Sflong_t)r.integer; return v; case RSH: - v.integer = (Sfulong_t)v.floating >> (Sflong_t)r.floating; + v.integer = (Sfulong_t)v.integer >> (Sflong_t)r.integer; return v; case '<': v.integer = v.integer < r.integer; -- 2.40.0