Skip to content
This repository has been archived by the owner on Aug 11, 2022. It is now read-only.

Commit

Permalink
install: version: Fix package.json handling to always allow BOM at start
Browse files Browse the repository at this point in the history
Fixes: #3358

PR-URL: #8724
  • Loading branch information
iarna committed Jul 1, 2015
1 parent 2875ba3 commit 28064e5
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 26 deletions.
7 changes: 2 additions & 5 deletions lib/cache/caching-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var mkdirp = require('mkdirp')
var rimraf = require('rimraf')
var chownr = require('chownr')
var writeFile = require('write-file-atomic')
var parseJSON = require('../utils/parse-json')

function CachingRegistryClient (config) {
RegistryClient.call(this, adaptConfig(config))
Expand Down Expand Up @@ -78,11 +79,7 @@ function get (uri, params, cb) {
fs.stat(cachePath, function (er, stat) {
if (!er) {
fs.readFile(cachePath, function (er, data) {
try {
data = JSON.parse(data)
} catch (ex) {
data = null
}
data = parseJSON.noExceptions(data)

params.stat = stat
params.data = data
Expand Down
6 changes: 3 additions & 3 deletions lib/cache/update-index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var cacheFile = require('npm-cache-filename')
var getCacheStat = require('./get-stat.js')
var mapToRegistry = require('../utils/map-to-registry.js')
var pulseTillDone = require('../utils/pulse-till-done.js')
var parseJSON = require('../utils/parse-json.js')

/* /-/all is special.
* It uses timestamp-based caching and partial updates,
Expand Down Expand Up @@ -47,9 +48,8 @@ function updateIndex (staleness, cb) {
chownr(made || cachePath, st.uid, st.gid, function (er) {
if (er) return cb(er)

try {
data = JSON.parse(data)
} catch (ex) {
data = parseJSON.noExceptions(data)
if (!data) {
fs.writeFile(cachePath, '{}', function (er) {
if (er) return cb(new Error('Broken cache.'))

Expand Down
3 changes: 2 additions & 1 deletion lib/fetch-package-metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var tempFilename = require('./utils/temp-filename.js')
var getCacheStat = require('./cache/get-stat.js')
var unpack = require('./utils/tar.js').unpack
var pulseTillDone = require('./utils/pulse-till-done.js')
var parseJSON = require('./utils/parse-json.js')

function andLogAndFinish (spec, tracker, done) {
validate('SF', [spec, done])
Expand Down Expand Up @@ -184,7 +185,7 @@ module.exports.addShrinkwrap = function addShrinkwrap (pkg, next) {
untar.close()
log.silly('addShrinkwrap', 'Done reading shrinkwrap')
try {
pkg._shrinkwrap = JSON.parse(shrinkwrap)
pkg._shrinkwrap = parseJSON(shrinkwrap)
} catch (ex) {
var er = new Error('Error parsing ' + pkgname + '@' + ver + "'s npm-shrinkwrap.json: " + ex.message)
er.type = 'ESHRINKWRAP'
Expand Down
15 changes: 4 additions & 11 deletions lib/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ var getSaveType = require('./install/save.js').getSaveType
var doSerialActions = require('./install/actions.js').doSerial
var doParallelActions = require('./install/actions.js').doParallel
var doOneAction = require('./install/actions.js').doOne
var parseJSON = require('./utils/parse-json.js')

function unlockCB (lockPath, name, cb) {
validate('SSF', arguments)
Expand Down Expand Up @@ -396,21 +397,13 @@ Installer.prototype.computeLinked = function (cb) {
})
}

function safeJSONparse (data) {
try {
return JSON.parse(data)
} catch (ex) {
return
}
}

function isLinkable (pkg, cb) {
var globalPackage = path.resolve(npm.globalPrefix, 'lib', 'node_modules', pkg.package.name)
var globalPackageJson = path.resolve(globalPackage, 'package.json')
fs.stat(globalPackage, function (er) {
if (er) return cb(true, true)
fs.readFile(globalPackageJson, function (er, data) {
var json = safeJSONparse(data)
var json = parseJSON.noExceptions(data)
cb(false, json && json.version === pkg.package.version)
})
})
Expand Down Expand Up @@ -520,10 +513,10 @@ Installer.prototype.readLocalPackageData = function (cb) {
}
if (!currentTree.package) currentTree.package = {}
if (currentTree.package._shrinkwrap) return cb()
fs.readFile(path.join(self.where, 'npm-shrinkwrap.json'), {encoding: 'utf8'}, function (er, data) {
fs.readFile(path.join(self.where, 'npm-shrinkwrap.json'), function (er, data) {
if (er) return cb()
try {
currentTree.package._shrinkwrap = JSON.parse(data)
currentTree.package._shrinkwrap = parseJSON(data)
} catch (ex) {
return cb(ex)
}
Expand Down
5 changes: 3 additions & 2 deletions lib/install/read-shrinkwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ var path = require('path')
var fs = require('graceful-fs')
var iferr = require('iferr')
var inflateShrinkwrap = require('./inflate-shrinkwrap.js')
var parseJSON = require('../utils/parse-json.js')

var readShrinkwrap = module.exports = function (child, next) {
fs.readFile(path.join(child.path, 'npm-shrinkwrap.json'), {encoding: 'utf-8'}, function (er, data) {
fs.readFile(path.join(child.path, 'npm-shrinkwrap.json'), function (er, data) {
if (er) {
child.package._shrinkwrap = null
return next()
}
try {
child.package._shrinkwrap = JSON.parse(data)
child.package._shrinkwrap = parseJSON(data)
} catch (ex) {
child.package._shrinkwrap = null
return next(ex)
Expand Down
3 changes: 2 additions & 1 deletion lib/install/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var validate = require('aproba')
var without = require('lodash.without')
var npm = require('../npm.js')
var deepSortObject = require('../utils/deep-sort-object.js')
var parseJSON = require('../utils/parse-json.js')

// if the -S|--save option is specified, then write installed packages
// as dependencies to a package.json file.
Expand Down Expand Up @@ -62,7 +63,7 @@ function savePackageJson (args, tree, next) {
// tricky npm-specific stuff that's in there.
fs.readFile(saveTarget, iferr(next, function (packagejson) {
try {
packagejson = JSON.parse(packagejson.toString('utf8'))
packagejson = parseJSON(packagejson)
} catch (ex) {
return next(ex)
}
Expand Down
3 changes: 2 additions & 1 deletion lib/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
var abbrev = require('abbrev')
var which = require('which')
var CachingRegClient = require('./cache/caching-client.js')
var parseJSON = require('./utils/parse-json.js')

npm.config = {
loaded: false,
Expand All @@ -43,7 +44,7 @@

try {
// startup, ok to do this synchronously
var j = JSON.parse(fs.readFileSync(
var j = parseJSON(fs.readFileSync(
path.join(__dirname, '../package.json')) + '')
npm.version = j.version
} catch (ex) {
Expand Down
24 changes: 24 additions & 0 deletions lib/utils/parse-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'
var parseJSON = module.exports = function (content) {
return JSON.parse(stripBOM(content))
}

parseJSON.noExceptions = function (content) {
try {
return parseJSON(content)
} catch (ex) {
return
}
}

// from read-package-json
function stripBOM (content) {
content = content.toString()
// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
// because the buffer-to-string conversion in `fs.readFileSync()`
// translates it to FEFF, the UTF-16 BOM.
if (content.charCodeAt(0) === 0xFEFF) {
content = content.slice(1)
}
return content
}
5 changes: 3 additions & 2 deletions lib/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var npm = require('./npm.js')
var git = require('./utils/git.js')
var assert = require('assert')
var lifecycle = require('./utils/lifecycle.js')
var parseJSON = require('./utils/parse-json.js')

version.usage = 'npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease]' +
'\n(run in package dir)\n' +
Expand All @@ -32,7 +33,7 @@ function version (args, silent, cb_) {
fs.readFile(packagePath, function (er, data) {
if (data) data = data.toString()
try {
data = JSON.parse(data)
data = parseJSON(data)
} catch (e) {
er = e
data = null
Expand Down Expand Up @@ -107,7 +108,7 @@ function updateShrinkwrap (newVersion, cb) {

try {
data = data.toString()
data = JSON.parse(data)
data = parseJSON(data)
} catch (er) {
log.error('version', 'Bad npm-shrinkwrap.json data')
return cb(er)
Expand Down

0 comments on commit 28064e5

Please sign in to comment.