VYPR
Moderate severityNVD Advisory· Published Nov 3, 2021· Updated Sep 16, 2024

Prototype Pollution

CVE-2021-23624

Description

A type confusion flaw in dotty before 0.1.2 allows prototype pollution via array keys, bypassing a previous fix.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A type confusion flaw in dotty before 0.1.2 allows prototype pollution via array keys, bypassing a previous fix.

Vulnerability

The package dotty before version 0.1.2 contains a type confusion vulnerability that can lead to prototype pollution. The issue specifically arises when user-provided keys used in the path parameter are arrays. Prior to the fix, the put function did not coerce array elements to strings, allowing the insertion of special keys like __proto__ and bypassing the protection added for CVE-2021-25912. The vulnerable versions are all releases before 0.1.2. [1][2]

Exploitation

An attacker can exploit this vulnerability by providing a path argument that is an array containing a key like __proto__ (or constructor, prototype) as an element. When dotty.put is called with such an array, the type confusion prevents the existing __proto__ check from triggering, enabling the attacker to overwrite Object.prototype properties. No special network position or authentication is required beyond the ability to pass crafted input to a function that uses dotty. [2][3]

Impact

Successful exploitation results in prototype pollution, where properties are injected into the base Object.prototype. This can lead to denial of service via exceptions, or in certain application contexts, remote code execution if the polluted properties influence security decisions or code paths. The attacker can effectively tamper with all objects in the JavaScript runtime. [3]

Mitigation

Version 0.1.2 fixes the issue by converting array path elements to strings with "" + path.shift(), ensuring that special keys like __proto__ are correctly detected and blocked. Users should upgrade to dotty 0.1.2 or later. No workaround is provided for older versions. The fix commit is at GitHub [2]. The vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog as of this writing. [2]

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
dottynpm
< 0.1.20.1.2

Affected products

2

Patches

1
88f61860dcc2

Address different method of prototype pollution (#32)

https://github.com/deoxxa/dottyMichael StramelOct 26, 2021via ghsa
12 files changed · +241 191
  • docs/docco.css+6 6 modified
    @@ -213,7 +213,7 @@ ul.sections > li > div {
     
     /*---------------------- Low resolutions (> 320px) ---------------------*/
     @media only screen and (min-width: 320px) {
    -  .pilwrap { display: none; }
    +  .sswrap { display: none; }
     
       ul.sections > li > div {
         display: block;
    @@ -330,12 +330,12 @@ ul.sections > li > div {
         box-shadow: none;
       }
     
    -  .pilwrap {
    +  .sswrap {
         position: relative;
         display: inline;
       }
     
    -  .pilcrow {
    +  .ss {
         font: 12px Arial;
         text-decoration: none;
         color: #454545;
    @@ -345,14 +345,14 @@ ul.sections > li > div {
         opacity: 0;
         -webkit-transition: opacity 0.2s linear;
       }
    -    .for-h1 .pilcrow {
    +    .for-h1 .ss {
           top: 47px;
         }
    -    .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow {
    +    .for-h2 .ss, .for-h3 .ss, .for-h4 .ss {
           top: 35px;
         }
     
    -  ul.sections > li > div.annotation:hover .pilcrow {
    +  ul.sections > li > div.annotation:hover .ss {
         opacity: 1;
       }
     }
    
  • docs/lib/index.html+97 97 modified
    @@ -24,8 +24,8 @@ <h1>index.js</h1>
             <li id="section-1">
                 <div class="annotation">
                   
    -              <div class="pilwrap ">
    -                <a class="pilcrow" href="#section-1">&#182;</a>
    +              <div class="sswrap ">
    +                <a class="ss" href="#section-1">&#x00a7;</a>
                   </div>
                   <p>Dotty makes it easy to programmatically access arbitrarily nested objects and
     their properties.</p>
    @@ -38,8 +38,8 @@ <h1>index.js</h1>
             <li id="section-2">
                 <div class="annotation">
                   
    -              <div class="pilwrap ">
    -                <a class="pilcrow" href="#section-2">&#182;</a>
    +              <div class="sswrap ">
    +                <a class="ss" href="#section-2">&#x00a7;</a>
                   </div>
                   <p><code>object</code> is an object, <code>path</code> is the path to the property you want to check
     for existence of.</p>
    @@ -50,27 +50,27 @@ <h1>index.js</h1>
                 </div>
                 
                 <div class="content"><div class='highlight'><pre>
    -<span class="hljs-keyword">var</span> exists = (<span class="hljs-built_in">module</span>.exports.exists = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">exists</span>(<span class="hljs-params">object, path</span>) </span>{
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">"string"</span>) {
    -    path = path.split(<span class="hljs-string">"."</span>);
    +<span class="hljs-keyword">var</span> exists = (<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>.<span class="hljs-property">exists</span> = <span class="hljs-keyword">function</span> <span class="hljs-title function_">exists</span>(<span class="hljs-params">object, path</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">&quot;string&quot;</span>) {
    +    path = path.<span class="hljs-title function_">split</span>(<span class="hljs-string">&quot;.&quot;</span>);
       }
     
    -  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>) || path.length === <span class="hljs-number">0</span>) {
    +  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Array</span>) || path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
         <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
       }
     
    -  path = path.slice();
    +  path = path.<span class="hljs-title function_">slice</span>();
     
    -  <span class="hljs-keyword">var</span> key = path.shift();
    +  <span class="hljs-keyword">var</span> key = path.<span class="hljs-title function_">shift</span>();
     
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">"object"</span> || object === <span class="hljs-literal">null</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">&quot;object&quot;</span> || object === <span class="hljs-literal">null</span>) {
         <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
       }
     
    -  <span class="hljs-keyword">if</span> (path.length === <span class="hljs-number">0</span>) {
    -    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.hasOwnProperty.apply(object, [key]);
    +  <span class="hljs-keyword">if</span> (path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
    +    <span class="hljs-keyword">return</span> <span class="hljs-title class_">Object</span>.<span class="hljs-property">hasOwnProperty</span>.<span class="hljs-title function_">apply</span>(object, [key]);
       } <span class="hljs-keyword">else</span> {
    -    <span class="hljs-keyword">return</span> exists(object[key], path);
    +    <span class="hljs-keyword">return</span> <span class="hljs-title function_">exists</span>(object[key], path);
       }
     });</pre></div></div>
                 
    @@ -80,8 +80,8 @@ <h1>index.js</h1>
             <li id="section-3">
                 <div class="annotation">
                   
    -              <div class="pilwrap ">
    -                <a class="pilcrow" href="#section-3">&#182;</a>
    +              <div class="sswrap ">
    +                <a class="ss" href="#section-3">&#x00a7;</a>
                   </div>
                   <p>These arguments are the same as those for <code>exists</code>.</p>
     <p>The return value, however, is the property you’re trying to access, or
    @@ -93,29 +93,29 @@ <h1>index.js</h1>
                 </div>
                 
                 <div class="content"><div class='highlight'><pre>
    -<span class="hljs-keyword">var</span> get = (<span class="hljs-built_in">module</span>.exports.get = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get</span>(<span class="hljs-params">object, path</span>) </span>{
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">"string"</span>) {
    -    path = path.split(<span class="hljs-string">"."</span>);
    +<span class="hljs-keyword">var</span> get = (<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>.<span class="hljs-property">get</span> = <span class="hljs-keyword">function</span> <span class="hljs-title function_">get</span>(<span class="hljs-params">object, path</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">&quot;string&quot;</span>) {
    +    path = path.<span class="hljs-title function_">split</span>(<span class="hljs-string">&quot;.&quot;</span>);
       }
     
    -  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>) || path.length === <span class="hljs-number">0</span>) {
    +  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Array</span>) || path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
         <span class="hljs-keyword">return</span>;
       }
     
    -  path = path.slice();
    +  path = path.<span class="hljs-title function_">slice</span>();
     
    -  <span class="hljs-keyword">var</span> key = path.shift();
    +  <span class="hljs-keyword">var</span> key = path.<span class="hljs-title function_">shift</span>();
     
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">"object"</span> || object === <span class="hljs-literal">null</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">&quot;object&quot;</span> || object === <span class="hljs-literal">null</span>) {
         <span class="hljs-keyword">return</span>;
       }
     
    -  <span class="hljs-keyword">if</span> (path.length === <span class="hljs-number">0</span>) {
    +  <span class="hljs-keyword">if</span> (path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
         <span class="hljs-keyword">return</span> object[key];
       }
     
    -  <span class="hljs-keyword">if</span> (path.length) {
    -    <span class="hljs-keyword">return</span> get(object[key], path);
    +  <span class="hljs-keyword">if</span> (path.<span class="hljs-property">length</span>) {
    +    <span class="hljs-keyword">return</span> <span class="hljs-title function_">get</span>(object[key], path);
       }
     });</pre></div></div>
                 
    @@ -125,8 +125,8 @@ <h1>index.js</h1>
             <li id="section-4">
                 <div class="annotation">
                   
    -              <div class="pilwrap ">
    -                <a class="pilcrow" href="#section-4">&#182;</a>
    +              <div class="sswrap ">
    +                <a class="ss" href="#section-4">&#x00a7;</a>
                   </div>
                   <p>Arguments are similar to <code>exists</code> and <code>get</code>, with the exception that path
     components are regexes with some special cases. If a path component is <code>&quot;*&quot;</code>
    @@ -139,48 +139,48 @@ <h1>index.js</h1>
                 </div>
                 
                 <div class="content"><div class='highlight'><pre>
    -<span class="hljs-keyword">var</span> search = (<span class="hljs-built_in">module</span>.exports.search = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">search</span>(<span class="hljs-params">object, path, action</span>) </span>{
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">"string"</span>) {
    -    path = path.split(<span class="hljs-string">"."</span>);
    +<span class="hljs-keyword">var</span> search = (<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>.<span class="hljs-property">search</span> = <span class="hljs-keyword">function</span> <span class="hljs-title function_">search</span>(<span class="hljs-params">object, path, action</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">&quot;string&quot;</span>) {
    +    path = path.<span class="hljs-title function_">split</span>(<span class="hljs-string">&quot;.&quot;</span>);
       }
     
    -  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>) || path.length === <span class="hljs-number">0</span>) {
    +  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Array</span>) || path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
         <span class="hljs-keyword">return</span>;
       }
     
    -  path = path.slice();
    +  path = path.<span class="hljs-title function_">slice</span>();
     
    -  <span class="hljs-keyword">var</span> key = path.shift();
    +  <span class="hljs-keyword">var</span> key = path.<span class="hljs-title function_">shift</span>();
     
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">"object"</span> || object === <span class="hljs-literal">null</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">&quot;object&quot;</span> || object === <span class="hljs-literal">null</span>) {
         <span class="hljs-keyword">return</span>;
       }
     
    -  <span class="hljs-keyword">if</span> (key === <span class="hljs-string">"*"</span>) {
    -    key = <span class="hljs-string">".*"</span>;
    +  <span class="hljs-keyword">if</span> (key === <span class="hljs-string">&quot;*&quot;</span>) {
    +    key = <span class="hljs-string">&quot;.*&quot;</span>;
       }
     
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> key === <span class="hljs-string">"string"</span>) {
    -    key = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(key);
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> key === <span class="hljs-string">&quot;string&quot;</span>) {
    +    key = <span class="hljs-keyword">new</span> <span class="hljs-title class_">RegExp</span>(key);
       }
     
    -  <span class="hljs-keyword">if</span> (path.length === <span class="hljs-number">0</span>) {
    -    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.keys(object)
    -      .filter(key.test.bind(key))
    -      .map(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">k</span>) </span>{
    +  <span class="hljs-keyword">if</span> (path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
    +    <span class="hljs-keyword">return</span> <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(object)
    +      .<span class="hljs-title function_">filter</span>(key.<span class="hljs-property">test</span>.<span class="hljs-title function_">bind</span>(key))
    +      .<span class="hljs-title function_">map</span>(<span class="hljs-keyword">function</span> (<span class="hljs-params">k</span>) {
             <span class="hljs-keyword">var</span> value = object[k];
             <span class="hljs-keyword">if</span> (action) {
    -          action(value, object, k);
    +          <span class="hljs-title function_">action</span>(value, object, k);
             }
             <span class="hljs-keyword">return</span> value;
           });
       } <span class="hljs-keyword">else</span> {
    -    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Array</span>.prototype.concat.apply(
    +    <span class="hljs-keyword">return</span> <span class="hljs-title class_">Array</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">concat</span>.<span class="hljs-title function_">apply</span>(
           [],
    -      <span class="hljs-built_in">Object</span>.keys(object)
    -        .filter(key.test.bind(key))
    -        .map(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">k</span>) </span>{
    -          <span class="hljs-keyword">return</span> search(object[k], path, action);
    +      <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(object)
    +        .<span class="hljs-title function_">filter</span>(key.<span class="hljs-property">test</span>.<span class="hljs-title function_">bind</span>(key))
    +        .<span class="hljs-title function_">map</span>(<span class="hljs-keyword">function</span> (<span class="hljs-params">k</span>) {
    +          <span class="hljs-keyword">return</span> <span class="hljs-title function_">search</span>(object[k], path, action);
             })
         );
       }
    @@ -192,20 +192,20 @@ <h1>index.js</h1>
             <li id="section-5">
                 <div class="annotation">
                   
    -              <div class="pilwrap ">
    -                <a class="pilcrow" href="#section-5">&#182;</a>
    +              <div class="sswrap ">
    +                <a class="ss" href="#section-5">&#x00a7;</a>
                   </div>
                   <p>Perform a search and remove the matched keys.
     The return value is the same object argument with modifications.</p>
     
                 </div>
                 
                 <div class="content"><div class='highlight'><pre>
    -<span class="hljs-keyword">var</span> removeSearch = (<span class="hljs-built_in">module</span>.exports.removeSearch = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">removeSearch</span>(<span class="hljs-params">
    +<span class="hljs-keyword">var</span> removeSearch = (<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>.<span class="hljs-property">removeSearch</span> = <span class="hljs-keyword">function</span> <span class="hljs-title function_">removeSearch</span>(<span class="hljs-params">
       object,
       path
    -</span>) </span>{
    -  search(object, path, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">value, object, key</span>) </span>{
    +</span>) {
    +  <span class="hljs-title function_">search</span>(object, path, <span class="hljs-keyword">function</span> (<span class="hljs-params">value, object, key</span>) {
         <span class="hljs-keyword">delete</span> object[key];
       });
       <span class="hljs-keyword">return</span> object;
    @@ -217,8 +217,8 @@ <h1>index.js</h1>
             <li id="section-6">
                 <div class="annotation">
                   
    -              <div class="pilwrap ">
    -                <a class="pilcrow" href="#section-6">&#182;</a>
    +              <div class="sswrap ">
    +                <a class="ss" href="#section-6">&#x00a7;</a>
                   </div>
                   <p>The first two arguments for <code>put</code> are the same as <code>exists</code> and <code>get</code>.</p>
     <p>The third argument is a value to <code>put</code> at the <code>path</code> of the <code>object</code>.
    @@ -231,34 +231,34 @@ <h1>index.js</h1>
                 </div>
                 
                 <div class="content"><div class='highlight'><pre>
    -<span class="hljs-keyword">var</span> put = (<span class="hljs-built_in">module</span>.exports.put = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">put</span>(<span class="hljs-params">object, path, value</span>) </span>{
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">"string"</span>) {
    -    path = path.split(<span class="hljs-string">"."</span>);
    +<span class="hljs-keyword">var</span> put = (<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>.<span class="hljs-property">put</span> = <span class="hljs-keyword">function</span> <span class="hljs-title function_">put</span>(<span class="hljs-params">object, path, value</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">&quot;string&quot;</span>) {
    +    path = path.<span class="hljs-title function_">split</span>(<span class="hljs-string">&quot;.&quot;</span>);
       }
     
    -  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>) || path.length === <span class="hljs-number">0</span>) {
    +  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Array</span>) || path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
         <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
       }
     
    -  path = path.slice();
    +  path = path.<span class="hljs-title function_">slice</span>();
     
    -  <span class="hljs-keyword">var</span> key = path.shift();
    +  <span class="hljs-keyword">var</span> key = <span class="hljs-string">&quot;&quot;</span> + path.<span class="hljs-title function_">shift</span>();
     
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">"object"</span> || object === <span class="hljs-literal">null</span> || key === <span class="hljs-string">"__proto__"</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">&quot;object&quot;</span> || object === <span class="hljs-literal">null</span> || key === <span class="hljs-string">&quot;__proto__&quot;</span>) {
         <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
       }
    -  <span class="hljs-keyword">if</span> (path.length === <span class="hljs-number">0</span>) {
    +  <span class="hljs-keyword">if</span> (path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
         object[key] = value;
       } <span class="hljs-keyword">else</span> {
    -    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object[key] === <span class="hljs-string">"undefined"</span>) {
    +    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object[key] === <span class="hljs-string">&quot;undefined&quot;</span>) {
           object[key] = {};
         }
     
    -    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object[key] !== <span class="hljs-string">"object"</span> || object[key] === <span class="hljs-literal">null</span>) {
    +    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object[key] !== <span class="hljs-string">&quot;object&quot;</span> || object[key] === <span class="hljs-literal">null</span>) {
           <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
         }
     
    -    <span class="hljs-keyword">return</span> put(object[key], path, value);
    +    <span class="hljs-keyword">return</span> <span class="hljs-title function_">put</span>(object[key], path, value);
       }
     });</pre></div></div>
                 
    @@ -268,8 +268,8 @@ <h1>index.js</h1>
             <li id="section-7">
                 <div class="annotation">
                   
    -              <div class="pilwrap ">
    -                <a class="pilcrow" href="#section-7">&#182;</a>
    +              <div class="sswrap ">
    +                <a class="ss" href="#section-7">&#x00a7;</a>
                   </div>
                   <p><code>remove</code> is like <code>put</code> in reverse!</p>
     <p>The return value is <code>true</code> in the case that the value existed and was removed
    @@ -278,33 +278,33 @@ <h1>index.js</h1>
                 </div>
                 
                 <div class="content"><div class='highlight'><pre>
    -<span class="hljs-keyword">var</span> remove = (<span class="hljs-built_in">module</span>.exports.remove = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">remove</span>(<span class="hljs-params">object, path, value</span>) </span>{
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">"string"</span>) {
    -    path = path.split(<span class="hljs-string">"."</span>);
    +<span class="hljs-keyword">var</span> remove = (<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>.<span class="hljs-property">remove</span> = <span class="hljs-keyword">function</span> <span class="hljs-title function_">remove</span>(<span class="hljs-params">object, path, value</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> path === <span class="hljs-string">&quot;string&quot;</span>) {
    +    path = path.<span class="hljs-title function_">split</span>(<span class="hljs-string">&quot;.&quot;</span>);
       }
     
    -  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>) || path.length === <span class="hljs-number">0</span>) {
    +  <span class="hljs-keyword">if</span> (!(path <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Array</span>) || path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
         <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
       }
     
    -  path = path.slice();
    +  path = path.<span class="hljs-title function_">slice</span>();
     
    -  <span class="hljs-keyword">var</span> key = path.shift();
    +  <span class="hljs-keyword">var</span> key = path.<span class="hljs-title function_">shift</span>();
     
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">"object"</span> || object === <span class="hljs-literal">null</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object !== <span class="hljs-string">&quot;object&quot;</span> || object === <span class="hljs-literal">null</span>) {
         <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
       }
     
    -  <span class="hljs-keyword">if</span> (path.length === <span class="hljs-number">0</span>) {
    -    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">Object</span>.hasOwnProperty.call(object, key)) {
    +  <span class="hljs-keyword">if</span> (path.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
    +    <span class="hljs-keyword">if</span> (!<span class="hljs-title class_">Object</span>.<span class="hljs-property">hasOwnProperty</span>.<span class="hljs-title function_">call</span>(object, key)) {
           <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
         }
     
         <span class="hljs-keyword">delete</span> object[key];
     
         <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
       } <span class="hljs-keyword">else</span> {
    -    <span class="hljs-keyword">return</span> remove(object[key], path, value);
    +    <span class="hljs-keyword">return</span> <span class="hljs-title function_">remove</span>(object[key], path, value);
       }
     });</pre></div></div>
                 
    @@ -314,57 +314,57 @@ <h1>index.js</h1>
             <li id="section-8">
                 <div class="annotation">
                   
    -              <div class="pilwrap ">
    -                <a class="pilcrow" href="#section-8">&#182;</a>
    +              <div class="sswrap ">
    +                <a class="ss" href="#section-8">&#x00a7;</a>
                   </div>
                   <p><code>deepKeys</code> creates a list of all possible key paths for a given object.</p>
     <p>The return value is always an array, the members of which are paths in array
     format. If you want them in dot-notation format, do something like this:</p>
    -<pre><code class="lang-js">dotty.deepKeys(obj).map(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
    -  <span class="hljs-keyword">return</span> e.join(<span class="hljs-string">"."</span>);
    +<pre><code class="language-js">dotty.<span class="hljs-title function_">deepKeys</span>(obj).<span class="hljs-title function_">map</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) {
    +  <span class="hljs-keyword">return</span> e.<span class="hljs-title function_">join</span>(<span class="hljs-string">&quot;.&quot;</span>);
     });
     </code></pre>
     <p><em>Note: this will probably explode on recursive objects. Be careful.</em></p>
     
                 </div>
                 
                 <div class="content"><div class='highlight'><pre>
    -<span class="hljs-keyword">var</span> deepKeys = (<span class="hljs-built_in">module</span>.exports.deepKeys = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">deepKeys</span>(<span class="hljs-params">
    +<span class="hljs-keyword">var</span> deepKeys = (<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>.<span class="hljs-property">deepKeys</span> = <span class="hljs-keyword">function</span> <span class="hljs-title function_">deepKeys</span>(<span class="hljs-params">
       object,
       options,
       prefix
    -</span>) </span>{
    +</span>) {
       options = options || {};
     
    -  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> prefix === <span class="hljs-string">"undefined"</span>) {
    +  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> prefix === <span class="hljs-string">&quot;undefined&quot;</span>) {
         prefix = [];
       }
     
       <span class="hljs-keyword">var</span> keys = [];
     
       <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> k <span class="hljs-keyword">in</span> object) {
    -    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">Object</span>.hasOwnProperty.call(object, k)) {
    +    <span class="hljs-keyword">if</span> (!<span class="hljs-title class_">Object</span>.<span class="hljs-property">hasOwnProperty</span>.<span class="hljs-title function_">call</span>(object, k)) {
           <span class="hljs-keyword">continue</span>;
         }
     
    -    <span class="hljs-keyword">if</span> (!options.leavesOnly || <span class="hljs-keyword">typeof</span> object[k] !== <span class="hljs-string">"object"</span>) {
    -      keys.push(prefix.concat([k]));
    +    <span class="hljs-keyword">if</span> (!options.<span class="hljs-property">leavesOnly</span> || <span class="hljs-keyword">typeof</span> object[k] !== <span class="hljs-string">&quot;object&quot;</span>) {
    +      keys.<span class="hljs-title function_">push</span>(prefix.<span class="hljs-title function_">concat</span>([k]));
         }
     
    -    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object[k] === <span class="hljs-string">"object"</span> &amp;&amp; object[k] !== <span class="hljs-literal">null</span>) {
    -      keys = keys.concat(
    -        deepKeys(
    +    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object[k] === <span class="hljs-string">&quot;object&quot;</span> &amp;&amp; object[k] !== <span class="hljs-literal">null</span>) {
    +      keys = keys.<span class="hljs-title function_">concat</span>(
    +        <span class="hljs-title function_">deepKeys</span>(
               object[k],
    -          { <span class="hljs-attr">leavesOnly</span>: options.leavesOnly },
    -          prefix.concat([k])
    +          { <span class="hljs-attr">leavesOnly</span>: options.<span class="hljs-property">leavesOnly</span> },
    +          prefix.<span class="hljs-title function_">concat</span>([k])
             )
           );
         }
       }
     
    -  <span class="hljs-keyword">if</span> (options.asStrings) {
    -    keys = keys.map(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">e</span>) </span>{
    -      <span class="hljs-keyword">return</span> e.join(<span class="hljs-string">"."</span>);
    +  <span class="hljs-keyword">if</span> (options.<span class="hljs-property">asStrings</span>) {
    +    keys = keys.<span class="hljs-title function_">map</span>(<span class="hljs-keyword">function</span> (<span class="hljs-params">e</span>) {
    +      <span class="hljs-keyword">return</span> e.<span class="hljs-title function_">join</span>(<span class="hljs-string">&quot;.&quot;</span>);
         });
       }
     
    
  • docs/public/fonts/roboto-black.eot+0 0 modified
  • docs/public/fonts/roboto-black.ttf+0 0 modified
  • docs/public/fonts/roboto-black.woff+0 0 modified
  • .DS_Store+0 0 removed
  • .github/workflows/main.yml+2 3 modified
    @@ -5,17 +5,16 @@ on:
         branches:
           - main
           - master
    -
     jobs:
       build:
         runs-on: ubuntu-latest
         strategy:
           matrix:
    -        node-version: [6.x, 8.x]
    +        node-version: [10.x, 12.x, 14.x, 16.x]
         steps:
           - uses: actions/checkout@v2
           - name: Use Node.js ${{ matrix.node-version }}
    -        uses: actions/setup-node@v1
    +        uses: actions/setup-node@v2
             with:
               node-version: ${{ matrix.node-version }}
           - run: npm install
    
  • lib/index.js+3 1 modified
    @@ -170,7 +170,7 @@ var put = (module.exports.put = function put(object, path, value) {
     
       path = path.slice();
     
    -  var key = path.shift();
    +  var key = "" + path.shift();
     
       if (typeof object !== "object" || object === null || key === "__proto__") {
         return false;
    @@ -188,6 +188,8 @@ var put = (module.exports.put = function put(object, path, value) {
     
         return put(object[key], path, value);
       }
    +
    +  return true;
     });
     
     //
    
  • package.json+2 2 modified
    @@ -21,7 +21,7 @@
       "author": "Conrad Pankoff <deoxxa@fknsrs.biz> (http://www.fknsrs.biz/)",
       "license": "BSD-3-Clause",
       "devDependencies": {
    -    "vows": "^0.8.0",
    -    "docco": "^0.8.0"
    +    "vows": "^0.8.3",
    +    "docco": "^0.8.1"
       }
     }
    
  • package-lock.json+96 79 modified
    @@ -4,22 +4,44 @@
       "lockfileVersion": 1,
       "requires": true,
       "dependencies": {
    +    "balanced-match": {
    +      "version": "1.0.2",
    +      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
    +      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
    +      "dev": true
    +    },
    +    "brace-expansion": {
    +      "version": "1.1.11",
    +      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
    +      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
    +      "dev": true,
    +      "requires": {
    +        "balanced-match": "^1.0.0",
    +        "concat-map": "0.0.1"
    +      }
    +    },
         "commander": {
    -      "version": "2.14.1",
    -      "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
    -      "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==",
    +      "version": "8.3.0",
    +      "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
    +      "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
    +      "dev": true
    +    },
    +    "concat-map": {
    +      "version": "0.0.1",
    +      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
    +      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
           "dev": true
         },
         "diff": {
    -      "version": "1.0.8",
    -      "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.8.tgz",
    -      "integrity": "sha1-NDJ2MI7Jkbe8giZ+1VvBQR+XFmY=",
    +      "version": "4.0.2",
    +      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
    +      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
           "dev": true
         },
         "docco": {
    -      "version": "0.8.0",
    -      "resolved": "https://registry.npmjs.org/docco/-/docco-0.8.0.tgz",
    -      "integrity": "sha512-QcWBDnnGaT+rgC0wqynznXv0/4hd6nAFdWNs2fN4FvkH2yAnCYVeRU7GIZXNCeUQ955Lufq+TmZcSXiBa1cGQQ==",
    +      "version": "0.8.1",
    +      "resolved": "https://registry.npmjs.org/docco/-/docco-0.8.1.tgz",
    +      "integrity": "sha512-OFVdjpxw4aTI+FThrCY2NEWZV/nvGDFlfeQxUTMkKL+oY2gD2sMl0N5ogoAj3YLZU05UDBSh64ROYzLFzxSoSQ==",
           "dev": true,
           "requires": {
             "commander": ">= 0.5.2",
    @@ -36,94 +58,89 @@
           "dev": true
         },
         "fs-extra": {
    -      "version": "5.0.0",
    -      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
    -      "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
    +      "version": "10.0.0",
    +      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
    +      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
           "dev": true,
           "requires": {
    -        "graceful-fs": "^4.1.2",
    -        "jsonfile": "^4.0.0",
    -        "universalify": "^0.1.0"
    +        "graceful-fs": "^4.2.0",
    +        "jsonfile": "^6.0.1",
    +        "universalify": "^2.0.0"
           }
         },
    +    "fs.realpath": {
    +      "version": "1.0.0",
    +      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
    +      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
    +      "dev": true
    +    },
         "glob": {
    -      "version": "4.0.6",
    -      "resolved": "https://registry.npmjs.org/glob/-/glob-4.0.6.tgz",
    -      "integrity": "sha1-aVxQvdTi+1xdNwsJHziNNwfikac=",
    +      "version": "7.2.0",
    +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
    +      "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
           "dev": true,
           "requires": {
    -        "graceful-fs": "^3.0.2",
    +        "fs.realpath": "^1.0.0",
    +        "inflight": "^1.0.4",
             "inherits": "2",
    -        "minimatch": "^1.0.0",
    -        "once": "^1.3.0"
    -      },
    -      "dependencies": {
    -        "graceful-fs": {
    -          "version": "3.0.11",
    -          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
    -          "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=",
    -          "dev": true,
    -          "requires": {
    -            "natives": "^1.1.0"
    -          }
    -        }
    +        "minimatch": "^3.0.4",
    +        "once": "^1.3.0",
    +        "path-is-absolute": "^1.0.0"
           }
         },
         "graceful-fs": {
    -      "version": "4.1.11",
    -      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
    -      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
    +      "version": "4.2.8",
    +      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
    +      "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
           "dev": true
         },
         "highlight.js": {
    -      "version": "10.5.0",
    -      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.5.0.tgz",
    -      "integrity": "sha512-xTmvd9HiIHR6L53TMC7TKolEj65zG1XU+Onr8oi86mYa+nLcIbxTTWkpW7CsEwv/vK7u1zb8alZIMLDqqN6KTw==",
    +      "version": "11.3.1",
    +      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.3.1.tgz",
    +      "integrity": "sha512-PUhCRnPjLtiLHZAQ5A/Dt5F8cWZeMyj9KRsACsWT+OD6OP0x6dp5OmT5jdx0JgEyPxPZZIPQpRN2TciUT7occw==",
           "dev": true
         },
    +    "inflight": {
    +      "version": "1.0.6",
    +      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
    +      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
    +      "dev": true,
    +      "requires": {
    +        "once": "^1.3.0",
    +        "wrappy": "1"
    +      }
    +    },
         "inherits": {
    -      "version": "2.0.3",
    -      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
    -      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
    +      "version": "2.0.4",
    +      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
    +      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
           "dev": true
         },
         "jsonfile": {
    -      "version": "4.0.0",
    -      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
    -      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
    +      "version": "6.1.0",
    +      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
    +      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
           "dev": true,
           "requires": {
    -        "graceful-fs": "^4.1.6"
    +        "graceful-fs": "^4.1.6",
    +        "universalify": "^2.0.0"
           }
         },
    -    "lru-cache": {
    -      "version": "2.7.3",
    -      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
    -      "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
    -      "dev": true
    -    },
         "marked": {
    -      "version": "1.2.7",
    -      "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.7.tgz",
    -      "integrity": "sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA==",
    +      "version": "3.0.8",
    +      "resolved": "https://registry.npmjs.org/marked/-/marked-3.0.8.tgz",
    +      "integrity": "sha512-0gVrAjo5m0VZSJb4rpL59K1unJAMb/hm8HRXqasD8VeC8m91ytDPMritgFSlKonfdt+rRYYpP/JfLxgIX8yoSw==",
           "dev": true
         },
         "minimatch": {
    -      "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz",
    -      "integrity": "sha1-4N0hILSeG3JM6NcUxSCCKpQ4V20=",
    +      "version": "3.0.4",
    +      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
    +      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
           "dev": true,
           "requires": {
    -        "lru-cache": "2",
    -        "sigmund": "~1.0.0"
    +        "brace-expansion": "^1.1.7"
           }
         },
    -    "natives": {
    -      "version": "1.1.1",
    -      "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.1.tgz",
    -      "integrity": "sha512-8eRaxn8u/4wN8tGkhlc2cgwwvOLMLUMUn4IYTexMgWd+LyUDfeXVkk2ygQR0hvIHbJQXgHujia3ieUUDwNGkEA==",
    -      "dev": true
    -    },
         "once": {
           "version": "1.4.0",
           "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
    @@ -133,33 +150,33 @@
             "wrappy": "1"
           }
         },
    -    "sigmund": {
    +    "path-is-absolute": {
           "version": "1.0.1",
    -      "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
    -      "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
    +      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
    +      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
           "dev": true
         },
         "underscore": {
    -      "version": "1.8.3",
    -      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
    -      "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=",
    +      "version": "1.13.1",
    +      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
    +      "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
           "dev": true
         },
         "universalify": {
    -      "version": "0.1.1",
    -      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
    -      "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=",
    +      "version": "2.0.0",
    +      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
    +      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
           "dev": true
         },
         "vows": {
    -      "version": "0.8.1",
    -      "resolved": "https://registry.npmjs.org/vows/-/vows-0.8.1.tgz",
    -      "integrity": "sha1-4J6YjOWUygWgjXKrzKNOiNtVkTE=",
    +      "version": "0.8.3",
    +      "resolved": "https://registry.npmjs.org/vows/-/vows-0.8.3.tgz",
    +      "integrity": "sha512-PVIxa/ovXhrw5gA3mz6M+ZF3PHlqX4tutR2p/y9NWPAaFVKcWBE8b2ktfr0opQM/qFmcOVWKjSCJVjnYOvjXhw==",
           "dev": true,
           "requires": {
    -        "diff": "~1.0.8",
    +        "diff": "^4.0.1",
             "eyes": "~0.1.6",
    -        "glob": "~4.0.6"
    +        "glob": "^7.1.2"
           }
         },
         "wrappy": {
    
  • test/put-test.js+9 0 modified
    @@ -26,6 +26,15 @@ vows
               assert.equal(res.a, "b");
             },
           },
    +      "returns true": {
    +        topic: (function () {
    +          var res = dotty.put({}, ["a"], "b");
    +          return res;
    +        })(),
    +        "should set the correct value": function (res) {
    +          assert.equal(res, true);
    +        },
    +      },
         },
         "A two-level path": {
           "as a string": {
    
  • test/security-test.js+26 3 modified
    @@ -1,4 +1,4 @@
    -var dotty = require("../lib/index"),
    +const dotty = require("../lib/index"),
       vows = require("vows"),
       assert = require("assert");
     
    @@ -7,17 +7,40 @@ vows
       .addBatch({
         "When we attempt to update the prototype": {
           topic() {
    -        var obj = {};
    +        const obj = {};
             dotty.put(obj, "__proto__.polluted", "Muhahahaha");
             return obj;
           },
           "it should not update": function (res) {
             assert.equal(res.polluted, undefined);
    +        assert.equal(Object.prototype.polluted, undefined);
    +      },
    +    },
    +    "When we attempt to update the prototype using an array": {
    +      topic() {
    +        const obj = {};
    +        dotty.put(obj, ["__proto__", "polluted"], "Muhahahaha");
    +        return obj;
    +      },
    +      "it should not update": function (res) {
    +        assert.equal(res.polluted, undefined);
    +        assert.equal(Object.prototype.polluted, undefined);
    +      },
    +    },
    +    "When we attempt to update the prototype using a non-string": {
    +      topic() {
    +        const obj = {};
    +        dotty.put(obj, [["__proto__"], "polluted"], "Muhahahaha");
    +        return obj;
    +      },
    +      "it should not update": function (res) {
    +        assert.equal(res.polluted, undefined);
    +        assert.equal(Object.prototype.polluted, undefined);
           },
         },
         "When we attempt to update the constructor prototype": {
           topic() {
    -        var obj = {};
    +        const obj = {};
             dotty.put(obj, "constructor.prototype.polluted", "Muhahahaha");
             return obj;
           },
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.