{"record":{"id":"17a2eeb1d3bb5b72","repo":"phalcon/cphalcon","slug":"invalid-wkb-empty-value","errorCode":null,"errorMessage":"Invalid WKB: empty value","messagePattern":"Invalid WKB: empty value","errorType":"exception","errorClass":"Phalcon\\Db\\Exceptions\\InvalidWkb","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Geometry/WkbParser.zep","lineNumber":42,"sourceCode":"    /**\n     * @var string\n     */\n    protected buffer = \"\";\n    /**\n     * @var int\n     */\n    protected length = 0;\n    /**\n     * @var int\n     */\n    protected position = 0;\n\n    public function parse(string raw) -> <GeometryInterface>\n    {\n        var srid = 0, body, arr;\n\n        if raw === \"\" {\n            throw new InvalidWkb(\"empty value\");\n        }\n\n        /**\n         * PostGIS returns EWKB as an even-length ASCII-hex string; MySQL\n         * returns binary (4-byte LE SRID prefix + standard WKB). Real binary\n         * WKB is not valid ASCII hex (it carries the 0x01 byte-order byte and\n         * arbitrary double bytes), so this distinguishes the two.\n         */\n        if strlen(raw) % 2 === 0 && ctype_xdigit(raw) {\n            let body = hex2bin(raw);\n        } else {\n            if strlen(raw) < 5 {\n                throw new InvalidWkb(\"buffer too short for MySQL prefix\");\n            }\n\n            let arr  = unpack(\"V\", substr(raw, 0, 4)),\n                srid = (int) arr[1],\n                body = substr(raw, 4);","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Geometry/WkbParser.zep#L24-L60","documentation":"Phalcon\\Db\\Geometry\\WkbParser::parse() converts WKB/EWKB geometry values from databases into geometry objects. An empty string input is rejected up front with InvalidWkb('empty value') before any parsing, because an empty payload cannot contain a geometry.","triggerScenarios":"Feeding $row['geom'] from a nullable geometry column that returned '' instead of NULL; LEFT JOIN rows where the geometry side is missing; fixtures that insert '' as a placeholder geometry.","commonSituations":"Drivers or ORMs coercing NULL to ''; batch imports over tables with empty-string defaults on geometry columns; test fixtures hand-written without real WKB.","solutions":["Treat empty/null geometry as null before parsing: if ($value === '' || $value === null) return null;","Fix the query or schema: filter with WHERE geom IS NOT NULL, or stop storing '' in geometry columns","Regenerate fixtures with real WKB from ST_AsBinary/ST_AsEWKB"],"exampleFix":"// before\n$point = $parser->parse($row['geom']);\n\n// after\n$point = ($row['geom'] === '' || $row['geom'] === null)\n    ? null\n    : $parser->parse($row['geom']);","handlingStrategy":"validation","validationCode":"if (!is_string($raw) || '' === $raw) {\n    return null; // no geometry on this row\n}\nreturn $parser->parse($raw);","typeGuard":"function isNonEmptyWkb(mixed $value): bool\n{\n    return is_string($value) && '' !== $value;\n}","tryCatchPattern":"try {\n    $geom = $parser->parse($row['geom']);\n} catch (\\Phalcon\\Db\\Exceptions\\InvalidWkb $e) {\n    $logger->warning('Unparseable geometry', ['id' => $row['id']]);\n    $geom = null;\n}","preventionTips":["Filter nullable geometry columns with WHERE geom IS NOT NULL in read queries","Never store '' in geometry columns — use real NULL","Generate fixtures with ST_AsBinary so payloads are real WKB"],"tags":["wkb","geometry","phalcon-db","spatial","parser"],"backgroundTag":"invalid-wkb-payload","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}