user: What is the c source code of the assembly code below:

```asm
<decompress_lz>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0x40(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <le32toh@plt>
  mov    %rax,-0x10(%rbp)
  mov    -0x38(%rbp),%rax
  sub    $0x1,%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x40(%rbp),%rax
  add    $0x4,%rax
  mov    %rax,-0x18(%rbp)
  movl   $0x0,-0x30(%rbp)
  movl   $0x0,-0x2c(%rbp)
L17:
  jmp    L169
L10:
  mov    -0x18(%rbp),%rax
  sub    -0x40(%rbp),%rax
  sub    $0x4,%rax
  cmp    %rax,-0x48(%rbp)
  ja     L156
  mov    $0xfffffffa,%eax
  jmp    L228
L156:
  mov    -0x38(%rbp),%rdx
  mov    -0x10(%rbp),%rax
  add    %rax,%rdx
  mov    -0x20(%rbp),%rax
  cmp    %rax,%rdx
  ja     L263
  mov    $0xfffffff9,%eax
  jmp    L228
L263:
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  mov    -0x20(%rbp),%rdx
  add    $0x1,%rdx
  mov    %rdx,-0x20(%rbp)
  mov    -0x20(%rbp),%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
L169:
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  test   %eax,%eax
  jne    L10
  movl   $0x1,-0x28(%rbp)
  movl   $0x0,-0x24(%rbp)
L121:
  shll   -0x28(%rbp)
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  add    %eax,-0x28(%rbp)
  mov    -0x18(%rbp),%rax
  sub    -0x40(%rbp),%rax
  sub    $0x4,%rax
  cmp    %rax,-0x48(%rbp)
  ja     L82
  mov    $0xfffffff7,%eax
  jmp    L228
L82:
  cmpl   $0x1000002,-0x28(%rbp)
  jle    L238
  mov    $0xfffffff6,%eax
  jmp    L228
L238:
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  test   %eax,%eax
  jne    L175
  subl   $0x1,-0x28(%rbp)
  shll   -0x28(%rbp)
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  add    %eax,-0x28(%rbp)
  jmp    L121
L175:
  nop
  cmpl   $0x2,-0x28(%rbp)
  jne    L92
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  mov    %eax,-0x24(%rbp)
  mov    -0x2c(%rbp),%eax
  mov    %eax,-0x28(%rbp)
  jmp    L251
L92:
  mov    -0x18(%rbp),%rax
  sub    -0x40(%rbp),%rax
  sub    $0x4,%rax
  cmp    %rax,-0x48(%rbp)
  ja     L140
  mov    $0xfffffff8,%eax
  jmp    L228
L140:
  subl   $0x3,-0x28(%rbp)
  shll   $0x8,-0x28(%rbp)
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  add    %eax,-0x28(%rbp)
  cmpl   $0xffffffff,-0x28(%rbp)
  jne    L297
  mov    -0x18(%rbp),%rax
  sub    -0x40(%rbp),%rax
  sub    $0x4,%rax
  cmp    %rax,-0x48(%rbp)
  ja     L178
  mov    $0xffffffff,%eax
  jmp    L228
L178:
  mov    $0x0,%eax
  jmp    L228
L297:
  mov    -0x28(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,-0x24(%rbp)
L251:
  cmpl   $0x0,-0x24(%rbp)
  jne    L88
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  test   %eax,%eax
  je     L144
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  add    $0x3,%eax
  mov    %eax,-0x24(%rbp)
  jmp    L351
L144:
  addl   $0x1,-0x24(%rbp)
L51:
  shll   -0x24(%rbp)
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  add    %eax,-0x24(%rbp)
  mov    -0x40(%rbp),%rdx
  mov    -0x48(%rbp),%rax
  add    %rax,%rdx
  mov    -0x18(%rbp),%rax
  cmp    %rax,%rdx
  ja     L273
  mov    $0xfffffffc,%eax
  jmp    L228
L273:
  mov    -0x24(%rbp),%eax
  cltq
  cmp    %rax,-0x10(%rbp)
  ja     L138
  mov    $0xfffffffb,%eax
  jmp    L228
L138:
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  test   %eax,%eax
  je     L51
  addl   $0x3,-0x24(%rbp)
  jmp    L351
L88:
  lea    -0x30(%rbp),%rdx
  lea    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <next@plt>
  add    $0x1,%eax
  mov    %eax,-0x24(%rbp)
L351:
  mov    -0x28(%rbp),%eax
  mov    %eax,-0x2c(%rbp)
  mov    -0x28(%rbp),%eax
  sar    %eax
  cmp    $0x500,%eax
  jle    L71
  addl   $0x1,-0x24(%rbp)
L71:
  mov    -0x20(%rbp),%rdx
  mov    -0x24(%rbp),%eax
  cltq
  add    %rax,%rdx
  mov    -0x38(%rbp),%rcx
  mov    -0x10(%rbp),%rax
  add    %rcx,%rax
  cmp    %rax,%rdx
  jb     L58
  mov    $0xfffffffe,%eax
  jmp    L228
L58:
  mov    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%eax
  sar    %eax
  cltq
  neg    %rax
  add    %rdx,%rax
  cmp    %rax,-0x38(%rbp)
  jbe    L44
  mov    $0xfffffffd,%eax
  jmp    L228
L44:
  mov    -0x28(%rbp),%eax
  sar    %eax
  mov    %eax,%ecx
  mov    -0x24(%rbp),%edx
  lea    -0x20(%rbp),%rax
  mov    %ecx,%esi
  mov    %rax,%rdi
  call   <copy@plt>
  jmp    L17
L228:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L233
  call   <__stack_chk_fail@plt>
L233:
  leave
  ret
```

assistant: ```c
int decompress_lz(char *dst, char *src, size_t src_length) {
  size_t dst_length = le32toh(*((uint32_t *)src));
  char *out = dst - 1;
  char *in = src + 4;
  uint16_t ctrl = 0;
  uint32_t off_copy = 0;
  while (1) {
    while (next(&in, &ctrl)) {
      if (in - src - 4 >= src_length)
        return -6;
      if (out >= dst + dst_length)
        return -7;
      *(++out) = *in++;
    }
    uint32_t off = 1;
    int32_t lng = 0;
    while (1) {
      off *= 2;
      off += next(&in, &ctrl);
      if (in - src - 4 >= src_length)
        return -9;
      if (off > 0x1000002)
        return -10;
      if (next(&in, &ctrl)) {
        break;
      }
      off--;
      off *= 2;
      off += next(&in, &ctrl);
    }
    if (off == 2) {
      lng = next(&in, &ctrl);
      off = off_copy;
    } else {
      if (in - src - 4 >= src_length)
        return -8;
      off -= 3;
      off <<= 8;
      off += (unsigned char)(*in++);
      if (off == -1) {
        if (in - src - 4 >= src_length)
          return -1;
        return 0;
      }
      lng = (off ^ 1) & 1;
    }
    if (lng == 0) {
      if (next(&in, &ctrl)) {
        lng = 3 + next(&in, &ctrl);
      } else {
        ++lng;
        do {
          lng *= 2;
          lng += next(&in, &ctrl);
          if (in >= src + src_length)
            return -4;
          if (lng >= dst_length)
            return -5;
        } while (!next(&in, &ctrl));
        lng += 3;
      }
    } else {
      lng = 1 + next(&in, &ctrl);
    }
    off_copy = off;
    if ((off >> 1) > 0x500)
      ++lng;
    if ((out + lng) >= (dst + dst_length))
      return -2;
    if ((out - (off >> 1)) < dst)
      return -3;
    ;
    copy(&out, off >> 1, lng);
  }
}
```