Skip to content

Commit

Permalink
Fix source path determination for transcoding
Browse files Browse the repository at this point in the history
Using a glob for this logic does not work well, because certain common
characters like square brackets get interpreted specially. Instead, we
need to just implement the prefix checking ourselves.

This also updates the tests to catch this particular problem.

Fixes #66.
  • Loading branch information
khenriks committed Mar 8, 2021
1 parent 9e45a2e commit 3b410b8
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 36 deletions.
46 changes: 16 additions & 30 deletions src/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,54 +20,40 @@

#include "path.h"

#include <glob.h>
#include <dirent.h>

#include <algorithm>
#include <cstddef>
#include <iterator>
#include <memory>
#include <string>
#include <vector>

#include "codecs/coders.h"
#include "mp3fs.h"

namespace {

// Simple C++ wrapper for glob.
std::vector<std::string> glob_match(const std::string& pattern) {
std::vector<std::string> result;

glob_t globbuf;
if (glob(pattern.c_str(), 0, nullptr, &globbuf) == 0) {
std::copy(globbuf.gl_pathv, globbuf.gl_pathv + globbuf.gl_pathc,
std::back_inserter(result));
}

globfree(&globbuf);
return result;
}

} // namespace

std::string Path::NormalSource() const {
return std::string(params.basepath) + relative_path_;
}

std::string Path::TranscodeSource() const {
const std::string source = NormalSource();
const size_t dot_idx = source.rfind('.');
const size_t slash_idx = source.rfind('/');
const std::string source_dir = source.substr(0, slash_idx);

if (dot_idx != std::string::npos &&
source.substr(dot_idx + 1) == params.desttype) {
const std::string source_base = source.substr(0, dot_idx);
for (const std::string& candidate : glob_match(source_base + ".*")) {
const std::string candidate_ext =
candidate.substr(candidate.rfind('.') + 1);

if (Decoder::CreateDecoder(candidate_ext) != nullptr) {
/* This is a valid transcode source file. */
return candidate;
const std::string source_base =
source.substr(slash_idx + 1, dot_idx - slash_idx);
std::unique_ptr<DIR, decltype(&closedir)> dp(
opendir(source_dir.c_str()), closedir);
while (struct dirent* de = readdir(dp.get())) {
std::string de_name = de->d_name;
if (de_name.find(source_base) == 0) {
const std::string de_ext =
de_name.substr(de_name.rfind('.') + 1);
if (Decoder::CreateDecoder(de_ext) != nullptr) {
/* This is a valid transcode source file. */
return source_dir + "/" + de_name;
}
}
}
}
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion test/test_audio
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
. "${BASH_SOURCE%/*}/funcs.sh"

[ "$(./fpcompare "$SRCDIR/obama.fLaC" "$DIRNAME/obama.mp3" 2>&-)" \< 0.05 ]
[ "$(./fpcompare "$SRCDIR/raven.ogg" "$DIRNAME/raven.mp3" 2>&-)" \< 0.05 ]
[ "$(./fpcompare "$SRCDIR/ra[ven].ogg" "$DIRNAME/ra[ven].mp3" 2>&-)" \< 0.05 ]
2 changes: 1 addition & 1 deletion test/test_filenames
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
. "${BASH_SOURCE%/*}/funcs.sh"

check_equal "$(ls -m "$DIRNAME")" \
"dir.flac, obama.mp3, obama2.mp3, random.mp3, raven.mp3, some.txt"
"dir.flac, obama.mp3, obama2.mp3, ra[ven].mp3, random.mp3, some.txt"
4 changes: 2 additions & 2 deletions test/test_filesize
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Ensure log contains file sizes, predicted and actual
cat "$DIRNAME/obama.mp3" > /dev/null
cat "$DIRNAME/raven.mp3" > /dev/null
cat "$DIRNAME/ra[ven].mp3" > /dev/null

check_equal "$(stat -c %s "$DIRNAME/obama.mp3")" 106781
check_equal "$(stat -c %s "$DIRNAME/raven.mp3")" 346594
check_equal "$(stat -c %s "$DIRNAME/ra[ven].mp3")" 346594
2 changes: 1 addition & 1 deletion test/test_picture
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ END
}

check_equal "$(hash_image "$DIRNAME/obama.mp3")" 794865299f4fac10ba5719b203f0c71b5b524e95
check_equal "$(hash_image "$DIRNAME/raven.mp3")" 5cd44d9e64c90d137ed3614213e309afec060dbc
check_equal "$(hash_image "$DIRNAME/ra[ven].mp3")" 5cd44d9e64c90d137ed3614213e309afec060dbc
2 changes: 1 addition & 1 deletion test/test_tags
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ TRCK=1/1
TSSE=MP3FS
END

cmp -s - <(get_metadata "$DIRNAME/raven.mp3") <<END
cmp -s - <(get_metadata "$DIRNAME/ra[ven].mp3") <<END
TALB=The Raven
TCON=Speech
TDRC=2007
Expand Down

0 comments on commit 3b410b8

Please sign in to comment.