Uploaded image for project: 'Couchbase Server'
  1. Couchbase Server
  2. MB-30278

Subdoc: Invalid path un-escaping can result in ops targeting wrong document location

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Critical
    • 5.5.0
    • 4.5.0, 4.6.5, 5.0.1, 5.1.1, 5.5.0
    • memcached
    • Triaged
    • No

    Description

      Summary

      As reported on the forums by kstrek, there is an error in the handling of escaped paths (those containing a backtick `) when un-escaping the path.

      For lookup operations this would typically result in data unavailability (a field would report PATH_ENOENT when it does exist). For mutation operations this could result in the wrong field being mutated.

      Steps to Reproduce
      Quoting from the forum:

      I’m having trouble trying to store and retrieve documents containing ` (backtick) characters in document’s property names.

      Following test is “successful”:

      @Test
      public void backtickTest()
      {
      	final String docId = UUID.randomUUID().toString();
      	final JsonObject storedContent = JsonObject.from(ImmutableMap.of("prop`", 5));
       
      	bucket.upsert(JsonDocument.create(docId, storedContent));
       
      	final JsonDocument document = bucket.get(docId);
      	assertThat(document.content()).isEqualTo(storedContent);
       
      	final DocumentFragment<Lookup> lookupResult = bucket.lookupIn(docId).get("prop``").execute();
      	assertThat(lookupResult.content(0)).isEqualTo(5); // <- FAILS on 5th run
      }
      

      Although it’s successful, it can be run only 4 times, on 5th try lookup result is null with status SUBDOC_PATH_NOT_FOUND. Starts working again after couchbase restart. Behavior is repeatable, each time after restart we can run 4 lookups, 5th and so on fails. For properties without backticks everything works like a charm at any point.

      The problem is in Path::convert_escape(), which uses a local cache of std::string objects for path components. Items taken from the cache are not correctly reset before use; which has the effect that we end up appending the current path to the previously used path.

      This caching is why it sometimes works - the first subdoc request which is serviced by a given front-end worker thread will succeed; but the caching of paths means subsequent attempts can fail.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            drigby Dave Rigby (Inactive)
            drigby Dave Rigby (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              PagerDuty