neilg       2003/12/11 14:21:26

  Modified:    c/src/xercesc/util XMLUri.cpp XMLUri.hpp
  Log:
  fixes for the URI implementation to take registry names into account; much thanks to 
Michael Glavassevich
  
  Revision  Changes    Path
  1.18      +262 -84   xml-xerces/c/src/xercesc/util/XMLUri.cpp
  
  Index: XMLUri.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLUri.cpp,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- XMLUri.cpp        1 Oct 2003 16:32:39 -0000       1.17
  +++ XMLUri.cpp        11 Dec 2003 22:21:25 -0000      1.18
  @@ -112,6 +112,16 @@
       chDollarSign, chPeriod, chNull
   };
   
  +//
  +//      reg_name     = 1*( unreserved | escaped | "$" | "," |
  +//                         ";" | ":" | "@" | "&" | "=" | "+" )
  +//
  +const XMLCh XMLUri::REG_NAME_CHARACTERS[] =
  +{
  +    chDollarSign, chComma, chSemiColon, chColon, chAt,
  +    chAmpersand, chEqual, chPlus, chNull
  +};
  +
   //      pchar plus ';' and '/'.
   //      pchar         = unreserved | escaped |
   //                      ":" | "@" | "&" | "=" | "+" | "$" | ","
  @@ -135,6 +145,7 @@
   // "UserInfo"
   // "Host"
   // "Port"
  +// "RegName"
   // "Path"
   // "Query"
   // "Fragment"
  @@ -175,6 +186,12 @@
       chLatin_P, chLatin_o, chLatin_r, chLatin_t, chNull
   };
   
  +static const XMLCh errMsg_REGNAME[] =
  +{
  +    chLatin_R, chLatin_e, chLatin_g, 
  +    chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull
  +};
  +
   static const XMLCh errMsg_PATH[] =
   {
       chLatin_P, chLatin_a, chLatin_t, chLatin_h, chNull
  @@ -256,6 +273,7 @@
   , fUserInfo(0)
   , fHost(0)
   , fPort(-1)
  +, fRegAuth(0)
   , fPath(0)
   , fQueryString(0)
   , fFragment(0)
  @@ -284,6 +302,7 @@
   , fUserInfo(0)
   , fHost(0)
   , fPort(-1)
  +, fRegAuth(0)
   , fPath(0)
   , fQueryString(0)
   , fFragment(0)
  @@ -310,6 +329,7 @@
   , fUserInfo(0)
   , fHost(0)
   , fPort(-1)
  +, fRegAuth(0)
   , fPath(0)
   , fQueryString(0)
   , fFragment(0)
  @@ -363,6 +383,9 @@
   
       if (fHost)
           fMemoryManager->deallocate(fHost);//delete[] fHost;
  +        
  +    if (fRegAuth)
  +        fMemoryManager->deallocate(fRegAuth);//delete[] fRegAuth;
   
       if (fPath)
           fMemoryManager->deallocate(fPath);//delete[] fPath;
  @@ -384,12 +407,13 @@
       //
       fMemoryManager = toCopy.fMemoryManager;
       fScheme = XMLString::replicate(toCopy.fScheme, fMemoryManager);
  -     fUserInfo = XMLString::replicate(toCopy.fUserInfo, fMemoryManager);
  -     fHost = XMLString::replicate(toCopy.fHost, fMemoryManager);
  -     fPort = toCopy.fPort;
  -     fPath = XMLString::replicate(toCopy.fPath, fMemoryManager);
  -     fQueryString = XMLString::replicate(toCopy.fQueryString, fMemoryManager);
  -     fFragment = XMLString::replicate(toCopy.fFragment, fMemoryManager);
  +    fUserInfo = XMLString::replicate(toCopy.fUserInfo, fMemoryManager);
  +    fHost = XMLString::replicate(toCopy.fHost, fMemoryManager);
  +    fPort = toCopy.fPort;
  +    fRegAuth = XMLString::replicate(toCopy.fRegAuth, fMemoryManager);
  +    fPath = XMLString::replicate(toCopy.fPath, fMemoryManager);
  +    fQueryString = XMLString::replicate(toCopy.fQueryString, fMemoryManager);
  +    fFragment = XMLString::replicate(toCopy.fFragment, fMemoryManager);
   }
   
   void XMLUri::initialize(const XMLUri* const baseURI
  @@ -528,13 +552,14 @@
           // identified this as a bug in the RFC
           if ((!fPath || !*fPath) &&
               fScheme == 0 &&
  -            fHost == 0)
  +            fHost == 0 && fRegAuth == 0)
           {
               fScheme = XMLString::replicate(baseURI->getScheme(), fMemoryManager);
               fMemoryManager->deallocate(fUserInfo);//delete [] fUserInfo;
               fUserInfo = XMLString::replicate(baseURI->getUserInfo(), 
fMemoryManager);
               fHost = XMLString::replicate(baseURI->getHost(), fMemoryManager);
               fPort = baseURI->getPort();
  +            fRegAuth = XMLString::replicate(baseURI->getRegBasedAuthority(), 
fMemoryManager);
               fMemoryManager->deallocate(fPath);//delete [] fPath;
               fPath = XMLString::replicate(baseURI->getPath(), fMemoryManager);
   
  @@ -558,12 +583,13 @@
   
           // check for authority - RFC 2396 5.2 #4
           // if we found a host, then we've got a network path, so we're done
  -        if (fHost == 0)
  +        if (fHost == 0 && fRegAuth == 0)
           {
               fMemoryManager->deallocate(fUserInfo);//delete [] fUserInfo;
               fUserInfo = XMLString::replicate(baseURI->getUserInfo(), 
fMemoryManager);
               fHost = XMLString::replicate(baseURI->getHost(), fMemoryManager);
               fPort = baseURI->getPort();
  +            fRegAuth = XMLString::replicate(baseURI->getRegBasedAuthority(), 
fMemoryManager);
           }
           else
           {
  @@ -628,7 +654,7 @@
           // path segment not equal to ".."
           index = -1;
           int segIndex = -1;
  -             int offset = 1;
  +        int offset = 1;
   
           while ((index = XMLString::patternMatch(&(path[offset]), 
SLASH_DOTDOT_SLASH)) != -1)
           {
  @@ -803,11 +829,23 @@
           }
       } // if > 0
   
  -    // The order is important, do not change
  -    //
  -    setHost(host);
  -    setPort(port);
  -    setUserInfo(userinfo);
  +    // Check if we have server based authority.
  +    if (isValidServerBasedAuthority(host, port, userinfo))
  +    {
  +        if (fHost)
  +            fMemoryManager->deallocate(fHost);//delete [] fHost;
  +        
  +        if (fUserInfo)
  +            fMemoryManager->deallocate(fUserInfo);//delete[] fUserInfo;
  +            
  +        fHost = XMLString::replicate(host, fMemoryManager);
  +        fPort = port;
  +        fUserInfo = XMLString::replicate(userinfo, fMemoryManager);
  +        
  +        return;
  +    }
  +    // This must be registry based authority or the URI is malformed.
  +    setRegBasedAuthority(uriSpec);
   }
   
   // scheme = alpha *( alpha | digit | "+" | "-" | "." )
  @@ -1169,6 +1207,7 @@
       }
   
       fHost = XMLString::replicate(newHost, fMemoryManager);
  +    setRegBasedAuthority(0);
   }
   
   void XMLUri::setPort(int newPort)
  @@ -1193,7 +1232,33 @@
       }
   
       fPort = newPort;
  +}
   
  +void XMLUri::setRegBasedAuthority(const XMLCh* const newRegAuth)
  +{
  +    if ( !newRegAuth )
  +    {
  +        if (getRegBasedAuthority())
  +            fMemoryManager->deallocate(fRegAuth);//delete [] fRegAuth;
  +        
  +        fRegAuth = 0;
  +        return;
  +    }
  +    // reg_name = 1*( unreserved | escaped | "$" | "," | 
  +    //            ";" | ":" | "@" | "&" | "=" | "+" )
  +    else if ( !*newRegAuth || !isValidRegistryBasedAuthority(newRegAuth) ) 
  +    {    
  +        ThrowXML2(MalformedURLException
  +                , XMLExcepts::XMLNUM_URI_Component_Not_Conformant
  +                , errMsg_REGNAME
  +                , newRegAuth);
  +    }
  +    
  +    if (getRegBasedAuthority())
  +        fMemoryManager->deallocate(fRegAuth);//delete [] fRegAuth;
  +    
  +    fRegAuth = XMLString::replicate(newRegAuth, fMemoryManager);
  +    setHost(0);
   }
   
   //
  @@ -1384,6 +1449,143 @@
       return;
   }
   
  +bool XMLUri::isValidServerBasedAuthority(const XMLCh* const host,
  +                                         const int hostLen,
  +                                         const int port,
  +                                         const XMLCh* const userinfo,
  +                                         const int userLen)
  +{
  +    // The order is important, do not change
  +    if (!isWellFormedAddress(host, hostLen))
  +        return false;
  +
  +    // check port number
  +    if ((port > 65535) || (port < 0 && port != -1))
  +        return false;
  +
  +    // check userinfo
  +    int index = 0;
  +    while (index < userLen)
  +    {
  +        if (isUnreservedCharacter(userinfo[index]) ||
  +            (XMLString::indexOf(USERINFO_CHARACTERS, userinfo[index]) != -1))
  +        {
  +            index++;
  +        }
  +        else if (userinfo[index] == chPercent)               // '%'
  +        {
  +            if (XMLString::isHex(userinfo[index+1]) &&     // 1st hex
  +                XMLString::isHex(userinfo[index+2])  )     // 2nd hex
  +                index +=3;
  +            else
  +                return false;
  +        }
  +        else
  +            return false;
  +    } //while
  +
  +    return true;
  +}
  +
  +bool XMLUri::isValidServerBasedAuthority(const XMLCh* const host,
  +                                         const int port,
  +                                         const XMLCh* const userinfo)
  +{
  +    // The order is important, do not change
  +    if (!isWellFormedAddress(host))
  +        return false;
  +
  +    // check port number
  +    if ((port > 65535) || (port < 0 && port != -1))
  +        return false;
  +    
  +    // check userinfo
  +    if (!userinfo)
  +        return false;
  +        
  +    const XMLCh* tmpStr = userinfo;
  +    while (*tmpStr)
  +    {
  +        if ( isUnreservedCharacter(*tmpStr) ||
  +            (XMLString::indexOf(USERINFO_CHARACTERS, *tmpStr) != -1))
  +        {
  +            tmpStr++;
  +        }
  +        else if (*tmpStr == chPercent)               // '%'
  +        {
  +            if (XMLString::isHex(*(tmpStr+1)) &&     // 1st hex
  +                XMLString::isHex(*(tmpStr+2))  )     // 2nd hex
  +            {
  +                tmpStr+=3;
  +            }
  +            else
  +                return false;
  +        }
  +        else
  +            return false;
  +    } //while
  +    
  +    return true;
  +}
  +
  +bool XMLUri::isValidRegistryBasedAuthority(const XMLCh* const authority,
  +                                           const int authLen)
  +{
  +    // check authority
  +    int index = 0;
  +    while (index < authLen)
  +    {
  +        if (isUnreservedCharacter(authority[index]) ||
  +            (XMLString::indexOf(REG_NAME_CHARACTERS, authority[index]) != -1))
  +        {
  +            index++;
  +        }
  +        else if (authority[index] == chPercent)               // '%'
  +        {
  +            if (XMLString::isHex(authority[index+1]) &&     // 1st hex
  +                XMLString::isHex(authority[index+2])  )     // 2nd hex
  +                index +=3;
  +            else
  +                return false;
  +        }
  +        else
  +            return false;
  +    } //while
  +
  +    return true;
  +}
  +
  +bool XMLUri::isValidRegistryBasedAuthority(const XMLCh* const authority)
  +{
  +    // check authority
  +    if (!authority)
  +        return false;
  +        
  +    const XMLCh* tmpStr = authority;
  +    while (*tmpStr)
  +    {
  +        if (isUnreservedCharacter(*tmpStr) ||
  +            (XMLString::indexOf(REG_NAME_CHARACTERS, *tmpStr) != -1))
  +        {
  +            tmpStr++;
  +        }
  +        else if (*tmpStr == chPercent)               // '%'
  +        {
  +            if (XMLString::isHex(*(tmpStr+1)) &&     // 1st hex
  +                XMLString::isHex(*(tmpStr+2))  )     // 2nd hex
  +            {
  +                tmpStr+=3;
  +            }
  +            else
  +                return false;
  +        }
  +        else
  +            return false;
  +    } //while
  +    
  +    return true;
  +}
  +
   //
   // uric     = reserved | unreserved | escaped
   // escaped  = "%" hex hex
  @@ -1731,11 +1933,11 @@
   //  never required.
   //
   void XMLUri::buildFullText()
  -{
  +{   
       // Calculate the worst case size of the buffer required
       unsigned int bufSize = XMLString::stringLen(fScheme) + 1
                              + XMLString::stringLen(fFragment) + 1
  -                           + XMLString::stringLen(fHost) + 2
  +                           + XMLString::stringLen(fHost ? fHost : fRegAuth) + 2
                              + XMLString::stringLen(fPath)
                              + XMLString::stringLen(fQueryString) + 1
                              + XMLString::stringLen(fUserInfo) + 1
  @@ -1752,47 +1954,48 @@
           XMLString::catString(fURIText, getScheme());
           outPtr += XMLString::stringLen(fURIText);
           *outPtr++ = chColon;
  -        *outPtr++ = chForwardSlash;
  -        *outPtr++ = chForwardSlash;
       }
   
  -    if (fUserInfo)
  +    // Authority
  +    if (fHost || fRegAuth)
       {
  -        XMLString::copyString(outPtr, fUserInfo);
  -        outPtr += XMLString::stringLen(fUserInfo);
  -
  -
  -        /*REVISIT dont have password field in uri - is this right??
  -        if (fPassword)
  -        {
  -            *outPtr++ = chColon;
  -            XMLString::copyString(outPtr, fPassword);
  -            outPtr += XMLString::stringLen(fPassword);
  -        }
  -        */
  -        *outPtr++ = chAt;
  -    }
  -
  -    if (fHost)
  -    {
  -        XMLString::copyString(outPtr, fHost);
  -        outPtr += XMLString::stringLen(fHost);
  -
  -        //
  -        //  If the port is -1, then we don't put it in. Else we need
  -        //  to because it was explicitly provided.
  -        //
  -        if (fPort != -1)
  +        *outPtr++ = chForwardSlash;
  +        *outPtr++ = chForwardSlash;
  +        
  +        // Server based authority.
  +        if (fHost)
           {
  -            *outPtr++ = chColon;
  +            if (fUserInfo)
  +            {
  +                XMLString::copyString(outPtr, fUserInfo);
  +                outPtr += XMLString::stringLen(fUserInfo);
  +                *outPtr++ = chAt;
  +            }
  +            
  +            XMLString::copyString(outPtr, fHost);
  +            outPtr += XMLString::stringLen(fHost);
  +            
  +            //
  +            //  If the port is -1, then we don't put it in. Else we need
  +            //  to because it was explicitly provided.
  +            //
  +            if (fPort != -1)
  +            {
  +                *outPtr++ = chColon;
   
  -            XMLCh tmpBuf[16];
  -            XMLString::binToText(fPort, tmpBuf, 16, 10);
  -            XMLString::copyString(outPtr, tmpBuf);
  -            outPtr += XMLString::stringLen(tmpBuf);
  +                XMLCh tmpBuf[16];
  +                XMLString::binToText(fPort, tmpBuf, 16, 10);
  +                XMLString::copyString(outPtr, tmpBuf);
  +                outPtr += XMLString::stringLen(tmpBuf);
  +            }
  +        }
  +        // Registry based authority.
  +        else {
  +            XMLString::copyString(outPtr, fRegAuth);
  +            outPtr += XMLString::stringLen(fRegAuth);
           }
       }
  -
  +    
       if (fPath)
       {
           XMLString::copyString(outPtr, fPath);
  @@ -1909,10 +2112,10 @@
           }
       }
   
  -    // we need to check if index has exceed the lenght or not
  +    // we need to check if index has exceed the length or not
       if (index < trimedUriSpecLen)
       {
  -         if (!processPath(trimedUriSpec + index, trimedUriSpecLen - index, 
foundScheme))
  +        if (!processPath(trimedUriSpec + index, trimedUriSpecLen - index, 
foundScheme))
               return false;
       }
   
  @@ -2114,37 +2317,9 @@
           
           }
       }
  -
  -    // The order is important, do not change
  -    if (!isWellFormedAddress(host, hostLen))
  -        return false;
  -
  -    // check port number
  -    if ((port > 65535) || (port < 0 && port != -1))
  -        return false;
  -
  -    // check userinfo
  -    index = 0;
  -     while (index < userInfoLen)
  -    {
  -        if (isUnreservedCharacter(userinfo[index]) ||
  -            (XMLString::indexOf(USERINFO_CHARACTERS, userinfo[index]) != -1))
  -        {
  -            index++;
  -        }
  -        else if (userinfo[index] == chPercent)               // '%'
  -        {
  -            if (XMLString::isHex(userinfo[index+1]) &&     // 1st hex
  -                XMLString::isHex(userinfo[index+2])  )     // 2nd hex
  -                index +=3;
  -            else
  -                return false;
  -        }
  -        else
  -            return false;
  -    } //while
  -
  -    return true;
  +    
  +    return isValidServerBasedAuthority(host, hostLen, port, userinfo, userInfoLen)
  +        || isValidRegistryBasedAuthority(authSpec, authLen);
   }
   
   bool XMLUri::processPath(const XMLCh* const pathStr,
  @@ -2236,6 +2411,7 @@
   
           serEng<<fPort;
   
  +        serEng.writeString(fRegAuth);
           serEng.writeString(fPath);
           serEng.writeString(fQueryString);
           serEng.writeString(fFragment);
  @@ -2249,6 +2425,7 @@
   
           serEng>>fPort;
   
  +        serEng.readString(fRegAuth);
           serEng.readString(fPath);
           serEng.readString(fQueryString);
           serEng.readString(fFragment);
  @@ -2262,6 +2439,7 @@
   , fUserInfo(0)
   , fHost(0)
   , fPort(-1)
  +, fRegAuth(0)
   , fPath(0)
   , fQueryString(0)
   , fFragment(0)
  
  
  
  1.14      +74 -0     xml-xerces/c/src/xercesc/util/XMLUri.hpp
  
  Index: XMLUri.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/XMLUri.hpp,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- XMLUri.hpp        2 Dec 2003 17:50:21 -0000       1.13
  +++ XMLUri.hpp        11 Dec 2003 22:21:25 -0000      1.14
  @@ -57,6 +57,9 @@
   /*
    * $Id$
    * $Log$
  + * Revision 1.14  2003/12/11 22:21:25  neilg
  + * fixes for the URI implementation to take registry names into account; much 
thanks to Michael Glavassevich
  + *
    * Revision 1.13  2003/12/02 17:50:21  neilg
    * additional fix for bug 25118; once again, thanks to Jeroen Whitmond
    *
  @@ -255,6 +258,13 @@
        * @return the port for this URI (-1 if not specified).
        */
        int getPort() const;
  +     
  +    /**
  +     * Get the registry based authority for this URI.
  +     * 
  +     * @return the registry based authority (null if not specified).
  +     */
  +     const XMLCh* getRegBasedAuthority() const;
   
       /**
        * Get the path for this URI. Note that the value returned is the path
  @@ -308,6 +318,9 @@
        * Set the host for this URI. If null is passed in, the userinfo
        * field is also set to null and the port is set to -1.
        *
  +     * Note: This method overwrites registry based authority if it
  +     * previously existed in this URI.
  +     *
        * @param newHost the host for this URI
        *
        */
  @@ -323,6 +336,16 @@
        *
        */
        void setPort(int newPort);
  +     
  +    /**
  +     * Sets the registry based authority for this URI.
  +     * 
  +     * Note: This method overwrites server based authority
  +     * if it previously existed in this URI.
  +     * 
  +     * @param newRegAuth the registry based authority for this URI
  +     */
  +     void setRegBasedAuthority(const XMLCh* const newRegAuth);
   
       /**
        * Set the path for this URI.
  @@ -398,6 +421,7 @@
       static const XMLCh MARK_CHARACTERS[];
       static const XMLCh SCHEME_CHARACTERS[];
       static const XMLCh USERINFO_CHARACTERS[];
  +    static const XMLCh REG_NAME_CHARACTERS[];
       static const XMLCh PATH_CHARACTERS[];
   
       //helper method for getUriText
  @@ -443,6 +467,50 @@
        * @return true if the scheme is conformant, false otherwise
        */
       static void isConformantUserInfo(const XMLCh* const userInfo);
  +    
  +    /**
  +     * Determines whether the components host, port, and user info
  +     * are valid as a server authority.
  +     *
  +     * @return true if the given host, port, and userinfo compose
  +     * a valid server authority
  +     */
  +    static bool isValidServerBasedAuthority(const XMLCh* const host
  +                                           , const int hostLen
  +                                           , const int port
  +                                           , const XMLCh* const userinfo
  +                                           , const int userLen);
  +                                           
  +    /**
  +     * Determines whether the components host, port, and user info
  +     * are valid as a server authority.
  +     *
  +     * @return true if the given host, port, and userinfo compose
  +     * a valid server authority
  +     */
  +    static bool isValidServerBasedAuthority(const XMLCh* const host
  +                                           , const int port
  +                                           , const XMLCh* const userinfo);
  +      
  +   /**
  +    * Determines whether the given string is a registry based authority.
  +    * 
  +    * @param authority the authority component of a URI
  +    * 
  +    * @return true if the given string is a registry based authority
  +    */
  +    static bool isValidRegistryBasedAuthority(const XMLCh* const authority
  +                                             , const int authLen);
  +
  +   /**
  +    * Determines whether the given string is a registry based authority.
  +    * 
  +    * @param authority the authority component of a URI
  +    * 
  +    * @return true if the given string is a registry based authority
  +    */
  +    static bool isValidRegistryBasedAuthority(const XMLCh* const authority);
  +
       /**
        * Determine whether a string is syntactically capable of representing
        * a valid IPv4 address, IPv6 reference or the domain name of a network host.
  @@ -593,6 +661,7 @@
       XMLCh*          fUserInfo;
       XMLCh*          fHost;
       int             fPort;
  +    XMLCh*          fRegAuth;
       XMLCh*          fPath;
       XMLCh*          fQueryString;
       XMLCh*          fFragment;
  @@ -621,6 +690,11 @@
   inline int XMLUri::getPort() const
   {
        return fPort;
  +}
  +
  +inline const XMLCh* XMLUri::getRegBasedAuthority() const
  +{
  +     return fRegAuth;
   }
   
   inline const XMLCh* XMLUri::getPath() const
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to