]> granicus.if.org Git - graphviz/commitdiff
expr: fix misinterpretation of shifts
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sun, 16 Jan 2022 18:47:37 +0000 (10:47 -0800)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Wed, 19 Jan 2022 16:21:09 +0000 (08:21 -0800)
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
lib/expr/exeval.c

index 2f095fddeaa79de52b71451de12d529fff78ce73..4ebfe780602dd9cc81fd6303f254e409935d1d2d 100644 (file)
@@ -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
 
index e2b8e8f81180a327a96c11224eb099ffcfca368c..0af282ee2a192a9dda3297d9f423c1d8615084e7 100644 (file)
@@ -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;