Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

DataLakeDirectoryClient::ListPaths() throws exception due to incorrect format used for date-time fields

Chiusa
#7,436 11 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@Jinming-Hu ci sta già lavorando.

Dal 2/10/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

bug customer-reported issue-addressed

Title
DataLakeDirectoryClient::ListPaths() throws exception due to incorrect format used for date-time fields

Describe the bug

Azure::Storage::Files::DataLake::DataLakeDirectoryClient::ListPaths()
throws std::invalid_argument (what() == "stoll") on completely
well-formed, valid ADLS Gen2 ListPaths REST responses, whenever the
server returns the creationTime/expiryTime path-property fields as
RFC1123 date-time text rather than a numeric Win32 FILETIME string.

Root cause: in DataLakeDirectoryClient::ListPaths()
(sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp),
the loop that copies protocol-layer _detail::PathItem results into the
public Models::PathItem results unconditionally assumes
creationTime/expiryTime are numeric Win32 FILETIME strings (100-ns
ticks since 1601-01-01) and calls std::stoll() directly on them:

if (path.CreatedOn.HasValue())
{
  item.CreatedOn = _detail::Win32FileTimeConverter::Win32FileTimeToDateTime(
      std::stoll(path.CreatedOn.Value()));
}
if (path.ExpiresOn.HasValue() && path.ExpiresOn.Value() != "0")
{
  item.ExpiresOn = _detail::Win32FileTimeConverter::Win32FileTimeToDateTime(
      std::stoll(path.ExpiresOn.Value()));
}

However, for at least some accounts/API versions, the server instead
returns these fields pre-formatted as RFC1123 date-time text — the
exact same textual format used for the lastModified field, which the
protocol layer (rest_client.cpp) parses correctly a few lines earlier
via DateTime::Parse(var0["lastModified"].get<std::string>(), Azure::DateTime::DateFormat::Rfc1123). When creationTime/expiryTime
are present in this text form (e.g. "Fri, 11 Oct 2019 22:32:19 GMT"),
std::stoll() immediately throws std::invalid_argument, aborting the
entire ListPaths() call for the whole page of results — even though the
response is completely well-formed, and the sibling
FileSystemClient::ListPaths() call (which never derives a DateTime
from creationTime/expiryTime at all) handles the identical response
bytes without any issue.

Exception or Stack Trace

terminate called after throwing an instance of 'std::invalid_argument'
  what():  stoll

Reproduced 100% deterministically (unlike the related UB-driven bug
reported separately in BUG-REPORT-1-owner-group-permissions-UB.md) —
every single call against the affected account/filesystem throws this
exact exception, because std::stoll() is being handed non-numeric text.

To Reproduce

Steps to reproduce the behavior:

  1. Use (or point at) an ADLS Gen2 account/filesystem whose ListPaths
    REST responses return creationTime/expiryTime as RFC1123 text
    rather than a numeric FILETIME string (observed consistently against a
    production Azure Storage account in our testing).
  2. Call DataLakeDirectoryClient::ListPaths() (e.g. via
    DataLakeDirectoryClient(...).ListPaths(recursive, options)) against
    any directory in that filesystem that has at least one path with a
    creationTime/expiryTime value present in the response.
  3. Observe std::invalid_argument ("stoll") thrown on every call,
    preventing any results from ever being returned — even though the raw
    HTTP response is valid, well-formed JSON.

