Skip to content

Commit

Permalink
feat(general): Coerce PHP frame vars array to object (#159)
Browse files Browse the repository at this point in the history
  • Loading branch information
untitaker authored and jan-auer committed Jan 22, 2019
1 parent 4cfe5dc commit 827374c
Showing 1 changed file with 69 additions and 6 deletions.
75 changes: 69 additions & 6 deletions general/src/protocol/stacktrace.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::protocol::{Addr, RegVal};
use crate::types::{Annotated, Array, Object, Value};
use crate::types::{Annotated, Array, FromValue, Object, Value};

/// Holds information about a single stacktrace frame.
#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, ToValue, ProcessValue)]
Expand Down Expand Up @@ -72,8 +72,7 @@ pub struct Frame {

/// Local variables in a convenient format.
#[metastructure(pii = "true")]
#[metastructure(skip_serialization = "empty")]
pub vars: Annotated<Object<Value>>,
pub vars: Annotated<FrameVars>,

/// Start address of the containing code module (image).
pub image_addr: Annotated<Addr>,
Expand All @@ -93,6 +92,35 @@ pub struct Frame {
pub other: Object<Value>,
}

#[derive(Clone, Debug, Default, PartialEq, Empty, ToValue, ProcessValue)]
pub struct FrameVars(#[metastructure(skip_serialization = "empty")] pub Object<Value>);

impl From<Object<Value>> for FrameVars {
fn from(value: Object<Value>) -> Self {
FrameVars(value)
}
}

impl FromValue for FrameVars {
fn from_value(mut value: Annotated<Value>) -> Annotated<FrameVars> {
value = value.map_value(|value| {
if let Value::Array(value) = value {
Value::Object(
value
.into_iter()
.enumerate()
.map(|(i, v)| (i.to_string(), v))
.collect(),
)
} else {
value
}
});

FromValue::from_value(value).map_value(FrameVars)
}
}

/// Holds information about an entirey stacktrace.
#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, ToValue, ProcessValue)]
#[metastructure(process_func = "process_stacktrace", value_type = "Stacktrace")]
Expand Down Expand Up @@ -157,7 +185,7 @@ fn test_frame_roundtrip() {
"variable".to_string(),
Annotated::new(Value::String("value".to_string())),
);
Annotated::new(vars)
Annotated::new(vars.into())
},
image_addr: Annotated::new(Addr(0x400)),
instruction_addr: Annotated::new(Addr(0x404)),
Expand Down Expand Up @@ -258,7 +286,7 @@ fn test_frame_vars_null_preserved() {
vars: Annotated::new({
let mut vars = Object::new();
vars.insert("despacito".to_string(), Annotated::empty());
vars
vars.into()
}),
..Default::default()
});
Expand All @@ -280,7 +308,7 @@ fn test_frame_vars_empty_annotated_is_serialized() {
let mut vars = Object::new();
vars.insert("despacito".to_string(), Annotated::empty());
vars.insert("despacito2".to_string(), Annotated::empty());
vars
vars.into()
}),
..Default::default()
});
Expand Down Expand Up @@ -310,3 +338,38 @@ fn test_frame_empty_context_lines() {
assert_eq_dbg!(frame, Annotated::from_json(json).unwrap());
assert_eq_str!(json, frame.to_json_pretty().unwrap());
}

#[test]
fn test_php_frame_vars() {
// Buggy PHP SDKs send us this stuff
//
// Port of https://github.com/getsentry/sentry/commit/73d9a061dcac3ab8c318a09735601a12e81085dd

let input = r#"{
"vars": ["foo", "bar", "baz", null]
}"#;

let output = r#"{
"vars": {
"0": "foo",
"1": "bar",
"2": "baz",
"3": null
}
}"#;

let frame = Annotated::new(Frame {
vars: Annotated::new({
let mut vars = Object::new();
vars.insert("0".to_string(), Annotated::new("foo".to_string().into()));
vars.insert("1".to_string(), Annotated::new("bar".to_string().into()));
vars.insert("2".to_string(), Annotated::new("baz".to_string().into()));
vars.insert("3".to_string(), Annotated::empty());
vars.into()
}),
..Default::default()
});

assert_eq_dbg!(frame, Annotated::from_json(input).unwrap());
assert_eq_str!(output, frame.to_json_pretty().unwrap());
}

0 comments on commit 827374c

Please sign in to comment.