Bug Summary

File:out/../deps/v8/src/wasm/wasm-module-sourcemap.cc
Warning:line 147, column 10
Although the value stored to 'qnt' is used in the enclosing expression, the value is never actually read from 'qnt'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name wasm-module-sourcemap.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D V8_GYP_BUILD -D V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D V8_TARGET_ARCH_X64 -D V8_HAVE_TARGET_OS -D V8_TARGET_OS_LINUX -D V8_EMBEDDER_STRING="-node.8" -D ENABLE_DISASSEMBLER -D V8_PROMISE_INTERNAL_FIELD_COUNT=1 -D V8_SHORT_BUILTIN_CALLS -D OBJECT_PRINT -D V8_INTL_SUPPORT -D V8_ATOMIC_OBJECT_FIELD_WRITES -D V8_ENABLE_LAZY_SOURCE_POSITIONS -D V8_USE_SIPHASH -D V8_SHARED_RO_HEAP -D V8_WIN64_UNWINDING_INFO -D V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH -D V8_SNAPSHOT_COMPRESSION -D V8_ENABLE_WEBASSEMBLY -D V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS -D V8_ALLOCATION_FOLDING -D V8_ALLOCATION_SITE_TRACKING -D V8_SCRIPTORMODULE_LEGACY_LIFETIME -D V8_ADVANCED_BIGINT_ALGORITHMS -D ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC -D UCONFIG_NO_SERVICE=1 -D U_ENABLE_DYLOAD=0 -D U_STATIC_IMPLEMENTATION=1 -D U_HAVE_STD_STRING=1 -D UCONFIG_NO_BREAK_ITERATION=0 -I ../deps/v8 -I ../deps/v8/include -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/inspector-generated-output-root -I ../deps/v8/third_party/inspector_protocol -I /home/maurizio/node-v18.6.0/out/Release/obj/gen -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/generate-bytecode-output-root -I ../deps/icu-small/source/i18n -I ../deps/icu-small/source/common -I ../deps/v8/third_party/zlib -I ../deps/v8/third_party/zlib/google -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/backward -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-return-type -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c++ ../deps/v8/src/wasm/wasm-module-sourcemap.cc
1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/wasm/wasm-module-sourcemap.h"
6
7#include <algorithm>
8
9#include "include/v8-context.h"
10#include "include/v8-json.h"
11#include "include/v8-local-handle.h"
12#include "include/v8-object.h"
13#include "include/v8-primitive.h"
14#include "src/api/api.h"
15#include "src/base/vlq-base64.h"
16
17namespace v8 {
18
19class String;
20
21namespace internal {
22namespace wasm {
23
24WasmModuleSourceMap::WasmModuleSourceMap(v8::Isolate* v8_isolate,
25 v8::Local<v8::String> src_map_str) {
26 v8::HandleScope scope(v8_isolate);
27 v8::Local<v8::Context> context = v8::Context::New(v8_isolate);
28
29 v8::Local<v8::Value> src_map_value;
30 if (!v8::JSON::Parse(context, src_map_str).ToLocal(&src_map_value)) return;
31 v8::Local<v8::Object> src_map_obj =
32 v8::Local<v8::Object>::Cast(src_map_value);
33
34 v8::Local<v8::Value> version_value, sources_value, mappings_value;
35 bool has_valid_version =
36 src_map_obj
37 ->Get(context, v8::String::NewFromUtf8Literal(v8_isolate, "version"))
38 .ToLocal(&version_value) &&
39 version_value->IsUint32();
40 uint32_t version = 0;
41 if (!has_valid_version || !version_value->Uint32Value(context).To(&version) ||
42 version != 3u)
43 return;
44
45 bool has_valid_sources =
46 src_map_obj
47 ->Get(context, v8::String::NewFromUtf8Literal(v8_isolate, "sources"))
48 .ToLocal(&sources_value) &&
49 sources_value->IsArray();
50 if (!has_valid_sources) return;
51
52 v8::Local<v8::Object> sources_arr =
53 v8::Local<v8::Object>::Cast(sources_value);
54 v8::Local<v8::Value> sources_len_value;
55 if (!sources_arr
56 ->Get(context, v8::String::NewFromUtf8Literal(v8_isolate, "length"))
57 .ToLocal(&sources_len_value))
58 return;
59 uint32_t sources_len = 0;
60 if (!sources_len_value->Uint32Value(context).To(&sources_len)) return;
61
62 for (uint32_t i = 0; i < sources_len; ++i) {
63 v8::Local<v8::Value> file_name_value;
64 if (!sources_arr->Get(context, i).ToLocal(&file_name_value) ||
65 !file_name_value->IsString())
66 return;
67 v8::Local<v8::String> file_name =
68 v8::Local<v8::String>::Cast(file_name_value);
69 auto file_name_sz = file_name->Utf8Length(v8_isolate);
70 std::unique_ptr<char[]> file_name_buf(new char[file_name_sz + 1]);
71 file_name->WriteUtf8(v8_isolate, file_name_buf.get());
72 file_name_buf.get()[file_name_sz] = '\0';
73 filenames.emplace_back(file_name_buf.get());
74 }
75
76 bool has_valid_mappings =
77 src_map_obj
78 ->Get(context, v8::String::NewFromUtf8Literal(v8_isolate, "mappings"))
79 .ToLocal(&mappings_value) &&
80 mappings_value->IsString();
81 if (!has_valid_mappings) return;
82
83 v8::Local<v8::String> mappings = v8::Local<v8::String>::Cast(mappings_value);
84 int mappings_sz = mappings->Utf8Length(v8_isolate);
85 std::unique_ptr<char[]> mappings_buf(new char[mappings_sz + 1]);
86 mappings->WriteUtf8(v8_isolate, mappings_buf.get());
87 mappings_buf.get()[mappings_sz] = '\0';
88
89 valid_ = DecodeMapping(mappings_buf.get());
90}
91
92size_t WasmModuleSourceMap::GetSourceLine(size_t wasm_offset) const {
93 std::vector<std::size_t>::const_iterator up =
94 std::upper_bound(offsets.begin(), offsets.end(), wasm_offset);
95 CHECK_NE(offsets.begin(), up)do { bool _cmp = ::v8::base::CmpNEImpl< typename ::v8::base
::pass_value_or_ref<decltype(offsets.begin())>::type, typename
::v8::base::pass_value_or_ref<decltype(up)>::type>(
(offsets.begin()), (up)); do { if ((__builtin_expect(!!(!(_cmp
)), 0))) { V8_Fatal("Check failed: %s.", "offsets.begin()" " "
"!=" " " "up"); } } while (false); } while (false)
;
96 size_t source_idx = up - offsets.begin() - 1;
97 return source_row[source_idx];
98}
99
100std::string WasmModuleSourceMap::GetFilename(size_t wasm_offset) const {
101 std::vector<size_t>::const_iterator up =
102 std::upper_bound(offsets.begin(), offsets.end(), wasm_offset);
103 CHECK_NE(offsets.begin(), up)do { bool _cmp = ::v8::base::CmpNEImpl< typename ::v8::base
::pass_value_or_ref<decltype(offsets.begin())>::type, typename
::v8::base::pass_value_or_ref<decltype(up)>::type>(
(offsets.begin()), (up)); do { if ((__builtin_expect(!!(!(_cmp
)), 0))) { V8_Fatal("Check failed: %s.", "offsets.begin()" " "
"!=" " " "up"); } } while (false); } while (false)
;
104 size_t offset_idx = up - offsets.begin() - 1;
105 size_t filename_idx = file_idxs[offset_idx];
106 return filenames[filename_idx];
107}
108
109bool WasmModuleSourceMap::HasSource(size_t start, size_t end) const {
110 return start <= *(offsets.end() - 1) && end > *offsets.begin();
111}
112
113bool WasmModuleSourceMap::HasValidEntry(size_t start, size_t addr) const {
114 std::vector<size_t>::const_iterator up =
115 std::upper_bound(offsets.begin(), offsets.end(), addr);
116 if (up == offsets.begin()) return false;
117 size_t offset_idx = up - offsets.begin() - 1;
118 size_t entry_offset = offsets[offset_idx];
119 if (entry_offset < start) return false;
120 return true;
121}
122
123bool WasmModuleSourceMap::DecodeMapping(const std::string& s) {
124 size_t pos = 0, gen_col = 0, file_idx = 0, ori_line = 0;
125 int32_t qnt = 0;
126
127 while (pos < s.size()) {
128 // Skip redundant commas.
129 if (s[pos] == ',') {
130 ++pos;
131 continue;
132 }
133 if ((qnt = base::VLQBase64Decode(s.c_str(), s.size(), &pos)) ==
134 std::numeric_limits<int32_t>::min())
135 return false;
136 gen_col += qnt;
137 if ((qnt = base::VLQBase64Decode(s.c_str(), s.size(), &pos)) ==
138 std::numeric_limits<int32_t>::min())
139 return false;
140 file_idx += qnt;
141 if ((qnt = base::VLQBase64Decode(s.c_str(), s.size(), &pos)) ==
142 std::numeric_limits<int32_t>::min())
143 return false;
144 ori_line += qnt;
145 // Column number in source file is always 0 in source map generated by
146 // Emscripten. We just decode this value without further usage of it.
147 if ((qnt = base::VLQBase64Decode(s.c_str(), s.size(), &pos)) ==
Although the value stored to 'qnt' is used in the enclosing expression, the value is never actually read from 'qnt'
148 std::numeric_limits<int32_t>::min())
149 return false;
150
151 if (pos < s.size() && s[pos] != ',') return false;
152 pos++;
153
154 file_idxs.push_back(file_idx);
155 source_row.push_back(ori_line);
156 offsets.push_back(gen_col);
157 }
158 return true;
159}
160
161} // namespace wasm
162} // namespace internal
163} // namespace v8