• XSS.stack #1 – первый литературный журнал от юзеров форума

Дерева переписыватель для C/C++

salsa20

(L2) cache
Пользователь
Регистрация
03.05.2019
Сообщения
498
Реакции
110
Гарант сделки
1
Вдохновившись темой https://xss.pro/threads/106900/#post-748687 выложу код для реализации парса С/C++

Нам понадобится всего лишь Rust

Cargo.toml
Код:
[dependencies]
tree-sitter = "0.20.10"
tree-sitter-cpp = "0.20.3"
rand = "0.8.5"

main.rs (основной код программы который переписывает AST)

Код:
extern crate tree_sitter;
extern crate tree_sitter_cpp;
extern crate rand;

use tree_sitter::{Parser, Node};
use rand::Rng;


fn main() {
    let code = r#"
    #include <iostream>
    #include <vector>
    
    class Solution {
    public:
        double findMedianSortedArrays(std::vector<int>& nums1, std::vector<int>& nums2) {
            int m = nums1.size(), n = nums2.size();
            if(m > n) return findMedianSortedArrays(nums2, nums1);
            int lo = 0, hi = m, mid = (m + n + 1)/2;
            while(lo <= hi){
                int i = (lo + hi)/2;
                int j = mid - i;
                if(i < m && nums2[j - 1] > nums1[i])
                    lo = i + 1;
                else if(i > 0  && nums1[i - 1] > nums2[j])
                    hi = i - 1;
                else{
                    int maxLeft = (i == 0) ? nums2[j - 1] : (j == 0) ? nums1[i - 1] : std::max(nums1[i - 1], nums2[j - 1]);
                    int minRight = (i == m) ? nums2[j] : (j == n) ? nums1[i] : std::min(nums1[i], nums2[j]);
                    return (m + n) % 2 ? maxLeft : (maxLeft + minRight) / 2.0;
                }
            }
        }
    };
    
    int main() {
        /* trash code here */
        std::vector<int> nums1 = {1, 3};
        std::vector<int> nums2 = {2};
        Solution solution;
        /* trash code here */
        double median = solution.findMedianSortedArrays(nums1, nums2);
        std::cout << "Median: " << median << std::endl;
        /* trash code here */
        return 0;
    }
        "#;


        let mut parser = Parser::new();
        parser.set_language(tree_sitter_cpp::language()).expect("Error loading CPP grammar");
        let parsed = parser.parse(code, None).expect("Parsing error");
    
        let root_node = parsed.root_node();
    
        let mut code_string = String::from(code);
        let mut replacements = Vec::new();
    
        traverse_node(root_node, &code_string, 0, &mut replacements);
    
        for (start_byte, end_byte) in replacements.iter().rev() {
            let mut rng = rand::thread_rng(); // Initialize the random number generator

            let random_integer: i32 = rng.gen_range(1..=1000000);
            let formatted_string = format!("/* Random int = {} */", random_integer);

            code_string.replace_range(*start_byte..*end_byte, &formatted_string);
        }
    
        println!("Modified code:\n{}", code_string);
}

fn traverse_node(node: Node, code: &str, level: usize, replacements: &mut Vec<(usize, usize)>) {
    if node.kind() == "comment" {
        let comment_text = node.utf8_text(code.as_bytes()).unwrap();
        if comment_text.contains("trash code here") {
            let start_byte = node.start_byte();
            let end_byte = node.end_byte();
            replacements.push((start_byte, end_byte));
        }
    }

    let mut cursor = node.walk();
    for child in node.named_children(&mut cursor) {
        traverse_node(child, code, level + 1, replacements);
    }
}

Вкратце код меняет trash code hera на /* Random int = ...*/

То есть после запуска получим
C++:
Modified code:

    #include <iostream>
    #include <vector>
    
    class Solution {
    public:
        double findMedianSortedArrays(std::vector<int>& nums1, std::vector<int>& nums2) {
            int m = nums1.size(), n = nums2.size();
            if(m > n) return findMedianSortedArrays(nums2, nums1);
            int lo = 0, hi = m, mid = (m + n + 1)/2;
            while(lo <= hi){
                int i = (lo + hi)/2;
                int j = mid - i;
                if(i < m && nums2[j - 1] > nums1[i])
                    lo = i + 1;
                else if(i > 0  && nums1[i - 1] > nums2[j])
                    hi = i - 1;
                else{
                    int maxLeft = (i == 0) ? nums2[j - 1] : (j == 0) ? nums1[i - 1] : std::max(nums1[i - 1], nums2[j - 1]);
                    int minRight = (i == m) ? nums2[j] : (j == n) ? nums1[i] : std::min(nums1[i], nums2[j]);
                    return (m + n) % 2 ? maxLeft : (maxLeft + minRight) / 2.0;
                }
            }
        }
    };

    int main() {
        /* Random int = 446381 */
        std::vector<int> nums1 = {1, 3};
        std::vector<int> nums2 = {2};
        Solution solution;
        /* Random int = 259191 */
        double median = solution.findMedianSortedArrays(nums1, nums2);
        std::cout << "Median: " << median << std::endl;
        /* Random int = 629982 */
        return 0;
    }

Вообщем полезная утилита для морфа кода. Такой метод конти юзали ( в локере можете увидеть) )
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх