<commit_before>#if HAVE_CONFIG_H
#include "config.h"
#endif

#if HAVE_MALLOC_H
#include <malloc.h>
#endif

#if HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include <dlfcn.h>
#include <stdio.h>

#include "bluray.h"
#include "util/macro.h"
#include "util/logging.h"

BLURAY *bd_open(const char* device_path, const char* keyfile_path)
{
    BLURAY *bd = calloc(1, sizeof(BLURAY));

    if (device_path) {
        strncpy(bd->device_path, device_path, 100);

        bd->aacs = NULL;
        bd->h_libaacs = NULL;
        bd->fp = NULL;

        if (keyfile_path) {
            if ((bd->h_libaacs = dlopen("libaacs.so", RTLD_LAZY))) {
                fptr_p_void fptr;
                uint8_t *vid;

                DEBUG(DBG_BLURAY, "Downloaded libaacs (0x%08x)\n", bd->h_libaacs);

                if ((fptr = dlsym(bd->h_libaacs, "aacs_open"))) {
                    if ((bd->aacs = fptr(device_path, keyfile_path))) {
                        if ((fptr = dlsym(bd->h_libaacs, "aacs_get_vid"))) {
                            vid = fptr(bd->aacs);
                        }

                        if ((bd->h_libbdplus = dlopen("libbdplus.so", RTLD_LAZY))) {
                            DEBUG(DBG_BLURAY, "Downloaded libbdplus (0x%08x)\n", bd->h_libbdplus);

                            if ((fptr = dlsym(bd->h_libbdplus, "bdplus_open"))) {
                                if (!(bd->bdplus = fptr(device_path, keyfile_path, vid))) {
                                    DEBUG(DBG_BLURAY, "libbdplus ret NULL!\n");
                                }
                            }
                        } else {
                            DEBUG(DBG_BLURAY, "libbdplus not present!\n");
                        }
                    } else {
                        DEBUG(DBG_BLURAY, "libaacs ret NULL!\n");
                    }
                }
            } else {
                DEBUG(DBG_BLURAY, "libaacs not present!\n");
            }
        } else {
            DEBUG(DBG_BLURAY, "No keyfile provided. You will not be able to make use of crypto functionality (0x%08x)\n", bd);
        }

        DEBUG(DBG_BLURAY, "BLURAY initialized! (0x%08x)\n", bd);
    } else {
        X_FREE(bd);

        DEBUG(DBG_BLURAY, "No device path provided!\n");
    }

    return bd;
}

void bd_close(BLURAY *bd)
{
    if (bd->h_libaacs) {
        if (bd->aacs) {
            fptr_p_void fptr = dlsym(bd->h_libaacs, "aacs_close");
            fptr(bd->aacs);
        }

        dlclose(bd->h_libaacs);
    }

    if (bd->h_libbdplus) {
        if (bd->bdplus) {
            fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_close");
            fptr(bd->bdplus);
        }

        dlclose(bd->h_libaacs);
    }

    if (bd->fp) {
        file_close(bd->fp);
    }

    DEBUG(DBG_BLURAY, "BLURAY destroyed! (0x%08x)\n", bd);

    X_FREE(bd);
}

uint64_t bd_seek(BLURAY *bd, uint64_t pos)
{
    if (pos < bd->s_size) {
        bd->s_pos = pos - (pos % 6144);

        file_seek(bd->fp, bd->s_pos, SEEK_SET);

        if (bd->h_libbdplus && bd->bdplus) {
            fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_seek");
            fptr(bd->bdplus, bd->s_pos);
        }

        DEBUG(DBG_BLURAY, "Seek to %ld (0x%08x)\n", bd->s_pos, bd);
    }

    return bd->s_pos;
}

