|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Bounded entity and UTF-8 decoding for the no-heap XML pull reader. More...
#include <stddef.h>#include <stdint.h>#include <string.h>#include "ra8_attributes.h"#include "xml.h"#include "xml_internal.h"Go to the source code of this file.
Data Structures | |
| struct | priv_decode_cursor_t |
| Incremental decoded-byte cursor used for allocation-free comparison. More... | |
Functions | |
| static bool | internal_xml_char (uint32_t cp) |
| Test whether a scalar is an XML 1.0 character. | |
| static ra8_err_t | internal_utf8_lead (uint8_t lead, uint32_t *out_cp, size_t *out_used, uint32_t *out_minimum) |
| Classify one UTF-8 lead byte into its scalar width and payload. | |
| static ra8_err_t | internal_utf8_next (const uint8_t *source, size_t end, size_t position, uint32_t *out_cp, size_t *out_used) |
| Decode one canonical UTF-8 scalar. | |
| bool | priv_xml_span_valid (size_t source_len, xml_span_t span) |
| Check that a source-relative span is in range. | |
| static size_t | internal_utf8 (uint32_t cp, uint8_t out[4]) |
| Encode one valid Unicode scalar as UTF-8. | |
| static uint32_t | internal_digit (uint8_t c, uint32_t base) |
| Convert one numeric-reference digit. | |
| bool | priv_xml_bytes_equal (const uint8_t *source, size_t offset, const char *literal, size_t length) |
| Compare bounded source bytes against a literal of known length. | |
| static ra8_err_t | internal_entity (const uint8_t *source, size_t end, size_t position, uint32_t *out_cp, size_t *out_used) |
| Decode one entity beginning at a bounded position. | |
| static ra8_err_t | internal_decode_one (const uint8_t *source, size_t end, size_t cursor, char *destination, size_t capacity, bool truncate, size_t *output, bool *clipped, size_t *out_used) |
| Decode one character or entity and append it to the destination. | |
| static ra8_err_t | internal_decode (const uint8_t *source, xml_span_t span, char *destination, size_t capacity, bool truncate, size_t *out_length) |
| Decode, prefix-decode, or measure one already-bounded span. | |
| static ra8_err_t | internal_decoded_byte (const uint8_t *source, priv_decode_cursor_t *cursor, uint8_t *out) |
| Return one entity-decoded byte from a comparison cursor. | |
| ra8_err_t | xml_decode (const uint8_t *source, size_t source_len, xml_span_t span, char *destination, size_t capacity, size_t *out_length) |
| Entity-decode a source span into a bounded NUL-terminated buffer. | |
| ra8_err_t | xml_decode_prefix (const uint8_t *source, size_t source_len, xml_span_t span, char *destination, size_t capacity, size_t *out_length) |
| Decode the longest complete prefix that fits the destination. | |
| ra8_err_t | xml_decoded_size (const uint8_t *source, size_t source_len, xml_span_t span, size_t *out_length) |
| Measure the entity-decoded byte count of a bounded span. | |
| bool | xml_span_equal (const uint8_t *source, size_t source_len, xml_span_t span, const char *literal) |
| Compare a bounded span with an exact ASCII literal. | |
| bool | xml_span_local_equal (const uint8_t *source, size_t source_len, xml_span_t span, const char *literal) |
| Compare the namespace-local tail of a bounded span with an ASCII literal. | |
| bool | xml_decoded_equal (const uint8_t *source, size_t source_len, xml_span_t left, xml_span_t right) |
| Compare two entity-decoded spans from the same immutable source. | |
| ra8_err_t | priv_xml_raw (const uint8_t *source, size_t start, size_t end) |
| Validate canonical UTF-8 XML 1.0 characters over a byte range. | |
Bounded entity and UTF-8 decoding for the no-heap XML pull reader.
Owns the lexical half of the reader: canonical UTF-8 scalar validation and encoding, the five predefined entities plus decimal and hexadecimal character references, bounded span decoding into caller-owned storage, and the decoded comparisons the event walker layers on top. Nothing here reads reader state; the pull reader itself – markup scanning, element frames, and event emission – lives in xml.c.
[Ring 3 / LIB] {World: NS}
Definition in file xml_decode.c.
|
static |
Decode, prefix-decode, or measure one already-bounded span.
Validates the complete span even when prefix output clips.
| [in] | source | Immutable source containing span. |
| [in] | span | Valid source-relative encoded span. |
| [out] | destination | Optional decoded destination. |
| [in] | capacity | Writable destination capacity including NUL. |
| [in] | truncate | Permit a maximal complete prefix when capacity is short. |
| [out] | out_length | Decoded or emitted byte count. |
| k_ra8_ok | Complete validation/decode succeeded. |
| k_ra8_err_no_mem | Non-truncating destination capacity was insufficient. |
| k_ra8_err_validation_failed | UTF-8 or entity was invalid. |
span lies in the source extent. capacity writable bytes. Definition at line 430 of file xml_decode.c.
References internal_decode_one(), k_ra8_err_no_mem, k_ra8_ok, xml_span_t::length, xml_span_t::offset, and RA8_INTERNAL.
Referenced by xml_decode(), xml_decode_prefix(), and xml_decoded_size().
|
static |
Decode one character or entity and append it to the destination.
Decodes one XML character reference/entity, or one raw UTF-8 character, at cursor, then copies its UTF-8 bytes into destination, clipping (or rejecting, per truncate) once capacity is reached.
| [in] | source | Immutable validated XML source. |
| [in] | end | Exclusive end offset of the decodable span. |
| [in] | cursor | Current source offset to decode from. |
| [in,out] | destination | Caller-owned destination buffer, or NULL to measure only. |
| [in] | capacity | Writable capacity of destination in bytes. |
| [in] | truncate | Whether to clip rather than reject on overflow. |
| [in,out] | output | Running output byte count. |
| [in,out] | clipped | Whether the destination has already been clipped. |
| [out] | out_used | Source bytes consumed by this character or entity. |
| k_ra8_ok | One character or entity was decoded and appended. |
| k_ra8_err_no_mem | Capacity was exhausted and truncate is false. |
| k_ra8_err_validation_failed | The entity or UTF-8 sequence is malformed. |
cursor is within the decodable span, strictly less than end. output and clipped carry the running state of the enclosing span walk and do not alias source. output (unless clipped) and reports out_used. destination and latches clipped, so every later character is measured but never stored. Definition at line 364 of file xml_decode.c.
References internal_entity(), internal_utf8(), internal_utf8_next(), k_ra8_err_no_mem, k_ra8_ok, memcpy(), and RA8_INTERNAL.
Referenced by internal_decode().
|
static |
Return one entity-decoded byte from a comparison cursor.
Buffers remaining bytes when one entity decodes to multibyte UTF-8.
| [in] | source | Immutable source bytes. |
| [in,out] | cursor | Valid decoded-span cursor. |
| [out] | out | Next decoded byte. |
| k_ra8_ok | One byte returned and cursor advanced. |
| k_ra8_err_validation_failed | Cursor ended or entity was invalid. |
out is writable and does not overlap cursor/source. Definition at line 483 of file xml_decode.c.
References priv_decode_cursor_t::end, internal_entity(), internal_utf8(), k_ra8_err_validation_failed, k_ra8_ok, priv_decode_cursor_t::pending, priv_decode_cursor_t::pending_at, priv_decode_cursor_t::pending_len, and priv_decode_cursor_t::position.
Referenced by xml_decoded_equal().
|
static |
Convert one numeric-reference digit.
Supports decimal and hexadecimal reference bodies.
| [in] | c | Candidate ASCII digit. |
| [in] | base | Numeric base, ten or sixteen. |
| UINT32_MAX | c is invalid for base. |
base is 10 or 16. c is an unsigned source byte. Definition at line 223 of file xml_decode.c.
References k_priv_xml_decimal_base, and RA8_INTERNAL.
Referenced by internal_entity().
|
static |
Decode one entity beginning at a bounded position.
Accepts five predefined or decimal/hex numeric references only.
| [in] | source | Immutable source bytes. |
| [in] | end | One-past-last readable entity byte. |
| [in] | position | Offset of the leading ampersand. |
| [out] | out_cp | Decoded XML character. |
| [out] | out_used | Encoded bytes consumed. |
| k_ra8_ok | Entity decoded. |
| k_ra8_err_validation_failed | Entity or character was invalid. |
source spans at least end readable bytes. Definition at line 288 of file xml_decode.c.
References internal_digit(), internal_xml_char(), k_priv_xml_decimal_base, k_priv_xml_scalar_max, k_ra8_err_validation_failed, k_ra8_ok, priv_xml_bytes_equal(), RA8_INTERNAL, and strlen().
Referenced by internal_decode_one(), and internal_decoded_byte().
|
static |
Encode one valid Unicode scalar as UTF-8.
Writes the canonical one-to-four-byte representation.
| [in] | cp | Valid Unicode scalar. |
| [out] | out | Four-byte destination. |
| 1 | ASCII scalar encoded. |
| 2 | Two-byte scalar encoded. |
| 3 | Three-byte scalar encoded. |
| 4 | Four-byte scalar encoded. |
cp is a Unicode scalar accepted by internal_xml_char. out spans four writable bytes. out is modified. Definition at line 184 of file xml_decode.c.
References k_priv_utf8_continuation_tag, k_priv_utf8_four_lead_tag, k_priv_utf8_scalar_mask, k_priv_utf8_shift_second, k_priv_utf8_shift_third, k_priv_utf8_three_lead_tag, k_priv_utf8_three_scalar_min, k_priv_utf8_two_lead_tag, k_priv_xml_supplementary_min, and RA8_INTERNAL.
Referenced by internal_decode_one(), and internal_decoded_byte().
|
static |
Classify one UTF-8 lead byte into its scalar width and payload.
Distinguishes ASCII, 2/3/4-byte lead bytes, and rejects a bare continuation byte used as a lead.
| [in] | lead | One candidate lead byte. |
| [out] | out_cp | Payload bits decoded so far (lead byte only). |
| [out] | out_used | Total encoded byte width (1..4). |
| [out] | out_minimum | Minimum scalar value the payload must reach. |
| k_ra8_ok | The lead byte is a valid ASCII or multi-byte lead. |
| k_ra8_err_validation_failed | The byte is a bare continuation byte. |
lead is treated as untrusted input. out_cp, out_used, and out_minimum are writable and do not alias one another. out_used is in [1, 4] and out_cp holds the decoded lead-byte payload bits. Definition at line 81 of file xml_decode.c.
References k_priv_utf8_continuation_tag, k_priv_utf8_four_lead_max, k_priv_utf8_four_lead_min, k_priv_utf8_four_payload_mask, k_priv_utf8_three_lead_max, k_priv_utf8_three_lead_min, k_priv_utf8_three_payload_mask, k_priv_utf8_three_scalar_min, k_priv_utf8_two_lead_max, k_priv_utf8_two_lead_min, k_priv_utf8_two_payload_mask, k_priv_xml_supplementary_min, k_ra8_err_validation_failed, and k_ra8_ok.
Referenced by internal_utf8_next().
|
static |
Decode one canonical UTF-8 scalar.
Enforces shortest form, valid continuation bytes, and XML characters.
| [in] | source | Immutable byte source. |
| [in] | end | One-past-last readable byte. |
| [in] | position | Candidate scalar start. |
| [out] | out_cp | Decoded scalar. |
| [out] | out_used | Consumed byte count. |
| k_ra8_ok | One valid scalar decoded. |
| k_ra8_err_validation_failed | Encoding or character was invalid. |
source spans at least end readable bytes. Definition at line 127 of file xml_decode.c.
References internal_utf8_lead(), internal_xml_char(), k_priv_utf8_continuation_mask, k_priv_utf8_continuation_tag, k_priv_utf8_scalar_mask, k_ra8_err_validation_failed, k_ra8_ok, and RA8_INTERNAL.
Referenced by internal_decode_one(), and priv_xml_raw().
|
static |
Test whether a scalar is an XML 1.0 character.
Rejects forbidden controls, surrogates, and out-of-range scalars.
| [in] | cp | Unicode scalar candidate. |
| true | cp is permitted. |
| false | cp is forbidden. |
cp is represented without narrowing. cp. Definition at line 50 of file xml_decode.c.
References k_priv_xml_bmp_first_max, k_priv_xml_bmp_second_max, k_priv_xml_bmp_second_min, k_priv_xml_carriage_return, k_priv_xml_line_feed, k_priv_xml_printable_min, k_priv_xml_scalar_max, k_priv_xml_supplementary_min, k_priv_xml_tab, and RA8_INTERNAL.
Referenced by internal_entity(), and internal_utf8_next().
| bool priv_xml_bytes_equal | ( | const uint8_t * | source, |
| size_t | offset, | ||
| const char * | literal, | ||
| size_t | length ) |
Compare bounded source bytes against a literal of known length.
Compare bounded source bytes with an ASCII character sequence.
Walks both operands one byte at a time so the comparison never hands an essentially-character operand to memcmp(), whose ordering is implementation-defined for plain char (MISRA-C:2012 Rules 21.14, 21.16). Only equality is ever asked of this function, so the loop is the whole contract.
| [in] | source | Immutable source bytes. |
| [in] | offset | First source byte to compare. |
| [in] | literal | Literal whose first length bytes are compared. |
| [in] | length | Byte count to compare. |
| true | Every compared byte matched. |
| false | At least one byte differed. |
source spans at least offset + length readable bytes. literal spans at least length readable bytes. Definition at line 260 of file xml_decode.c.
Referenced by internal_encoding(), internal_entity(), internal_external_id(), internal_keyword(), internal_pi(), internal_special(), internal_terminator(), priv_xml_doctype(), and xml_span_equal().
| ra8_err_t priv_xml_raw | ( | const uint8_t * | source, |
| size_t | start, | ||
| size_t | end ) |
Validate canonical UTF-8 XML 1.0 characters over a byte range.
Rejects overlong encoding, invalid continuations, controls, and surrogates.
| [in] | source | Immutable XML source. |
| [in] | start | First byte to validate. |
| [in] | end | One-past-last byte to validate. |
| k_ra8_ok | Every byte belongs to a permitted canonical scalar. |
| k_ra8_err_validation_failed | Encoding or XML character was invalid. |
source spans at least end readable bytes. Definition at line 610 of file xml_decode.c.
References internal_utf8_next(), and k_ra8_ok.
Referenced by internal_cdata(), internal_comment(), internal_literal(), and internal_pi().
| bool priv_xml_span_valid | ( | size_t | source_len, |
| xml_span_t | span ) |
Check that a source-relative span is in range.
Uses subtraction after checking the offset to avoid overflow.
| [in] | source_len | Exact source byte extent. |
| [in] | span | Candidate source-relative span. |
| true | Offset and length are bounded. |
| false | The span is forged, stale, or out of range. |
source_len is the true readable extent. span uses the same source-relative coordinate system. Definition at line 161 of file xml_decode.c.
References xml_span_t::length, and xml_span_t::offset.
Referenced by xml_attr_next(), xml_decode(), xml_decode_prefix(), xml_decoded_size(), xml_span_equal(), and xml_span_local_equal().
|
nodiscard |
Entity-decode a source span into a bounded NUL-terminated buffer.
| [in] | source | Immutable source containing span. |
| [in] | source_len | Exact readable extent of source. |
| [in] | span | Source-relative encoded text span. |
| [out] | destination | Decoded UTF-8 destination. |
| [in] | capacity | Writable destination capacity including the NUL. |
| [out] | out_length | Decoded bytes excluding the NUL. |
| k_ra8_ok | Decoded completely. |
| k_ra8_err_null_ptr | A required pointer is NULL. |
| k_ra8_err_no_mem | Destination too small. |
| k_ra8_err_validation_failed | span, UTF-8, or an entity is invalid. |
source spans source_len readable bytes. destination spans capacity writable bytes and does not overlap source. destination is NUL-terminated and *out_length < capacity. source is unchanged on every result. destination may contain an unterminated prefix and out_length is unspecified; the operation is not output-atomic. Definition at line 511 of file xml_decode.c.
References internal_decode(), k_ra8_err_null_ptr, k_ra8_err_validation_failed, and priv_xml_span_valid().
Referenced by internal_intern_span(), and priv_epub_xml_attr_contains().
|
nodiscard |
Decode the longest complete prefix that fits the destination.
The prefix never splits an entity or UTF-8 sequence, and the entire encoded span is still validated after output clips.
| [in] | source | Immutable source containing span. |
| [in] | source_len | Exact readable extent of source. |
| [in] | span | Source-relative encoded text span. |
| [out] | destination | Decoded UTF-8 prefix destination. |
| [in] | capacity | Writable destination capacity including the NUL. |
| [out] | out_length | Decoded bytes excluding the NUL. |
| k_ra8_ok | Complete validation and maximal prefix decode succeeded. |
| k_ra8_err_null_ptr | A required pointer is NULL. |
| k_ra8_err_no_mem | capacity is zero. |
| k_ra8_err_validation_failed | span, UTF-8, or an entity is invalid. |
source spans source_len readable bytes. destination spans capacity writable bytes and does not overlap source. destination is NUL-terminated, *out_length < capacity, and no partial decoded codepoint/entity is present. source is unchanged on every result. destination may contain a prefix and out_length is unspecified; the operation is not output-atomic. Definition at line 527 of file xml_decode.c.
References internal_decode(), k_ra8_err_null_ptr, k_ra8_err_validation_failed, and priv_xml_span_valid().
Referenced by priv_epub_xml_copy().
|
nodiscard |
Compare two entity-decoded spans from the same immutable source.
| [in] | source | Immutable source containing both spans. |
| [in] | source_len | Exact readable extent of source. |
| [in] | left | First source-relative span. |
| [in] | right | Second source-relative span. |
| false | source is NULL, a span/entity is invalid, or values differ. |
source spans source_len bytes when non-NULL. Definition at line 584 of file xml_decode.c.
References internal_decoded_byte(), k_ra8_ok, xml_span_t::length, xml_span_t::offset, and xml_decoded_size().
Referenced by internal_manifest_lookup(), and internal_mark_metadata().
|
nodiscard |
Measure the entity-decoded byte count of a bounded span.
| [in] | source | Immutable source containing span. |
| [in] | source_len | Exact readable extent of source. |
| [in] | span | Source-relative encoded text span. |
| [out] | out_length | Exact decoded UTF-8 byte count excluding any NUL. |
| k_ra8_ok | Complete span measured. |
| k_ra8_err_null_ptr | source or out_length is NULL. |
| k_ra8_err_validation_failed | span, UTF-8, or an entity is invalid. |
source spans source_len readable bytes. out_length is exact; on failure it is unspecified. source is unchanged. Definition at line 544 of file xml_decode.c.
References internal_decode(), k_ra8_err_null_ptr, k_ra8_err_validation_failed, and priv_xml_span_valid().
Referenced by internal_attr_parse(), internal_intern_span(), internal_text(), internal_text(), and xml_decoded_equal().
|
nodiscard |
Compare a bounded span with an exact ASCII literal.
| [in] | source | Immutable source containing span. |
| [in] | source_len | Exact readable extent of source. |
| [in] | span | Candidate source-relative byte span. |
| [in] | literal | NUL-terminated ASCII literal. |
| false | A pointer is NULL, span is out of range, or bytes differ. |
source spans source_len bytes when non-NULL. Definition at line 555 of file xml_decode.c.
References xml_span_t::length, xml_span_t::offset, priv_xml_bytes_equal(), priv_xml_span_valid(), and strlen().
Referenced by internal_collect_spine(), internal_declaration_attr(), internal_font_type(), internal_opf_metadata_child(), internal_opf_shape(), internal_select_event(), priv_epub_xml_attr(), and xml_span_local_equal().
|
nodiscard |
Compare the namespace-local tail of a bounded span with an ASCII literal.
| [in] | source | Immutable source containing span. |
| [in] | source_len | Exact readable extent of source. |
| [in] | span | Candidate QName span. |
| [in] | literal | NUL-terminated local-name literal. |
literal. | false | A pointer is NULL, span is out of range, or bytes differ. |
source spans source_len bytes when non-NULL. Definition at line 565 of file xml_decode.c.
References xml_span_t::length, xml_span_t::offset, priv_xml_span_valid(), and xml_span_equal().
Referenced by internal_ancestor_depth(), internal_collect_spine(), internal_manifest_lookup(), internal_mark_metadata(), internal_nav_event(), internal_nav_event_start(), internal_nav_has_list(), internal_ncx_event(), internal_opf_first_event(), internal_opf_metadata_child(), internal_opf_shape(), internal_select_nav(), internal_toc_capacity(), and priv_epub_xml_find().