eXist-db / exist

eXist Native XML Database and Application Platform
https://exist-db.org
GNU Lesser General Public License v2.1
428 stars 179 forks source link

[BUG] No base-uri assigned to static context in REST request. #4242

Open paulmer opened 2 years ago

paulmer commented 2 years ago

Describe the bug Scripts executed through the REST interface do not receive a base-uri, breaking any use of resolve-uri to resolve paths relative to the script. See example and output below.

Expected behavior I'd expect a reasonable value to be set for the base-uri, specifically the path of the script within the database, that's suitable for locating other resources in the database relative to the script. Executing a saved script via the eXist client returns a reasonable value, but executing the same script via the REST interface throws an exception.

To Reproduce Save the following XQuery in the database with execute permission: (For example, save at /db/demo.xqy)

xquery version "3.0";

resolve-uri('.')

Via the web interface, run the script. The result is an error:

http://localhost:8080/exist/rest/db/demo.xqy

returns

<exception>
<path>/db/demo.xqy</path>
<message>
err:FONS0005 base URI of the static context has not been assigned a value. [at line 3, column 1, source: /db/demo.xqy]
</message>
</exception>

I'd expect /db/demo.xqy to be returned instead.

Context (please always complete the following information):

Additional context

dizzzz commented 2 years ago

Should there be a base-uri according the spec?

paulmer commented 2 years ago

@dizzzz I'm not intimately familiar with the spec, so I can't address whether this is required, but I can say that both BaseX and Saxon return logical consistent values for the expression. Both have chosen to omit the file name, but return a URI that correctly indicates the directory containing the script such that the result can be used to resolve relative URIs correctly. Perhaps this example better illustrates the issue:

Create a script /db/a/b/c/script.xqy containing

let $b := resolve-uri('.')
let $s1 := string(resolve-uri('../c/script.xqy', $b))
let $s2 := string(resolve-uri('../c/script.xqy'))
return ($b, $s1, $s2)

This should output three strings. At the very least, the third string should be the path to the original script. Both Saxon and BaseX return the original script path as both the second and third values.

Expected Output

/db/a/b/c/
/db/a/b/c/script.xqy
/db/a/b/c/script.xqy

Actual Output

/db/a/b/
/db/a/c/script.xqy
/db/a/c/script.xqy

So perhaps my original analysis was incorrect. eXist is returning a value for resolve-uri('.'), but it's omitting the final component of the path.

There may be a second related bug in base-uri, as this code also fails the test, although the output is different:

let $b := base-uri(<a/>)
let $s1 := string(resolve-uri('../c/script.xqy', $b))
let $s2 := string(resolve-uri('../c/script.xqy'))
return ($b, $s1, $s2)

Actual Output

/db/a/b/c
/db/a/c/script.xqy
/db/a/c/script.xqy

One more bizarre example is this:

let $p := string(resolve-uri('../b/c/script.xqy'))
return (util:binary-doc($p), '--------------', util:binary-doc('script.xqy'))

I'd expect this to return two copies of script.xqy separated by a line of hyphens (given that the first path compensates for eXist's behavior), but only one copy is returned. It's not clear at all what path the second binary-doc is using as no error is reported.

dizzzz commented 2 years ago

Thank you for your extensive follow-up; I asked it as I remember I have been struggling with this in the past. This is a good moment to have another look :-P

line-o commented 2 years ago

I see you are running this on Java 17. Could you retest on Java8 to see if that changes the behaviour?

paulmer commented 2 years ago

I see the same behavior regardless of Java version. (8, 11, 14, 17)

On Mar 1, 2022, at 7:51 AM, Juri Leino @.**@.>> wrote:

I see you are running this on Java 17. Could you retest on Java8 to see if that changes the behaviour?

— Reply to this email directly, view it on GitHubhttps://github.com/eXist-db/exist/issues/4242#issuecomment-1055410623, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAN5F7ZAYKJRL32YXZCAPYTU5YHDPANCNFSM5OMORNEQ. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you authored the thread.Message ID: @.***>

line-o commented 2 years ago

@paulmer thanks for checking.