int bd_read(BLURAY *bd, unsigned char *buf, int len)
{
    if (bd->fp) {
        DEBUG(DBG_BLURAY, "Reading unit [%d bytes] at %ld... (0x%08x)\n", len, bd->s_pos, bd);

        if (len + bd->s_pos < bd->s_size) {
            int read_len;

            if ((read_len = file_read(bd->fp, buf, len))) {
                if (bd->h_libaacs && bd->aacs) {
                    if ((bd->libaacs_decrypt_unit = dlsym(bd->h_libaacs, "aacs_decrypt_unit"))) {
                        if (!bd->libaacs_decrypt_unit(bd->aacs, buf, len, bd->s_pos)) {
                            DEBUG(DBG_BLURAY, "Unable decrypt unit! (0x%08x)\n", bd);

                            return 0;
                        }

                        if (bd->h_libbdplus && bd->bdplus) {
                            fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_fixup");<commit_msg>Allow reading the last byte of clip<commit_after>#if HAVE_CONFIG_H
#include "config.h"
#endif

#if HAVE_MALLOC_H
#include <malloc.h>
#endif

#if HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include <dlfcn.h>
#include <stdio.h>

#include "bluray.h"
#include "util/macro.h"
#include "util/logging.h"

BLURAY *bd_open(const char* device_path, const char* keyfile_path)
{
    BLURAY *bd = calloc(1, sizeof(BLURAY));

    if (device_path) {
        strncpy(bd->device_path, device_path, 100);

        bd->aacs = NULL;
        bd->h_libaacs = NULL;
        bd->fp = NULL;

        if (keyfile_path) {
            if ((bd->h_libaacs = dlopen("libaacs.so", RTLD_LAZY))) {
                fptr_p_void fptr;
                uint8_t *vid;

                DEBUG(DBG_BLURAY, "Downloaded libaacs (0x%08x)\n", bd->h_libaacs);

                if ((fptr = dlsym(bd->h_libaacs, "aacs_open"))) {
                    if ((bd->aacs = fptr(device_path, keyfile_path))) {
                        if ((fptr = dlsym(bd->h_libaacs, "aacs_get_vid"))) {
                            vid = fptr(bd->aacs);
                        }

                        if ((bd->h_libbdplus = dlopen("libbdplus.so", RTLD_LAZY))) {
                            DEBUG(DBG_BLURAY, "Downloaded libbdplus (0x%08x)\n", bd->h_libbdplus);

                            if ((fptr = dlsym(bd->h_libbdplus, "bdplus_open"))) {
                                if (!(bd->bdplus = fptr(device_path, keyfile_path, vid))) {
                                    DEBUG(DBG_BLURAY, "libbdplus ret NULL!\n");
                                }
                            }
                        } else {
                            DEBUG(DBG_BLURAY, "libbdplus not present!\n");
                        }
                    } else {
                        DEBUG(DBG_BLURAY, "libaacs ret NULL!\n");
                    }
                }
            } else {
                DEBUG(DBG_BLURAY, "libaacs not present!\n");
            }
        } else {
            DEBUG(DBG_BLURAY, "No keyfile provided. You will not be able to make use of crypto functionality (0x%08x)\n", bd);
        }

        DEBUG(DBG_BLURAY, "BLURAY initialized! (0x%08x)\n", bd);
    } else {
        X_FREE(bd);

        DEBUG(DBG_BLURAY, "No device path provided!\n");
    }

    return bd;
}

void bd_close(BLURAY *bd)
{
    if (bd->h_libaacs) {
        if (bd->aacs) {
            fptr_p_void fptr = dlsym(bd->h_libaacs, "aacs_close");
            fptr(bd->aacs);
        }

        dlclose(bd->h_libaacs);
    }

    if (bd->h_libbdplus) {
        if (bd->bdplus) {
            fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_close");
            fptr(bd->bdplus);
        }

        dlclose(bd->h_libaacs);
    }

    if (bd->fp) {
        file_close(bd->fp);
    }

    DEBUG(DBG_BLURAY, "BLURAY destroyed! (0x%08x)\n", bd);

    X_FREE(bd);
}

uint64_t bd_seek(BLURAY *bd, uint64_t pos)
{
    if (pos < bd->s_size) {
        bd->s_pos = pos - (pos % 6144);

        file_seek(bd->fp, bd->s_pos, SEEK_SET);

        if (bd->h_libbdplus && bd->bdplus) {
            fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_seek");
            fptr(bd->bdplus, bd->s_pos);
        }

        DEBUG(DBG_BLURAY, "Seek to %ld (0x%08x)\n", bd->s_pos, bd);
    }

    return bd->s_pos;
}

int bd_read(BLURAY *bd, unsigned char *buf, int len)
{
    if (bd->fp) {
        DEBUG(DBG_BLURAY, "Reading unit [%d bytes] at %ld... (0x%08x)\n", len, bd->s_pos, bd);

        if (len + bd->s_pos <= bd->s_size) {
            int read_len;

            if ((read_len = file_read(bd->fp, buf, len))) {
                if (bd->h_libaacs && bd->aacs) {
                    if ((bd->libaacs_decrypt_unit = dlsym(bd->h_libaacs, "aacs_decrypt_unit"))) {
                        if (!bd->libaacs_decrypt_unit(bd->aacs, buf, len, bd->s_pos)) {
                            DEBUG(DBG_BLURAY, "Unable decrypt unit! (0x%08x)\n", bd);

                            return 0;
                        }

                        if (bd->h_libbdplus && bd->bdplus) {
                            fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_fixup");
{'fraction_non_alphanumeric': 0.14382813448234008, 'fraction_numerical': 0.00922442043937371, 'mean_word_length': 1.5661787605107442, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 115, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4387269', 'n_tokens_mistral': 3137, 'n_tokens_neox': 2984, 'n_words': 543}