<commit_before>/*
 *  linux/fs/hfsplus/brec.c
 *
 * Copyright (C) 2001
 * <NAME> (<EMAIL>)
 * (C) 2003 Ardis Technologies <<EMAIL>>
 *
 * Handle individual btree records
 */

#include "hfsplus_fs.h"
#include "hfsplus_raw.h"

static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd);
static int hfs_brec_update_parent(struct hfs_find_data *fd);
static int hfs_btree_inc_height(struct hfs_btree *);

/* Get the length and offset of the given record in the given node */
u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off)
{
	__be16 retval[2];
	u16 dataoff;

	dataoff = node->tree->node_size - (rec + 2) * 2;
	hfs_bnode_read(node, retval, dataoff, 4);
	*off = be16_to_cpu(retval[1]);
	return be16_to_cpu(retval[0]) - *off;
}

/* Get the length of the key from a keyed record */
u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec)
{
	u16 retval, recoff;

	if (node->type != HFS_NODE_INDEX && node->type != HFS_NODE_LEAF)
		return 0;

	if ((node->type == HFS_NODE_INDEX) &&
	   !(node->tree->attributes & HFS_TREE_VARIDXKEYS)) {
		retval = node->tree->max_key_len + 2;
	} else {
		recoff = hfs_bnode_read_u16(node,
			node->tree->node_size - (rec + 1) * 2);
		if (!recoff)
			return 0;

		retval = hfs_bnode_read_u16(node, recoff) + 2;
		if (retval > node->tree->max_key_len + 2) {
			printk(KERN_ERR "hfs: keylen %d too large\n",
				retval);
			retval = 0;
		}
	}
	return retval;
}
<commit_msg>hfsplus: Add additional range check to handle on-disk corruptions<commit_after>/*
 *  linux/fs/hfsplus/brec.c
 *
 * Copyright (C) 2001
 * <NAME> (<EMAIL>)
 * (C) 2003 Ardis Technologies <<EMAIL>>
 *
 * Handle individual btree records
 */

#include "hfsplus_fs.h"
#include "hfsplus_raw.h"

static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd);
static int hfs_brec_update_parent(struct hfs_find_data *fd);
static int hfs_btree_inc_height(struct hfs_btree *);

/* Get the length and offset of the given record in the given node */
u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off)
{
	__be16 retval[2];
	u16 dataoff;

	dataoff = node->tree->node_size - (rec + 2) * 2;
	hfs_bnode_read(node, retval, dataoff, 4);
	*off = be16_to_cpu(retval[1]);
	return be16_to_cpu(retval[0]) - *off;
}

/* Get the length of the key from a keyed record */
u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec)
{
	u16 retval, recoff;

	if (node->type != HFS_NODE_INDEX && node->type != HFS_NODE_LEAF)
		return 0;

	if ((node->type == HFS_NODE_INDEX) &&
	   !(node->tree->attributes & HFS_TREE_VARIDXKEYS)) {
		retval = node->tree->max_key_len + 2;
	} else {
		recoff = hfs_bnode_read_u16(node,
			node->tree->node_size - (rec + 1) * 2);
		if (!recoff)
			return 0;
		if (recoff > node->tree->node_size - 2) {
			printk(KERN_ERR "hfs: recoff %d too large\n", recoff);
			return 0;
		}

		retval = hfs_bnode_read_u16(node, recoff) + 2;
		if (retval > node->tree->max_key_len + 2) {
			printk(KERN_ERR "hfs: keylen %d too large\n",
				retval);
			retval = 0;
		}
	}
	return retval;
}

{'fraction_non_alphanumeric': 0.14080747414080746, 'fraction_numerical': 0.0313646980313647, 'mean_word_length': 4.055649241146711, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3694813', 'n_tokens_mistral': 1350, 'n_tokens_neox': 1238, 'n_words': 297}