Compare commits

..
Author SHA1 Message Date
Yang Jun aeb5ac8782 docs: update testmu sponsor link 2026-02-14 13:52:56 +08:00
13 changed files with 33 additions and 57 deletions
-9
View File
@@ -784,15 +784,6 @@
"contributions": [
"code"
]
},
{
"login": "MorielHarush",
"name": "MorielHarush",
"avatar_url": "https://avatars.githubusercontent.com/u/93482738?v=4",
"profile": "https://github.com/MorielHarush",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,
-1
View File
@@ -217,7 +217,6 @@ Want to contribute? see [Contribution Guidelines][contribution]. Thanks goes to
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rongjiecomputer"><img src="https://avatars.githubusercontent.com/u/13115060?v=4?s=100" width="100px;" alt="Loo Rong Jie"/><br /><sub><b>Loo Rong Jie</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=rongjiecomputer" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MorielHarush"><img src="https://avatars.githubusercontent.com/u/93482738?v=4?s=100" width="100px;" alt="MorielHarush"/><br /><sub><b>MorielHarush</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=MorielHarush" title="Code">💻</a></td>
</tr>
</tbody>
</table>
+1 -1
View File
@@ -8,7 +8,7 @@ const engine = new Liquid({
// layout files for `{% layout %}`
layouts: process.cwd() + '/layouts',
// partial files for `{% include %}` and `{% render %}`
partials: [process.cwd() + '/partials', 'node_modules']
partials: process.cwd() + '/partials'
})
const ctx = {
+1 -1
View File
@@ -1,3 +1,3 @@
set -e
set -ex
npm start | grep 'LiquidJS Demo'
+1 -1
View File
@@ -1,4 +1,4 @@
set -e
set -x
LOG_FILE=$(mktemp)
npm start > $LOG_FILE 2>&1 &
+1 -1
View File
@@ -1,3 +1,3 @@
set -e
set -ex
npm start | grep 'NodeJS Demo for LiquidJS'
+1 -1
View File
@@ -1,3 +1,3 @@
set -e
set -ex
npm start | grep '\[11:8] {{ todo }}'
+1 -1
View File
@@ -1,3 +1,3 @@
set -e
set -ex
npm run build && npm start | grep 'TypeScript Demo for LiquidJS'
+1 -1
View File
@@ -1,4 +1,4 @@
set -e
set -ex
npm run build
npm start | grep 'Webpack Demo for LiquidJS'
+13 -7
View File
@@ -45,20 +45,26 @@ It can be a string-typed path (see above example), or a list of root directories
```javascript
var engine = new Liquid({
root: ['views/'],
partials: ['views/partials/'],
layouts: ['views/layouts/'],
root: ['views/', 'views/partials/'],
extname: '.liquid'
});
```
{% note tip Relative Paths %}Relative paths in <code>root</code> will be resolved against <code>cwd()</code>.{% endnote %}
- When `parse()`, `render()` functions are called, for example `liquid.renderFile('foo')`, templates under `root` will be looked up.
- When a partial is requested, for example `{% raw %}{% render "foo" %}{% endraw %}`, templates under `partials` will be looked up.
- When a layout is requested, for example `{% raw %}{% layout "foo" %}{% endraw %}`, templates under `layouts` will be looked up.
When `{% raw %}{% render "foo" %}{% endraw %}` is rendered or `liquid.renderFile('foo')` is called, the following files will be looked up and the first existing file will be used:
When LiquidJS is used in browser, the paths will be resolved based on current location. Here's a demo for browsers: [demo/browser](https://github.com/harttle/liquidjs/tree/master/demo/browser).
- `cwd()`/views/foo.liquid
- `cwd()`/views/partials/foo.liquid
If none of the above files exists, an `ENOENT` error will be thrown. Here's a demo for Node.js: [demo/nodejs](https://github.com/harttle/liquidjs/tree/master/demo/nodejs).
When LiquidJS is used in browser, say current location is <https://example.com/bar/index.html>, only the first `root` will be used and the file to be fetched is:
- <https://example.com/bar/foo.liquid>
If fetch fails, a 404/500 error or network failures for example, an `ENOENT` error will be thrown.
Here's a demo for browsers: [demo/browser](https://github.com/harttle/liquidjs/tree/master/demo/browser).
## Abstract File System
+11 -12
View File
@@ -43,26 +43,25 @@ export class Loader {
public * candidates (file: string, dirs: string[], currentFile?: string, enforceRoot?: boolean) {
const { fs, extname } = this.options
const isAllowed = (filepath: string) => {
if (!enforceRoot) return true
for (const dir of dirs) {
if (this.contains(dir, filepath)) return true
}
return false
}
if (this.shouldLoadRelative(file) && currentFile) {
const referenced = fs.resolve(this.dirname(currentFile), file, extname)
if (isAllowed(referenced)) yield referenced
for (const dir of dirs) {
if (!enforceRoot || this.contains(dir, referenced)) {
// the relatively referenced file is within one of root dirs
yield referenced
break
}
}
}
for (const dir of dirs) {
const referenced = fs.resolve(dir, file, extname)
if (isAllowed(referenced)) yield referenced
if (!enforceRoot || this.contains(dir, referenced)) {
yield referenced
}
}
if (fs.fallback !== undefined) {
const filepath = fs.fallback(file)
if (filepath !== undefined && isAllowed(filepath)) yield filepath
if (filepath !== undefined) yield filepath
}
}
-20
View File
@@ -1,6 +1,4 @@
import { TopLevelToken, TagToken, Tokenizer, Context, Liquid, Drop, toValueSync, LiquidError, IfTag } from '../..'
import { spawnSync } from 'child_process'
import { resolve as resolvePath } from 'path'
const LiquidUMD = require('../../dist/liquid.browser.umd.js').Liquid
describe('Issues', function () {
@@ -175,24 +173,6 @@ describe('Issues', function () {
const html = await engine.render(tpl, { my_variable: 'foo' })
expect(html).toBe('CONTENT for /tmp/prefix/foo-bar/suffix')
})
it('should prevent path traversal in dynamic include with restricted root, #851', () => {
const projectRoot = resolvePath(__dirname, '../..')
const poc = `
const { Liquid } = require('./dist/liquid.node.js');
const e = new Liquid({ root: ['/tmp'], partials: ['/tmp'], dynamicPartials: true });
e.parseAndRender('{% include page %}', { page: '../../../etc/passwd' })
.then(() => { console.log('OK'); })
.catch(err => { console.error('ERR:' + err.message); process.exit(1); });
`
const result = spawnSync(
process.execPath,
['-e', poc],
{ cwd: projectRoot, encoding: 'utf8' }
)
expect(result.status).not.toBe(0)
expect(result.stderr).toContain('Failed to lookup')
})
it('Implement liquid/echo tags #428', () => {
const template = `{%- liquid
for value in array
+2 -1
View File
@@ -10,7 +10,8 @@
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"downlevelIteration": true,
"strict": true
"strict": true,
"suppressImplicitAnyIndexErrors": true
},
"all": true
}