update review bug and remove useless comments
What changed, and why it matters
This commit fixes a logic bug in how Tron transactions are routed based on QR code type. Previously the firmware treated 'TronSignRequest' as if it were a Keystone-style request and vice versa, which could send the wrong data to the wrong parser/signer. It also fixes a floating-point precision bug in how token amounts are formatted for display, replacing an unsafe logarithm calculation with a loop-based decimal count. A test helper and some comments were removed, but no security disclosure or researcher credit is present.
Review the inverted-routing fix carefully to confirm it matches the intended UR type handling for all Tron flows (parse, check, sign). Add regression tests covering both TronSignRequest and KeystoneSignRequest paths. Verify the new precision loop correctly handles all expected divider values and edge cases such as very large or non-power-of-ten dividers. Consider whether the removed test helper exercised a security-relevant scenario that should be preserved.
Security signals we found
Inverted conditional routing between TronSignRequest and KeystoneSignRequest in Tron transaction parse/check/sign paths
Floating-point precision fix in token amount formatting (log10 rounding replaced with iterative decimal counting)
Removal of a hard-coded Tron standard request test vector from rust_c test commands
Removal of explanatory comments rather than adding security documentation
Evidence from the diff
The C code in gui_trx.c had inverted conditionals: it checked urType == KeystoneSignRequest and then called the Tron-specific tron_parse_keystone, tron_check_keystone, and tron_sign_keystone functions, while the else branch used tron_parse_sign_request, tron_check_sign_request, and tron_sign_request. The patch swaps the condition to urType == TronSignRequest and routes the request to the correct Tron-specific handlers, with Keystone-style requests falling through to the keystone handlers. In wrapped_tron.rs, the precision calculation changed from log10().round() (which can miscompute powers of ten due to floating-point error) to a loop dividing by 10 until the divider is below 9.99999. A test fixture and comments were deleted. No CVE, advisory, or vendor security statement is visible in the materials.
Changed components
src/ui/gui_chain/multi/web3/gui_trx.crust/apps/tron/src/transaction/wrapped_tron.rsrust/apps/tron/src/lib.rsrust/rust_c/src/test_cmd/general_test_cmd.rsInspect captured patch +21 / −25
diff --git a/rust/apps/tron/src/lib.rs b/rust/apps/tron/src/lib.rs
index 77adf2e..545cc21 100644
--- a/rust/apps/tron/src/lib.rs
+++ b/rust/apps/tron/src/lib.rs
@@ -229,7 +229,6 @@ mod test {
let sign_data = hex::decode(mock_pb_hex).unwrap();
let result = check_tx_request(&sign_data, &path, xpub);
- // This should fail because xfp doesn't match but we're testing the decoding works
assert!(result.is_err());
}
diff --git a/rust/apps/tron/src/transaction/wrapped_tron.rs b/rust/apps/tron/src/transaction/wrapped_tron.rs
index 5c0b75c..d8764f2 100644
--- a/rust/apps/tron/src/transaction/wrapped_tron.rs
+++ b/rust/apps/tron/src/transaction/wrapped_tron.rs
@@ -464,13 +464,20 @@ impl WrappedTron {
let raw_val = f64::from_str(self.value.as_str())?;
let amount = raw_val / self.divider;
let unit = self.format_unit()?;
- let precision = if self.divider == 1.0 {
+
+ // Calculate precision from divider (power of 10)
+ let precision = if self.divider <= 1.0 {
0
- } else if self.divider.is_sign_positive() && self.divider.is_finite() {
- self.divider.log10().round() as usize
} else {
- 0
+ let mut count = 0;
+ let mut d = self.divider;
+ while d >= 9.99999 { // Account for float precision
+ d /= 10.0;
+ count += 1;
+ }
+ count
};
+
let formatted = format!("{:.*}", precision, amount);
let trimmed = if formatted.contains('.') {
formatted
@@ -641,7 +648,6 @@ mod tests {
let payload = prepare_payload(hex);
let context = prepare_parse_context(pubkey_str);
let tx = WrappedTron::from_payload(payload, &context).unwrap();
- println!("Valid Address from Payload: {}", tx.from);
let hash = tx.signature_hash().unwrap();
assert_eq!(32, hash.len());
}
diff --git a/rust/rust_c/src/test_cmd/general_test_cmd.rs b/rust/rust_c/src/test_cmd/general_test_cmd.rs
index 7958d45..e1b6208 100644
--- a/rust/rust_c/src/test_cmd/general_test_cmd.rs
+++ b/rust/rust_c/src/test_cmd/general_test_cmd.rs
@@ -62,15 +62,6 @@ pub unsafe extern "C" fn test_get_tron_keystone_bytes() -> *mut URParseResult {
URParseResult::single(ViewType::TronTx, QRCodeType::Bytes, bytes).c_ptr()
}
-#[no_mangle]
-pub unsafe extern "C" fn test_get_tron_standard_request_bytes() -> *mut URParseResult {
- let hex_str = "a30258d47b2266726f6d223a22545868745972386e6d6769537033645933635366694b426a6564337a4e3874654853222c22746f223a22544b43735874664b6648326436614561514363747962444339756141334d536a3268222c2276616c7565223a2231303030303030227d03d90130a1018a182cf518c3f51800f51800f51800f5";
-
- let bytes = Bytes::new(hex::decode(hex_str).unwrap());
-
- URParseResult::single(ViewType::TronTx, QRCodeType::TronSignRequest, bytes).c_ptr()
-}
-
#[no_mangle]
pub unsafe extern "C" fn test_get_tron_check_failed_keystone_bytes() -> *mut URParseResult {
let bytes = Bytes::new(hex::decode("1f8b08000000000000030dcfbd4ac34000c071220ea58bdaa9742a41a84bc87d27270e9ab61890c4268d54bb5dee2e26607b508b4a9fa26fe01bf8b128f812be82b383b8161703ffe9bffd1a5bad9d64d1374a77470bb334d2dc7436567d1b1e96540920ec6fabb99da5e7716b5f4a4e58ae91e36b221d8272ed088ca04399a058f8b2a09075f62297909e0b39edb9a0ce05dde79faf8f0d3868048f56c7ce2e86d3b13abb35833089f4f4be2a97ca04554cd8eaa13c9d5ca9d0b6b3315d8d4c9f5c0e83597837884fe6f309ba0e719494328d5995ce90050fe3e671c17c0ab9d2bc904011a031a502f202e414032e19c60c78be209e409aab1cfa9041e603c204821ad588ddd7f5baddfefd7c7aff03e1cbdbd13f2aab0f710f010000").unwrap());
diff --git a/src/ui/gui_chain/multi/web3/gui_trx.c b/src/ui/gui_chain/multi/web3/gui_trx.c
index 487136b..3015f75 100644
--- a/src/ui/gui_chain/multi/web3/gui_trx.c
+++ b/src/ui/gui_chain/multi/web3/gui_trx.c
@@ -49,10 +49,10 @@ void *GuiGetTrxData(void)
GetMasterFingerPrint(mfp);
do {
PtrT_TransactionParseResult_DisplayTron parseResult = NULL;
- if( urType == KeystoneSignRequest) {
- parseResult = tron_parse_keystone(data, urType, mfp, sizeof(mfp), trxXpub);
- }else{
+ if (urType == TronSignRequest) {
parseResult = tron_parse_sign_request(data);
+ } else {
+ parseResult = tron_parse_keystone(data, urType, mfp, sizeof(mfp), trxXpub);
}
CHECK_CHAIN_BREAK(parseResult);
@@ -69,10 +69,10 @@ PtrT_TransactionCheckResult GuiGetTrxCheckResult(void)
char *trxXpub = GetCurrentAccountPublicKey(XPUB_TYPE_TRX);
QRCodeType urType = g_isMulti ? g_urMultiResult->ur_type : g_urResult->ur_type;
GetMasterFingerPrint(mfp);
- if( urType == KeystoneSignRequest) {
- return tron_check_keystone(data, urType, mfp, sizeof(mfp), trxXpub);
+ if (urType == TronSignRequest) {
+ return tron_check_sign_request(data, trxXpub, mfp, sizeof(mfp));
}
- return tron_check_sign_request(data, trxXpub, mfp, sizeof(mfp));
+ return tron_check_keystone(data, urType, mfp, sizeof(mfp), trxXpub);
}
void FreeTrxMemory(void)
@@ -148,11 +148,11 @@ static UREncodeResult *GuiGetTrxSignUrDataDynamic(bool unLimit)
if (ret != 0) {
break;
}
- if( urType == KeystoneSignRequest) {
+ if (urType == TronSignRequest) {
+ encodeResult = tron_sign_request(data, seed, GetCurrentAccountSeedLen(), fragmentLen);
+ } else {
encodeResult = tron_sign_keystone(data, urType, mfp, sizeof(mfp), GetCurrentAccountPublicKey(XPUB_TYPE_TRX),
SOFTWARE_VERSION, seed, GetCurrentAccountSeedLen());
- } else {
- encodeResult = tron_sign_request(data, seed, GetCurrentAccountSeedLen(), fragmentLen);
}
CHECK_CHAIN_BREAK(encodeResult);
@@ -249,7 +249,7 @@ void GetTrxMessageUtf8(void *indata, void *param, uint32_t maxLen)
void GetTrxMessageRaw(void *indata, void *param, uint32_t maxLen)
{
- const char *warning = "\n#F5C131 The data is not parseable. Please#\n#F5C131 refer to the software wallet interface#\n#F5C131 for viewing.#";
+ const char *warning = "\n#F5C131 The data cannot be processed in its#\n#F5C131 current format. Please use your software #\n#F5C131 wallet interface to access and view the#\n#F5C131 data.#";
size_t warningLen = strlen(warning);
DisplayTRONPersonalMessage *message = (DisplayTRONPersonalMessage *)param;
size_t rawLen = message && message->raw_message ? strlen(message->raw_message) : 0;
Why this scored 44/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.