You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by ar...@apache.org on 2026/10/03 12:01:03 UTC
(openoffice) 01/02: Accept local files
This is an automated email from the ASF dual-hosted git repository.
ardovm pushed a commit to branch AOO41X
in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit 55a8ef8e3097bc8de5b02d37bbedbcebe84d576b
Author: Peter <pe...@apache.org>
AuthorDate: Sat Sep 26 22:16:29 2026 +0200
Accept local files
Co-Authored-By: Claude Opus 5.5 <no...@anthropic.com>
(cherry picked and adapted from commit 06d7e6fcc50631716e4dd8909f5d630a5b1f52c5)
---
main/jvmaccess/source/classpath.cxx | 87 ++++++++++++++++++++++++++++++++-----
1 file changed, 77 insertions(+), 10 deletions(-)
diff --git a/main/jvmaccess/source/classpath.cxx b/main/jvmaccess/source/classpath.cxx
index c27a530ba7..f0e7d6f001 100644
--- a/main/jvmaccess/source/classpath.cxx
+++ b/main/jvmaccess/source/classpath.cxx
@@ -37,6 +37,7 @@
#include "com/sun/star/uri/XVndSunStarExpandUrlReference.hpp"
#include "com/sun/star/util/XMacroExpander.hpp"
#include "osl/diagnose.h"
+#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
@@ -49,22 +50,88 @@ namespace {
namespace css = ::com::sun::star;
#if defined SOLAR_JAVA
+int hexDigitValue(sal_Unicode c)
+{
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ }
+ if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ }
+ if (c >= 'a' && c <= 'f') {
+ return c - 'a' + 10;
+ }
+ return -1;
+}
+
+// Undoes one level of %HH escapes, as the JDK's file: handler does before it
+// opens a path. Only the ASCII separators matter to the caller, so each escape
+// simply becomes the code unit of its byte value; a malformed escape is kept.
+::rtl::OUString percentDecoded(::rtl::OUString const & s)
+{
+ sal_Int32 const n = s.getLength();
+ ::rtl::OUStringBuffer buf(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ sal_Unicode c = s[i];
+ if (c == '%' && n - i > 2) {
+ int const hi = hexDigitValue(s[i + 1]);
+ int const lo = hexDigitValue(s[i + 2]);
+ if (hi != -1 && lo != -1) {
+ c = static_cast< sal_Unicode >(hi * 16 + lo);
+ i += 2;
+ }
+ }
+ buf.append(c);
+ }
+ return buf.makeStringAndClear();
+}
+
+// Whether the part of a file: URL after the scheme names a path on this
+// machine: the authority, if any, must be empty or localhost, and the path must
+// not name another machine by itself. The path is judged decoded, because the
+// JDK's file: handler percent-decodes it and, on Windows, turns slashes into
+// backslashes before opening it -- a leading escaped slash or backslash would
+// otherwise reach the file system as a reference to a share.
+bool isLocalFileLocation(::rtl::OUString const & afterScheme)
+{
+ ::rtl::OUString rest(afterScheme);
+ if (rest.indexOf('\\') != -1) {
+ return false;
+ }
+ if (rest.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("//"))) {
+ sal_Int32 const end = rest.indexOf('/', 2);
+ ::rtl::OUString const authority(
+ end == -1 ? rest.copy(2) : rest.copy(2, end - 2));
+ if (authority.getLength() != 0
+ && !authority.equalsIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("localhost")))
+ {
+ return false;
+ }
+ rest = end == -1 ? ::rtl::OUString() : rest.copy(end);
+ }
+ rest = percentDecoded(rest);
+ return rest.getLength() >= 2 && rest[0] == '/' && rest[1] != '/'
+ && rest.indexOf('\\') == -1;
+}
+
// URL schemes that resolve to the local file system or the running JVM image,
-// optionally wrapped in a jar: URL.
+// optionally wrapped in a jar: URL; a file: URL must in addition name a path on
+// this machine.
//
// com.sun.star.comp.sdbc.Tools enforces the same allow-list on the Java side;
// keep the two in sync.
bool isLocalClassPathUrl(::rtl::OUString const & url)
{
- return url.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("file:"))
- || url.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("jrt:"))
- || url.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("jmod:"))
- || url.matchIgnoreAsciiCaseAsciiL(
- RTL_CONSTASCII_STRINGPARAM("jar:file:"))
- || url.matchIgnoreAsciiCaseAsciiL(
- RTL_CONSTASCII_STRINGPARAM("jar:jrt:"))
- || url.matchIgnoreAsciiCaseAsciiL(
- RTL_CONSTASCII_STRINGPARAM("jar:jmod:"));
+ ::rtl::OUString rest(url);
+ if (rest.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("jar:"))) {
+ rest = rest.copy(RTL_CONSTASCII_LENGTH("jar:"));
+ }
+ if (rest.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("file:"))) {
+ return isLocalFileLocation(rest.copy(RTL_CONSTASCII_LENGTH("file:")));
+ }
+ return rest.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("jrt:"))
+ || rest.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("jmod:"));
}
#endif