@@ -2689,24 +2689,35 @@ public function decodePoint(string $wkb): array
26892689 return [(float )$ coords [0 ], (float )$ coords [1 ]];
26902690 }
26912691
2692- // MySQL SRID-aware WKB layout:
2693- // 1 byte = endian (1 = little endian)
2694- // 4 bytes = type + SRID flag
2695- // 4 bytes = SRID
2696- // 16 bytes = X,Y coordinates (double each, little endian)
2692+ /**
2693+ * [0..3] SRID (4 bytes, little-endian)
2694+ * [4] Byte order (1 = little-endian, 0 = big-endian)
2695+ * [5..8] Geometry type (with SRID flag bit)
2696+ * [9..] Geometry payload (coordinates, etc.)
2697+ */
26972698
2698- $ byteOrder = ord ($ wkb [0 ]);
2699+ if (strlen ($ wkb ) < 25 ) {
2700+ throw new DatabaseException ('Invalid WKB: too short for POINT ' );
2701+ }
2702+
2703+ // 4 bytes SRID first → skip to byteOrder at offset 4
2704+ $ byteOrder = ord ($ wkb [4 ]);
26992705 $ littleEndian = ($ byteOrder === 1 );
27002706
2701- // Skip 1 + 4 + 4 = 9 bytes to get coordinates
2702- $ coordsBin = substr ($ wkb , 9 , 16 );
2707+ if (!$ littleEndian ) {
2708+ throw new DatabaseException ('Only little-endian WKB supported ' );
2709+ }
27032710
2704- // Unpack doubles
2705- $ format = $ littleEndian ? 'd2 ' : 'd2 ' ; // little-endian doubles
2706- $ coords = unpack ($ format , $ coordsBin );
2711+ // After SRID (4) + byteOrder (1) + type (4) = 9 bytes
2712+ $ coordsBin = substr ($ wkb , 9 , 16 );
2713+ if (strlen ($ coordsBin ) !== 16 ) {
2714+ throw new DatabaseException ('Invalid WKB: missing coordinate bytes ' );
2715+ }
27072716
2717+ // Unpack two doubles
2718+ $ coords = unpack ('d2 ' , $ coordsBin );
27082719 if ($ coords === false || !isset ($ coords [1 ], $ coords [2 ])) {
2709- throw new DatabaseException ('Invalid WKB for POINT: cannot unpack coordinates ' );
2720+ throw new DatabaseException ('Invalid WKB: failed to unpack coordinates ' );
27102721 }
27112722
27122723 return [(float )$ coords [1 ], (float )$ coords [2 ]];
0 commit comments