set.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. var staticParseInt = require('./staticParseInt')
  2. var helperGetHGSKeys = require('./helperGetHGSKeys')
  3. var hasOwnProp = require('./hasOwnProp')
  4. var sKeyRE = /(.+)\[(\d+)\]$/
  5. function setDeepProps (obj, key, isSet, value) {
  6. if (obj[key]) {
  7. if (isSet) {
  8. obj[key] = value
  9. }
  10. } else {
  11. var index
  12. var matchs = key ? key.match(sKeyRE) : null
  13. var rest = isSet ? value : {}
  14. if (matchs) {
  15. index = staticParseInt(matchs[2])
  16. if (obj[matchs[1]]) {
  17. obj[matchs[1]][index] = rest
  18. } else {
  19. obj[matchs[1]] = new Array(index + 1)
  20. obj[matchs[1]][index] = rest
  21. }
  22. } else {
  23. obj[key] = rest
  24. }
  25. return rest
  26. }
  27. return obj[key]
  28. }
  29. /**
  30. * 设置对象属性上的值。如果属性不存在则创建它
  31. * @param {Object/Array} obj 对象
  32. * @param {String/Function} property 键、路径
  33. * @param {Object} value 值
  34. */
  35. function set (obj, property, value) {
  36. if (obj) {
  37. if ((obj[property] || hasOwnProp(obj, property)) && !isPrototypePolluted(property)) {
  38. obj[property] = value
  39. } else {
  40. var rest = obj
  41. var props = helperGetHGSKeys(property)
  42. var len = props.length
  43. for (var index = 0; index < len; index++) {
  44. if (isPrototypePolluted(props[index])) continue
  45. rest = setDeepProps(rest, props[index], index === len - 1, value)
  46. }
  47. }
  48. }
  49. return obj
  50. }
  51. /**
  52. * Blacklist certain keys to prevent Prototype Pollution
  53. * @param {string} key
  54. */
  55. function isPrototypePolluted(key) {
  56. return key === '__proto__' || key === 'constructor' || key === 'prototype'
  57. }
  58. module.exports = set