Skip to content

Commit

Permalink
allow chm -named-dest to be chm filepath; some TempStr refactors (fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Krzysztof Kowalczyk committed Nov 24, 2023
1 parent 95ecfa7 commit 6b41bc1
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 81 deletions.
96 changes: 46 additions & 50 deletions src/ChmModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@
#include "GlobalPrefs.h"
#include "ChmModel.h"

static TocItem* NewChmTocItem(TocItem* parent, const char* title, int pageNo, const char* url) {
auto res = new TocItem(parent, title, pageNo);
static IPageDestination* NewChmNamedDest(const char* url, int pageNo) {
if (!url) {
return res;
return nullptr;
}

IPageDestination* dest = nullptr;
if (IsExternalUrl(url)) {
dest = new PageDestinationURL(url);
Expand All @@ -36,14 +34,13 @@ static TocItem* NewChmTocItem(TocItem* parent, const char* title, int pageNo, co
}
dest->pageNo = pageNo;
CrashIf(!dest->kind);

dest->rect = RectF(DEST_USE_DEFAULT, DEST_USE_DEFAULT, DEST_USE_DEFAULT, DEST_USE_DEFAULT);
res->dest = dest;
return res;
return dest;
}

static TocItem* NewChmNamedDest(const char* url, int pageNo) {
auto res = NewChmTocItem(nullptr, url, pageNo, nullptr);
static TocItem* NewChmTocItem(TocItem* parent, const char* title, int pageNo, const char* url) {
auto res = new TocItem(parent, title, pageNo);
res->dest = NewChmNamedDest(url, pageNo);
return res;
}

Expand Down Expand Up @@ -176,7 +173,10 @@ LRESULT ChmModel::PassUIMsg(UINT msg, WPARAM wp, LPARAM lp) const {
return htmlWindow->SendMsg(msg, wp, lp);
}

void ChmModel::DisplayPage(const char* pageUrl) {
bool ChmModel::DisplayPage(const char* pageUrl) {
if (!pageUrl) {
return false;
}
if (IsExternalUrl(pageUrl)) {
// open external links in an external browser
// (same as for PDF, XPS, etc. documents)
Expand All @@ -186,11 +186,12 @@ void ChmModel::DisplayPage(const char* pageUrl) {
cb->GotoLink(item->dest);
delete item;
}
return;
return true;
}

int pageNo = pages.Find(url::GetFullPathTemp(pageUrl)) + 1;
if (pageNo) {
TempStr url = url::GetFullPathTemp(pageUrl);
int pageNo = pages.Find(url) + 1;
if (pageNo > 0) {
currentPageNo = pageNo;
}

Expand All @@ -208,10 +209,8 @@ void ChmModel::DisplayPage(const char* pageUrl) {
pageUrl++;
}

CrashIf(!htmlWindow);
if (htmlWindow) {
htmlWindow->NavigateToDataUrl(pageUrl);
}
htmlWindow->NavigateToDataUrl(pageUrl);
return pageNo > 0;
}

void ChmModel::ScrollTo(int, RectF, float) {
Expand All @@ -221,10 +220,12 @@ void ChmModel::ScrollTo(int, RectF, float) {
bool ChmModel::HandleLink(IPageDestination* link, ILinkHandler*) {
CrashIf(link->GetKind() != kindDestinationScrollTo);
char* url = link->GetName();
if (url) {
DisplayPage(url);
if (DisplayPage(url)) {
return true;
}
return false;
int pageNo = link->GetPageNo();
GoToPage(pageNo, false);
return true;
}

bool ChmModel::CanNavigate(int dir) const {
Expand Down Expand Up @@ -314,7 +315,7 @@ class ChmTocBuilder : public EbookTocVisitor {
return 0;
}

char* plainUrl = url::GetFullPathTemp(url);
TempStr plainUrl = url::GetFullPathTemp(url);
int pageNo = (int)pages->size() + 1;
bool inserted = urlsSet.Insert(plainUrl, pageNo, &pageNo);
if (inserted) {
Expand Down Expand Up @@ -405,7 +406,7 @@ void ChmModel::OnDocumentComplete(const char* url) {
if (*url == '/') {
++url;
}
char* toFind = url::GetFullPathTemp(url);
TempStr toFind = url::GetFullPathTemp(url);
int pageNo = pages.Find(toFind) + 1;
if (!pageNo) {
return;
Expand Down Expand Up @@ -449,7 +450,7 @@ bool ChmModel::OnBeforeNavigate(const char* url, bool newWindow) {
// Load and cache data for a given url inside CHM file.
ByteSlice ChmModel::GetDataForUrl(const char* url) {
ScopedCritSec scope(&docAccess);
char* plainUrl = url::GetFullPathTemp(url);
TempStr plainUrl = url::GetFullPathTemp(url);
ChmCacheEntry* e = FindDataForUrl(plainUrl);
if (!e) {
char* s = str::Dup(&poolAlloc, plainUrl);
Expand Down Expand Up @@ -479,40 +480,35 @@ void ChmModel::OnLButtonDown() {

// named destinations are either in-document URLs or Alias topic IDs
IPageDestination* ChmModel::GetNamedDest(const char* name) {
char* plainUrl = url::GetFullPathTemp(name);
char* url = str::DupTemp(plainUrl);
TempStr url = url::GetFullPathTemp(name);
int pageNo = pages.Find(url) + 1;
if (pageNo >= 1) {
return NewChmNamedDest(url, pageNo);
}
if (doc->HasData(url)) {
return NewChmNamedDest(url, 1);
}
unsigned int topicID;
if (!str::Parse(name, "%u%$", &topicID)) {
return nullptr;
}
char* topicURL = doc->ResolveTopicID(topicID);
if (!topicURL) {
return nullptr;
}
url = str::DupTemp(topicURL);
str::Free(topicURL);
if (!doc->HasData(url)) {
unsigned int topicID;
if (str::Parse(name, "%u%$", &topicID)) {
char* s = doc->ResolveTopicID(topicID);
url = str::DupTemp(s);
str::Free(s);
if (url && doc->HasData(url)) {
plainUrl = url;
name = plainUrl;
} else {
url = nullptr;
}
} else {
url = nullptr;
}
return nullptr;
}
int pageNo = pages.Find(plainUrl) + 1;
if (!pageNo && !str::IsEmpty(url)) {
pageNo = pages.Find(url) + 1;
if (pageNo < 1) {
// some documents use redirection URLs which aren't listed in the ToC
// return pageNo=1 for these, as HandleLink will ignore that anyway
// but LinkHandler::ScrollTo doesn't
pageNo = 1;
}
if (pageNo > 0) {
// TODO: make a function just for constructing a destination
auto tmp = NewChmNamedDest(name, pageNo);
auto res = tmp->dest;
tmp->dest = nullptr;
delete tmp;
return res;
}
return nullptr;
return NewChmNamedDest(url, pageNo);
}

TocTree* ChmModel::GetToc() {
Expand Down
2 changes: 1 addition & 1 deletion src/ChmModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ struct ChmModel : DocController {
PoolAllocator poolAlloc;

bool Load(const char* fileName);
void DisplayPage(const char* pageUrl);
bool DisplayPage(const char* pageUrl);

ChmCacheEntry* FindDataForUrl(const char* url) const;

Expand Down
4 changes: 2 additions & 2 deletions src/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,10 @@ static bool PrintToDevice(const PrintData& pd) {
DOCINFOW di{};
di.cbSize = sizeof(DOCINFO);
if (gPluginMode) {
AutoFreeStr fileName = url::GetFileName(gPluginURL);
TempStr fileName = url::GetFileNameTemp(gPluginURL);
// fall back to a generic "filename" instead of the more confusing temporary filename
if (!fileName) {
fileName.Set("filename");
fileName = (TempStr) "filename";
}
di.lpszDocName = ToWStrTemp(fileName);
} else {
Expand Down
14 changes: 7 additions & 7 deletions src/SumatraPDF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,9 +464,9 @@ char* HwndPasswordUI::GetPassword(const char* path, u8* fileDigest, u8 decryptio
// extract the filename from the URL in plugin mode instead
// of using the more confusing temporary filename
if (gPluginMode) {
char* urlName = url::GetFileName(gPluginURL);
TempStr urlName = url::GetFileNameTemp(gPluginURL);
if (urlName) {
path = urlName; // TODO: leaks
path = urlName;
}
}
path = path::GetBaseNameTemp(path);
Expand Down Expand Up @@ -783,7 +783,7 @@ void ControllerCallbackHandler::FocusFrame(bool always) {
}

void ControllerCallbackHandler::SaveDownload(const char* url, const ByteSlice& data) {
char* path = url::GetFileName(url);
TempStr path = url::GetFileNameTemp(url);
// LinkSaver linkSaver(win->CurrentTab(), win->hwndFrame, fileName);
SaveDataToFile(win->hwndFrame, path, data);
}
Expand Down Expand Up @@ -2742,13 +2742,13 @@ static void SaveCurrentFileAs(MainWindow* win) {
}

auto* ctrl = win->ctrl;
const char* srcFileName = ctrl->GetFilePath();
TempStr srcFileName = (TempStr)ctrl->GetFilePath();
if (gPluginMode) {
// fall back to a generic "filename" instead of the more confusing temporary filename
srcFileName = "filename";
char* urlName = url::GetFileName(gPluginURL);
srcFileName = (TempStr) "filename";
TempStr urlName = url::GetFileNameTemp(gPluginURL);
if (urlName) {
srcFileName = urlName; // TODO: leaks
srcFileName = urlName;
}
}

Expand Down
5 changes: 1 addition & 4 deletions src/utils/HtmlWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ class HtmlWindowCallback {
// HtmlWindow embeds a web browser (Internet Explorer) control
// inside provided HWND so that an app can display html content.
class HtmlWindow {
protected:
friend class FrameSite;

public:
int windowId = 0;
HWND hwndParent = nullptr;
IWebBrowser2* webBrowser = nullptr;
Expand Down Expand Up @@ -68,7 +66,6 @@ class HtmlWindow {
void SetHtmlReal(const ByteSlice&);
void FreeHtmlSetInProgressData();

public:
~HtmlWindow();

void OnSize(Size size);
Expand Down
10 changes: 5 additions & 5 deletions src/utils/StrUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2531,15 +2531,15 @@ bool IsAbsolute(const char* url) {
return colon && (!hash || hash > colon);
}

char* GetFullPathTemp(const char* url) {
char* path = str::Dup(url);
TempStr GetFullPathTemp(const char* url) {
TempStr path = str::DupTemp(url);
str::TransCharsInPlace(path, "#?", "\0\0");
DecodeInPlace(path);
return path;
}

char* GetFileName(const char* url) {
char* path = str::DupTemp(url);
TempStr GetFileNameTemp(const char* url) {
TempStr path = str::DupTemp(url);
str::TransCharsInPlace(path, "#?", "\0\0");
char* base = path + str::Len(path);
for (; base > path; base--) {
Expand All @@ -2551,7 +2551,7 @@ char* GetFileName(const char* url) {
return nullptr;
}
DecodeInPlace(base);
return str::Dup(base);
return str::DupTemp(base);
}

} // namespace url
Expand Down
4 changes: 2 additions & 2 deletions src/utils/StrUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ namespace url {

void DecodeInPlace(char* url);
bool IsAbsolute(const char* url);
char* GetFullPathTemp(const char* url);
char* GetFileName(const char* url);
TempStr GetFullPathTemp(const char* url);
TempStr GetFileNameTemp(const char* url);

} // namespace url

Expand Down
19 changes: 9 additions & 10 deletions src/utils/tests/StrUtil_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,20 +109,19 @@ static void StrConvTest() {
}

static void StrUrlExtractTest() {
utassert(!url::GetFileName(""));
utassert(!url::GetFileName("#hash_only"));
utassert(!url::GetFileName("?query=only"));
AutoFreeStr fileName = url::GetFileName("http://example.net/filename.ext");
utassert(!url::GetFileNameTemp(""));
utassert(!url::GetFileNameTemp("#hash_only"));
utassert(!url::GetFileNameTemp("?query=only"));
TempStr fileName = url::GetFileNameTemp("http://example.net/filename.ext");
utassert(str::Eq(fileName, "filename.ext"));
fileName.Set(url::GetFileName("http://example.net/filename.ext#with_hash"));
fileName = url::GetFileNameTemp("http://example.net/filename.ext#with_hash");
utassert(str::Eq(fileName, "filename.ext"));
fileName.Set(url::GetFileName("http://example.net/path/to/filename.ext?more=data"));
fileName = url::GetFileNameTemp("http://example.net/path/to/filename.ext?more=data");
utassert(str::Eq(fileName, "filename.ext"));
fileName.Set(url::GetFileName("http://example.net/pa%74h/na%2f%6d%65%2ee%78t"));
fileName = url::GetFileNameTemp("http://example.net/pa%74h/na%2f%6d%65%2ee%78t");
utassert(str::Eq(fileName, "na/me.ext"));
fileName.Set(url::GetFileName("http://example.net/%E2%82%AC"));
char* s = fileName.Get();
utassert(str::Eq(s, "\xE2\x82\xaC"));
fileName = url::GetFileNameTemp("http://example.net/%E2%82%AC");
utassert(str::Eq(fileName, "\xE2\x82\xaC"));
}

void strStrTest() {
Expand Down

0 comments on commit 6b41bc1

Please sign in to comment.