# C to Rust translator

**URL:** <https://users.rust-lang.org/t/c-to-rust-translator/55381>\
**Category:** community\
**Created:** [February 9, 2021, 10:48pm UTC](https://users.rust-lang.org/t/c-to-rust-translator/55381 "2021-02-09T22:48:34Z")\
**Posts on this page:** 1\
**Showing post:** 14

<div class="post-metadata">

**Author:** ![John\_Nagle](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/john_nagle/32/17844_2.png) [@John\_Nagle](https://users.rust-lang.org/u/John_Nagle)\
**Post date:** [February 10, 2021, 7:15pm UTC](https://users.rust-lang.org/t/c-to-rust-translator/55381/14 "2021-02-10T19:15:23Z")

</div>

So many "it can't be done" comments. Here's an outline of how to approach the problem.

Here's some C code with pointer arithmetic from OpenJPEG. This module has has buffer overflows reported in security advisories, so it's a good place to start.

```
static void opj_dwt_deinterleave_h(const OPJ_INT32 *OPJ_RESTRICT a,
                                   OPJ_INT32 *OPJ_RESTRICT b,
                                   OPJ_INT32 dn,
                                   OPJ_INT32 sn, 
                                   OPJ_INT32 cas)
{
    OPJ_INT32 i;
    OPJ_INT32 * OPJ_RESTRICT l_dest = b;
    const OPJ_INT32 * OPJ_RESTRICT l_src = a + cas;

    for (i = 0; i < sn; ++i) {
        *l_dest++ = *l_src;
        l_src += 2;
    }

    l_dest = b + sn;
    l_src = a + 1 - cas;

    for (i = 0; i < dn; ++i) {
        *l_dest++ = *l_src;
        l_src += 2;
    }

```

So how would an analyzer proceed?

First, expand OBJ\_RESTRICT, which is defined as C "restrict". That means no aliasing. Nice to know.

Which parameters are arrays? This function calls no other functions, so this is decidable from the code here. Parameters a and b are potentially arrays.

Pointer arithmetic is detected at `*l_dest++` and at `l_src = a + cas`. **l\_dest** gets its value from **b**. So parameters **a** and **b** are definitely arrays. \ ***l\_dest++** appears on the left side of an assignment, so b is mutated.

We can now write the function definition in Rust.

`fn opj_dwt_deinterleave_h(a: &[i32], b: &mut[i32], dn: i32, sn: i32, cas: i32)`

That's straightforward, safe Rust.

OK, here's a pointer that gets mutated.

```
`OPJ_INT32 * OPJ_RESTRICT l_dest = b;`

```

What do we do there? l\_dest always points to  
some part of b. So it can be expressed as a  
subscript into b. So

```
let mut l_dest: usize = 0;

```

Next,

```
const OPJ_INT32 * OPJ_RESTRICT l_src = a + cas;

```

which always points to some part of a. So

```
let mut l_src: usize = cas as usize;

```

Now the hard part, pointer arithmetic in the first FOR loop.

```
for (i = 0; i < sn; ++i) {
    *l_dest++ = *l_src;
    l_src += 2;
}

```

The "for" statement is such a common C idiom that it needs to be recognized. Corrode does that. So

```
for i in 0..sn {

```

Now, we know that **l\_dest** points to somewhere in `b`, and `l_src` points to somewhere in `a`. So we just have to calculate the subscript.

```
b[l_dest] = a[l_src];

```

Now we need to figure out the incrementation.

```
l_dest++

```

increments by one size of the thing pointed to,  
so it's

```
l_dest += 1;

```

and

```
l_src += 2;

```

And that's the first loop, converted to safe Rust.

This is a bit long, but I wanted to show that this is not an impossible problem.

There are hard cases to resolve. Those involve cases where you have a pointer that's hard to tie back to the underlying array. Those may need human assistance. But most code doesn't do that, unless it's a storage allocator. **If you can determine which array a pointer points to, you can convert pointer arithmetic into subscripts automatically.**

After conversion to Rust, subscript checking will protect against buffer overflow attacks.

So, this is not impossible. Just hard. A good thesis project for someone getting their CS degree.

---

_[View the full topic](https://users.rust-lang.org/t/c-to-rust-translator/55381)._
