Files
AnyPS5/docs/dev/debt/libSceJson2.md
T

7.8 KiB

libSceJson2 technical debt

Unknown function info

  • sce::Json::Parser::parse with a read callback (libSceJson2) - the callback's contract is taken from PPSA04540's: it returns 0 with the next character, and at the end of its data writes '\0' and returns -1. Characters are read until the callback returns non-zero or gives '\0', and the text read is then parsed as by the (text, size) overload, so trailing characters after the value are rejected as there. Whether the console stops reading at the end of the top-level value, and what it returns when the callback fails before the end, are unknown
  • sce::Json::Parser::parse (libSceJson2) - a null text pointer or zero size returns JsonErrorParse (0x80920101) without modifying the destination Value; whether the console distinguishes a null pointer from a syntax error with a separate parameter error code is unknown. A number that overflows a double (e.g. 1e309) throws: whether the console rejects the document or stores an infinite real is unknown
  • sce::Json::InitParameter2, InitParameterRtti and InitParameterRtti2 (libSceJson2) - layouts inferred, not known. InitParameter2 is taken as the 40-byte object of SharpEmu and KytyPS5: the allocator, its user data, the file buffer size, the 32-bit special float format type at 0x18 and 12 bytes both zero, and both constructors zero all of it. InitParameterRtti2::setAllocatorRtti writes the allocation parameters and user data where setAllocator writes the allocator, as both references do; whether the console also marks the object as using RTTI allocation is unknown. InitParameterRtti's constructor writes the allocation parameters, user data and file buffer size to the first 24 bytes, an order inferred from its mangled arguments. The values of SpecialFloatFormatType and what they select are unknown, so setSpecialFloatFormatType stores any value and nothing reads it: Initializer::initialize(InitParameter2) ignores every field as initialize(InitParameter) does, serializing a non-finite real throws whatever the type, and whether the type lets the parser accept NaN or infinity is unknown. The setters return nothing; whether the console's return this is unknown
  • sce::Json::Object::Pair, sce::Json::Array::iterator and sce::Json::Object::iterator members (libSceJson2) - the signatures follow the mangled names, with Array::iterator::operator++(int) and Object::iterator::operator++(int) returning their copy through a result pointer before this as begin does, since the iterators have non-trivial destructors. Pair(const String&, const Value&) and default Pair() deep-copy or initialize into the layout Object iteration already hands out (key at 0, value at 0x10) and zeroes the 8 bytes between them; what the console keeps there is unknown. Default-constructed iterators are singular
  • sce::Json::Value::setTypeMismatchHandler, setElementAccessFailureHandler and setSpecialFloatHandler (libSceJson2) - members of Value that return an int, inferred from a caller that registers them on its root Value before parsing into it, with the handler and its context, and accepts 0 or 0x80848104 as success; they return 0. The PS Vita library's Value::setNullAccessCallback is such a member too (vitasdk). The handler signatures follow the mangled names. A handler applies to the Value it is set on and to the values that Value holds then, and Parser::parse gives the values it creates the handlers of the Value it parses into, since the title reads the errors its handlers record after accessing parsed members; copies, push_back and Object::operator[] do not carry them, and how the console finds the handler of an accessed value is unknown. A typed getter on a non-null value of another type calls the type mismatch handler with the requested type, the value, null and the context, and returns the value the handler returns if it has the requested type, else the getter's default; passing null as the third handler argument (the second Value pointer), and the order of the two Value pointers, remain unverified against the console. The element access failure handler is not called: a failed operator[] or getValue on a value carrying it throws, as the error code the console passes, which the title records as its error, is unknown; without one the access still reaches the null-access callback. The special float handler is not called: serializing a non-finite real throws with or without it, as the FunctionType values and the bool* output are unknown, and the title's handler returns a different replacement for each of its two types
  • sce::Json::MemAllocator::notifyError (libSceJson2) - the base class's virtual does nothing. A title's allocator that does not override it calls it through its own vtable; the library never calls the title's allocator, so it never reports an allocation failure. Whether the console's base implementation logs anything is unknown
  • sce::Json::String size, capacity, resize, compare and operator==(const String&), append(const char*, size_t), operator+=; Value::swap; Array::iterator and Object::iterator copy constructor, advance and operator== (libSceJson2) - the signatures follow the mangled names and the behaviour is that of the matching std::string or container operation, with no cited source in KytyPS5, shadPS4, SharpProspero or disassembly. append(text, length) throws on a null text with a non-zero length; operator+= returns the String; Value::swap exchanges the node pointers; advance moves the iterator in place, returns it, and does not check the distance against the end. Whether the console returns the iterator from advance and how it bounds it is unverified
  • sce::Json::Value::operator bool (libSceJson2) - member of Value returning bool as a conversion operator, with no cited source in KytyPS5, shadPS4, SharpProspero, or disassembly: evaluates to false for TypeNull and boolean false, and true for boolean true. For all other value types it currently returns true; whether the console converts them, throws, or checks container emptiness is unverified
  • sce::Json::Object::insert and sce::Json::Object::erase (libSceJson2) - signatures and behaviors have no cited source in KytyPS5, shadPS4, SharpProspero, or disassembly: insert returns an iterator through a result pointer before this as Object::begin does, and takes a const Pair reference. If the key exists, it updates the existing value and returns an iterator to it; otherwise it appends a deep copy of the pair and returns an iterator to the new element; whether the console updates existing keys, appends duplicates, or ignores duplicate insertion is unverified. erase removes the item with matching key and returns 1 if found and removed, or 0 if not; whether the console returns size_t, bool, or an iterator is unverified

Functional

  • sce::Json::InitParameter2 base-object constructor (libSceJson2) - forwards to the complete-object constructor and uses its inferred layout and default field values; constructor equivalence and initialization bytes remain unverified on the console