Unicode metadata: Change most logic to use guesser

Most file formats the player supports may or may not have UTF-8 safe
strings in their metadata. This should not be assumed to be UTF-8, and
when it is assumed, it results in nil NSString objects, which results in
inline initializers crashing due to uncaught exceptions.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
swiftingly
Christopher Snowhill 2022-05-24 01:07:55 -07:00
parent f7dc6beda1
commit 8cf37cadf3
13 changed files with 65 additions and 65 deletions

View File

@ -60,9 +60,9 @@
NSString *artist = @"";
if(!p_player->gettitle().empty())
title = [NSString stringWithUTF8String:p_player->gettitle().c_str()];
title = guess_encoding_of_string(p_player->gettitle().c_str());
if(!p_player->getauthor().empty())
artist = [NSString stringWithUTF8String:p_player->getauthor().c_str()];
artist = guess_encoding_of_string(p_player->getauthor().c_str());
delete p_player;
delete p_emu;

View File

@ -53,7 +53,7 @@ static NSString *g_make_unpack_path(NSString *archive, NSString *file, NSString
NSMutableArray *files = [NSMutableArray array];
while(!fex_done(fex)) {
NSString *name = [NSString stringWithUTF8String:fex_name(fex)];
NSString *name = guess_encoding_of_string(fex_name(fex));
if([[NSClassFromString(@"AudioPlayer") fileTypes] containsObject:[[name pathExtension] lowercaseString]])
[files addObject:[NSURL URLWithDataRepresentation:[g_make_unpack_path([url path], name, @"fex") dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil]];
fex_next(fex);

View File

@ -92,7 +92,7 @@ static BOOL g_parse_unpack_path(NSString *src, NSString **archive, NSString **fi
}
while(!fex_done(fex)) {
if([file isEqualToString:[NSString stringWithUTF8String:fex_name(fex)]])
if([file isEqualToString:guess_encoding_of_string(fex_name(fex))])
break;
fex_next(fex);
}

View File

@ -523,7 +523,7 @@ static uint8_t reverse_bits[0x100];
if(formatCtx->metadata) {
while((tag = av_dict_get(formatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
if(!strcasecmp(tag->key, "streamtitle")) {
NSString *artistTitle = [NSString stringWithUTF8String:tag->value];
NSString *artistTitle = guess_encoding_of_string(tag->value);
NSArray *splitValues = [artistTitle componentsSeparatedByString:@" - "];
_artist = @"";
_title = [splitValues objectAtIndex:0];
@ -532,37 +532,37 @@ static uint8_t reverse_bits[0x100];
_title = [splitValues objectAtIndex:1];
}
} else if(!strcasecmp(tag->key, "icy-url")) {
_album = [NSString stringWithUTF8String:tag->value];
_album = guess_encoding_of_string(tag->value);
} else if(!strcasecmp(tag->key, "icy-genre")) {
_genre = [NSString stringWithUTF8String:tag->value];
_genre = guess_encoding_of_string(tag->value);
} else if(!strcasecmp(tag->key, "album")) {
_album = [NSString stringWithUTF8String:tag->value];
_album = guess_encoding_of_string(tag->value);
} else if(!strcasecmp(tag->key, "album_artist")) {
_albumartist = [NSString stringWithUTF8String:tag->value];
_albumartist = guess_encoding_of_string(tag->value);
} else if(!strcasecmp(tag->key, "artist")) {
_artist = [NSString stringWithUTF8String:tag->value];
_artist = guess_encoding_of_string(tag->value);
} else if(!strcasecmp(tag->key, "title")) {
_title = [NSString stringWithUTF8String:tag->value];
_title = guess_encoding_of_string(tag->value);
} else if(!strcasecmp(tag->key, "date")) {
NSString *dateString = [NSString stringWithUTF8String:tag->value];
NSString *dateString = guess_encoding_of_string(tag->value);
_year = @([dateString intValue]);
} else if(!strcasecmp(tag->key, "track")) {
NSString *trackString = [NSString stringWithUTF8String:tag->value];
NSString *trackString = guess_encoding_of_string(tag->value);
_track = @([trackString intValue]);
} else if(!strcasecmp(tag->key, "disc")) {
NSString *discString = [NSString stringWithUTF8String:tag->value];
NSString *discString = guess_encoding_of_string(tag->value);
_disc = @([discString intValue]);
} else if(!strcasecmp(tag->key, "replaygain_album_gain")) {
NSString *rgValue = [NSString stringWithUTF8String:tag->value];
NSString *rgValue = guess_encoding_of_string(tag->value);
_replayGainAlbumGain = [rgValue floatValue];
} else if(!strcasecmp(tag->key, "replaygain_album_peak")) {
NSString *rgValue = [NSString stringWithUTF8String:tag->value];
NSString *rgValue = guess_encoding_of_string(tag->value);
_replayGainAlbumPeak = [rgValue floatValue];
} else if(!strcasecmp(tag->key, "replaygain_track_gain")) {
NSString *rgValue = [NSString stringWithUTF8String:tag->value];
NSString *rgValue = guess_encoding_of_string(tag->value);
_replayGainTrackGain = [rgValue floatValue];
} else if(!strcasecmp(tag->key, "replaygain_track_peak")) {
NSString *rgValue = [NSString stringWithUTF8String:tag->value];
NSString *rgValue = guess_encoding_of_string(tag->value);
_replayGainTrackPeak = [rgValue floatValue];
}
}
@ -886,18 +886,18 @@ static uint8_t reverse_bits[0x100];
}
- (NSDictionary *)properties {
return @{@"channels": [NSNumber numberWithInt:channels],
@"channelConfig": [NSNumber numberWithUnsignedInt:channelConfig],
@"bitsPerSample": [NSNumber numberWithInt:bitsPerSample],
@"Unsigned": [NSNumber numberWithBool:(bitsPerSample == 8)],
@"sampleRate": [NSNumber numberWithFloat:frequency],
@"floatingPoint": [NSNumber numberWithBool:floatingPoint],
@"totalFrames": [NSNumber numberWithDouble:totalFrames],
@"bitrate": [NSNumber numberWithInt:bitrate],
@"seekable": [NSNumber numberWithBool:seekable],
@"codec": [NSString stringWithUTF8String:avcodec_get_name(codecCtx->codec_id)],
@"endian": @"host",
@"encoding": lossy ? @"lossy" : @"lossless"};
return @{ @"channels": [NSNumber numberWithInt:channels],
@"channelConfig": [NSNumber numberWithUnsignedInt:channelConfig],
@"bitsPerSample": [NSNumber numberWithInt:bitsPerSample],
@"Unsigned": [NSNumber numberWithBool:(bitsPerSample == 8)],
@"sampleRate": [NSNumber numberWithFloat:frequency],
@"floatingPoint": [NSNumber numberWithBool:floatingPoint],
@"totalFrames": [NSNumber numberWithDouble:totalFrames],
@"bitrate": [NSNumber numberWithInt:bitrate],
@"seekable": [NSNumber numberWithBool:seekable],
@"codec": guess_encoding_of_string(avcodec_get_name(codecCtx->codec_id)),
@"endian": @"host",
@"encoding": lossy ? @"lossy" : @"lossless" };
}
- (NSDictionary *)metadata {

View File

@ -95,18 +95,18 @@
gme_delete(emu);
NSString *title = [NSString stringWithUTF8String:info->song];
NSString *title = guess_encoding_of_string(info->song);
if(!title || ![title length]) {
// this is needed to distinguish between different tracks in NSF, for example
// otherwise they will all be displayed as 'blahblah.nsf' in playlist
title = [[url lastPathComponent] stringByAppendingFormat:@" [%d]", track_num];
}
NSDictionary *dict = @{@"genre": [NSString stringWithUTF8String:info->system],
@"album": [NSString stringWithUTF8String:info->game],
@"title": title,
@"artist": [NSString stringWithUTF8String:info->author],
@"track": [NSNumber numberWithInt:track_num + 1]};
NSDictionary *dict = @{ @"genre": guess_encoding_of_string(info->system),
@"album": guess_encoding_of_string(info->game),
@"title": title,
@"artist": guess_encoding_of_string(info->author),
@"track": [NSNumber numberWithInt:track_num + 1] };
gme_free_info(info);

View File

@ -223,9 +223,9 @@ static int parse_time_crap(NSString *value) {
static int psf_info_meta(void *context, const char *name, const char *value) {
struct psf_info_meta_state *state = (struct psf_info_meta_state *)context;
NSString *tag = [NSString stringWithUTF8String:name];
NSString *tag = guess_encoding_of_string(name);
NSString *taglc = [tag lowercaseString];
NSString *svalue = [NSString stringWithUTF8String:value];
NSString *svalue = guess_encoding_of_string(value);
if(svalue == nil)
return 0;
@ -307,8 +307,8 @@ typedef struct {
static int psf1_info(void *context, const char *name, const char *value) {
struct psf1_load_state *state = (struct psf1_load_state *)context;
NSString *sname = [[NSString stringWithUTF8String:name] lowercaseString];
NSString *svalue = [NSString stringWithUTF8String:value];
NSString *sname = [guess_encoding_of_string(name) lowercaseString];
NSString *svalue = guess_encoding_of_string(value);
if(!state->refresh && [sname isEqualToString:@"_refresh"]) {
state->refresh = [svalue intValue];
@ -808,8 +808,8 @@ static int twosf_loader(void *context, const uint8_t *exe, size_t exe_size,
static int twosf_info(void *context, const char *name, const char *value) {
struct twosf_loader_state *state = (struct twosf_loader_state *)context;
NSString *sname = [[NSString stringWithUTF8String:name] lowercaseString];
NSString *svalue = [NSString stringWithUTF8String:value];
NSString *sname = [guess_encoding_of_string(name) lowercaseString];
NSString *svalue = guess_encoding_of_string(value);
if([sname isEqualToString:@"_frames"]) {
state->initial_frames = [svalue intValue];
@ -844,8 +844,8 @@ static int usf_loader(void *context, const uint8_t *exe, size_t exe_size,
static int usf_info(void *context, const char *name, const char *value) {
struct usf_loader_state *uUsf = (struct usf_loader_state *)context;
NSString *sname = [[NSString stringWithUTF8String:name] lowercaseString];
NSString *svalue = [NSString stringWithUTF8String:value];
NSString *sname = [guess_encoding_of_string(name) lowercaseString];
NSString *svalue = guess_encoding_of_string(value);
if([sname isEqualToString:@"_enablecompare"] && [svalue length])
uUsf->enablecompare = 1;

View File

@ -48,7 +48,7 @@
if(!tune)
return nil;
NSString *title = [[NSString stringWithUTF8String:tune->ht_Name] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *title = [guess_encoding_of_string(tune->ht_Name) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
hvl_FreeTune(tune);

View File

@ -62,18 +62,18 @@
midi_meta_data_item item;
bool remap_display_name = !metadata.get_item("title", item);
NSArray *allowedKeys = @[@"title", @"artist", @"album", @"year"];
NSArray *allowedKeys = @[@"title", @"artist", @"albumartist", @"album", @"year", @"genre"];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:10];
for(size_t i = 0; i < metadata.get_count(); ++i) {
const midi_meta_data_item &item = metadata[i];
NSString *name = [[NSString stringWithUTF8String:item.m_name.c_str()] lowercaseString];
NSString *name = [guess_encoding_of_string(item.m_name.c_str()) lowercaseString];
if(![name isEqualToString:@"type"]) {
if(remap_display_name && [name isEqualToString:@"display_name"])
name = @"title";
if([allowedKeys containsObject:name])
[dict setObject:[NSString stringWithUTF8String:item.m_value.c_str()] forKey:name];
[dict setObject:guess_encoding_of_string(item.m_value.c_str()) forKey:name];
}
}

View File

@ -65,15 +65,15 @@
for(std::vector<std::string>::iterator key = keys.begin(); key != keys.end(); ++key) {
if(*key == "title")
title = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
title = guess_encoding_of_string(mod->get_metadata(*key).c_str());
else if(*key == "artist")
artist = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
artist = guess_encoding_of_string(mod->get_metadata(*key).c_str());
/*else if ( *key == "message" )
comment = [NSString stringWithUTF8String: mod->get_metadata( *key ).c_str()];*/
comment = guess_encoding_of_string(mod->get_metadata( *key ).c_str());*/
else if(*key == "date")
date = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
date = guess_encoding_of_string(mod->get_metadata(*key).c_str());
else if(*key == "type_long")
type = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
type = guess_encoding_of_string(mod->get_metadata(*key).c_str());
}
delete mod;

View File

@ -65,15 +65,15 @@
for(std::vector<std::string>::iterator key = keys.begin(); key != keys.end(); ++key) {
if(*key == "title")
title = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
title = guess_encoding_of_string(mod->get_metadata(*key).c_str());
else if(*key == "artist")
artist = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
artist = guess_encoding_of_string(mod->get_metadata(*key).c_str());
/*else if ( *key == "message" )
comment = [NSString stringWithUTF8String: mod->get_metadata( *key ).c_str()];*/
comment = guess_encoding_of_string(mod->get_metadata( *key ).c_str());*/
else if(*key == "date")
date = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
date = guess_encoding_of_string(mod->get_metadata(*key).c_str());
else if(*key == "type_long")
type = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
type = guess_encoding_of_string(mod->get_metadata(*key).c_str());
}
delete mod;

View File

@ -139,11 +139,11 @@ static std::string FCC2Str(UINT32 fcc) {
const char* const* tagList = player->GetTags();
for(const char* const* t = tagList; *t; t += 2) {
if(!strcmp(t[0], "TITLE"))
title = [NSString stringWithUTF8String:t[1]];
title = guess_encoding_of_string(t[1]);
else if(!strcmp(t[0], "ARTIST"))
artist = [NSString stringWithUTF8String:t[1]];
artist = guess_encoding_of_string(t[1]);
else if(!strcmp(t[0], "GAME"))
album = [NSString stringWithUTF8String:t[1]];
album = guess_encoding_of_string(t[1]);
else if(!strcmp(t[0], "DATE")) {
char* end;
unsigned long theYear = strtoul(t[1], &end, 10);

View File

@ -52,9 +52,9 @@
const SidTuneInfo *info = tune->getInfo();
unsigned int count = info->numberOfInfoStrings();
NSString *title = count >= 1 ? [[NSString stringWithUTF8String:info->infoString(0)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
NSString *title = count >= 1 ? [guess_encoding_of_string(info->infoString(0)) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
NSString *titletag = info->songs() > 1 ? @"album" : @"title";
NSString *artist = count >= 2 ? [[NSString stringWithUTF8String:info->infoString(1)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
NSString *artist = count >= 2 ? [guess_encoding_of_string(info->infoString(1)) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
delete tune;

View File

@ -115,7 +115,7 @@ static NSString *get_description_tag(const char *description, const char *tag, c
tags = vgmstream_tags_init(&tag_key, &tag_val);
vgmstream_tags_reset(tags, [filename UTF8String]);
while(vgmstream_tags_next_tag(tags, tagFile)) {
NSString *value = [NSString stringWithUTF8String:tag_val];
NSString *value = guess_encoding_of_string(tag_val);
if(!strncasecmp(tag_key, "REPLAYGAIN_", strlen("REPLAYGAIN_"))) {
if(!strncasecmp(tag_key + strlen("REPLAYGAIN_"), "TRACK_", strlen("TRACK_"))) {
if(!strcasecmp(tag_key + strlen("REPLAYGAIN_TRACK_"), "GAIN")) {
@ -167,7 +167,7 @@ static NSString *get_description_tag(const char *description, const char *tag, c
if([title isEqualToString:@""]) {
if(stream->num_streams > 1) {
title = [NSString stringWithFormat:@"%@ - %s", [[urlTrimmed URLByDeletingPathExtension] lastPathComponent], stream->stream_name];
title = [NSString stringWithFormat:@"%@ - %@", [[urlTrimmed URLByDeletingPathExtension] lastPathComponent], guess_encoding_of_string(stream->stream_name)];
} else {
title = [[urlTrimmed URLByDeletingPathExtension] lastPathComponent];
}