printflags: improve protobuf decode error message
Include the file path and first bytes of file in the error message in case aconfig fails to parse one of the protobuf files. Example output: $ adb shell printflags Error: failed to parse /vendor/etc/aconfig_flags.pb ([0a], 1 byte(s)) Caused by: Unexpected EOF Bug: 304278614 Test: atest printflags.test Change-Id: I18ff88bd25d72dd477c4b11a32505e75884906ee
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
|
||||
use aconfig_protos::aconfig::Flag_state as State;
|
||||
use aconfig_protos::aconfig::Parsed_flags as ProtoParsedFlags;
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use regex::Regex;
|
||||
use std::collections::HashMap;
|
||||
use std::process::Command;
|
||||
@@ -39,6 +39,19 @@ fn parse_device_config(raw: &str) -> HashMap<String, String> {
|
||||
flags
|
||||
}
|
||||
|
||||
fn xxd(bytes: &[u8]) -> String {
|
||||
let n = 8.min(bytes.len());
|
||||
let mut v = Vec::with_capacity(n);
|
||||
for byte in bytes.iter().take(n) {
|
||||
v.push(format!("{:02x}", byte));
|
||||
}
|
||||
let trailer = match bytes.len() {
|
||||
0..=8 => "",
|
||||
_ => " ..",
|
||||
};
|
||||
format!("[{}{}]", v.join(" "), trailer)
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// read device_config
|
||||
let output = Command::new("/system/bin/device_config").arg("list").output()?;
|
||||
@@ -60,7 +73,10 @@ fn main() -> Result<()> {
|
||||
eprintln!("warning: failed to read {}", path);
|
||||
continue;
|
||||
};
|
||||
let parsed_flags: ProtoParsedFlags = protobuf::Message::parse_from_bytes(&bytes)?;
|
||||
let parsed_flags: ProtoParsedFlags = protobuf::Message::parse_from_bytes(&bytes)
|
||||
.with_context(|| {
|
||||
format!("failed to parse {} ({}, {} byte(s))", path, xxd(&bytes), bytes.len())
|
||||
})?;
|
||||
for flag in parsed_flags.parsed_flag {
|
||||
let key = format!("{}/{}.{}", flag.namespace(), flag.package(), flag.name());
|
||||
let value = format!("{:?} + {:?} ({})", flag.permission(), flag.state(), partition);
|
||||
@@ -85,7 +101,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_foo() {
|
||||
fn test_parse_device_config() {
|
||||
let input = r#"
|
||||
namespace_one/com.foo.bar.flag_one=true
|
||||
namespace_one/com.foo.bar.flag_two=false
|
||||
@@ -107,4 +123,16 @@ namespace_two/android.flag_two=nonsense
|
||||
let actual = parse_device_config(input);
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_xxd() {
|
||||
let input = [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9];
|
||||
assert_eq!("[]", &xxd(&input[0..0]));
|
||||
assert_eq!("[00]", &xxd(&input[0..1]));
|
||||
assert_eq!("[00 01]", &xxd(&input[0..2]));
|
||||
assert_eq!("[00 01 02 03 04 05 06]", &xxd(&input[0..7]));
|
||||
assert_eq!("[00 01 02 03 04 05 06 07]", &xxd(&input[0..8]));
|
||||
assert_eq!("[00 01 02 03 04 05 06 07 ..]", &xxd(&input[0..9]));
|
||||
assert_eq!("[00 01 02 03 04 05 06 07 ..]", &xxd(&input));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user