mirror of
https://github.com/xroche/httrack.git
synced 2026-08-14 11:42:27 +03:00
* WebHTTrack settings pages interpolate values into double-quoted attributes unescaped #988 escaped the templates' element bodies and event handlers but left attribute values alone, because cat_html_escaped() keeps the double quote raw on purpose: the tooltips are written title='${html:LANG_x}'. The settings pages put about seventy values inside double-quoted attributes, where a " opens a new attribute. Add a fourth interpolation mode, attr:, escaping < > & ' " as entities and nothing else, and point the 230 double-quoted attribute positions at it. file.html's file:// href stays on the html-urlescaped mode, which now emits %22 for the quote the way unquoted: already did, and step2.html's in-script literal moves to js:. Test 185 now requires attr: in a double-quoted attribute and js: inside a script block; 217 drives hostile values through three templates and a translation. Closes #989 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Xavier Roche <roche@httrack.com> * Close the two attribute sites the template sweep could not reach The liststr: format builds its own <option value="..."> in C, so no template edit covers it, and it escaped with the helper that leaves the double quote raw. Its values are the project directory names and the Category= line of each project's winprofile.ini, both of which can hold a quote. The save side kept hex-decoding a backslash plus two hex digits, so a path typed as C:\ab displayed correctly but was written to ~/.httrack.ini as C: plus byte 0xAB. The ini writer has no inverse for that escape; the one caller that needs it is a template literal (${test:proxytype:\3A//}), so the decode now applies only there. Test 185 classified attributes with a regex that missed a spaced =, an unquoted or single-quoted value, a template outside html/server/*.html, and an output-mode region the file never closes; the counting floors it asserted also survived a count-preserving rewrite. It now walks tags, asserts the property on every site it classifies, and proves it can see each of those forms on a synthetic template first. Test 217 gains a Latin-1 byte in a translation, the POST-render-POST round trip, and the two fixes above. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Xavier Roche <roche@httrack.com> * Trim the comments the last commit added Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Xavier Roche <roche@httrack.com> --------- Signed-off-by: Xavier Roche <roche@httrack.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
203 lines
9.9 KiB
HTML
203 lines
9.9 KiB
HTML
<html xmlns="http://www.w3.org/1999/xhtml" lang="${attr:LANGUAGE_ISO}">
|
|
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=${attr:LANGUAGE_CHARSET}" />
|
|
<meta name="description" content="${attr:LANG_METADESC}" />
|
|
<meta name="keywords" content="${attr:LANG_METAKEYW}" />
|
|
<title>'${html:projname}' - HTTrack Website Copier</title>
|
|
|
|
<link rel="stylesheet" type="text/css" media="screen" href="style.css">
|
|
<script type="text/javascript" src="ping.js" defer></script>
|
|
|
|
<script language="javascript">
|
|
<!--
|
|
function do_load() {
|
|
window.status=' ';
|
|
${do:if-not-empty:closeme}
|
|
window.close();
|
|
${do:end-if}
|
|
${do:set:closeme:}
|
|
}
|
|
function do_unload() {
|
|
}
|
|
function info(str) {
|
|
window.status = str;
|
|
}
|
|
// -->
|
|
</script>
|
|
|
|
</head>
|
|
<body onLoad="do_load();" onUnload="do_unload();">
|
|
|
|
<table width="76%" border="0" align="center" cellspacing="0" cellpadding="0" class="tableWidth">
|
|
<tr>
|
|
<td><img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier" title="" border="0" id="title" /></td>
|
|
</tr>
|
|
</table>
|
|
|
|
<table width="76%" border="0" align="center" cellspacing="0" cellpadding="3" class="tableWidth">
|
|
<tr>
|
|
<td id="subTitle">${LANG_OSFWB}</td>
|
|
</tr>
|
|
</table>
|
|
<table width="76%" border="0" align="center" cellspacing="0" cellpadding="0" class="tableWidth">
|
|
<tr class="blak">
|
|
<td>
|
|
<table width="100%" border="0" align="center" cellspacing="1" cellpadding="0">
|
|
<tr>
|
|
<td colspan="6">
|
|
<table width="100%" border="0" align="center" cellspacing="0" cellpadding="10">
|
|
<tr>
|
|
<td id="pageContent">
|
|
<!-- ==================== End prologue ==================== -->
|
|
|
|
<table border="0" width="100%">
|
|
<tr><td width="90%">
|
|
<h2 align="center"><em>${LANG_O2} - ${LANG_IOPT2}</em></h2>
|
|
</td>
|
|
${/* show help only if available */}
|
|
${do:if-file-exists:html/index.html}
|
|
<td>
|
|
<a href="/guide.html#web/opt-build" target="_blank"
|
|
onClick="window.open('/guide.html#web/opt-build', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=980, height=760'); return false"
|
|
title='${html:LANG_TIPHELP}' onMouseOver="info('${js:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
|
>${LANG_TIPHELP}</a>
|
|
</td>
|
|
${do:end-if}
|
|
</tr></table>
|
|
|
|
<br>
|
|
|
|
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
|
<tr>
|
|
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${js:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${js:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${js:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${js:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${js:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${js:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
|
</tr><tr>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${js:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${js:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${js:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${js:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
|
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${js:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
|
<td class="tabCtrl" align="center"> </td>
|
|
|
|
</tr>
|
|
</table>
|
|
|
|
<br><br>
|
|
|
|
<table>
|
|
<tr><td>
|
|
|
|
<form method="POST" action="${attr:thisfile}" name="form">
|
|
<input type="hidden" name="sid" value="${attr:sid}">
|
|
<input type="hidden" name="redirect" value="">
|
|
<input type="hidden" name="closeme" value="">
|
|
|
|
<!-- clear if not checked -->
|
|
<input type="hidden" name="errpage" value="">
|
|
<input type="hidden" name="external" value="">
|
|
<input type="hidden" name="hidepwd" value="">
|
|
<input type="hidden" name="hidequery" value="">
|
|
<input type="hidden" name="nopurge" value="">
|
|
<input type="hidden" name="singlefile" value="">
|
|
|
|
${LANG_I33}
|
|
<br>
|
|
<select name="build"
|
|
title='${html:LANG_I3}' onMouseOver="info('${js:LANG_I3}'); return true" onMouseOut="info(' '); return true"
|
|
>
|
|
${listid:build:LISTDEF_3}
|
|
</select>
|
|
<input type="button" value="${attr:LANG_O2}"
|
|
onClick="form.build.selectedIndex=14; window.open('option2b.html', 'option2b', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480').wparent=document; form.submit();"
|
|
title='${html:LANG_I4}' onMouseOver="info('${js:LANG_I4}'); return true" onMouseOut="info(' '); return true"
|
|
>
|
|
|
|
<!-- checkboxes -->
|
|
<table border="0" width="100%" cellspacing="0">
|
|
<tr><td>
|
|
<select name="dos"
|
|
title='${html:LANG_I8} ${html:LANG_I8b}' onMouseOver="info('${js:LANG_I8}\r\n${js:LANG_I8b}'); return true" onMouseOut="info(' '); return true"
|
|
>
|
|
<option value="0"${ztest:dos: selected::}> </option>
|
|
<option value="1"${ztest:dos:: selected:}>${LANG_I37}</option>
|
|
<option value="2"${ztest:dos::: selected}>${LANG_I37b}</option>
|
|
</select>
|
|
</td></tr>
|
|
<tr><td><input type="checkbox" name="errpage" ${checked:errpage}
|
|
title='${html:LANG_I9}' onMouseOver="info('${js:LANG_I9}'); return true" onMouseOut="info(' '); return true"
|
|
> ${LANG_I38}</td></tr>
|
|
<tr><td><input type="checkbox" name="external" ${checked:external}
|
|
title='${html:LANG_I29}' onMouseOver="info('${js:LANG_I29}'); return true" onMouseOut="info(' '); return true"
|
|
> ${LANG_I56}</td></tr>
|
|
<tr><td><input type="checkbox" name="hidepwd" ${checked:hidepwd}
|
|
title='${html:LANG_I30}' onMouseOver="info('${js:LANG_I30}'); return true" onMouseOut="info(' '); return true"
|
|
> ${LANG_I66}</td></tr>
|
|
<tr><td><input type="checkbox" name="hidequery" ${checked:hidequery}
|
|
title='${html:LANG_I30b}' onMouseOver="info('${js:LANG_I30b}'); return true" onMouseOut="info(' '); return true"
|
|
> ${LANG_I67}</td></tr>
|
|
<tr><td><input type="checkbox" name="nopurge" ${checked:nopurge}
|
|
title='${html:LANG_I1a}' onMouseOver="info('${js:LANG_I1a}'); return true" onMouseOut="info(' '); return true"
|
|
> ${LANG_I57}</td></tr>
|
|
<tr><td><input type="checkbox" name="singlefile" ${checked:singlefile}
|
|
title='${html:LANG_SINGLEFILETIP}' onMouseOver="info('${js:LANG_SINGLEFILETIP}'); return true" onMouseOut="info(' '); return true"
|
|
> ${LANG_SINGLEFILE}</td></tr>
|
|
<tr><td>${LANG_SINGLEFILEMAX}
|
|
<input name="singlefilemax" value="${attr:singlefilemax}" size="12"
|
|
title='${html:LANG_SINGLEFILEMAXTIP}' onMouseOver="info('${js:LANG_SINGLEFILEMAXTIP}'); return true" onMouseOut="info(' '); return true"
|
|
></td></tr>
|
|
</table>
|
|
|
|
<tr><td>
|
|
<table width="100%">
|
|
<tr><td align="left">
|
|
<input type="submit" value="${attr:LANG_OK}"
|
|
onClick="form.closeme.value=1; form.submit(); return false;"
|
|
title='${html:LANG_TIPOK}' onMouseOver="info('${js:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
|
>
|
|
</td><td align="right">
|
|
<input type="button" value="${attr:LANG_CANCEL}"
|
|
onClick="window.close();"
|
|
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${js:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
|
>
|
|
</td></tr>
|
|
</table>
|
|
</td></tr>
|
|
|
|
</form>
|
|
|
|
</td></tr>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
<!-- ==================== Start epilogue ==================== -->
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
|
|
<tr>
|
|
<td id="footer"><small><small>© 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
|
|
</tr>
|
|
</table>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
|