From 30c64b06c5936b60bfe4e923432c5420290585d0 Mon Sep 17 00:00:00 2001 From: Daniel Leech Date: Mon, 28 Apr 2025 22:00:33 +0100 Subject: [PATCH 1/4] Enabled extended properties --- src/app.rs | 16 +++++++++++----- src/dbgp/client.rs | 1 - 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/app.rs b/src/app.rs index 94c3903..001907d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -249,7 +249,10 @@ impl App { terminal: &mut Terminal>, event: AppEvent, ) -> Result<()> { - info!("Handling event {:?}", event); + match event { + AppEvent::Tick => (), + _ => info!("Handling event {:?}", event), + }; match event { AppEvent::Tick => (), AppEvent::Quit => self.quit = true, @@ -296,10 +299,13 @@ impl App { AppEvent::ClientConnected(s) => { let mut client = self.client.lock().await; let response = client.deref_mut().connect(s).await?; - client.feature_set( - "max_depth", - self.context_depth.to_string().as_str() - ).await?; + for (feature, value) in [ + ("max_depth",self.context_depth.to_string().as_str()), + ("extended_properties","1"), + ] { + info!("setting feature {} to {:?}", feature, value); + client.feature_set(feature, value).await?; + } self.is_connected = true; self.server_status = None; self.view_current = CurrentView::Session; diff --git a/src/dbgp/client.rs b/src/dbgp/client.rs index 4a1a0d7..671829e 100644 --- a/src/dbgp/client.rs +++ b/src/dbgp/client.rs @@ -187,7 +187,6 @@ impl DbgpClient { if xml.is_empty() { return Err(anyhow::anyhow!("Empty XML response")); } - debug!("[dbgp] << {}", xml); parse_xml(xml.as_str()) } From f12c9b7615a520dfaba8ca48404f7ba65b37b409 Mon Sep 17 00:00:00 2001 From: Daniel Leech Date: Mon, 28 Apr 2025 22:47:45 +0100 Subject: [PATCH 2/4] Support extended properties --- CHANGELOG.md | 7 +++++ src/dbgp/client.rs | 69 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64e6663..4a5978f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ CHANGELOG ========= +main +---- + +- Show value of variables on current line +- Support `extended_properties` #5 + + 0.0.2 ----- diff --git a/src/dbgp/client.rs b/src/dbgp/client.rs index 671829e..84e0606 100644 --- a/src/dbgp/client.rs +++ b/src/dbgp/client.rs @@ -389,17 +389,24 @@ fn parse_context_get(element: &mut Element) -> Result name.to_string(), + None => decode_element(child.get_child("name")).unwrap_or("".to_string()) + }, + fullname: match child .attributes - .get("name") - .expect("Expected fullname to be set") - .to_string(), - classname: child.attributes.get("classname").map(|s| s.to_string()), + .get("fullname") { + Some(name) => name.to_string(), + None => decode_element(child.get_child("fullname")).unwrap_or("".to_string()) + }, + classname: match child + .attributes + .get("classname") { + Some(name) => Some(name.to_string()), + None => decode_element(child.get_child("classname")) + }, page: child .attributes .get("page") @@ -442,6 +449,28 @@ fn parse_context_get(element: &mut Element) -> Result) -> Option { + match element { + Some(e) => { + let encoding = e.attributes.get("encoding"); + match e.children.first() { + Some(XMLNode::CData(cdata)) => match encoding { + Some(encoding) => match encoding.as_str() { + "base64" => { + Some(String::from_utf8(general_purpose::STANDARD.decode(cdata).unwrap()) + .unwrap()) + } + _ => Some(cdata.to_string()), + }, + _ => Some(cdata.to_string()), + }, + _ => None, + } + } + None => None, + } +} + fn parse_stack_get(element: &Element) -> StackGetResponse { let mut entries: Vec = Vec::new(); for ce in &element.children { @@ -593,6 +622,7 @@ function call_function(string $hello) { + "#, )?; @@ -674,7 +704,7 @@ function call_function(string $hello) { children: vec![ Property { name: "true".to_string(), - fullname: "true".to_string(), + fullname: "$this->true".to_string(), classname: None, page: None, pagesize: None, @@ -689,7 +719,7 @@ function call_function(string $hello) { }, Property { name: "bar".to_string(), - fullname: "bar".to_string(), + fullname: "$this->bar".to_string(), classname: None, page: None, pagesize: None, @@ -704,7 +734,7 @@ function call_function(string $hello) { }, Property { name: "handle".to_string(), - fullname: "handle".to_string(), + fullname: "$this->handle".to_string(), classname: None, page: None, pagesize: None, @@ -723,6 +753,21 @@ function call_function(string $hello) { encoding: None, value: None, }, + Property { + name: "$arr😸ay".to_string(), + fullname: "$arr😸ay".to_string(), + classname: None, + page: None, + pagesize: None, + property_type: PropertyType::Array, + facet: None, + size: None, + children: vec![], + key: None, + address: None, + encoding: None, + value: None, + }, ], }; assert_eq!(expected, response) From 33409954812987865a37e6ac5dfffde9856bec99 Mon Sep 17 00:00:00 2001 From: Daniel Leech Date: Mon, 28 Apr 2025 22:53:12 +0100 Subject: [PATCH 3/4] Reuse function --- src/dbgp/client.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/dbgp/client.rs b/src/dbgp/client.rs index 84e0606..fab8288 100644 --- a/src/dbgp/client.rs +++ b/src/dbgp/client.rs @@ -430,19 +430,7 @@ fn parse_context_get(element: &mut Element) -> Result Some(match encoding { - Some(encoding) => match encoding.as_str() { - "base64" => { - String::from_utf8(general_purpose::STANDARD.decode(cdata).unwrap()) - .unwrap() - } - _ => cdata.to_string(), - }, - _ => cdata.to_string(), - }), - _ => None, - }, + value: decode_element(Some(&child)), }; properties.push(p); } From 582b7435671c04a1361300ae75e2ddf92763e26f Mon Sep 17 00:00:00 2001 From: Daniel Leech Date: Mon, 28 Apr 2025 23:05:45 +0100 Subject: [PATCH 4/4] TODO: multibyte variables not being tracked --- php/test.php | 56 ++++++++++++++++++++++++++++++++++++++++++++++ src/analyzer.rs | 17 ++++++++++++++ src/view/source.rs | 1 + 3 files changed, 74 insertions(+) create mode 100644 php/test.php diff --git a/php/test.php b/php/test.php new file mode 100644 index 0000000..cf17f5a --- /dev/null +++ b/php/test.php @@ -0,0 +1,56 @@ + 123, + 'float' => 123.4, + 'string' => "string", + 'bool' => true, + 'more' => [ + 'int' => 123, + 'float' => 123.4, + 'string' => "string", + 'bool' => true, + ], +]; +$a = 2; +$foo = $a; +$foo = $arra😸ay; + +$bar = $foo; + + +(new Foo(true, "foo"))->method3(); +call_function("hello"); + + + +function call_function(string $hello) { + $var = 123; + $obj = new Foo(false, 'good day'); + another_function($hello); + another_function($hello); + another_function($hello); +} + +function another_function(string $goodbye) { + echo $goodbye; + + + foreach (['one', 'two', 'three', 'four'] as $number) { + if ($number === 'one') { + echo "number"; + } + echo $number; + } +} + +class Foo { + public function __construct(public bool $true, public string $bar) {} + public function method1() { + } + public function method2() { + } + public function method3() { + } +} + diff --git a/src/analyzer.rs b/src/analyzer.rs index ff6bd70..407ca33 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -166,5 +166,22 @@ list($var1, $var2) = some_call(); }, line.get(&5).unwrap()); Ok(()) } + + #[test] + fn test_cats() -> Result<(), anyhow::Error> { + let source = r#"