@@ -173,10 +173,21 @@ MDSectionOffset findProtocolMetadataOffset(MDMetadataReader* metadata, const cha
173173 std::string structname;
174174 const char * nameStart = *encoding + 1 ; // skip '{'
175175 const char * c = nameStart;
176- while (*c != ' =' ) {
176+ while (*c != ' \0 ' && *c != ' =' ) {
177177 structname += *c;
178178 c++;
179179 }
180+ if (*c != ' =' ) {
181+ // Malformed struct encoding. Advance to the end of this token and
182+ // fallback to pointer conversion to avoid reading past the buffer.
183+ while (**encoding != ' \0 ' && **encoding != ' }' ) {
184+ (*encoding)++;
185+ }
186+ if (**encoding == ' }' ) {
187+ (*encoding)++;
188+ }
189+ return &ffi_type_pointer;
190+ }
180191
181192 // Check if we're already processing this struct (cycle detection)
182193 if (processingEncodingStructs.find (structname) != processingEncodingStructs.end ()) {
@@ -201,16 +212,18 @@ MDSectionOffset findProtocolMetadataOffset(MDMetadataReader* metadata, const cha
201212 }
202213
203214 // Check if we already have a forward declaration for this struct
204- auto forwardIt = forwardDeclaredEncodingStructs.find (structname);
205- if (forwardIt != forwardDeclaredEncodingStructs.end ()) {
215+ auto existingForwardIt = forwardDeclaredEncodingStructs.find (structname);
216+ if (existingForwardIt != forwardDeclaredEncodingStructs.end ()) {
206217 // Skip the struct encoding
207218 (*encoding)++; // skip '{'
208- while (**encoding != ' }' ) {
219+ while (**encoding != ' \0 ' && **encoding != ' }' ) {
209220 (*encoding)++;
210221 }
211- (*encoding)++; // skip '}'
222+ if (**encoding == ' }' ) {
223+ (*encoding)++; // skip '}'
224+ }
212225
213- return forwardIt ->second ;
226+ return existingForwardIt ->second ;
214227 }
215228
216229 // Mark this struct as being processed
@@ -226,18 +239,25 @@ MDSectionOffset findProtocolMetadataOffset(MDMetadataReader* metadata, const cha
226239
227240 (*encoding)++; // skip '{'
228241
229- while (**encoding != ' =' ) {
242+ while (**encoding != ' \0 ' && **encoding != ' =' ) {
230243 (*encoding)++;
231244 } // skip name
245+ if (**encoding == ' \0 ' ) {
246+ processingEncodingStructs.erase (structname);
247+ delete type;
248+ return &ffi_type_pointer;
249+ }
232250
233251 (*encoding)++; // skip '='
234252
235- while (**encoding != ' }' ) {
253+ while (**encoding != ' \0 ' && **encoding != ' }' ) {
236254 ffi_type* elementType = TypeConv::Make (env, encoding)->type ;
237255 elements.push_back (elementType);
238256 }
239257
240- (*encoding)++; // skip '}'
258+ if (**encoding == ' }' ) {
259+ (*encoding)++; // skip '}'
260+ }
241261
242262 type->elements = (ffi_type**)malloc (sizeof (ffi_type*) * (elements.size () + 1 ));
243263 for (int i = 0 ; i < elements.size (); i++) {
@@ -247,8 +267,9 @@ MDSectionOffset findProtocolMetadataOffset(MDMetadataReader* metadata, const cha
247267 type->elements [elements.size ()] = nullptr ;
248268
249269 // If this was a forward declaration, update it with the real layout
250- if (forwardIt != forwardDeclaredEncodingStructs.end ()) {
251- ffi_type* forwardType = forwardIt->second ;
270+ auto resolvedForwardIt = forwardDeclaredEncodingStructs.find (structname);
271+ if (resolvedForwardIt != forwardDeclaredEncodingStructs.end ()) {
272+ ffi_type* forwardType = resolvedForwardIt->second ;
252273 forwardType->type = type->type ;
253274 forwardType->size = type->size ;
254275 forwardType->alignment = type->alignment ;
@@ -257,7 +278,7 @@ MDSectionOffset findProtocolMetadataOffset(MDMetadataReader* metadata, const cha
257278 // Clean up the temporary type and use the forward declaration
258279 delete type;
259280 type = forwardType;
260- forwardDeclaredEncodingStructs.erase (forwardIt );
281+ forwardDeclaredEncodingStructs.erase (resolvedForwardIt );
261282 }
262283
263284 // Remove from processing set
@@ -283,9 +304,9 @@ MDSectionOffset findProtocolMetadataOffset(MDMetadataReader* metadata, const cha
283304 }
284305
285306 // Check if we already have a forward declaration for this struct
286- auto forwardIt = forwardDeclaredStructs.find (structOffset);
287- if (forwardIt != forwardDeclaredStructs.end ()) {
288- return forwardIt ->second ;
307+ auto existingForwardIt = forwardDeclaredStructs.find (structOffset);
308+ if (existingForwardIt != forwardDeclaredStructs.end ()) {
309+ return existingForwardIt ->second ;
289310 }
290311
291312 // Mark this struct as being processed
@@ -326,8 +347,9 @@ MDSectionOffset findProtocolMetadataOffset(MDMetadataReader* metadata, const cha
326347 type->elements [elements.size ()] = nullptr ;
327348
328349 // If this was a forward declaration, update it with the real layout
329- if (forwardIt != forwardDeclaredStructs.end ()) {
330- ffi_type* forwardType = forwardIt->second ;
350+ auto resolvedForwardIt = forwardDeclaredStructs.find (structOffset);
351+ if (resolvedForwardIt != forwardDeclaredStructs.end ()) {
352+ ffi_type* forwardType = resolvedForwardIt->second ;
331353 forwardType->type = type->type ;
332354 forwardType->size = type->size ;
333355 forwardType->alignment = type->alignment ;
@@ -336,7 +358,7 @@ MDSectionOffset findProtocolMetadataOffset(MDMetadataReader* metadata, const cha
336358 // Clean up the temporary type and use the forward declaration
337359 delete type;
338360 type = forwardType;
339- forwardDeclaredStructs.erase (forwardIt );
361+ forwardDeclaredStructs.erase (resolvedForwardIt );
340362 }
341363
342364 // Remove from processing set
@@ -3101,10 +3123,19 @@ void writeFromArrayElements(napi_env env, napi_value value, void* result, bool*
31013123 case ' {' : {
31023124 std::string structname;
31033125 const char * c = *encoding + 1 ;
3104- while (*c != ' =' ) {
3126+ while (*c != ' \0 ' && *c != ' =' ) {
31053127 structname += *c;
31063128 c++;
31073129 }
3130+ if (*c != ' =' ) {
3131+ while (**encoding != ' \0 ' && **encoding != ' }' ) {
3132+ (*encoding)++;
3133+ }
3134+ if (**encoding == ' }' ) {
3135+ (*encoding)++;
3136+ }
3137+ return pointerTypeConv;
3138+ }
31083139
31093140 // Check if we already have a cached StructTypeConv for this encoding-based struct
31103141 auto cacheIt = encodingStructCache.find (structname);
@@ -3113,9 +3144,13 @@ void writeFromArrayElements(napi_env env, napi_value value, void* result, bool*
31133144 }
31143145
31153146 auto bridgeState = ObjCBridgeState::InstanceData (env);
3116- // NSLog(@"struct: %s, %d", structname.c_str(),
3117- // bridgeState->structOffsets[structname]);
3118- auto structOffset = bridgeState->structOffsets [structname];
3147+ MDSectionOffset structOffset = MD_SECTION_OFFSET_NULL;
3148+ if (bridgeState != nullptr ) {
3149+ auto structOffsetIt = bridgeState->structOffsets .find (structname);
3150+ if (structOffsetIt != bridgeState->structOffsets .end ()) {
3151+ structOffset = structOffsetIt->second ;
3152+ }
3153+ }
31193154 auto type = typeFromStruct (env, encoding);
31203155 auto structTypeConv = std::make_shared<StructTypeConv>(StructTypeConv (structOffset, type));
31213156
0 commit comments