A raw, captured ListPaths response we observed that reliably triggers
this (with contentLength sometimes present as a numeric-looking string
too, per Bug 1's separate contentLength handling):

{"paths":[
  {
    "contentLength":"82372",
    "creationTime":"Fri, 11 Oct 2019 22:32:19 GMT",
    "etag":"0x8D74E9AE06DE5D2",
    "lastModified":"Fri, 11 Oct 2019 22:32:19 GMT",
    "name":"data/archive/archive.json.gz"
  }
]}

Independently re-parsing this exact JSON with a fresh json::parse()
call succeeds cleanly (every field a string, creationTime and
lastModified both valid RFC1123 text) — yet
DataLakeDirectoryClient::ListPaths() throws on every call against it,
100% reproducibly, because of the unconditional
std::stoll(path.CreatedOn.Value()).

Code Snippet

The buggy code, in
sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp,
DataLakeDirectoryClient::ListPaths():

item.Permissions = std::move(path.Permissions);
item.EncryptionScope = std::move(path.EncryptionScope);
item.ETag = std::move(path.ETag);
if (path.CreatedOn.HasValue())
{
  item.CreatedOn = _detail::Win32FileTimeConverter::Win32FileTimeToDateTime(
      std::stoll(path.CreatedOn.Value()));
}
if (path.ExpiresOn.HasValue() && path.ExpiresOn.Value() != "0")
{
  item.ExpiresOn = _detail::Win32FileTimeConverter::Win32FileTimeToDateTime(
      std::stoll(path.ExpiresOn.Value()));
}
item.EncryptionContext = std::move(path.EncryptionContext);

A minimal, standalone repro of just the failing conversion:

#include <string>
#include <stdexcept>

long long ToFileTime(const std::string& raw) {
  // Throws std::invalid_argument("stoll") when raw is RFC1123 text
  // instead of a numeric FILETIME string, e.g. "Fri, 11 Oct 2019 22:32:19 GMT".
  return std::stoll(raw);
}

int main() {
  ToFileTime("Fri, 11 Oct 2019 22:32:19 GMT");  // throws immediately
}

Expected behavior

ListPaths() should handle both representations the ADLS Gen2 service may
return for creationTime/expiryTime — numeric Win32 FILETIME strings
and RFC1123 date-time text (the same format already handled for
lastModified) — by detecting which format was actually returned before
choosing how to convert it to a DateTime, rather than assuming FILETIME
unconditionally. It should never throw an uncaught, undifferentiated
std::invalid_argument for a well-formed, documented server response.

Screenshots

Not applicable (this is a backend/library exception, not a UI issue).

Setup (please complete the following information):

  • OS: SUSE Linux Enterprise Server 15 SP7 (SLES 15-SP7, x86_64); also
    expected to reproduce on any platform, since the bug is in
    platform-independent deserialization code
  • IDE: N/A (reproduced via a standalone C++ test harness, not an IDE)
  • Compiler/toolchain: GCC 14.3.0, CMake 3.28.3
  • Version of the Library used: azure-storage-files-datalake 12.15.0
    (root cause confirmed still present by source inspection of the current
    main branch of azure-sdk-for-cpp as of this report)

Additional context

  • This bug was discovered while investigating a customer-reported issue in
    which a CREATE FOREIGN TABLE-style directory listing against a
    container containing archive-tier blobs (Azure Blob Storage) surfaced a
    confusing client-side deserialization error instead of the correct,
    expected 409 "operation not permitted on an archived blob" server
    error. This bug was masked behind a separate, independent bug (filed
    separately — see BUG-REPORT-1-owner-group-permissions-UB.md — an
    undefined-behavior/UB issue reading optional owner/group/
    permissions/contentLength fields in the sibling
    FileSystemClient::ListPaths() protocol-layer function) which, being
    nondeterministic, sometimes fired first and masked this deterministic
    bug entirely. Once Bug 1 was fixed in isolation, this bug then surfaced
    100% reproducibly on every single call.
  • We'd suggest double-checking whether other date/time fields elsewhere in
    the DataLake (and possibly Blob) client code make the same
    FILETIME-only assumption without considering the RFC1123-text
    possibility, since both formats are apparently valid depending on
    account/API-version/response path.
  • A minimal, self-contained fix is attached as a unified diff:
    NOS-14641-createdon-expireson-format-guard.patch. Full before/after
    source is also attached: datalake_directory_client.cpp.orig /
    datalake_directory_client.cpp.patched. The fix detects an all-digit
    string (FILETIME) vs. text (RFC1123, parsed via
    Azure::DateTime::DateFormat::Rfc1123, consistent with how
    lastModified is already parsed) before converting, and was built and
    verified end-to-end against a live Azure Storage account whose
    ListPaths responses previously triggered this bug on every call.

Information Checklist

Kindly make sure that you have added all the following information above
and checkoff the required fields otherwise we will treat the issuer as an
incomplete report

  • Bug Description Added
  • Repro Steps Added
  • Setup information Added
Lingua principale
C++
Stelle
206
Fork
177
Merge medio
2g 17h
PR unite (30g)
37

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Azure/azure-sdk-for-cpp

Tutte le issue di Azure/azure-sdk-for-cpp

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.