@@ -355,6 +355,247 @@ func TestUUID(t *testing.T) {
355355 })
356356}
357357
358+ // =============================================================================
359+ // Test: UUID Parse Error Paths
360+ // =============================================================================
361+
362+ // TestUUID_ParseErrorPaths tests error detection in UUID parsing functions.
363+ // This validates that malformed UUIDs are properly rejected and return error codes,
364+ // preventing silent corruption from accepting invalid data.
365+ func TestUUID_ParseErrorPaths (t * testing.T ) {
366+ t .Run ("invalid_uuid_format_too_short" , func (t * testing.T ) {
367+ // UUID must be exactly 36 characters (plus NUL)
368+ tooShort := "550e8400-e29b-41d4-a716-44665544"
369+ var uuid AVUUID
370+
371+ cStr := ToCStr (tooShort )
372+ defer cStr .Free ()
373+
374+ ret , err := AVUuidParse (cStr , & uuid )
375+ if ret == 0 || err == nil {
376+ t .Errorf ("AVUuidParse should fail for too-short UUID, got ret=%d err=%v" , ret , err )
377+ }
378+
379+ t .Logf ("Correctly rejected too-short UUID: ret=%d" , ret )
380+ })
381+
382+ t .Run ("invalid_uuid_format_too_long" , func (t * testing.T ) {
383+ // Too many characters
384+ tooLong := "550e8400-e29b-41d4-a716-446655440000-extra"
385+ var uuid AVUUID
386+
387+ cStr := ToCStr (tooLong )
388+ defer cStr .Free ()
389+
390+ ret , err := AVUuidParse (cStr , & uuid )
391+ if ret == 0 || err == nil {
392+ t .Errorf ("AVUuidParse should fail for too-long UUID, got ret=%d err=%v" , ret , err )
393+ }
394+
395+ t .Logf ("Correctly rejected too-long UUID: ret=%d" , ret )
396+ })
397+
398+ t .Run ("invalid_uuid_missing_dashes" , func (t * testing.T ) {
399+ // Correct length but missing dashes
400+ noDashes := "550e8400e29b41d4a716446655440000"
401+ var uuid AVUUID
402+
403+ cStr := ToCStr (noDashes )
404+ defer cStr .Free ()
405+
406+ ret , err := AVUuidParse (cStr , & uuid )
407+ if ret == 0 || err == nil {
408+ t .Errorf ("AVUuidParse should fail for UUID without dashes, got ret=%d err=%v" , ret , err )
409+ }
410+
411+ t .Logf ("Correctly rejected UUID without dashes: ret=%d" , ret )
412+ })
413+
414+ t .Run ("invalid_uuid_wrong_dash_positions" , func (t * testing.T ) {
415+ // Dashes in wrong positions
416+ wrongDashes := "550e8400e29b-41d4-a716-446655440000"
417+ var uuid AVUUID
418+
419+ cStr := ToCStr (wrongDashes )
420+ defer cStr .Free ()
421+
422+ ret , err := AVUuidParse (cStr , & uuid )
423+ if ret == 0 || err == nil {
424+ t .Errorf ("AVUuidParse should fail for UUID with wrong dash positions, got ret=%d err=%v" , ret , err )
425+ }
426+
427+ t .Logf ("Correctly rejected UUID with wrong dashes: ret=%d" , ret )
428+ })
429+
430+ t .Run ("invalid_uuid_non_hex_characters" , func (t * testing.T ) {
431+ // Contains non-hex characters
432+ invalidChars := "550e8400-e29b-41d4-a716-44665544GGGG"
433+ var uuid AVUUID
434+
435+ cStr := ToCStr (invalidChars )
436+ defer cStr .Free ()
437+
438+ ret , err := AVUuidParse (cStr , & uuid )
439+ if ret == 0 || err == nil {
440+ t .Errorf ("AVUuidParse should fail for non-hex characters, got ret=%d err=%v" , ret , err )
441+ }
442+
443+ t .Logf ("Correctly rejected UUID with non-hex chars: ret=%d" , ret )
444+ })
445+
446+ t .Run ("invalid_uuid_empty_string" , func (t * testing.T ) {
447+ // Empty string
448+ var uuid AVUUID
449+
450+ cStr := ToCStr ("" )
451+ defer cStr .Free ()
452+
453+ ret , err := AVUuidParse (cStr , & uuid )
454+ if ret == 0 || err == nil {
455+ t .Errorf ("AVUuidParse should fail for empty string, got ret=%d err=%v" , ret , err )
456+ }
457+
458+ t .Logf ("Correctly rejected empty UUID string: ret=%d" , ret )
459+ })
460+
461+ t .Run ("valid_uuid_uppercase_accepted" , func (t * testing.T ) {
462+ // RFC 4122 specifies parsing should be case-insensitive
463+ uppercaseUUID := "550E8400-E29B-41D4-A716-446655440000"
464+ var uuid AVUUID
465+
466+ cStr := ToCStr (uppercaseUUID )
467+ defer cStr .Free ()
468+
469+ ret , err := AVUuidParse (cStr , & uuid )
470+ if ret != 0 || err != nil {
471+ t .Fatalf ("AVUuidParse should accept uppercase UUID, got ret=%d err=%v" , ret , err )
472+ }
473+
474+ // Verify by unparsing (should be lowercase)
475+ outStr := AllocCStr (37 )
476+ defer outStr .Free ()
477+ AVUuidUnparse (& uuid , outStr )
478+
479+ result := outStr .String ()
480+ expected := "550e8400-e29b-41d4-a716-446655440000"
481+ if result != expected {
482+ t .Errorf ("Unparsed UUID mismatch: got %s, want %s" , result , expected )
483+ }
484+
485+ t .Logf ("Uppercase UUID correctly parsed and normalized: %s -> %s" , uppercaseUUID , result )
486+ })
487+
488+ t .Run ("urn_invalid_format_missing_prefix" , func (t * testing.T ) {
489+ // URN must start with "urn:uuid:"
490+ noPrefix := "550e8400-e29b-41d4-a716-446655440000"
491+ var uuid AVUUID
492+
493+ cStr := ToCStr (noPrefix )
494+ defer cStr .Free ()
495+
496+ ret , err := AVUuidUrnParse (cStr , & uuid )
497+ if ret == 0 || err == nil {
498+ t .Errorf ("AVUuidUrnParse should fail without urn:uuid: prefix, got ret=%d err=%v" , ret , err )
499+ }
500+
501+ t .Logf ("Correctly rejected URN without prefix: ret=%d" , ret )
502+ })
503+
504+ t .Run ("urn_invalid_format_wrong_prefix" , func (t * testing.T ) {
505+ // Wrong URN prefix
506+ wrongPrefix := "uuid:uuid:550e8400-e29b-41d4-a716-446655440000"
507+ var uuid AVUUID
508+
509+ cStr := ToCStr (wrongPrefix )
510+ defer cStr .Free ()
511+
512+ ret , err := AVUuidUrnParse (cStr , & uuid )
513+ if ret == 0 || err == nil {
514+ t .Errorf ("AVUuidUrnParse should fail with wrong prefix, got ret=%d err=%v" , ret , err )
515+ }
516+
517+ t .Logf ("Correctly rejected URN with wrong prefix: ret=%d" , ret )
518+ })
519+
520+ t .Run ("urn_invalid_uuid_part" , func (t * testing.T ) {
521+ // URN with invalid UUID part
522+ invalidURN := "urn:uuid:550e8400-e29b-41d4-a716-GGGGGGGGGGGG"
523+ var uuid AVUUID
524+
525+ cStr := ToCStr (invalidURN )
526+ defer cStr .Free ()
527+
528+ ret , err := AVUuidUrnParse (cStr , & uuid )
529+ if ret == 0 || err == nil {
530+ t .Errorf ("AVUuidUrnParse should fail with invalid UUID part, got ret=%d err=%v" , ret , err )
531+ }
532+
533+ t .Logf ("Correctly rejected URN with invalid UUID: ret=%d" , ret )
534+ })
535+
536+ t .Run ("urn_case_insensitive" , func (t * testing.T ) {
537+ // URN parsing should be case-insensitive for the "urn:uuid:" prefix
538+ mixedCase := "URN:UUID:550e8400-e29b-41d4-a716-446655440000"
539+ var uuid AVUUID
540+
541+ cStr := ToCStr (mixedCase )
542+ defer cStr .Free ()
543+
544+ // This may or may not be accepted depending on FFmpeg's strictness
545+ // Document the actual behaviour
546+ ret , _ := AVUuidUrnParse (cStr , & uuid )
547+
548+ if ret == 0 {
549+ t .Logf ("Mixed-case URN prefix accepted: %s" , mixedCase )
550+ } else {
551+ t .Logf ("Mixed-case URN prefix rejected (ret=%d) - prefix is case-sensitive" , ret )
552+ }
553+ })
554+
555+ t .Run ("parse_range_exact_length" , func (t * testing.T ) {
556+ // AVUuidParseRange requires exact 36-character range
557+ uuidStr := "550e8400-e29b-41d4-a716-446655440000"
558+ var uuid AVUUID
559+
560+ // Create start and end pointers into the UUID string
561+ start := ToCStr (uuidStr )
562+ defer start .Free ()
563+
564+ // End pointer should be exactly 36 chars after start
565+ ret , err := AVUuidParseRange (start , start , & uuid )
566+ if ret == 0 || err == nil {
567+ t .Errorf ("AVUuidParseRange should fail with zero-length range, got ret=%d err=%v" , ret , err )
568+ }
569+
570+ t .Logf ("Correctly rejected zero-length range: ret=%d" , ret )
571+ })
572+
573+ t .Run ("error_code_is_negative" , func (t * testing.T ) {
574+ // All UUID parse errors should return negative codes
575+ testCases := []string {
576+ "" , // empty
577+ "invalid" , // too short
578+ "550e8400-e29b-41d4-a716-44665544XXXX" , // invalid chars
579+ }
580+
581+ for _ , testStr := range testCases {
582+ var uuid AVUUID
583+ cStr := ToCStr (testStr )
584+ ret , err := AVUuidParse (cStr , & uuid )
585+ cStr .Free ()
586+
587+ if ret >= 0 && ret != 0 {
588+ t .Errorf ("Error code should be negative or zero, got %d for %q" , ret , testStr )
589+ }
590+ if ret < 0 && err == nil {
591+ t .Errorf ("Negative return code should have non-nil error, got nil for %q" , testStr )
592+ }
593+ }
594+
595+ t .Log ("All UUID parse errors correctly return negative codes" )
596+ })
597+ }
598+
358599// TestGeneratorCharVsUint8 verifies that char parameters use C.char, not C.uint8_t
359600// This is a regression test for the av_match_list compilation error.
360601func TestGeneratorCharVsUint8 (t * testing.T ) {
0 commit comments