Coverage Report

Created: 2026-10-28 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/httrack/src/htsmodules.c
Line
Count
Source
1
/* ------------------------------------------------------------ */
2
/*
3
HTTrack Website Copier, Offline Browser for Windows and Unix
4
Copyright (C) 1998 Xavier Roche and other contributors
5
6
SPDX-License-Identifier: GPL-3.0-or-later
7
8
This program is free software: you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation, either version 3 of the License, or
11
(at your option) any later version.
12
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21
Ethical use: we kindly ask that you NOT use this software to harvest email
22
addresses or to collect any other private information about people. Doing so
23
would dishonor our work and waste the many hours we have spent on it.
24
25
Please visit our Website: http://www.httrack.com
26
*/
27
28
/* ------------------------------------------------------------ */
29
/* File: htsmodules.c subroutines:                              */
30
/*       external modules (parsers)                             */
31
/* Author: Xavier Roche                                         */
32
/* ------------------------------------------------------------ */
33
34
/* Internal engine bytecode */
35
#define HTS_INTERNAL_BYTECODE
36
37
#include "htsglobal.h"
38
#include "htsmodules.h"
39
#include "htsopt.h"
40
#include "htsbasenet.h"
41
#include "htslib.h"
42
43
extern int fspc(httrackp * opt, FILE * fp, const char *type);
44
45
#ifndef _WIN32
46
#if HTS_DLOPEN
47
#include <dlfcn.h>
48
#endif
49
#endif
50
51
/* >>> Put all modules definitions here */
52
#include "htszlib.h"
53
#include "htsbase.h"
54
/* <<< */
55
56
/* >>> Put all modules variables here */
57
58
int V6_is_available = HTS_INET6;
59
60
static char WHAT_is_available[64] = "";
61
62
/* <<< */
63
64
0
HTSEXT_API const char *hts_get_version_info(httrackp * opt) {
65
0
  size_t size;
66
0
  int i;
67
68
0
  strcpy(opt->state.HTbuff, WHAT_is_available);
69
0
  size = strlen(opt->state.HTbuff);
70
0
  for(i = 0; i < opt->libHandles.count; i++) {
71
0
    const char *name = opt->libHandles.handles[i].moduleName;
72
73
0
    if (name != NULL) {
74
0
      size_t nsize = strlen(name) + sizeof("+");
75
76
0
      size += nsize;
77
0
      if (size + 1 >= sizeof(opt->state.HTbuff))
78
0
        break;
79
0
      strcat(opt->state.HTbuff, "+");
80
0
      strcat(opt->state.HTbuff, name);
81
0
    }
82
0
  }
83
0
  return opt->state.HTbuff;
84
0
}
85
86
static void htspe_log(htsmoduleStruct * str, const char *msg);
87
88
0
int hts_parse_externals(htsmoduleStruct * str) {
89
0
  str->wrapper_name = "wrapper-lib";
90
91
  /* External callback */
92
0
  if (RUN_CALLBACK1(str->opt, detect, str)) {
93
0
    if (str->wrapper_name == NULL)
94
0
      str->wrapper_name = "wrapper-lib";
95
    /* Blacklisted */
96
0
    if (multipleStringMatch
97
0
        (str->wrapper_name, StringBuff(str->opt->mod_blacklist))) {
98
0
      return -1;
99
0
    } else {
100
0
      htspe_log(str, str->wrapper_name);
101
0
      return RUN_CALLBACK1(str->opt, parse, str);
102
0
    }
103
0
  }
104
105
  /* Not detected */
106
0
  return -1;
107
0
}
108
109
void clearCallbacks(htscallbacks * chain_);
110
0
void clearCallbacks(htscallbacks * chain_) {
111
0
  htscallbacks *chain;
112
113
0
  chain = chain_;
114
0
  while(chain != NULL) {
115
0
    if (chain->exitFnc != NULL) {
116
0
      (void) chain->exitFnc();  /* result ignored */
117
0
      chain->exitFnc = NULL;
118
0
    }
119
0
    chain = chain->next;
120
0
  }
121
0
  chain = chain_;
122
0
  while(chain != NULL) {
123
0
    if (chain->moduleHandle != NULL) {
124
#ifdef _WIN32
125
      FreeLibrary(chain->moduleHandle);
126
#else
127
0
      dlclose(chain->moduleHandle);
128
0
#endif
129
0
    }
130
0
    chain = chain->next;
131
0
  }
132
0
  chain = chain_->next;         // Don't free the block #0
133
0
  while(chain != NULL) {
134
0
    htscallbacks *nextchain = chain->next;
135
136
0
    freet(chain);
137
0
    chain = nextchain;
138
0
  }
139
0
  chain_->next = NULL;          // Empty
140
0
}
141
142
0
void *openFunctionLib(const char *file_) {
143
0
  void *handle;
144
0
  char *file = malloct(strlen(file_) + 32);
145
146
0
  if (file == NULL)
147
0
    return NULL; /* no module, which the caller already reports */
148
0
  strcpy(file, file_);
149
#ifdef _WIN32
150
  handle = LoadLibraryA(file);
151
  if (handle == NULL) {
152
    sprintf(file, "%s.dll", file_);
153
    handle = LoadLibraryA(file);
154
  }
155
#else
156
0
  handle = dlopen(file, RTLD_LAZY);
157
0
  if (handle == NULL) {
158
0
    sprintf(file, "lib%s.so", file_);
159
0
    handle = dlopen(file, RTLD_LAZY);
160
0
  }
161
0
#endif
162
0
  freet(file);
163
0
  return handle;
164
0
}
165
166
0
void closeFunctionLib(void *handle) {
167
#ifdef _WIN32
168
  FreeLibrary(handle);
169
#else
170
0
  dlclose(handle);
171
0
#endif
172
0
}
173
174
0
void *getFunctionPtr(void *handle, const char *fncname_) {
175
0
  if (handle) {
176
0
    void *userfunction = NULL;
177
0
    char *fncname = strdupt(fncname_);
178
179
    /* Strip optional comma */
180
0
    char *comma;
181
182
0
    if ((comma = strchr(fncname, ',')) != NULL) {       /* empty arg */
183
0
      *comma++ = '\0';
184
0
    }
185
186
    /* the function itself */
187
0
    userfunction = (void *) DynamicGet(handle, (char *) fncname);
188
189
0
    freet(fncname);
190
191
0
    return userfunction;
192
0
  }
193
0
  return NULL;
194
0
}
195
196
0
void htspe_init(void) {
197
0
  static int initOk = 0;
198
199
0
  if (!initOk) {
200
0
    initOk = 1;
201
202
    /* See CVE-2010-5252 */
203
#if (defined(_WIN32) && (!defined(_DEBUG)))
204
    {
205
      /* See KB 2389418
206
         "If this parameter is an empty string (""), the call removes the 
207
         current directory from the default DLL search order" */
208
      BOOL (WINAPI*const k32_SetDllDirectoryA)(LPCSTR) = 
209
        (BOOL (WINAPI *)(LPCSTR))
210
        GetProcAddress(GetModuleHandle("kernel32.dll"), "SetDllDirectoryA");
211
      if (k32_SetDllDirectoryA != NULL && !k32_SetDllDirectoryA("")) {
212
        /* Do no choke on NT or 98SE with KernelEx NT API (James Blough) */
213
        const DWORD dwVersion = GetVersion();
214
        const DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
215
        const DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
216
        if (dwMajorVersion >= 5) {
217
          assertf(!"SetDllDirectory failed");
218
        }
219
      }
220
    }
221
#endif
222
223
    /* Options availability */
224
0
    sprintf(WHAT_is_available, "%s%s%s", V6_is_available ? "" : "-noV6",
225
0
            "",
226
#if HTS_USEOPENSSL
227
            ""
228
#else
229
0
            "-nossl"
230
0
#endif
231
0
            );
232
0
  }
233
0
}
234
235
0
void htspe_uninit(void) {
236
0
}
237
238
0
static void htspe_log(htsmoduleStruct * str, const char *msg) {
239
0
  const char *savename = str->filename;
240
0
  httrackp *opt = (httrackp *) str->opt;
241
242
0
  hts_log_print(opt, LOG_DEBUG, "(External module): parsing %s using module %s",
243
0
                savename, msg);
244
0
}
245
246
0
HTSEXT_API const char *hts_is_available(void) {
247
0
  return WHAT_is_available;
248
0
}