Changeset 2536e65c1266d9ec992acf4c516d8eb90acc81b3
- Timestamp:
- 02/07/08 21:57:31 (5 months ago)
- git-parent:
- Files:
-
- modules/demux/asf/libasf.c (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
modules/demux/asf/libasf.c
ra746607 r2536e65 45 45 (guid).v4[4],(guid).v4[5],(guid).v4[6],(guid).v4[7] 46 46 47 /* Helpers: 48 * They ensure that invalid reads will not create problems. 49 * They are expansion safe 50 * They make the following assumptions: 51 * const uint8_t *p_peek exists and points to the start of a buffer 52 * int i_peek gives the size of the buffer pointed by p_peek 53 * const uint8_t *p_data exits and points to the data inside p_peek to be read. 54 */ 55 /* ASF_HAVE(n): 56 * Check that n bytes can be read */ 57 static inline bool AsfObjectHelperHave( const uint8_t *p_peek, int i_peek, const uint8_t *p_current, int i_wanted ) 58 { 59 if( i_wanted < 0 || i_wanted > i_peek ) 60 return false; 61 return &p_current[i_wanted] <= &p_peek[i_peek]; 62 } 63 #define ASF_HAVE(n) AsfObjectHelperHave( p_peek, i_peek, p_data, n ) 64 65 /* ASF_SKIP(n) 66 * Skip n bytes if possible */ 67 static inline void AsfObjectHelperSkip( const uint8_t *p_peek, int i_peek, uint8_t **pp_data, int i_wanted ) 68 { 69 if( AsfObjectHelperHave( p_peek, i_peek, *pp_data, i_wanted ) ) 70 *pp_data += i_wanted; 71 else 72 *pp_data = (uint8_t*)&p_peek[i_peek]; 73 } 74 #define ASF_SKIP(n) AsfObjectHelperSkip( p_peek, i_peek, (uint8_t**)&p_data, n ) 75 76 /* ASF_READX() 77 * Read X byte if possible, else return 0 */ 78 #define ASF_FUNCTION_READ_X(type, x, cmd ) \ 79 static inline type AsfObjectHelperRead##x( const uint8_t *p_peek, int i_peek, uint8_t **pp_data ) { \ 80 uint8_t *p_data = *pp_data; \ 81 type i_ret = 0; \ 82 if( ASF_HAVE(x) ) \ 83 i_ret = cmd; \ 84 ASF_SKIP(x); \ 85 *pp_data = p_data; \ 86 return i_ret; } 87 ASF_FUNCTION_READ_X( uint8_t, 1, *p_data ) 88 ASF_FUNCTION_READ_X( uint16_t, 2, GetWLE(p_data) ) 89 ASF_FUNCTION_READ_X( uint32_t, 4, GetDWLE(p_data) ) 90 ASF_FUNCTION_READ_X( uint64_t, 8, GetQWLE(p_data) ) 91 #define ASF_READ1() AsfObjectHelperRead1( p_peek, i_peek, (uint8_t**)&p_data ) 92 #define ASF_READ2() AsfObjectHelperRead2( p_peek, i_peek, (uint8_t**)&p_data ) 93 #define ASF_READ4() AsfObjectHelperRead4( p_peek, i_peek, (uint8_t**)&p_data ) 94 #define ASF_READ8() AsfObjectHelperRead8( p_peek, i_peek, (uint8_t**)&p_data ) 95 96 /* ASF_READS(n) 97 * Read a string of n/2 wchar long ie n bytes. Do a stupid conversion (suppose latin1) 98 * Return allocated "" if not possible */ 99 static char *AsfObjectHelperReadString( const uint8_t *p_peek, int i_peek, uint8_t **pp_data, int i_size ) 100 { 101 uint8_t *p_data = *pp_data; 102 char *psz_string; 103 if( ASF_HAVE(i_size) ) 104 { 105 psz_string = calloc( i_size/2 + 1, sizeof( char ) ); 106 if( psz_string ) 107 { 108 int i; 109 for( i = 0; i < i_size/2; i++ ) 110 psz_string[i] = GetWLE( &p_data[2*i] ); 111 psz_string[i_size/2] = '\0'; \ 112 } 113 } 114 else 115 { 116 psz_string = strdup(""); 117 } 118 ASF_SKIP(i_size); 119 *pp_data = p_data; 120 return psz_string; 121 } 122 #define ASF_READS(n) AsfObjectHelperReadString( p_peek, i_peek, (uint8_t**)&p_data, n ) 123 47 124 /**************************************************************************** 48 125 * … … 336 413 int i_name; 337 414 int i_data; 338 int j; 339 340 if( &p_data[2+2+2+2+4] > &p_peek[i_peek] ) 341 break; 342 343 if( GetWLE( p_data ) != 0 ) 344 break; 345 p_data += 2; 346 347 p_record->i_stream = GetWLE( p_data ); p_data += 2; 348 i_name = GetWLE( p_data ); p_data += 2; 349 p_record->i_type = GetWLE( p_data ); p_data += 2; 350 i_data = GetDWLE( p_data ); p_data += 4; 351 352 if( &p_data[i_name+i_data] > &p_peek[i_peek] ) 415 416 if( !ASF_HAVE( 2+2+2+2+4 ) ) 417 break; 418 419 if( ASF_READ2() != 0 ) 420 break; 421 422 p_record->i_stream = ASF_READ2(); 423 i_name = ASF_READ2(); 424 p_record->i_type = ASF_READ2(); 425 i_data = ASF_READ4(); 426 427 if( !ASF_HAVE( i_name + i_data ) ) 353 428 break; 354 429 355 430 /* Read name */ 356 p_record->psz_name = malloc( i_name/2 + 1 ); 357 for( j = 0; j < i_name/2; j++ ) 358 { 359 p_record->psz_name[j] = GetWLE( p_data ); p_data += 2; 360 } 361 p_record->psz_name[j] = 0; 431 p_record->psz_name = ASF_READS( i_name ); 362 432 363 433 /* Read data */ 364 434 if( p_record->i_type == ASF_METADATA_TYPE_STRING ) 365 435 { 366 p_record->p_data = malloc( i_data/2 + 1);436 p_record->p_data = ASF_READS( i_data ); 367 437 p_record->i_data = i_data/2; /* FIXME Is that needed ? */ 368 for( j = 0; j < i_data/2; j++ )369 {370 p_record->p_data[j] = GetWLE( &p_data[2*j] );371 }372 p_record->p_data[j] = 0; /* just to make sure */373 374 p_data += i_data;375 438 } 376 439 else if( p_record->i_type == ASF_METADATA_TYPE_BYTE ) … … 385 448 else if( p_record->i_type == ASF_METADATA_TYPE_QWORD ) 386 449 { 387 p_record->i_val = GetQWLE( p_data ); p_data += 8;450 p_record->i_val = ASF_READ8(); 388 451 } 389 452 else if( p_record->i_type == ASF_METADATA_TYPE_DWORD ) 390 453 { 391 p_record->i_val = GetDWLE( p_data ); p_data += 4;454 p_record->i_val = ASF_READ4(); 392 455 } 393 456 else if( p_record->i_type == ASF_METADATA_TYPE_WORD ) 394 457 { 395 p_record->i_val = GetWLE( p_data ); p_data += 2;458 p_record->i_val = ASF_READ2(); 396 459 } 397 460 else if( p_record->i_type == ASF_METADATA_TYPE_BOOL ) 398 461 { 399 p_record->i_val = GetWLE( p_data ); p_data += 2;462 p_record->i_val = ASF_READ2(); 400 463 } 401 464 else … … 446 509 if( p_he->i_header_extension_size ) 447 510 { 511 if( i_peek-46 < (int)p_he->i_header_extension_size ) 512 return VLC_EGENERIC; 513 448 514 p_he->p_header_extension_data = 449 515 malloc( p_he->i_header_extension_size ); 516 if( !p_he->p_header_extension_data ) 517 return VLC_ENOMEM; 518 450 519 memcpy( p_he->p_header_extension_data, p_peek + 46, 451 520 p_he->i_header_extension_size ); … … 606 675 p_cl->codec = calloc( p_cl->i_codec_entries_count, 607 676 sizeof( asf_codec_entry_t ) ); 677 if( !p_cl->codec ) 678 return VLC_ENOMEM; 608 679 609 680 for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ ) 610 681 { 611 682 asf_codec_entry_t *p_codec = &p_cl->codec[i_codec]; 612 int i_len, i; 613 614 p_codec->i_type = GetWLE( p_data ); p_data += 2; 683 684 if( !ASF_HAVE( 2+2+2 ) ) 685 break; 686 687 /* */ 688 p_codec->i_type = ASF_READ2(); 689 690 /* XXX the length here are the number of *unicode* characters and 691 * not of bytes like nearly every elsewhere */ 692 615 693 /* codec name */ 616 i_len = GetWLE( p_data ); p_data += 2; 617 p_codec->psz_name = calloc( i_len + 1, sizeof(char) ); 618 for( i = 0; i < i_len; i++ ) 619 { 620 p_codec->psz_name[i] = GetWLE( p_data + 2*i ); 621 } 622 p_codec->psz_name[i_len] = '\0'; 623 p_data += 2 * i_len; 694 p_codec->psz_name = ASF_READS( 2*ASF_READ2() ); 624 695 625 696 /* description */ 626 i_len = GetWLE( p_data ); p_data += 2; 627 p_codec->psz_description = calloc( i_len + 1, sizeof(char) ); 628 for( i = 0; i < i_len; i++ ) 629 { 630 p_codec->psz_description[i] = GetWLE( p_data + 2*i ); 631 } 632 p_codec->psz_description[i_len] = '\0'; 633 p_data += 2 * i_len; 697 p_codec->psz_description = ASF_READS( 2*ASF_READ2() ); 634 698 635 699 /* opaque information */ 636 p_codec->i_information_length = GetWLE( p_data ); p_data += 2;637 if( p_codec->i_information_length > 0 )700 p_codec->i_information_length = ASF_READ2(); 701 if( p_codec->i_information_length > 0 && ASF_HAVE( p_codec->i_information_length ) ) 638 702 { 639 703 p_codec->p_information = malloc( p_codec->i_information_length ); … … 646 710 } 647 711 } 648 } 649 else 650 { 651 p_cl->codec = NULL; 712 p_cl->i_codec_entries_count = i_codec; 652 713 } 653 714 … … 659 720 for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ ) 660 721 { 661 #define codec p_cl->codec[i_codec] 722 const asf_codec_entry_t *p_codec = &p_cl->codec[i_codec]; 723 662 724 msg_Dbg( s, " - codec[%d] %s name:\"%s\" " 663 725 "description:\"%s\" information_length:%d", 664 i_codec, ( codec.i_type == ASF_CODEC_TYPE_VIDEO ) ?665 "video" : ( ( codec.i_type == ASF_CODEC_TYPE_AUDIO ) ?726 i_codec, ( p_codec->i_type == ASF_CODEC_TYPE_VIDEO ) ? 727 "video" : ( ( p_codec->i_type == ASF_CODEC_TYPE_AUDIO ) ? 666 728 "audio" : "unknown" ), 667 codec.psz_name, codec.psz_description, 668 codec.i_information_length ); 669 #undef codec 729 p_codec->psz_name, p_codec->psz_description, 730 p_codec->i_information_length ); 670 731 } 671 732 #endif … … 724 785 725 786 p_data = p_peek + 24; 726 727 i_title = GetWLE( p_data ); p_data += 2; 728 i_artist= GetWLE( p_data ); p_data += 2; 729 i_copyright = GetWLE( p_data ); p_data += 2; 730 i_description = GetWLE( p_data ); p_data += 2; 731 i_rating = GetWLE( p_data ); p_data += 2; 787 788 i_title = ASF_READ2(); 789 i_artist = ASF_READ2(); 790 i_copyright = ASF_READ2(); 791 i_description = ASF_READ2(); 792 i_rating = ASF_READ2(); 793 794 if( !ASF_HAVE( i_title+i_artist+i_copyright+i_description+i_rating ) ) 795 { 796 vlc_iconv_close( cd ); 797 return VLC_EGENERIC; 798 } 732 799 733 800 GETSTRINGW( p_cd->psz_title, i_title ); … … 779 846 p_data = &p_peek[24]; 780 847 781 p_ll->i_language = GetWLE( &p_data[0] ); p_data += 2;848 p_ll->i_language = ASF_READ2(); 782 849 if( p_ll->i_language > 0 ) 783 850 { … … 786 853 for( i = 0; i < p_ll->i_language; i++ ) 787 854 { 788 char *psz; 789 int i_size = *p_data++; 790 int i_len; 791 792 psz = calloc( i_size/2 + 1, sizeof(char) ); 793 for( i_len = 0; i_len < i_size/2; i_len++ ) 794 { 795 psz[i_len] = GetWLE( p_data + 2*i_len ); 796 } 797 psz[i_size/2] = '\0'; \ 798 p_data += i_size; 799 800 p_ll->ppsz_language[i] = psz; 801 } 855 if( !ASF_HAVE(1) ) 856 break; 857 p_ll->ppsz_language[i] = ASF_READS( ASF_READ1() ); 858 } 859 p_ll->i_language = i; 802 860 } 803 861 … … 838 896 p_data = &p_peek[24]; 839 897 840 p_sb->i_bitrate = GetWLE( &p_data[0] ); p_data += 2; 841 if( p_sb->i_bitrate > 127 ) p_sb->i_bitrate = 127; /* Buggy ? */ 898 p_sb->i_bitrate = ASF_READ2(); 899 if( p_sb->i_bitrate > 127 ) 900 p_sb->i_bitrate = 127; /* Buggy ? */ 842 901 for( i = 0; i < p_sb->i_bitrate; i++ ) 843 902 { 844 p_sb->bitrate[i].i_stream_number = GetWLE( &p_data[0] )& 0x7f; 845 p_sb->bitrate[i].i_avg_bitrate = GetDWLE( &p_data[2] ); 846 847 p_data += 2+4; 848 } 903 if( !ASF_HAVE(2 + 4) ) 904 break; 905 p_sb->bitrate[i].i_stream_number = ASF_READ2()& 0x7f; 906 p_sb->bitrate[i].i_avg_bitrate = ASF_READ4(); 907 } 908 p_sb->i_bitrate = i; 849 909 850 910 #ifdef ASF_DEBUG … … 901 961 for( i = 0; i < p_esp->i_stream_name_count; i++ ) 902 962 { 903 int i_size; 904 char *psz; 905 int i_len; 906 907 p_esp->pi_stream_name_language[i] = GetWLE( &p_data[0] ); 908 i_size = GetWLE( &p_data[2] ); 909 p_data += 2+2; 910 911 psz = calloc( i_size/2 + 1, sizeof(char) ); 912 for( i_len = 0; i_len < i_size/2; i_len++ ) 913 { 914 psz[i_len] = GetWLE( p_data + 2*i_len ); 915 } 916 psz[i_size/2] = '\0'; \ 917 p_data += i_size; 918 919 p_esp->ppsz_stream_name[i] = psz; 920 } 963 if( !ASF_HAVE( 2+2 ) ) 964 break; 965 p_esp->pi_stream_name_language[i] = ASF_READ2(); 966 p_esp->ppsz_stream_name[i] = ASF_READS( ASF_READ2() ); 967 } 968 p_esp->i_stream_name_count = i; 921 969 922 970 for( i = 0; i < p_esp->i_payload_extension_system_count; i++ ) 923 971 { 924 /* Skip them */ 925 int i_size = GetDWLE( &p_data[16 + 2] ); 926 927 p_data += 16+2+4+i_size; 972 ASF_SKIP( 16 ); // GUID 973 ASF_SKIP( 2 ); 974 ASF_SKIP( ASF_READ4() ); 928 975 } 929 976 … … 1004 1051 1005 1052 ASF_GetGUID( &p_ae->type, &p_data[0] ); 1006 p_ae->i_stream_number_count = GetWLE( &p_data[16] ); 1007 1008 p_data += 16 + 2; 1009 p_ae->pi_stream_number = calloc( p_ae->i_stream_number_count, 1010 sizeof(int) ); 1053 ASF_SKIP( 16 ); 1054 p_ae->i_stream_number_count = ASF_READ2(); 1055 p_ae->pi_stream_number = calloc( p_ae->i_stream_number_count, sizeof(int) ); 1056 1011 1057 for( i = 0; i < p_ae->i_stream_number_count; i++ ) 1012 1058 { 1013 p_ae->pi_stream_number[i] = GetWLE( p_data ); 1014 p_data += 2; 1015 } 1059 if( !ASF_HAVE(2) ) 1060 break; 1061 p_ae->pi_stream_number[i] = ASF_READ2(); 1062 } 1063 p_ae->i_stream_number_count = i; 1016 1064 1017 1065 #ifdef ASF_DEBUG … … 1045 1093 p_data = &p_peek[24]; 1046 1094 1047 p_sp->i_priority_count = GetWLE( &p_data[0] ); 1048 p_data += 2; 1095 p_sp->i_priority_count = ASF_READ2(); 1049 1096 1050 1097 p_sp->pi_priority_flag = calloc( p_sp->i_priority_count, sizeof(int) ); … … 1054 1101 for( i = 0; i < p_sp->i_priority_count; i++ ) 1055 1102 { 1056 p_sp->pi_priority_stream_number[i] = GetWLE( p_data ); p_data += 2; 1057 p_sp->pi_priority_flag[i] = GetWLE( p_data ); p_data += 2; 1058 } 1103 if( !ASF_HAVE(2+2) ) 1104 break; 1105 p_sp->pi_priority_stream_number[i] = ASF_READ2(); 1106 p_sp->pi_priority_flag[i] = ASF_READ2(); 1107 } 1108 p_sp->i_priority_count = i; 1109 1059 1110 #ifdef ASF_DEBUG 1060 1111 msg_Dbg( s, "read \"stream prioritization object\"" ); … … 1090 1141 p_data = &p_peek[24]; 1091 1142 1092 p_ec->i_count = GetWLE( p_data ); p_data += 2;1093 p_ec->ppsz_name = calloc( p_ec->i_count, sizeof(char*) );1143 p_ec->i_count = ASF_READ2(); 1144 p_ec->ppsz_name = calloc( p_ec->i_count, sizeof(char*) ); 1094 1145 p_ec->ppsz_value = calloc( p_ec->i_count, sizeof(char*) ); 1146 if( !p_ec->ppsz_name || !p_ec->ppsz_value ) 1147 { 1148 free( p_ec->ppsz_name ); 1149 free( p_ec->ppsz_value ); 1150 return VLC_ENOMEM; 1151 } 1095 1152 for( i = 0; i < p_ec->i_count; i++ ) 1096 1153 { 1097 1154 int i_size; 1098 1155 int i_type; 1099 int i_len; 1100 #define GETSTRINGW( psz_str, i_size ) \ 1101 psz_str = calloc( i_size/2 + 1, sizeof( char ) ); \ 1102 for( i_len = 0; i_len < i_size/2; i_len++ ) \ 1103 { \ 1104 psz_str[i_len] = GetWLE( p_data + 2*i_len ); \ 1105 } \ 1106 psz_str[i_size/2] = '\0'; 1107 1108 i_size = GetWLE( p_data ); p_data += 2; 1109 GETSTRINGW( p_ec->ppsz_name[i], i_size ); 1110 p_data += i_size; 1156 1157 if( !ASF_HAVE(2 + 2+2) ) 1158 break; 1159 1160 p_ec->ppsz_name[i] = ASF_READS( ASF_READ2() ); 1111 1161 1112 1162 /* Grrr */ 1113 i_type = GetWLE( p_data ); p_data += 2; 1114 i_size = GetWLE( p_data ); p_data += 2; 1163 i_type = ASF_READ2(); 1164 i_size = ASF_READ2(); 1165 1115 1166 if( i_type == 0 ) 1116 1167 { 1117 GETSTRINGW( p_ec->ppsz_value[i],i_size );1168 p_ec->ppsz_value[i] = ASF_READS( i_size ); 1118 1169 } 1119 1170 else if( i_type == 1 ) 1120 1171 { 1172 /* Byte array */ 1173 static const char hex[16] = "0123456789ABCDEF"; 1121 1174 int j; 1122 /* Byte array */ 1175 1123 1176 p_ec->ppsz_value[i] = malloc( 2*i_size + 1 ); 1124 1177 for( j = 0; j < i_size; j++ ) 1125 1178 { 1126 static const char hex[16] = "0123456789ABCDEF";1127 p_ec->ppsz_value[i][2*j+0] = hex[ p_data[0]>>4];1128 p_ec->ppsz_value[i][2*j+1] = hex[ p_data[0]&0xf];1179 const uint8_t v = ASF_READ1(); 1180 p_ec->ppsz_value[i][2*j+0] = hex[v>>4]; 1181 p_ec->ppsz_value[i][2*j+1] = hex[v&0xf]; 1129 1182 } 1130 1183 p_ec->ppsz_value[i][2*i_size] = '\0'; … … 1133 1186 { 1134 1187 /* Bool */ 1135 p_ec->ppsz_value[i] = strdup( *p_data ? "true" : "false" ); 1188 p_ec->ppsz_value[i] = strdup( ASF_READ1() ? "true" : "false" ); 1189 ASF_SKIP(i_size-1); 1136 1190 } 1137 1191 else if( i_type == 3 ) 1138 1192 { 1139 1193 /* DWord */ 1140 asprintf( &p_ec->ppsz_value[i], "%d", GetDWLE(p_data));1194 asprintf( &p_ec->ppsz_value[i], "%d", ASF_READ4() ); 1141 1195 } 1142 1196 else if( i_type == 4 ) 1143 1197 { 1144 1198 /* QWord */ 1145 asprintf( &p_ec->ppsz_value[i], "%"PRId64, GetQWLE(p_data));1199 asprintf( &p_ec->ppsz_value[i], "%"PRId64, ASF_READ8() ); 1146 1200 } 1147 1201 else if( i_type == 5 ) 1148 1202 { 1149 1203 /* Word */ 1150 asprintf( &p_ec->ppsz_value[i], "%d", GetWLE(p_data));1204 asprintf( &p_ec->ppsz_value[i], "%d", ASF_READ2() ); 1151 1205 } 1152 1206 else 1207 { 1153 1208 p_ec->ppsz_value[i] = NULL; 1154 1155 p_data += i_size; 1156 1157 1158 1159 #undef GETSTRINGW 1160 1161 } 1209 ASF_SKIP(i_size); 1210 } 1211 } 1212 p_ec->i_count = i; 1162 1213 1163 1214 #ifdef ASF_DEBUG … … 1407 1458 { &asf_object_stream_type_command, "Stream Type Command" }, 1408 1459 { &asf_object_language_list, "Language List" }, 1409 { &asf_object_stream_bitrate_properties, "Stream Bitrate Prop oerties" },1460 { &asf_object_stream_bitrate_properties, "Stream Bitrate Properties" }, 1410 1461 { &asf_object_padding, "Padding" }, 1411 1462 { &asf_object_extended_stream_properties, "Extended Stream Properties" },
