Skip to content

Commit 8e8d83d

Browse files
authored
fix: ignore high mode bits passed to constructor (#53)
The UnixFS Spec [says](https://github.com/ipfs/specs/blob/master/UNIXFS.md#metadata) high mode bits not defined in the version of the spec supported by a given implementation should be ignored but also persisted to ensure forwards compatibility. The change here: 1. Ignores high bits passed to the constructor 1. Respects high bits read out of a protobuf though does not expose them 1. Writes high bits back to a protobuf but only if they were read from a protobuf to begin with
1 parent 9e24119 commit 8e8d83d

File tree

5 files changed

+70
-5
lines changed

5 files changed

+70
-5
lines changed

packages/ipfs-unixfs-exporter/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"homepage": "https://github.com/ipfs/js-ipfs-unixfs#readme",
3737
"devDependencies": {
3838
"abort-controller": "^3.0.0",
39-
"aegir": "^21.9.0",
39+
"aegir": "^22.0.0",
4040
"chai": "^4.2.0",
4141
"chai-as-promised": "^7.1.1",
4242
"detect-node": "^2.0.4",

packages/ipfs-unixfs-importer/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
},
3636
"homepage": "https://github.com/ipfs/js-ipfs-unixfs#readme",
3737
"devDependencies": {
38-
"aegir": "^21.9.0",
38+
"aegir": "^22.0.0",
3939
"chai": "^4.2.0",
4040
"cids": "^0.8.0",
4141
"detect-node": "^2.0.4",

packages/ipfs-unixfs/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
},
3636
"homepage": "https://github.com/ipfs/js-ipfs-unixfs#readme",
3737
"devDependencies": {
38-
"aegir": "^21.9.0",
38+
"aegir": "^22.0.0",
3939
"chai": "^4.2.0",
4040
"dirty-chai": "^2.0.1",
4141
"nyc": "^15.0.0"

packages/ipfs-unixfs/src/index.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,18 @@ class Data {
129129
static unmarshal (marshaled) {
130130
const decoded = unixfsData.decode(marshaled)
131131

132-
return new Data({
132+
const data = new Data({
133133
type: types[decoded.Type],
134134
data: decoded.hasData() ? decoded.Data : undefined,
135135
blockSizes: decoded.blocksizes,
136136
mode: decoded.hasMode() ? decoded.mode : undefined,
137137
mtime: decoded.hasMtime() ? decoded.mtime : undefined
138138
})
139+
140+
// make sure we honor the original mode
141+
data._originalMode = decoded.hasMode() ? decoded.mode : undefined
142+
143+
return data
139144
}
140145

141146
constructor (...args) {
@@ -158,7 +163,6 @@ class Data {
158163
this.hashType = hashType
159164
this.fanout = fanout
160165
this.blockSizes = blockSizes || []
161-
this._originalMode = mode
162166

163167
const parsedMode = parseMode(mode)
164168

packages/ipfs-unixfs/test/unixfs-format.spec.js

+61
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,67 @@ describe('unixfs-format', () => {
331331
expect(entry).to.have.property('mode', mode)
332332
})
333333

334+
it('omits default file mode from protobuf', () => {
335+
const entry = new UnixFS({
336+
type: 'file',
337+
mode: 0o644
338+
})
339+
340+
const marshaled = entry.marshal()
341+
342+
const protobuf = unixfsData.decode(marshaled)
343+
expect(protobuf.hasMode()).to.be.false()
344+
})
345+
346+
it('omits default directory mode from protobuf', () => {
347+
const entry = new UnixFS({
348+
type: 'directory',
349+
mode: 0o755
350+
})
351+
352+
const marshaled = entry.marshal()
353+
354+
const protobuf = unixfsData.decode(marshaled)
355+
expect(protobuf.hasMode()).to.be.false()
356+
})
357+
358+
it('respects high bits in mode read from buffer', () => {
359+
const mode = 0o0100644 // similar to output from fs.stat
360+
const buf = unixfsData.encode({
361+
Type: unixfsData.DataType.File,
362+
mode
363+
})
364+
365+
const entry = UnixFS.unmarshal(buf)
366+
367+
// should have truncated mode to bits in the version of the spec this module supports
368+
expect(entry).to.have.property('mode', 0o644)
369+
370+
const marshaled = entry.marshal()
371+
372+
const protobuf = unixfsData.decode(marshaled)
373+
expect(protobuf).to.have.property('mode', mode)
374+
})
375+
376+
it('ignores high bits in mode passed to constructor', () => {
377+
const mode = 0o0100644 // similar to output from fs.stat
378+
const entry = new UnixFS({
379+
type: 'file',
380+
mode
381+
})
382+
383+
// should have truncated mode to bits in the version of the spec this module supports
384+
expect(entry).to.have.property('mode', 0o644)
385+
386+
const marshaled = entry.marshal()
387+
const unmarshaled = UnixFS.unmarshal(marshaled)
388+
389+
expect(unmarshaled).to.have.property('mode', 0o644)
390+
391+
const protobuf = unixfsData.decode(marshaled)
392+
expect(protobuf.hasMode()).to.be.false()
393+
})
394+
334395
// figuring out what is this metadata for https://github.com/ipfs/js-ipfs-data-importing/issues/3#issuecomment-182336526
335396
it('metadata', () => {
336397
const entry = new UnixFS({

0 commit comments

Comments
 (0)