/
githubmirror
/
libxmlb
Обзор
Документация
Войти
/
githubmirror
/
libxmlb
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/xb-silo-node.h
135 строк
3 KB
Richard Hughes
Do not construct an invalid silo when the XML component has >= 30 attributes
14 май 2026, 23:39
14 май 2026, 23:39
c9b2cec
Код
Авторство
О чём код?
/* * Copyright 2021 Richard Hughes <richard@hughsie.com> * * SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once #include "xb-compile.h" #define XB_SILO_UNSET 0xffffffff typedef enum { XB_SILO_NODE_FLAG_NONE = 0, XB_SILO_NODE_FLAG_IS_ELEMENT = 1 << 0, XB_SILO_NODE_FLAG_IS_TOKENIZED = 1 << 1, } XbSiloNodeFlag; typedef struct __attribute__((packed)) { guint8 flags : 2; guint8 attr_count : 6; guint8 token_count; /* ONLY when is_element */ guint32 element_name; /* ONLY when is_element: from strtab */ guint32 parent; /* ONLY when is_element: from 0 */ guint32 next; /* ONLY when is_element: from 0 */ guint32 text; /* ONLY when is_element: from strtab */ guint32 tail; /* ONLY when is_element: from strtab */ /* guint32 attrs[attr_count]; guint32 tokens[token_count]; */ } XbSiloNode; typedef struct __attribute__((packed)) { guint32 attr_name; /* from strtab */ guint32 attr_value; /* from strtab */ } XbSiloNodeAttr; gchar * xb_silo_node_to_string(const XbSiloNode *self) G_GNUC_NON_NULL(1); /* private */ static inline gboolean xb_silo_node_has_flag(const XbSiloNode *self, XbSiloNodeFlag flag) { return (self->flags & flag) > 0; } static inline guint32 xb_silo_node_get_size(const XbSiloNode *self) { if (xb_silo_node_has_flag(self, XB_SILO_NODE_FLAG_IS_ELEMENT)) { guint32 sz = sizeof(XbSiloNode); sz += self->attr_count * sizeof(XbSiloNodeAttr); sz += self->token_count * sizeof(guint32); return sz; } /* sentinel */ return sizeof(guint8); } /* private */ static inline guint8 xb_silo_node_get_flags(const XbSiloNode *self) { return self->flags; } /* private */ static inline guint32 xb_silo_node_get_text_idx(const XbSiloNode *self) { return self->text; } /* private */ static inline guint32 xb_silo_node_get_tail_idx(const XbSiloNode *self) { return self->tail; } /* private */ static inline guint8 xb_silo_node_get_attr_count(const XbSiloNode *self) { return self->attr_count; } /* private */ static inline XbSiloNodeAttr * xb_silo_node_get_attr(const XbSiloNode *self, guint8 idx) { guint32 off = sizeof(XbSiloNode); /* bounds check to prevent out-of-bounds read */ if (G_UNLIKELY(idx >= self->attr_count)) return NULL; off += sizeof(XbSiloNodeAttr) * idx; return (XbSiloNodeAttr *)(((guint8 *)self) + off); } /* private */ static inline guint8 xb_silo_node_get_token_count(const XbSiloNode *self) { return self->token_count; } /* private */ static inline guint32 xb_silo_node_get_token_idx(const XbSiloNode *self, guint idx) { guint32 off = 0; guint32 stridx; /* not valid */ if (!xb_silo_node_has_flag(self, XB_SILO_NODE_FLAG_IS_ELEMENT)) return XB_SILO_UNSET; if (!xb_silo_node_has_flag(self, XB_SILO_NODE_FLAG_IS_TOKENIZED)) return XB_SILO_UNSET; /* bounds check */ if (G_UNLIKELY(idx >= self->token_count)) return XB_SILO_UNSET; /* calculate offset to token */ off += sizeof(XbSiloNode); off += self->attr_count * sizeof(XbSiloNodeAttr); off += idx * sizeof(guint32); memcpy(&stridx, (guint8 *)self + off, sizeof(stridx)); return stridx; }