xmlschemas.c 812 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173
  1. /*
  2. * schemas.c : implementation of the XML Schema handling and
  3. * schema validity checking
  4. *
  5. * See Copyright for the status of this software.
  6. *
  7. * Daniel Veillard <veillard@redhat.com>
  8. */
  9. /*
  10. * TODO:
  11. * - when types are redefined in includes, check that all
  12. * types in the redef list are equal
  13. * -> need a type equality operation.
  14. * - if we don't intend to use the schema for schemas, we
  15. * need to validate all schema attributes (ref, type, name)
  16. * against their types.
  17. * - Eliminate item creation for: ??
  18. *
  19. * URGENT TODO:
  20. * - For xsi-driven schema acquisition, augment the IDCs after every
  21. * acquisition episode (xmlSchemaAugmentIDC).
  22. *
  23. * NOTES:
  24. * - Eliminated item creation for: <restriction>, <extension>,
  25. * <simpleContent>, <complexContent>, <list>, <union>
  26. *
  27. * PROBLEMS:
  28. * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
  29. * IDC XPath expression and chameleon includes: the targetNamespace is changed, so
  30. * XPath will have trouble to resolve to this namespace, since not known.
  31. *
  32. *
  33. * CONSTRAINTS:
  34. *
  35. * Schema Component Constraint:
  36. * All Group Limited (cos-all-limited)
  37. * Status: complete
  38. * (1.2)
  39. * In xmlSchemaGroupDefReferenceTermFixup() and
  40. * (2)
  41. * In xmlSchemaParseModelGroup()
  42. * TODO: Actually this should go to component-level checks,
  43. * but is done here due to performance. Move it to an other layer
  44. * is schema construction via an API is implemented.
  45. */
  46. /* To avoid EBCDIC trouble when parsing on zOS */
  47. #if defined(__MVS__)
  48. #pragma convert("ISO8859-1")
  49. #endif
  50. #define IN_LIBXML
  51. #include "libxml.h"
  52. #ifdef LIBXML_SCHEMAS_ENABLED
  53. #include <string.h>
  54. #include <libxml/xmlmemory.h>
  55. #include <libxml/parser.h>
  56. #include <libxml/parserInternals.h>
  57. #include <libxml/hash.h>
  58. #include <libxml/uri.h>
  59. #include <libxml/xmlschemas.h>
  60. #include <libxml/schemasInternals.h>
  61. #include <libxml/xmlschemastypes.h>
  62. #include <libxml/xmlautomata.h>
  63. #include <libxml/xmlregexp.h>
  64. #include <libxml/dict.h>
  65. #include <libxml/encoding.h>
  66. #include <libxml/xmlIO.h>
  67. #ifdef LIBXML_PATTERN_ENABLED
  68. #include <libxml/pattern.h>
  69. #endif
  70. #ifdef LIBXML_READER_ENABLED
  71. #include <libxml/xmlreader.h>
  72. #endif
  73. /* #define DEBUG 1 */
  74. /* #define DEBUG_CONTENT 1 */
  75. /* #define DEBUG_TYPE 1 */
  76. /* #define DEBUG_CONTENT_REGEXP 1 */
  77. /* #define DEBUG_AUTOMATA 1 */
  78. /* #define DEBUG_IDC */
  79. /* #define DEBUG_IDC_NODE_TABLE */
  80. /* #define WXS_ELEM_DECL_CONS_ENABLED */
  81. #ifdef DEBUG_IDC
  82. #ifndef DEBUG_IDC_NODE_TABLE
  83. #define DEBUG_IDC_NODE_TABLE
  84. #endif
  85. #endif
  86. /* #define ENABLE_PARTICLE_RESTRICTION 1 */
  87. #define ENABLE_REDEFINE
  88. /* #define ENABLE_NAMED_LOCALS */
  89. /* #define ENABLE_IDC_NODE_TABLES_TEST */
  90. #define DUMP_CONTENT_MODEL
  91. #ifdef LIBXML_READER_ENABLED
  92. /* #define XML_SCHEMA_READER_ENABLED */
  93. #endif
  94. #define UNBOUNDED (1 << 30)
  95. #define TODO \
  96. xmlGenericError(xmlGenericErrorContext, \
  97. "Unimplemented block at %s:%d\n", \
  98. __FILE__, __LINE__);
  99. #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
  100. /*
  101. * The XML Schemas namespaces
  102. */
  103. static const xmlChar *xmlSchemaNs = (const xmlChar *)
  104. "http://www.w3.org/2001/XMLSchema";
  105. static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
  106. "http://www.w3.org/2001/XMLSchema-instance";
  107. static const xmlChar *xmlNamespaceNs = (const xmlChar *)
  108. "http://www.w3.org/2000/xmlns/";
  109. /*
  110. * Come casting macros.
  111. */
  112. #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
  113. #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
  114. #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
  115. #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
  116. #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
  117. #define WXS_PTC_CAST (xmlSchemaParticlePtr)
  118. #define WXS_TYPE_CAST (xmlSchemaTypePtr)
  119. #define WXS_ELEM_CAST (xmlSchemaElementPtr)
  120. #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
  121. #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
  122. #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
  123. #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
  124. #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
  125. #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
  126. #define WXS_IDC_CAST (xmlSchemaIDCPtr)
  127. #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
  128. #define WXS_LIST_CAST (xmlSchemaItemListPtr)
  129. /*
  130. * Macros to query common properties of components.
  131. */
  132. #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
  133. #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
  134. /*
  135. * Macros for element declarations.
  136. */
  137. #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
  138. #define WXS_SUBST_HEAD(item) (item)->refDecl
  139. /*
  140. * Macros for attribute declarations.
  141. */
  142. #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
  143. /*
  144. * Macros for attribute uses.
  145. */
  146. #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
  147. #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
  148. #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
  149. #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
  150. /*
  151. * Macros for attribute groups.
  152. */
  153. #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
  154. #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
  155. /*
  156. * Macros for particles.
  157. */
  158. #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
  159. #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
  160. #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
  161. #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
  162. /*
  163. * Macros for model groups definitions.
  164. */
  165. #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
  166. /*
  167. * Macros for model groups.
  168. */
  169. #define WXS_IS_MODEL_GROUP(i) \
  170. (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
  171. ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
  172. ((i)->type == XML_SCHEMA_TYPE_ALL))
  173. #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
  174. /*
  175. * Macros for schema buckets.
  176. */
  177. #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
  178. ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
  179. #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
  180. ((t) == XML_SCHEMA_SCHEMA_IMPORT))
  181. #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
  182. #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
  183. /*
  184. * Macros for complex/simple types.
  185. */
  186. #define WXS_IS_ANYTYPE(i) \
  187. (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
  188. ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
  189. #define WXS_IS_COMPLEX(i) \
  190. (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
  191. ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
  192. #define WXS_IS_SIMPLE(item) \
  193. ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
  194. ((item->type == XML_SCHEMA_TYPE_BASIC) && \
  195. (item->builtInType != XML_SCHEMAS_ANYTYPE)))
  196. #define WXS_IS_ANY_SIMPLE_TYPE(i) \
  197. (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
  198. ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  199. #define WXS_IS_RESTRICTION(t) \
  200. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
  201. #define WXS_IS_EXTENSION(t) \
  202. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
  203. #define WXS_IS_TYPE_NOT_FIXED(i) \
  204. (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
  205. (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
  206. #define WXS_IS_TYPE_NOT_FIXED_1(item) \
  207. (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
  208. (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
  209. #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
  210. #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
  211. /*
  212. * Macros for exclusively for complex types.
  213. */
  214. #define WXS_HAS_COMPLEX_CONTENT(item) \
  215. ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
  216. (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
  217. (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
  218. #define WXS_HAS_SIMPLE_CONTENT(item) \
  219. ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
  220. (item->contentType == XML_SCHEMA_CONTENT_BASIC))
  221. #define WXS_HAS_MIXED_CONTENT(item) \
  222. (item->contentType == XML_SCHEMA_CONTENT_MIXED)
  223. #define WXS_EMPTIABLE(t) \
  224. (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
  225. #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
  226. #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
  227. #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
  228. /*
  229. * Macros for exclusively for simple types.
  230. */
  231. #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
  232. #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
  233. #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
  234. #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
  235. /*
  236. * Misc parser context macros.
  237. */
  238. #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
  239. #define WXS_HAS_BUCKETS(ctx) \
  240. ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
  241. (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
  242. #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
  243. #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
  244. #define WXS_SCHEMA(ctx) (ctx)->schema
  245. #define WXS_ADD_LOCAL(ctx, item) \
  246. xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
  247. #define WXS_ADD_GLOBAL(ctx, item) \
  248. xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
  249. #define WXS_ADD_PENDING(ctx, item) \
  250. xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
  251. /*
  252. * xmlSchemaItemList macros.
  253. */
  254. #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
  255. /*
  256. * Misc macros.
  257. */
  258. #define IS_SCHEMA(node, type) \
  259. ((node != NULL) && (node->ns != NULL) && \
  260. (xmlStrEqual(node->name, (const xmlChar *) type)) && \
  261. (xmlStrEqual(node->ns->href, xmlSchemaNs)))
  262. #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
  263. /*
  264. * Since we put the default/fixed values into the dict, we can
  265. * use pointer comparison for those values.
  266. * REMOVED: (xmlStrEqual((v1), (v2)))
  267. */
  268. #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
  269. #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
  270. #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
  271. #define HFAILURE if (res == -1) goto exit_failure;
  272. #define HERROR if (res != 0) goto exit_error;
  273. #define HSTOP(ctx) if ((ctx)->stop) goto exit;
  274. /*
  275. * Some flags used for various schema constraints.
  276. */
  277. #define SUBSET_RESTRICTION 1<<0
  278. #define SUBSET_EXTENSION 1<<1
  279. #define SUBSET_SUBSTITUTION 1<<2
  280. #define SUBSET_LIST 1<<3
  281. #define SUBSET_UNION 1<<4
  282. typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
  283. typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
  284. typedef struct _xmlSchemaItemList xmlSchemaItemList;
  285. typedef xmlSchemaItemList *xmlSchemaItemListPtr;
  286. struct _xmlSchemaItemList {
  287. void **items; /* used for dynamic addition of schemata */
  288. int nbItems; /* used for dynamic addition of schemata */
  289. int sizeItems; /* used for dynamic addition of schemata */
  290. };
  291. #define XML_SCHEMA_CTXT_PARSER 1
  292. #define XML_SCHEMA_CTXT_VALIDATOR 2
  293. typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
  294. typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
  295. struct _xmlSchemaAbstractCtxt {
  296. int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
  297. void *dummy; /* Fix alignment issues */
  298. };
  299. typedef struct _xmlSchemaBucket xmlSchemaBucket;
  300. typedef xmlSchemaBucket *xmlSchemaBucketPtr;
  301. #define XML_SCHEMA_SCHEMA_MAIN 0
  302. #define XML_SCHEMA_SCHEMA_IMPORT 1
  303. #define XML_SCHEMA_SCHEMA_INCLUDE 2
  304. #define XML_SCHEMA_SCHEMA_REDEFINE 3
  305. /**
  306. * xmlSchemaSchemaRelation:
  307. *
  308. * Used to create a graph of schema relationships.
  309. */
  310. typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
  311. typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
  312. struct _xmlSchemaSchemaRelation {
  313. xmlSchemaSchemaRelationPtr next;
  314. int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
  315. const xmlChar *importNamespace;
  316. xmlSchemaBucketPtr bucket;
  317. };
  318. #define XML_SCHEMA_BUCKET_MARKED 1<<0
  319. #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
  320. struct _xmlSchemaBucket {
  321. int type;
  322. int flags;
  323. const xmlChar *schemaLocation;
  324. const xmlChar *origTargetNamespace;
  325. const xmlChar *targetNamespace;
  326. xmlDocPtr doc;
  327. xmlSchemaSchemaRelationPtr relations;
  328. int located;
  329. int parsed;
  330. int imported;
  331. int preserveDoc;
  332. xmlSchemaItemListPtr globals; /* Global components. */
  333. xmlSchemaItemListPtr locals; /* Local components. */
  334. };
  335. /**
  336. * xmlSchemaImport:
  337. * (extends xmlSchemaBucket)
  338. *
  339. * Reflects a schema. Holds some information
  340. * about the schema and its toplevel components. Duplicate
  341. * toplevel components are not checked at this level.
  342. */
  343. typedef struct _xmlSchemaImport xmlSchemaImport;
  344. typedef xmlSchemaImport *xmlSchemaImportPtr;
  345. struct _xmlSchemaImport {
  346. int type; /* Main OR import OR include. */
  347. int flags;
  348. const xmlChar *schemaLocation; /* The URI of the schema document. */
  349. /* For chameleon includes, @origTargetNamespace will be NULL */
  350. const xmlChar *origTargetNamespace;
  351. /*
  352. * For chameleon includes, @targetNamespace will be the
  353. * targetNamespace of the including schema.
  354. */
  355. const xmlChar *targetNamespace;
  356. xmlDocPtr doc; /* The schema node-tree. */
  357. /* @relations will hold any included/imported/redefined schemas. */
  358. xmlSchemaSchemaRelationPtr relations;
  359. int located;
  360. int parsed;
  361. int imported;
  362. int preserveDoc;
  363. xmlSchemaItemListPtr globals;
  364. xmlSchemaItemListPtr locals;
  365. /* The imported schema. */
  366. xmlSchemaPtr schema;
  367. };
  368. /*
  369. * (extends xmlSchemaBucket)
  370. */
  371. typedef struct _xmlSchemaInclude xmlSchemaInclude;
  372. typedef xmlSchemaInclude *xmlSchemaIncludePtr;
  373. struct _xmlSchemaInclude {
  374. int type;
  375. int flags;
  376. const xmlChar *schemaLocation;
  377. const xmlChar *origTargetNamespace;
  378. const xmlChar *targetNamespace;
  379. xmlDocPtr doc;
  380. xmlSchemaSchemaRelationPtr relations;
  381. int located;
  382. int parsed;
  383. int imported;
  384. int preserveDoc;
  385. xmlSchemaItemListPtr globals; /* Global components. */
  386. xmlSchemaItemListPtr locals; /* Local components. */
  387. /* The owning main or import schema bucket. */
  388. xmlSchemaImportPtr ownerImport;
  389. };
  390. /**
  391. * xmlSchemaBasicItem:
  392. *
  393. * The abstract base type for schema components.
  394. */
  395. typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
  396. typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
  397. struct _xmlSchemaBasicItem {
  398. xmlSchemaTypeType type;
  399. void *dummy; /* Fix alignment issues */
  400. };
  401. /**
  402. * xmlSchemaAnnotItem:
  403. *
  404. * The abstract base type for annotated schema components.
  405. * (Extends xmlSchemaBasicItem)
  406. */
  407. typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
  408. typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
  409. struct _xmlSchemaAnnotItem {
  410. xmlSchemaTypeType type;
  411. xmlSchemaAnnotPtr annot;
  412. };
  413. /**
  414. * xmlSchemaTreeItem:
  415. *
  416. * The abstract base type for tree-like structured schema components.
  417. * (Extends xmlSchemaAnnotItem)
  418. */
  419. typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
  420. typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
  421. struct _xmlSchemaTreeItem {
  422. xmlSchemaTypeType type;
  423. xmlSchemaAnnotPtr annot;
  424. xmlSchemaTreeItemPtr next;
  425. xmlSchemaTreeItemPtr children;
  426. };
  427. #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
  428. /**
  429. * xmlSchemaAttributeUsePtr:
  430. *
  431. * The abstract base type for tree-like structured schema components.
  432. * (Extends xmlSchemaTreeItem)
  433. */
  434. typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
  435. typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
  436. struct _xmlSchemaAttributeUse {
  437. xmlSchemaTypeType type;
  438. xmlSchemaAnnotPtr annot;
  439. xmlSchemaAttributeUsePtr next; /* The next attr. use. */
  440. /*
  441. * The attr. decl. OR a QName-ref. to an attr. decl. OR
  442. * a QName-ref. to an attribute group definition.
  443. */
  444. xmlSchemaAttributePtr attrDecl;
  445. int flags;
  446. xmlNodePtr node;
  447. int occurs; /* required, optional */
  448. const xmlChar * defValue;
  449. xmlSchemaValPtr defVal;
  450. };
  451. /**
  452. * xmlSchemaAttributeUseProhibPtr:
  453. *
  454. * A helper component to reflect attribute prohibitions.
  455. * (Extends xmlSchemaBasicItem)
  456. */
  457. typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
  458. typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
  459. struct _xmlSchemaAttributeUseProhib {
  460. xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
  461. xmlNodePtr node;
  462. const xmlChar *name;
  463. const xmlChar *targetNamespace;
  464. int isRef;
  465. };
  466. /**
  467. * xmlSchemaRedef:
  468. */
  469. typedef struct _xmlSchemaRedef xmlSchemaRedef;
  470. typedef xmlSchemaRedef *xmlSchemaRedefPtr;
  471. struct _xmlSchemaRedef {
  472. xmlSchemaRedefPtr next;
  473. xmlSchemaBasicItemPtr item; /* The redefining component. */
  474. xmlSchemaBasicItemPtr reference; /* The referencing component. */
  475. xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
  476. const xmlChar *refName; /* The name of the to-be-redefined component. */
  477. const xmlChar *refTargetNs; /* The target namespace of the
  478. to-be-redefined comp. */
  479. xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
  480. };
  481. /**
  482. * xmlSchemaConstructionCtxt:
  483. */
  484. typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
  485. typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
  486. struct _xmlSchemaConstructionCtxt {
  487. xmlSchemaPtr mainSchema; /* The main schema. */
  488. xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
  489. xmlDictPtr dict;
  490. xmlSchemaItemListPtr buckets; /* List of schema buckets. */
  491. /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
  492. xmlSchemaBucketPtr bucket; /* The current schema bucket */
  493. xmlSchemaItemListPtr pending; /* All Components of all schemas that
  494. need to be fixed. */
  495. xmlHashTablePtr substGroups;
  496. xmlSchemaRedefPtr redefs;
  497. xmlSchemaRedefPtr lastRedef;
  498. };
  499. #define XML_SCHEMAS_PARSE_ERROR 1
  500. #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
  501. struct _xmlSchemaParserCtxt {
  502. int type;
  503. void *errCtxt; /* user specific error context */
  504. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  505. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  506. int err;
  507. int nberrors;
  508. xmlStructuredErrorFunc serror;
  509. xmlSchemaConstructionCtxtPtr constructor;
  510. int ownsConstructor; /* TODO: Move this to parser *flags*. */
  511. /* xmlSchemaPtr topschema; */
  512. /* xmlHashTablePtr namespaces; */
  513. xmlSchemaPtr schema; /* The main schema in use */
  514. int counter;
  515. const xmlChar *URL;
  516. xmlDocPtr doc;
  517. int preserve; /* Whether the doc should be freed */
  518. const char *buffer;
  519. int size;
  520. /*
  521. * Used to build complex element content models
  522. */
  523. xmlAutomataPtr am;
  524. xmlAutomataStatePtr start;
  525. xmlAutomataStatePtr end;
  526. xmlAutomataStatePtr state;
  527. xmlDictPtr dict; /* dictionary for interned string names */
  528. xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
  529. int options;
  530. xmlSchemaValidCtxtPtr vctxt;
  531. int isS4S;
  532. int isRedefine;
  533. int xsiAssemble;
  534. int stop; /* If the parser should stop; i.e. a critical error. */
  535. const xmlChar *targetNamespace;
  536. xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
  537. xmlSchemaRedefPtr redef; /* Used for redefinitions. */
  538. int redefCounter; /* Used for redefinitions. */
  539. xmlSchemaItemListPtr attrProhibs;
  540. };
  541. /**
  542. * xmlSchemaQNameRef:
  543. *
  544. * A component reference item (not a schema component)
  545. * (Extends xmlSchemaBasicItem)
  546. */
  547. typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
  548. typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
  549. struct _xmlSchemaQNameRef {
  550. xmlSchemaTypeType type;
  551. xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
  552. xmlSchemaTypeType itemType;
  553. const xmlChar *name;
  554. const xmlChar *targetNamespace;
  555. xmlNodePtr node;
  556. };
  557. /**
  558. * xmlSchemaParticle:
  559. *
  560. * A particle component.
  561. * (Extends xmlSchemaTreeItem)
  562. */
  563. typedef struct _xmlSchemaParticle xmlSchemaParticle;
  564. typedef xmlSchemaParticle *xmlSchemaParticlePtr;
  565. struct _xmlSchemaParticle {
  566. xmlSchemaTypeType type;
  567. xmlSchemaAnnotPtr annot;
  568. xmlSchemaTreeItemPtr next; /* next particle */
  569. xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
  570. a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
  571. etc.) */
  572. int minOccurs;
  573. int maxOccurs;
  574. xmlNodePtr node;
  575. };
  576. /**
  577. * xmlSchemaModelGroup:
  578. *
  579. * A model group component.
  580. * (Extends xmlSchemaTreeItem)
  581. */
  582. typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
  583. typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
  584. struct _xmlSchemaModelGroup {
  585. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
  586. xmlSchemaAnnotPtr annot;
  587. xmlSchemaTreeItemPtr next; /* not used */
  588. xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
  589. xmlNodePtr node;
  590. };
  591. #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
  592. #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
  593. /**
  594. * xmlSchemaModelGroupDef:
  595. *
  596. * A model group definition component.
  597. * (Extends xmlSchemaTreeItem)
  598. */
  599. typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
  600. typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
  601. struct _xmlSchemaModelGroupDef {
  602. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
  603. xmlSchemaAnnotPtr annot;
  604. xmlSchemaTreeItemPtr next; /* not used */
  605. xmlSchemaTreeItemPtr children; /* the "model group" */
  606. const xmlChar *name;
  607. const xmlChar *targetNamespace;
  608. xmlNodePtr node;
  609. int flags;
  610. };
  611. typedef struct _xmlSchemaIDC xmlSchemaIDC;
  612. typedef xmlSchemaIDC *xmlSchemaIDCPtr;
  613. /**
  614. * xmlSchemaIDCSelect:
  615. *
  616. * The identity-constraint "field" and "selector" item, holding the
  617. * XPath expression.
  618. */
  619. typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
  620. typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
  621. struct _xmlSchemaIDCSelect {
  622. xmlSchemaIDCSelectPtr next;
  623. xmlSchemaIDCPtr idc;
  624. int index; /* an index position if significant for IDC key-sequences */
  625. const xmlChar *xpath; /* the XPath expression */
  626. void *xpathComp; /* the compiled XPath expression */
  627. };
  628. /**
  629. * xmlSchemaIDC:
  630. *
  631. * The identity-constraint definition component.
  632. * (Extends xmlSchemaAnnotItem)
  633. */
  634. struct _xmlSchemaIDC {
  635. xmlSchemaTypeType type;
  636. xmlSchemaAnnotPtr annot;
  637. xmlSchemaIDCPtr next;
  638. xmlNodePtr node;
  639. const xmlChar *name;
  640. const xmlChar *targetNamespace;
  641. xmlSchemaIDCSelectPtr selector;
  642. xmlSchemaIDCSelectPtr fields;
  643. int nbFields;
  644. xmlSchemaQNameRefPtr ref;
  645. };
  646. /**
  647. * xmlSchemaIDCAug:
  648. *
  649. * The augmented IDC information used for validation.
  650. */
  651. typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
  652. typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
  653. struct _xmlSchemaIDCAug {
  654. xmlSchemaIDCAugPtr next; /* next in a list */
  655. xmlSchemaIDCPtr def; /* the IDC definition */
  656. int keyrefDepth; /* the lowest tree level to which IDC
  657. tables need to be bubbled upwards */
  658. };
  659. /**
  660. * xmlSchemaPSVIIDCKeySequence:
  661. *
  662. * The key sequence of a node table item.
  663. */
  664. typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
  665. typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
  666. struct _xmlSchemaPSVIIDCKey {
  667. xmlSchemaTypePtr type;
  668. xmlSchemaValPtr val;
  669. };
  670. /**
  671. * xmlSchemaPSVIIDCNode:
  672. *
  673. * The node table item of a node table.
  674. */
  675. typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
  676. typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
  677. struct _xmlSchemaPSVIIDCNode {
  678. xmlNodePtr node;
  679. xmlSchemaPSVIIDCKeyPtr *keys;
  680. int nodeLine;
  681. int nodeQNameID;
  682. };
  683. /**
  684. * xmlSchemaPSVIIDCBinding:
  685. *
  686. * The identity-constraint binding item of the [identity-constraint table].
  687. */
  688. typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
  689. typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
  690. struct _xmlSchemaPSVIIDCBinding {
  691. xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
  692. xmlSchemaIDCPtr definition; /* the IDC definition */
  693. xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
  694. int nbNodes; /* number of entries in the node table */
  695. int sizeNodes; /* size of the node table */
  696. xmlSchemaItemListPtr dupls;
  697. };
  698. #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
  699. #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
  700. #define XPATH_STATE_OBJ_MATCHES -2
  701. #define XPATH_STATE_OBJ_BLOCKED -3
  702. typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
  703. typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
  704. /**
  705. * xmlSchemaIDCStateObj:
  706. *
  707. * The state object used to evaluate XPath expressions.
  708. */
  709. typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
  710. typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
  711. struct _xmlSchemaIDCStateObj {
  712. int type;
  713. xmlSchemaIDCStateObjPtr next; /* next if in a list */
  714. int depth; /* depth of creation */
  715. int *history; /* list of (depth, state-id) tuples */
  716. int nbHistory;
  717. int sizeHistory;
  718. xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
  719. matcher */
  720. xmlSchemaIDCSelectPtr sel;
  721. void *xpathCtxt;
  722. };
  723. #define IDC_MATCHER 0
  724. /**
  725. * xmlSchemaIDCMatcher:
  726. *
  727. * Used to evaluate IDC selectors (and fields).
  728. */
  729. struct _xmlSchemaIDCMatcher {
  730. int type;
  731. int depth; /* the tree depth at creation time */
  732. xmlSchemaIDCMatcherPtr next; /* next in the list */
  733. xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
  734. xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
  735. int idcType;
  736. xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
  737. elements */
  738. int sizeKeySeqs;
  739. xmlSchemaItemListPtr targets; /* list of target-node
  740. (xmlSchemaPSVIIDCNodePtr) entries */
  741. xmlHashTablePtr htab;
  742. };
  743. /*
  744. * Element info flags.
  745. */
  746. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
  747. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
  748. #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
  749. #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
  750. #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
  751. #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
  752. #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
  753. #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
  754. #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
  755. #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
  756. #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
  757. /**
  758. * xmlSchemaNodeInfo:
  759. *
  760. * Holds information of an element node.
  761. */
  762. struct _xmlSchemaNodeInfo {
  763. int nodeType;
  764. xmlNodePtr node;
  765. int nodeLine;
  766. const xmlChar *localName;
  767. const xmlChar *nsName;
  768. const xmlChar *value;
  769. xmlSchemaValPtr val; /* the pre-computed value if any */
  770. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  771. int flags; /* combination of node info flags */
  772. int valNeeded;
  773. int normVal;
  774. xmlSchemaElementPtr decl; /* the element/attribute declaration */
  775. int depth;
  776. xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
  777. for the scope element*/
  778. xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
  779. element */
  780. xmlRegExecCtxtPtr regexCtxt;
  781. const xmlChar **nsBindings; /* Namespace bindings on this element */
  782. int nbNsBindings;
  783. int sizeNsBindings;
  784. int hasKeyrefs;
  785. int appliedXPath; /* Indicates that an XPath has been applied. */
  786. };
  787. #define XML_SCHEMAS_ATTR_UNKNOWN 1
  788. #define XML_SCHEMAS_ATTR_ASSESSED 2
  789. #define XML_SCHEMAS_ATTR_PROHIBITED 3
  790. #define XML_SCHEMAS_ATTR_ERR_MISSING 4
  791. #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
  792. #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
  793. #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
  794. #define XML_SCHEMAS_ATTR_DEFAULT 8
  795. #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
  796. #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
  797. #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
  798. #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
  799. #define XML_SCHEMAS_ATTR_WILD_SKIP 13
  800. #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
  801. #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
  802. #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
  803. #define XML_SCHEMAS_ATTR_META 17
  804. /*
  805. * @metaType values of xmlSchemaAttrInfo.
  806. */
  807. #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
  808. #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
  809. #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
  810. #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
  811. #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
  812. typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
  813. typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
  814. struct _xmlSchemaAttrInfo {
  815. int nodeType;
  816. xmlNodePtr node;
  817. int nodeLine;
  818. const xmlChar *localName;
  819. const xmlChar *nsName;
  820. const xmlChar *value;
  821. xmlSchemaValPtr val; /* the pre-computed value if any */
  822. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  823. int flags; /* combination of node info flags */
  824. xmlSchemaAttributePtr decl; /* the attribute declaration */
  825. xmlSchemaAttributeUsePtr use; /* the attribute use */
  826. int state;
  827. int metaType;
  828. const xmlChar *vcValue; /* the value constraint value */
  829. xmlSchemaNodeInfoPtr parent;
  830. };
  831. #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
  832. /**
  833. * xmlSchemaValidCtxt:
  834. *
  835. * A Schemas validation context
  836. */
  837. struct _xmlSchemaValidCtxt {
  838. int type;
  839. void *errCtxt; /* user specific data block */
  840. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  841. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  842. xmlStructuredErrorFunc serror;
  843. xmlSchemaPtr schema; /* The schema in use */
  844. xmlDocPtr doc;
  845. xmlParserInputBufferPtr input;
  846. xmlCharEncoding enc;
  847. xmlSAXHandlerPtr sax;
  848. xmlParserCtxtPtr parserCtxt;
  849. void *user_data; /* TODO: What is this for? */
  850. char *filename;
  851. int err;
  852. int nberrors;
  853. xmlNodePtr node;
  854. xmlNodePtr cur;
  855. /* xmlSchemaTypePtr type; */
  856. xmlRegExecCtxtPtr regexp;
  857. xmlSchemaValPtr value;
  858. int valueWS;
  859. int options;
  860. xmlNodePtr validationRoot;
  861. xmlSchemaParserCtxtPtr pctxt;
  862. int xsiAssemble;
  863. int depth;
  864. xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
  865. int sizeElemInfos;
  866. xmlSchemaNodeInfoPtr inode; /* the current element information */
  867. xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
  868. xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
  869. xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
  870. xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
  871. xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
  872. int nbIdcNodes;
  873. int sizeIdcNodes;
  874. xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
  875. int nbIdcKeys;
  876. int sizeIdcKeys;
  877. int flags;
  878. xmlDictPtr dict;
  879. #ifdef LIBXML_READER_ENABLED
  880. xmlTextReaderPtr reader;
  881. #endif
  882. xmlSchemaAttrInfoPtr *attrInfos;
  883. int nbAttrInfos;
  884. int sizeAttrInfos;
  885. int skipDepth;
  886. xmlSchemaItemListPtr nodeQNames;
  887. int hasKeyrefs;
  888. int createIDCNodeTables;
  889. int psviExposeIDCNodeTables;
  890. /* Locator for error reporting in streaming mode */
  891. xmlSchemaValidityLocatorFunc locFunc;
  892. void *locCtxt;
  893. };
  894. /**
  895. * xmlSchemaSubstGroup:
  896. *
  897. *
  898. */
  899. typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
  900. typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
  901. struct _xmlSchemaSubstGroup {
  902. xmlSchemaElementPtr head;
  903. xmlSchemaItemListPtr members;
  904. };
  905. /**
  906. * xmlIDCHashEntry:
  907. *
  908. * an entry in hash tables to quickly look up keys/uniques
  909. */
  910. typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
  911. typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
  912. struct _xmlIDCHashEntry {
  913. xmlIDCHashEntryPtr next; /* next item with same hash */
  914. int index; /* index into associated item list */
  915. };
  916. /************************************************************************
  917. * *
  918. * Some predeclarations *
  919. * *
  920. ************************************************************************/
  921. static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
  922. xmlSchemaPtr schema,
  923. xmlNodePtr node);
  924. static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
  925. xmlSchemaPtr schema,
  926. xmlNodePtr node);
  927. static int
  928. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  929. xmlSchemaAbstractCtxtPtr ctxt);
  930. static const xmlChar *
  931. xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
  932. static int
  933. xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  934. xmlNodePtr node);
  935. static int
  936. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  937. xmlSchemaParserCtxtPtr ctxt);
  938. static void
  939. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
  940. static xmlSchemaWhitespaceValueType
  941. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
  942. static xmlSchemaTreeItemPtr
  943. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  944. xmlNodePtr node, xmlSchemaTypeType type,
  945. int withParticle);
  946. static const xmlChar *
  947. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
  948. static xmlSchemaTypeLinkPtr
  949. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
  950. static void
  951. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  952. const char *funcName,
  953. const char *message) LIBXML_ATTR_FORMAT(3,0);
  954. static int
  955. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
  956. xmlSchemaTypePtr type,
  957. xmlSchemaTypePtr baseType,
  958. int subset);
  959. static void
  960. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  961. xmlSchemaParserCtxtPtr ctxt);
  962. static void
  963. xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
  964. static xmlSchemaQNameRefPtr
  965. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  966. xmlSchemaPtr schema,
  967. xmlNodePtr node);
  968. /************************************************************************
  969. * *
  970. * Helper functions *
  971. * *
  972. ************************************************************************/
  973. /**
  974. * xmlSchemaItemTypeToStr:
  975. * @type: the type of the schema item
  976. *
  977. * Returns the component name of a schema item.
  978. */
  979. static const xmlChar *
  980. xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
  981. {
  982. switch (type) {
  983. case XML_SCHEMA_TYPE_BASIC:
  984. return(BAD_CAST "simple type definition");
  985. case XML_SCHEMA_TYPE_SIMPLE:
  986. return(BAD_CAST "simple type definition");
  987. case XML_SCHEMA_TYPE_COMPLEX:
  988. return(BAD_CAST "complex type definition");
  989. case XML_SCHEMA_TYPE_ELEMENT:
  990. return(BAD_CAST "element declaration");
  991. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  992. return(BAD_CAST "attribute use");
  993. case XML_SCHEMA_TYPE_ATTRIBUTE:
  994. return(BAD_CAST "attribute declaration");
  995. case XML_SCHEMA_TYPE_GROUP:
  996. return(BAD_CAST "model group definition");
  997. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  998. return(BAD_CAST "attribute group definition");
  999. case XML_SCHEMA_TYPE_NOTATION:
  1000. return(BAD_CAST "notation declaration");
  1001. case XML_SCHEMA_TYPE_SEQUENCE:
  1002. return(BAD_CAST "model group (sequence)");
  1003. case XML_SCHEMA_TYPE_CHOICE:
  1004. return(BAD_CAST "model group (choice)");
  1005. case XML_SCHEMA_TYPE_ALL:
  1006. return(BAD_CAST "model group (all)");
  1007. case XML_SCHEMA_TYPE_PARTICLE:
  1008. return(BAD_CAST "particle");
  1009. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1010. return(BAD_CAST "unique identity-constraint");
  1011. /* return(BAD_CAST "IDC (unique)"); */
  1012. case XML_SCHEMA_TYPE_IDC_KEY:
  1013. return(BAD_CAST "key identity-constraint");
  1014. /* return(BAD_CAST "IDC (key)"); */
  1015. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1016. return(BAD_CAST "keyref identity-constraint");
  1017. /* return(BAD_CAST "IDC (keyref)"); */
  1018. case XML_SCHEMA_TYPE_ANY:
  1019. return(BAD_CAST "wildcard (any)");
  1020. case XML_SCHEMA_EXTRA_QNAMEREF:
  1021. return(BAD_CAST "[helper component] QName reference");
  1022. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  1023. return(BAD_CAST "[helper component] attribute use prohibition");
  1024. default:
  1025. return(BAD_CAST "Not a schema component");
  1026. }
  1027. }
  1028. /**
  1029. * xmlSchemaGetComponentTypeStr:
  1030. * @type: the type of the schema item
  1031. *
  1032. * Returns the component name of a schema item.
  1033. */
  1034. static const xmlChar *
  1035. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
  1036. {
  1037. switch (item->type) {
  1038. case XML_SCHEMA_TYPE_BASIC:
  1039. if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
  1040. return(BAD_CAST "complex type definition");
  1041. else
  1042. return(BAD_CAST "simple type definition");
  1043. default:
  1044. return(xmlSchemaItemTypeToStr(item->type));
  1045. }
  1046. }
  1047. /**
  1048. * xmlSchemaGetComponentNode:
  1049. * @item: a schema component
  1050. *
  1051. * Returns node associated with the schema component.
  1052. * NOTE that such a node need not be available; plus, a component's
  1053. * node need not to reflect the component directly, since there is no
  1054. * one-to-one relationship between the XML Schema representation and
  1055. * the component representation.
  1056. */
  1057. static xmlNodePtr
  1058. xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
  1059. {
  1060. switch (item->type) {
  1061. case XML_SCHEMA_TYPE_ELEMENT:
  1062. return (((xmlSchemaElementPtr) item)->node);
  1063. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1064. return (((xmlSchemaAttributePtr) item)->node);
  1065. case XML_SCHEMA_TYPE_COMPLEX:
  1066. case XML_SCHEMA_TYPE_SIMPLE:
  1067. return (((xmlSchemaTypePtr) item)->node);
  1068. case XML_SCHEMA_TYPE_ANY:
  1069. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1070. return (((xmlSchemaWildcardPtr) item)->node);
  1071. case XML_SCHEMA_TYPE_PARTICLE:
  1072. return (((xmlSchemaParticlePtr) item)->node);
  1073. case XML_SCHEMA_TYPE_SEQUENCE:
  1074. case XML_SCHEMA_TYPE_CHOICE:
  1075. case XML_SCHEMA_TYPE_ALL:
  1076. return (((xmlSchemaModelGroupPtr) item)->node);
  1077. case XML_SCHEMA_TYPE_GROUP:
  1078. return (((xmlSchemaModelGroupDefPtr) item)->node);
  1079. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1080. return (((xmlSchemaAttributeGroupPtr) item)->node);
  1081. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1082. case XML_SCHEMA_TYPE_IDC_KEY:
  1083. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1084. return (((xmlSchemaIDCPtr) item)->node);
  1085. case XML_SCHEMA_EXTRA_QNAMEREF:
  1086. return(((xmlSchemaQNameRefPtr) item)->node);
  1087. /* TODO: What to do with NOTATIONs?
  1088. case XML_SCHEMA_TYPE_NOTATION:
  1089. return (((xmlSchemaNotationPtr) item)->node);
  1090. */
  1091. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1092. return (((xmlSchemaAttributeUsePtr) item)->node);
  1093. default:
  1094. return (NULL);
  1095. }
  1096. }
  1097. #if 0
  1098. /**
  1099. * xmlSchemaGetNextComponent:
  1100. * @item: a schema component
  1101. *
  1102. * Returns the next sibling of the schema component.
  1103. */
  1104. static xmlSchemaBasicItemPtr
  1105. xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
  1106. {
  1107. switch (item->type) {
  1108. case XML_SCHEMA_TYPE_ELEMENT:
  1109. return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
  1110. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1111. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
  1112. case XML_SCHEMA_TYPE_COMPLEX:
  1113. case XML_SCHEMA_TYPE_SIMPLE:
  1114. return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
  1115. case XML_SCHEMA_TYPE_ANY:
  1116. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1117. return (NULL);
  1118. case XML_SCHEMA_TYPE_PARTICLE:
  1119. return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
  1120. case XML_SCHEMA_TYPE_SEQUENCE:
  1121. case XML_SCHEMA_TYPE_CHOICE:
  1122. case XML_SCHEMA_TYPE_ALL:
  1123. return (NULL);
  1124. case XML_SCHEMA_TYPE_GROUP:
  1125. return (NULL);
  1126. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1127. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
  1128. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1129. case XML_SCHEMA_TYPE_IDC_KEY:
  1130. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1131. return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
  1132. default:
  1133. return (NULL);
  1134. }
  1135. }
  1136. #endif
  1137. /**
  1138. * xmlSchemaFormatQName:
  1139. * @buf: the string buffer
  1140. * @namespaceName: the namespace name
  1141. * @localName: the local name
  1142. *
  1143. * Returns the given QName in the format "{namespaceName}localName" or
  1144. * just "localName" if @namespaceName is NULL.
  1145. *
  1146. * Returns the localName if @namespaceName is NULL, a formatted
  1147. * string otherwise.
  1148. */
  1149. static const xmlChar*
  1150. xmlSchemaFormatQName(xmlChar **buf,
  1151. const xmlChar *namespaceName,
  1152. const xmlChar *localName)
  1153. {
  1154. FREE_AND_NULL(*buf)
  1155. if (namespaceName != NULL) {
  1156. *buf = xmlStrdup(BAD_CAST "{");
  1157. *buf = xmlStrcat(*buf, namespaceName);
  1158. *buf = xmlStrcat(*buf, BAD_CAST "}");
  1159. }
  1160. if (localName != NULL) {
  1161. if (namespaceName == NULL)
  1162. return(localName);
  1163. *buf = xmlStrcat(*buf, localName);
  1164. } else {
  1165. *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
  1166. }
  1167. return ((const xmlChar *) *buf);
  1168. }
  1169. static const xmlChar*
  1170. xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
  1171. {
  1172. if (ns != NULL)
  1173. return (xmlSchemaFormatQName(buf, ns->href, localName));
  1174. else
  1175. return (xmlSchemaFormatQName(buf, NULL, localName));
  1176. }
  1177. static const xmlChar *
  1178. xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
  1179. {
  1180. switch (item->type) {
  1181. case XML_SCHEMA_TYPE_ELEMENT:
  1182. return (((xmlSchemaElementPtr) item)->name);
  1183. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1184. return (((xmlSchemaAttributePtr) item)->name);
  1185. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1186. return (((xmlSchemaAttributeGroupPtr) item)->name);
  1187. case XML_SCHEMA_TYPE_BASIC:
  1188. case XML_SCHEMA_TYPE_SIMPLE:
  1189. case XML_SCHEMA_TYPE_COMPLEX:
  1190. return (((xmlSchemaTypePtr) item)->name);
  1191. case XML_SCHEMA_TYPE_GROUP:
  1192. return (((xmlSchemaModelGroupDefPtr) item)->name);
  1193. case XML_SCHEMA_TYPE_IDC_KEY:
  1194. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1195. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1196. return (((xmlSchemaIDCPtr) item)->name);
  1197. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1198. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1199. return(xmlSchemaGetComponentName(
  1200. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1201. } else
  1202. return(NULL);
  1203. case XML_SCHEMA_EXTRA_QNAMEREF:
  1204. return (((xmlSchemaQNameRefPtr) item)->name);
  1205. case XML_SCHEMA_TYPE_NOTATION:
  1206. return (((xmlSchemaNotationPtr) item)->name);
  1207. default:
  1208. /*
  1209. * Other components cannot have names.
  1210. */
  1211. break;
  1212. }
  1213. return (NULL);
  1214. }
  1215. #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
  1216. #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
  1217. /*
  1218. static const xmlChar *
  1219. xmlSchemaGetQNameRefName(void *ref)
  1220. {
  1221. return(((xmlSchemaQNameRefPtr) ref)->name);
  1222. }
  1223. static const xmlChar *
  1224. xmlSchemaGetQNameRefTargetNs(void *ref)
  1225. {
  1226. return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
  1227. }
  1228. */
  1229. static const xmlChar *
  1230. xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
  1231. {
  1232. switch (item->type) {
  1233. case XML_SCHEMA_TYPE_ELEMENT:
  1234. return (((xmlSchemaElementPtr) item)->targetNamespace);
  1235. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1236. return (((xmlSchemaAttributePtr) item)->targetNamespace);
  1237. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1238. return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
  1239. case XML_SCHEMA_TYPE_BASIC:
  1240. return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
  1241. case XML_SCHEMA_TYPE_SIMPLE:
  1242. case XML_SCHEMA_TYPE_COMPLEX:
  1243. return (((xmlSchemaTypePtr) item)->targetNamespace);
  1244. case XML_SCHEMA_TYPE_GROUP:
  1245. return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
  1246. case XML_SCHEMA_TYPE_IDC_KEY:
  1247. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1248. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1249. return (((xmlSchemaIDCPtr) item)->targetNamespace);
  1250. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1251. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1252. return(xmlSchemaGetComponentTargetNs(
  1253. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1254. }
  1255. /* TODO: Will returning NULL break something? */
  1256. break;
  1257. case XML_SCHEMA_EXTRA_QNAMEREF:
  1258. return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
  1259. case XML_SCHEMA_TYPE_NOTATION:
  1260. return (((xmlSchemaNotationPtr) item)->targetNamespace);
  1261. default:
  1262. /*
  1263. * Other components cannot have names.
  1264. */
  1265. break;
  1266. }
  1267. return (NULL);
  1268. }
  1269. static const xmlChar*
  1270. xmlSchemaGetComponentQName(xmlChar **buf,
  1271. void *item)
  1272. {
  1273. return (xmlSchemaFormatQName(buf,
  1274. xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
  1275. xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
  1276. }
  1277. static const xmlChar*
  1278. xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
  1279. {
  1280. xmlChar *str = NULL;
  1281. *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
  1282. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1283. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
  1284. (xmlSchemaBasicItemPtr) item));
  1285. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1286. FREE_AND_NULL(str);
  1287. return(*buf);
  1288. }
  1289. static const xmlChar*
  1290. xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
  1291. {
  1292. return(xmlSchemaGetComponentDesignation(buf, idc));
  1293. }
  1294. /**
  1295. * xmlSchemaWildcardPCToString:
  1296. * @pc: the type of processContents
  1297. *
  1298. * Returns a string representation of the type of
  1299. * processContents.
  1300. */
  1301. static const xmlChar *
  1302. xmlSchemaWildcardPCToString(int pc)
  1303. {
  1304. switch (pc) {
  1305. case XML_SCHEMAS_ANY_SKIP:
  1306. return (BAD_CAST "skip");
  1307. case XML_SCHEMAS_ANY_LAX:
  1308. return (BAD_CAST "lax");
  1309. case XML_SCHEMAS_ANY_STRICT:
  1310. return (BAD_CAST "strict");
  1311. default:
  1312. return (BAD_CAST "invalid process contents");
  1313. }
  1314. }
  1315. /**
  1316. * xmlSchemaGetCanonValueWhtspExt:
  1317. * @val: the precomputed value
  1318. * @retValue: the returned value
  1319. * @ws: the whitespace type of the value
  1320. * @for_hash: non-zero if this is supposed to generate a string for hashing
  1321. *
  1322. * Get a the canonical representation of the value.
  1323. * The caller has to free the returned retValue.
  1324. *
  1325. * Returns 0 if the value could be built and -1 in case of
  1326. * API errors or if the value type is not supported yet.
  1327. */
  1328. static int
  1329. xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
  1330. xmlSchemaWhitespaceValueType ws,
  1331. xmlChar **retValue,
  1332. int for_hash)
  1333. {
  1334. int list;
  1335. xmlSchemaValType valType;
  1336. const xmlChar *value, *value2 = NULL;
  1337. if ((retValue == NULL) || (val == NULL))
  1338. return (-1);
  1339. list = xmlSchemaValueGetNext(val) ? 1 : 0;
  1340. *retValue = NULL;
  1341. do {
  1342. value = NULL;
  1343. valType = xmlSchemaGetValType(val);
  1344. switch (valType) {
  1345. case XML_SCHEMAS_STRING:
  1346. case XML_SCHEMAS_NORMSTRING:
  1347. case XML_SCHEMAS_ANYSIMPLETYPE:
  1348. value = xmlSchemaValueGetAsString(val);
  1349. if (value != NULL) {
  1350. if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
  1351. value2 = xmlSchemaCollapseString(value);
  1352. else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
  1353. value2 = xmlSchemaWhiteSpaceReplace(value);
  1354. if (value2 != NULL)
  1355. value = value2;
  1356. }
  1357. break;
  1358. default:
  1359. if (xmlSchemaGetCanonValue(val, &value2) == -1) {
  1360. if (value2 != NULL)
  1361. xmlFree((xmlChar *) value2);
  1362. goto internal_error;
  1363. }
  1364. if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
  1365. /* We can mostly use the canonical value for hashing,
  1366. except in the case of decimal. There the canonical
  1367. representation requires a trailing '.0' even for
  1368. non-fractional numbers, but for the derived integer
  1369. types it forbids any decimal point. Nevertheless they
  1370. compare equal if the value is equal. We need to generate
  1371. the same hash value for this to work, and it's easiest
  1372. to just cut off the useless '.0' suffix for the
  1373. decimal type. */
  1374. int len = xmlStrlen(value2);
  1375. if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
  1376. ((xmlChar*)value2)[len-2] = 0;
  1377. }
  1378. value = value2;
  1379. }
  1380. if (*retValue == NULL)
  1381. if (value == NULL) {
  1382. if (! list)
  1383. *retValue = xmlStrdup(BAD_CAST "");
  1384. } else
  1385. *retValue = xmlStrdup(value);
  1386. else if (value != NULL) {
  1387. /* List. */
  1388. *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
  1389. *retValue = xmlStrcat((xmlChar *) *retValue, value);
  1390. }
  1391. FREE_AND_NULL(value2)
  1392. val = xmlSchemaValueGetNext(val);
  1393. } while (val != NULL);
  1394. return (0);
  1395. internal_error:
  1396. if (*retValue != NULL)
  1397. xmlFree((xmlChar *) (*retValue));
  1398. if (value2 != NULL)
  1399. xmlFree((xmlChar *) value2);
  1400. return (-1);
  1401. }
  1402. static int
  1403. xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
  1404. xmlSchemaWhitespaceValueType ws,
  1405. xmlChar **retValue)
  1406. {
  1407. return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
  1408. }
  1409. static int
  1410. xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
  1411. xmlChar **retValue)
  1412. {
  1413. return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
  1414. retValue, 1);
  1415. }
  1416. /**
  1417. * xmlSchemaFormatItemForReport:
  1418. * @buf: the string buffer
  1419. * @itemDes: the designation of the item
  1420. * @itemName: the name of the item
  1421. * @item: the item as an object
  1422. * @itemNode: the node of the item
  1423. * @local: the local name
  1424. * @parsing: if the function is used during the parse
  1425. *
  1426. * Returns a representation of the given item used
  1427. * for error reports.
  1428. *
  1429. * The following order is used to build the resulting
  1430. * designation if the arguments are not NULL:
  1431. * 1a. If itemDes not NULL -> itemDes
  1432. * 1b. If (itemDes not NULL) and (itemName not NULL)
  1433. * -> itemDes + itemName
  1434. * 2. If the preceding was NULL and (item not NULL) -> item
  1435. * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
  1436. *
  1437. * If the itemNode is an attribute node, the name of the attribute
  1438. * will be appended to the result.
  1439. *
  1440. * Returns the formatted string and sets @buf to the resulting value.
  1441. */
  1442. static xmlChar*
  1443. xmlSchemaFormatItemForReport(xmlChar **buf,
  1444. const xmlChar *itemDes,
  1445. xmlSchemaBasicItemPtr item,
  1446. xmlNodePtr itemNode)
  1447. {
  1448. xmlChar *str = NULL;
  1449. int named = 1;
  1450. if (*buf != NULL) {
  1451. xmlFree(*buf);
  1452. *buf = NULL;
  1453. }
  1454. if (itemDes != NULL) {
  1455. *buf = xmlStrdup(itemDes);
  1456. } else if (item != NULL) {
  1457. switch (item->type) {
  1458. case XML_SCHEMA_TYPE_BASIC: {
  1459. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1460. if (WXS_IS_ATOMIC(type))
  1461. *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
  1462. else if (WXS_IS_LIST(type))
  1463. *buf = xmlStrdup(BAD_CAST "list type 'xs:");
  1464. else if (WXS_IS_UNION(type))
  1465. *buf = xmlStrdup(BAD_CAST "union type 'xs:");
  1466. else
  1467. *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
  1468. *buf = xmlStrcat(*buf, type->name);
  1469. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1470. }
  1471. break;
  1472. case XML_SCHEMA_TYPE_SIMPLE: {
  1473. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1474. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1475. *buf = xmlStrdup(BAD_CAST"");
  1476. } else {
  1477. *buf = xmlStrdup(BAD_CAST "local ");
  1478. }
  1479. if (WXS_IS_ATOMIC(type))
  1480. *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
  1481. else if (WXS_IS_LIST(type))
  1482. *buf = xmlStrcat(*buf, BAD_CAST "list type");
  1483. else if (WXS_IS_UNION(type))
  1484. *buf = xmlStrcat(*buf, BAD_CAST "union type");
  1485. else
  1486. *buf = xmlStrcat(*buf, BAD_CAST "simple type");
  1487. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1488. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1489. *buf = xmlStrcat(*buf, type->name);
  1490. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1491. }
  1492. }
  1493. break;
  1494. case XML_SCHEMA_TYPE_COMPLEX: {
  1495. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1496. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
  1497. *buf = xmlStrdup(BAD_CAST "");
  1498. else
  1499. *buf = xmlStrdup(BAD_CAST "local ");
  1500. *buf = xmlStrcat(*buf, BAD_CAST "complex type");
  1501. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1502. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1503. *buf = xmlStrcat(*buf, type->name);
  1504. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1505. }
  1506. }
  1507. break;
  1508. case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
  1509. xmlSchemaAttributeUsePtr ause;
  1510. ause = WXS_ATTR_USE_CAST item;
  1511. *buf = xmlStrdup(BAD_CAST "attribute use ");
  1512. if (WXS_ATTRUSE_DECL(ause) != NULL) {
  1513. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1514. *buf = xmlStrcat(*buf,
  1515. xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
  1516. FREE_AND_NULL(str)
  1517. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1518. } else {
  1519. *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
  1520. }
  1521. }
  1522. break;
  1523. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  1524. xmlSchemaAttributePtr attr;
  1525. attr = (xmlSchemaAttributePtr) item;
  1526. *buf = xmlStrdup(BAD_CAST "attribute decl.");
  1527. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1528. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1529. attr->targetNamespace, attr->name));
  1530. FREE_AND_NULL(str)
  1531. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1532. }
  1533. break;
  1534. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1535. xmlSchemaGetComponentDesignation(buf, item);
  1536. break;
  1537. case XML_SCHEMA_TYPE_ELEMENT: {
  1538. xmlSchemaElementPtr elem;
  1539. elem = (xmlSchemaElementPtr) item;
  1540. *buf = xmlStrdup(BAD_CAST "element decl.");
  1541. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1542. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1543. elem->targetNamespace, elem->name));
  1544. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1545. }
  1546. break;
  1547. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1548. case XML_SCHEMA_TYPE_IDC_KEY:
  1549. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1550. if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
  1551. *buf = xmlStrdup(BAD_CAST "unique '");
  1552. else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
  1553. *buf = xmlStrdup(BAD_CAST "key '");
  1554. else
  1555. *buf = xmlStrdup(BAD_CAST "keyRef '");
  1556. *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
  1557. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1558. break;
  1559. case XML_SCHEMA_TYPE_ANY:
  1560. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1561. *buf = xmlStrdup(xmlSchemaWildcardPCToString(
  1562. ((xmlSchemaWildcardPtr) item)->processContents));
  1563. *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
  1564. break;
  1565. case XML_SCHEMA_FACET_MININCLUSIVE:
  1566. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  1567. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  1568. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  1569. case XML_SCHEMA_FACET_TOTALDIGITS:
  1570. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  1571. case XML_SCHEMA_FACET_PATTERN:
  1572. case XML_SCHEMA_FACET_ENUMERATION:
  1573. case XML_SCHEMA_FACET_WHITESPACE:
  1574. case XML_SCHEMA_FACET_LENGTH:
  1575. case XML_SCHEMA_FACET_MAXLENGTH:
  1576. case XML_SCHEMA_FACET_MINLENGTH:
  1577. *buf = xmlStrdup(BAD_CAST "facet '");
  1578. *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
  1579. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1580. break;
  1581. case XML_SCHEMA_TYPE_GROUP: {
  1582. *buf = xmlStrdup(BAD_CAST "model group def.");
  1583. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1584. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1585. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1586. FREE_AND_NULL(str)
  1587. }
  1588. break;
  1589. case XML_SCHEMA_TYPE_SEQUENCE:
  1590. case XML_SCHEMA_TYPE_CHOICE:
  1591. case XML_SCHEMA_TYPE_ALL:
  1592. case XML_SCHEMA_TYPE_PARTICLE:
  1593. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1594. break;
  1595. case XML_SCHEMA_TYPE_NOTATION: {
  1596. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1597. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1598. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1599. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1600. FREE_AND_NULL(str);
  1601. }
  1602. /* Falls through. */
  1603. default:
  1604. named = 0;
  1605. }
  1606. } else
  1607. named = 0;
  1608. if ((named == 0) && (itemNode != NULL)) {
  1609. xmlNodePtr elem;
  1610. if (itemNode->type == XML_ATTRIBUTE_NODE)
  1611. elem = itemNode->parent;
  1612. else
  1613. elem = itemNode;
  1614. *buf = xmlStrdup(BAD_CAST "Element '");
  1615. if (elem->ns != NULL) {
  1616. *buf = xmlStrcat(*buf,
  1617. xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
  1618. FREE_AND_NULL(str)
  1619. } else
  1620. *buf = xmlStrcat(*buf, elem->name);
  1621. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1622. }
  1623. if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
  1624. *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
  1625. if (itemNode->ns != NULL) {
  1626. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1627. itemNode->ns->href, itemNode->name));
  1628. FREE_AND_NULL(str)
  1629. } else
  1630. *buf = xmlStrcat(*buf, itemNode->name);
  1631. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1632. }
  1633. FREE_AND_NULL(str)
  1634. return (xmlEscapeFormatString(buf));
  1635. }
  1636. /**
  1637. * xmlSchemaFormatFacetEnumSet:
  1638. * @buf: the string buffer
  1639. * @type: the type holding the enumeration facets
  1640. *
  1641. * Builds a string consisting of all enumeration elements.
  1642. *
  1643. * Returns a string of all enumeration elements.
  1644. */
  1645. static const xmlChar *
  1646. xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
  1647. xmlChar **buf, xmlSchemaTypePtr type)
  1648. {
  1649. xmlSchemaFacetPtr facet;
  1650. xmlSchemaWhitespaceValueType ws;
  1651. xmlChar *value = NULL;
  1652. int res, found = 0;
  1653. if (*buf != NULL)
  1654. xmlFree(*buf);
  1655. *buf = NULL;
  1656. do {
  1657. /*
  1658. * Use the whitespace type of the base type.
  1659. */
  1660. ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
  1661. for (facet = type->facets; facet != NULL; facet = facet->next) {
  1662. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  1663. continue;
  1664. found = 1;
  1665. res = xmlSchemaGetCanonValueWhtspExt(facet->val,
  1666. ws, &value);
  1667. if (res == -1) {
  1668. xmlSchemaInternalErr(actxt,
  1669. "xmlSchemaFormatFacetEnumSet",
  1670. "compute the canonical lexical representation");
  1671. if (*buf != NULL)
  1672. xmlFree(*buf);
  1673. *buf = NULL;
  1674. return (NULL);
  1675. }
  1676. if (*buf == NULL)
  1677. *buf = xmlStrdup(BAD_CAST "'");
  1678. else
  1679. *buf = xmlStrcat(*buf, BAD_CAST ", '");
  1680. *buf = xmlStrcat(*buf, BAD_CAST value);
  1681. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1682. if (value != NULL) {
  1683. xmlFree((xmlChar *)value);
  1684. value = NULL;
  1685. }
  1686. }
  1687. /*
  1688. * The enumeration facet of a type restricts the enumeration
  1689. * facet of the ancestor type; i.e., such restricted enumerations
  1690. * do not belong to the set of the given type. Thus we break
  1691. * on the first found enumeration.
  1692. */
  1693. if (found)
  1694. break;
  1695. type = type->baseType;
  1696. } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
  1697. return ((const xmlChar *) *buf);
  1698. }
  1699. /************************************************************************
  1700. * *
  1701. * Error functions *
  1702. * *
  1703. ************************************************************************/
  1704. #if 0
  1705. static void
  1706. xmlSchemaErrMemory(const char *msg)
  1707. {
  1708. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1709. msg);
  1710. }
  1711. #endif
  1712. static void
  1713. xmlSchemaPSimpleErr(const char *msg)
  1714. {
  1715. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1716. msg);
  1717. }
  1718. /**
  1719. * xmlSchemaPErrMemory:
  1720. * @node: a context node
  1721. * @extra: extra information
  1722. *
  1723. * Handle an out of memory condition
  1724. */
  1725. static void
  1726. xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
  1727. const char *extra, xmlNodePtr node)
  1728. {
  1729. if (ctxt != NULL)
  1730. ctxt->nberrors++;
  1731. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
  1732. extra);
  1733. }
  1734. /**
  1735. * xmlSchemaPErr:
  1736. * @ctxt: the parsing context
  1737. * @node: the context node
  1738. * @error: the error code
  1739. * @msg: the error message
  1740. * @str1: extra data
  1741. * @str2: extra data
  1742. *
  1743. * Handle a parser error
  1744. */
  1745. static void LIBXML_ATTR_FORMAT(4,0)
  1746. xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1747. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1748. {
  1749. xmlGenericErrorFunc channel = NULL;
  1750. xmlStructuredErrorFunc schannel = NULL;
  1751. void *data = NULL;
  1752. if (ctxt != NULL) {
  1753. ctxt->nberrors++;
  1754. ctxt->err = error;
  1755. channel = ctxt->error;
  1756. data = ctxt->errCtxt;
  1757. schannel = ctxt->serror;
  1758. }
  1759. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1760. error, XML_ERR_ERROR, NULL, 0,
  1761. (const char *) str1, (const char *) str2, NULL, 0, 0,
  1762. msg, str1, str2);
  1763. }
  1764. /**
  1765. * xmlSchemaPErr2:
  1766. * @ctxt: the parsing context
  1767. * @node: the context node
  1768. * @node: the current child
  1769. * @error: the error code
  1770. * @msg: the error message
  1771. * @str1: extra data
  1772. * @str2: extra data
  1773. *
  1774. * Handle a parser error
  1775. */
  1776. static void LIBXML_ATTR_FORMAT(5,0)
  1777. xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  1778. xmlNodePtr child, int error,
  1779. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1780. {
  1781. if (child != NULL)
  1782. xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
  1783. else
  1784. xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
  1785. }
  1786. /**
  1787. * xmlSchemaPErrExt:
  1788. * @ctxt: the parsing context
  1789. * @node: the context node
  1790. * @error: the error code
  1791. * @strData1: extra data
  1792. * @strData2: extra data
  1793. * @strData3: extra data
  1794. * @msg: the message
  1795. * @str1: extra parameter for the message display
  1796. * @str2: extra parameter for the message display
  1797. * @str3: extra parameter for the message display
  1798. * @str4: extra parameter for the message display
  1799. * @str5: extra parameter for the message display
  1800. *
  1801. * Handle a parser error
  1802. */
  1803. static void LIBXML_ATTR_FORMAT(7,0)
  1804. xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1805. const xmlChar * strData1, const xmlChar * strData2,
  1806. const xmlChar * strData3, const char *msg, const xmlChar * str1,
  1807. const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
  1808. const xmlChar * str5)
  1809. {
  1810. xmlGenericErrorFunc channel = NULL;
  1811. xmlStructuredErrorFunc schannel = NULL;
  1812. void *data = NULL;
  1813. if (ctxt != NULL) {
  1814. ctxt->nberrors++;
  1815. ctxt->err = error;
  1816. channel = ctxt->error;
  1817. data = ctxt->errCtxt;
  1818. schannel = ctxt->serror;
  1819. }
  1820. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1821. error, XML_ERR_ERROR, NULL, 0,
  1822. (const char *) strData1, (const char *) strData2,
  1823. (const char *) strData3, 0, 0, msg, str1, str2,
  1824. str3, str4, str5);
  1825. }
  1826. /************************************************************************
  1827. * *
  1828. * Allround error functions *
  1829. * *
  1830. ************************************************************************/
  1831. /**
  1832. * xmlSchemaVTypeErrMemory:
  1833. * @node: a context node
  1834. * @extra: extra information
  1835. *
  1836. * Handle an out of memory condition
  1837. */
  1838. static void
  1839. xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
  1840. const char *extra, xmlNodePtr node)
  1841. {
  1842. if (ctxt != NULL) {
  1843. ctxt->nberrors++;
  1844. ctxt->err = XML_SCHEMAV_INTERNAL;
  1845. }
  1846. __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
  1847. extra);
  1848. }
  1849. static void LIBXML_ATTR_FORMAT(2,0)
  1850. xmlSchemaPSimpleInternalErr(xmlNodePtr node,
  1851. const char *msg, const xmlChar *str)
  1852. {
  1853. __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
  1854. msg, (const char *) str);
  1855. }
  1856. #define WXS_ERROR_TYPE_ERROR 1
  1857. #define WXS_ERROR_TYPE_WARNING 2
  1858. /**
  1859. * xmlSchemaErr4Line:
  1860. * @ctxt: the validation context
  1861. * @errorLevel: the error level
  1862. * @error: the error code
  1863. * @node: the context node
  1864. * @line: the line number
  1865. * @msg: the error message
  1866. * @str1: extra data
  1867. * @str2: extra data
  1868. * @str3: extra data
  1869. * @str4: extra data
  1870. *
  1871. * Handle a validation error
  1872. */
  1873. static void LIBXML_ATTR_FORMAT(6,0)
  1874. xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
  1875. xmlErrorLevel errorLevel,
  1876. int error, xmlNodePtr node, int line, const char *msg,
  1877. const xmlChar *str1, const xmlChar *str2,
  1878. const xmlChar *str3, const xmlChar *str4)
  1879. {
  1880. xmlStructuredErrorFunc schannel = NULL;
  1881. xmlGenericErrorFunc channel = NULL;
  1882. void *data = NULL;
  1883. if (ctxt != NULL) {
  1884. if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  1885. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
  1886. const char *file = NULL;
  1887. int col = 0;
  1888. if (errorLevel != XML_ERR_WARNING) {
  1889. vctxt->nberrors++;
  1890. vctxt->err = error;
  1891. channel = vctxt->error;
  1892. } else {
  1893. channel = vctxt->warning;
  1894. }
  1895. schannel = vctxt->serror;
  1896. data = vctxt->errCtxt;
  1897. /*
  1898. * Error node. If we specify a line number, then
  1899. * do not channel any node to the error function.
  1900. */
  1901. if (line == 0) {
  1902. if ((node == NULL) &&
  1903. (vctxt->depth >= 0) &&
  1904. (vctxt->inode != NULL)) {
  1905. node = vctxt->inode->node;
  1906. }
  1907. /*
  1908. * Get filename and line if no node-tree.
  1909. */
  1910. if ((node == NULL) &&
  1911. (vctxt->parserCtxt != NULL) &&
  1912. (vctxt->parserCtxt->input != NULL)) {
  1913. file = vctxt->parserCtxt->input->filename;
  1914. line = vctxt->parserCtxt->input->line;
  1915. col = vctxt->parserCtxt->input->col;
  1916. }
  1917. } else {
  1918. /*
  1919. * Override the given node's (if any) position
  1920. * and channel only the given line number.
  1921. */
  1922. node = NULL;
  1923. /*
  1924. * Get filename.
  1925. */
  1926. if (vctxt->doc != NULL)
  1927. file = (const char *) vctxt->doc->URL;
  1928. else if ((vctxt->parserCtxt != NULL) &&
  1929. (vctxt->parserCtxt->input != NULL))
  1930. file = vctxt->parserCtxt->input->filename;
  1931. }
  1932. if (vctxt->locFunc != NULL) {
  1933. if ((file == NULL) || (line == 0)) {
  1934. unsigned long l;
  1935. const char *f;
  1936. vctxt->locFunc(vctxt->locCtxt, &f, &l);
  1937. if (file == NULL)
  1938. file = f;
  1939. if (line == 0)
  1940. line = (int) l;
  1941. }
  1942. }
  1943. if ((file == NULL) && (vctxt->filename != NULL))
  1944. file = vctxt->filename;
  1945. __xmlRaiseError(schannel, channel, data, ctxt,
  1946. node, XML_FROM_SCHEMASV,
  1947. error, errorLevel, file, line,
  1948. (const char *) str1, (const char *) str2,
  1949. (const char *) str3, 0, col, msg, str1, str2, str3, str4);
  1950. } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
  1951. xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
  1952. if (errorLevel != XML_ERR_WARNING) {
  1953. pctxt->nberrors++;
  1954. pctxt->err = error;
  1955. channel = pctxt->error;
  1956. } else {
  1957. channel = pctxt->warning;
  1958. }
  1959. schannel = pctxt->serror;
  1960. data = pctxt->errCtxt;
  1961. __xmlRaiseError(schannel, channel, data, ctxt,
  1962. node, XML_FROM_SCHEMASP, error,
  1963. errorLevel, NULL, 0,
  1964. (const char *) str1, (const char *) str2,
  1965. (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
  1966. } else {
  1967. TODO
  1968. }
  1969. }
  1970. }
  1971. /**
  1972. * xmlSchemaErr3:
  1973. * @ctxt: the validation context
  1974. * @node: the context node
  1975. * @error: the error code
  1976. * @msg: the error message
  1977. * @str1: extra data
  1978. * @str2: extra data
  1979. * @str3: extra data
  1980. *
  1981. * Handle a validation error
  1982. */
  1983. static void LIBXML_ATTR_FORMAT(4,0)
  1984. xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
  1985. int error, xmlNodePtr node, const char *msg,
  1986. const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
  1987. {
  1988. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  1989. msg, str1, str2, str3, NULL);
  1990. }
  1991. static void LIBXML_ATTR_FORMAT(4,0)
  1992. xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
  1993. int error, xmlNodePtr node, const char *msg,
  1994. const xmlChar *str1, const xmlChar *str2,
  1995. const xmlChar *str3, const xmlChar *str4)
  1996. {
  1997. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  1998. msg, str1, str2, str3, str4);
  1999. }
  2000. static void LIBXML_ATTR_FORMAT(4,0)
  2001. xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
  2002. int error, xmlNodePtr node, const char *msg,
  2003. const xmlChar *str1, const xmlChar *str2)
  2004. {
  2005. xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
  2006. }
  2007. static xmlChar *
  2008. xmlSchemaFormatNodeForError(xmlChar ** msg,
  2009. xmlSchemaAbstractCtxtPtr actxt,
  2010. xmlNodePtr node)
  2011. {
  2012. xmlChar *str = NULL;
  2013. *msg = NULL;
  2014. if ((node != NULL) &&
  2015. (node->type != XML_ELEMENT_NODE) &&
  2016. (node->type != XML_ATTRIBUTE_NODE))
  2017. {
  2018. /*
  2019. * Don't try to format other nodes than element and
  2020. * attribute nodes.
  2021. * Play safe and return an empty string.
  2022. */
  2023. *msg = xmlStrdup(BAD_CAST "");
  2024. return(*msg);
  2025. }
  2026. if (node != NULL) {
  2027. /*
  2028. * Work on tree nodes.
  2029. */
  2030. if (node->type == XML_ATTRIBUTE_NODE) {
  2031. xmlNodePtr elem = node->parent;
  2032. *msg = xmlStrdup(BAD_CAST "Element '");
  2033. if (elem->ns != NULL)
  2034. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2035. elem->ns->href, elem->name));
  2036. else
  2037. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2038. NULL, elem->name));
  2039. FREE_AND_NULL(str);
  2040. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  2041. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  2042. } else {
  2043. *msg = xmlStrdup(BAD_CAST "Element '");
  2044. }
  2045. if (node->ns != NULL)
  2046. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2047. node->ns->href, node->name));
  2048. else
  2049. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2050. NULL, node->name));
  2051. FREE_AND_NULL(str);
  2052. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  2053. } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  2054. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
  2055. /*
  2056. * Work on node infos.
  2057. */
  2058. if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
  2059. xmlSchemaNodeInfoPtr ielem =
  2060. vctxt->elemInfos[vctxt->depth];
  2061. *msg = xmlStrdup(BAD_CAST "Element '");
  2062. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2063. ielem->nsName, ielem->localName));
  2064. FREE_AND_NULL(str);
  2065. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  2066. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  2067. } else {
  2068. *msg = xmlStrdup(BAD_CAST "Element '");
  2069. }
  2070. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2071. vctxt->inode->nsName, vctxt->inode->localName));
  2072. FREE_AND_NULL(str);
  2073. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  2074. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  2075. /*
  2076. * Hmm, no node while parsing?
  2077. * Return an empty string, in case NULL will break something.
  2078. */
  2079. *msg = xmlStrdup(BAD_CAST "");
  2080. } else {
  2081. TODO
  2082. return (NULL);
  2083. }
  2084. /*
  2085. * xmlSchemaFormatItemForReport() also returns an escaped format
  2086. * string, so do this before calling it below (in the future).
  2087. */
  2088. xmlEscapeFormatString(msg);
  2089. /*
  2090. * VAL TODO: The output of the given schema component is currently
  2091. * disabled.
  2092. */
  2093. #if 0
  2094. if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
  2095. *msg = xmlStrcat(*msg, BAD_CAST " [");
  2096. *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
  2097. NULL, type, NULL, 0));
  2098. FREE_AND_NULL(str)
  2099. *msg = xmlStrcat(*msg, BAD_CAST "]");
  2100. }
  2101. #endif
  2102. return (*msg);
  2103. }
  2104. static void LIBXML_ATTR_FORMAT(3,0)
  2105. xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
  2106. const char *funcName,
  2107. const char *message,
  2108. const xmlChar *str1,
  2109. const xmlChar *str2)
  2110. {
  2111. xmlChar *msg = NULL;
  2112. if (actxt == NULL)
  2113. return;
  2114. msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
  2115. msg = xmlStrcat(msg, BAD_CAST message);
  2116. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2117. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
  2118. xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
  2119. (const char *) msg, (const xmlChar *) funcName, str1, str2);
  2120. else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
  2121. xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
  2122. (const char *) msg, (const xmlChar *) funcName, str1, str2);
  2123. FREE_AND_NULL(msg)
  2124. }
  2125. static void LIBXML_ATTR_FORMAT(3,0)
  2126. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  2127. const char *funcName,
  2128. const char *message)
  2129. {
  2130. xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
  2131. }
  2132. #if 0
  2133. static void LIBXML_ATTR_FORMAT(3,0)
  2134. xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
  2135. const char *funcName,
  2136. const char *message,
  2137. const xmlChar *str1,
  2138. const xmlChar *str2)
  2139. {
  2140. xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
  2141. str1, str2);
  2142. }
  2143. #endif
  2144. static void LIBXML_ATTR_FORMAT(5,0)
  2145. xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
  2146. xmlParserErrors error,
  2147. xmlNodePtr node,
  2148. xmlSchemaBasicItemPtr item,
  2149. const char *message,
  2150. const xmlChar *str1, const xmlChar *str2,
  2151. const xmlChar *str3, const xmlChar *str4)
  2152. {
  2153. xmlChar *msg = NULL;
  2154. if ((node == NULL) && (item != NULL) &&
  2155. (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
  2156. node = WXS_ITEM_NODE(item);
  2157. xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
  2158. msg = xmlStrcat(msg, BAD_CAST ": ");
  2159. } else
  2160. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2161. msg = xmlStrcat(msg, (const xmlChar *) message);
  2162. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2163. xmlSchemaErr4(actxt, error, node,
  2164. (const char *) msg, str1, str2, str3, str4);
  2165. FREE_AND_NULL(msg)
  2166. }
  2167. static void LIBXML_ATTR_FORMAT(5,0)
  2168. xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
  2169. xmlParserErrors error,
  2170. xmlNodePtr node,
  2171. xmlSchemaBasicItemPtr item,
  2172. const char *message,
  2173. const xmlChar *str1,
  2174. const xmlChar *str2)
  2175. {
  2176. xmlSchemaCustomErr4(actxt, error, node, item,
  2177. message, str1, str2, NULL, NULL);
  2178. }
  2179. static void LIBXML_ATTR_FORMAT(5,0)
  2180. xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
  2181. xmlParserErrors error,
  2182. xmlNodePtr node,
  2183. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2184. const char *message,
  2185. const xmlChar *str1,
  2186. const xmlChar *str2,
  2187. const xmlChar *str3)
  2188. {
  2189. xmlChar *msg = NULL;
  2190. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2191. msg = xmlStrcat(msg, (const xmlChar *) message);
  2192. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2193. /* URGENT TODO: Set the error code to something sane. */
  2194. xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
  2195. (const char *) msg, str1, str2, str3, NULL);
  2196. FREE_AND_NULL(msg)
  2197. }
  2198. static void LIBXML_ATTR_FORMAT(5,0)
  2199. xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
  2200. xmlParserErrors error,
  2201. xmlSchemaPSVIIDCNodePtr idcNode,
  2202. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2203. const char *message,
  2204. const xmlChar *str1,
  2205. const xmlChar *str2)
  2206. {
  2207. xmlChar *msg = NULL, *qname = NULL;
  2208. msg = xmlStrdup(BAD_CAST "Element '%s': ");
  2209. msg = xmlStrcat(msg, (const xmlChar *) message);
  2210. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2211. xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
  2212. error, NULL, idcNode->nodeLine, (const char *) msg,
  2213. xmlSchemaFormatQName(&qname,
  2214. vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
  2215. vctxt->nodeQNames->items[idcNode->nodeQNameID]),
  2216. str1, str2, NULL);
  2217. FREE_AND_NULL(qname);
  2218. FREE_AND_NULL(msg);
  2219. }
  2220. static int
  2221. xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
  2222. xmlNodePtr node)
  2223. {
  2224. if (node != NULL)
  2225. return (node->type);
  2226. if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
  2227. (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
  2228. return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
  2229. return (-1);
  2230. }
  2231. static int
  2232. xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
  2233. {
  2234. switch (item->type) {
  2235. case XML_SCHEMA_TYPE_COMPLEX:
  2236. case XML_SCHEMA_TYPE_SIMPLE:
  2237. if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
  2238. return(1);
  2239. break;
  2240. case XML_SCHEMA_TYPE_GROUP:
  2241. return (1);
  2242. case XML_SCHEMA_TYPE_ELEMENT:
  2243. if ( ((xmlSchemaElementPtr) item)->flags &
  2244. XML_SCHEMAS_ELEM_GLOBAL)
  2245. return(1);
  2246. break;
  2247. case XML_SCHEMA_TYPE_ATTRIBUTE:
  2248. if ( ((xmlSchemaAttributePtr) item)->flags &
  2249. XML_SCHEMAS_ATTR_GLOBAL)
  2250. return(1);
  2251. break;
  2252. /* Note that attribute groups are always global. */
  2253. default:
  2254. return(1);
  2255. }
  2256. return (0);
  2257. }
  2258. static void
  2259. xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2260. xmlParserErrors error,
  2261. xmlNodePtr node,
  2262. const xmlChar *value,
  2263. xmlSchemaTypePtr type,
  2264. int displayValue)
  2265. {
  2266. xmlChar *msg = NULL;
  2267. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2268. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2269. XML_ATTRIBUTE_NODE))
  2270. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2271. else
  2272. msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
  2273. "value of ");
  2274. if (! xmlSchemaIsGlobalItem(type))
  2275. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2276. else
  2277. msg = xmlStrcat(msg, BAD_CAST "the ");
  2278. if (WXS_IS_ATOMIC(type))
  2279. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2280. else if (WXS_IS_LIST(type))
  2281. msg = xmlStrcat(msg, BAD_CAST "list type");
  2282. else if (WXS_IS_UNION(type))
  2283. msg = xmlStrcat(msg, BAD_CAST "union type");
  2284. if (xmlSchemaIsGlobalItem(type)) {
  2285. xmlChar *str = NULL;
  2286. msg = xmlStrcat(msg, BAD_CAST " '");
  2287. if (type->builtInType != 0) {
  2288. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2289. str = xmlStrdup(type->name);
  2290. } else {
  2291. const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
  2292. if (!str)
  2293. str = xmlStrdup(qName);
  2294. }
  2295. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2296. msg = xmlStrcat(msg, BAD_CAST "'");
  2297. FREE_AND_NULL(str);
  2298. }
  2299. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2300. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2301. XML_ATTRIBUTE_NODE))
  2302. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2303. else
  2304. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2305. FREE_AND_NULL(msg)
  2306. }
  2307. static const xmlChar *
  2308. xmlSchemaFormatErrorNodeQName(xmlChar ** str,
  2309. xmlSchemaNodeInfoPtr ni,
  2310. xmlNodePtr node)
  2311. {
  2312. if (node != NULL) {
  2313. if (node->ns != NULL)
  2314. return (xmlSchemaFormatQName(str, node->ns->href, node->name));
  2315. else
  2316. return (xmlSchemaFormatQName(str, NULL, node->name));
  2317. } else if (ni != NULL)
  2318. return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
  2319. return (NULL);
  2320. }
  2321. static void
  2322. xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
  2323. xmlParserErrors error,
  2324. xmlSchemaAttrInfoPtr ni,
  2325. xmlNodePtr node)
  2326. {
  2327. xmlChar *msg = NULL, *str = NULL;
  2328. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2329. msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
  2330. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2331. xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
  2332. NULL);
  2333. FREE_AND_NULL(str)
  2334. FREE_AND_NULL(msg)
  2335. }
  2336. static void LIBXML_ATTR_FORMAT(5,0)
  2337. xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2338. xmlParserErrors error,
  2339. xmlNodePtr node,
  2340. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2341. const char *message,
  2342. int nbval,
  2343. int nbneg,
  2344. xmlChar **values)
  2345. {
  2346. xmlChar *str = NULL, *msg = NULL;
  2347. xmlChar *localName, *nsName;
  2348. const xmlChar *cur, *end;
  2349. int i;
  2350. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2351. msg = xmlStrcat(msg, (const xmlChar *) message);
  2352. msg = xmlStrcat(msg, BAD_CAST ".");
  2353. /*
  2354. * Note that is does not make sense to report that we have a
  2355. * wildcard here, since the wildcard might be unfolded into
  2356. * multiple transitions.
  2357. */
  2358. if (nbval + nbneg > 0) {
  2359. if (nbval + nbneg > 1) {
  2360. str = xmlStrdup(BAD_CAST " Expected is one of ( ");
  2361. } else
  2362. str = xmlStrdup(BAD_CAST " Expected is ( ");
  2363. nsName = NULL;
  2364. for (i = 0; i < nbval + nbneg; i++) {
  2365. cur = values[i];
  2366. if (cur == NULL)
  2367. continue;
  2368. if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
  2369. (cur[3] == ' ')) {
  2370. cur += 4;
  2371. str = xmlStrcat(str, BAD_CAST "##other");
  2372. }
  2373. /*
  2374. * Get the local name.
  2375. */
  2376. localName = NULL;
  2377. end = cur;
  2378. if (*end == '*') {
  2379. localName = xmlStrdup(BAD_CAST "*");
  2380. end++;
  2381. } else {
  2382. while ((*end != 0) && (*end != '|'))
  2383. end++;
  2384. localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
  2385. }
  2386. if (*end != 0) {
  2387. end++;
  2388. /*
  2389. * Skip "*|*" if they come with negated expressions, since
  2390. * they represent the same negated wildcard.
  2391. */
  2392. if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
  2393. /*
  2394. * Get the namespace name.
  2395. */
  2396. cur = end;
  2397. if (*end == '*') {
  2398. nsName = xmlStrdup(BAD_CAST "{*}");
  2399. } else {
  2400. while (*end != 0)
  2401. end++;
  2402. if (i >= nbval)
  2403. nsName = xmlStrdup(BAD_CAST "{##other:");
  2404. else
  2405. nsName = xmlStrdup(BAD_CAST "{");
  2406. nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
  2407. nsName = xmlStrcat(nsName, BAD_CAST "}");
  2408. }
  2409. str = xmlStrcat(str, BAD_CAST nsName);
  2410. FREE_AND_NULL(nsName)
  2411. } else {
  2412. FREE_AND_NULL(localName);
  2413. continue;
  2414. }
  2415. }
  2416. str = xmlStrcat(str, BAD_CAST localName);
  2417. FREE_AND_NULL(localName);
  2418. if (i < nbval + nbneg -1)
  2419. str = xmlStrcat(str, BAD_CAST ", ");
  2420. }
  2421. str = xmlStrcat(str, BAD_CAST " ).\n");
  2422. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2423. FREE_AND_NULL(str)
  2424. } else
  2425. msg = xmlStrcat(msg, BAD_CAST "\n");
  2426. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2427. xmlFree(msg);
  2428. }
  2429. static void LIBXML_ATTR_FORMAT(8,0)
  2430. xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
  2431. xmlParserErrors error,
  2432. xmlNodePtr node,
  2433. const xmlChar *value,
  2434. unsigned long length,
  2435. xmlSchemaTypePtr type,
  2436. xmlSchemaFacetPtr facet,
  2437. const char *message,
  2438. const xmlChar *str1,
  2439. const xmlChar *str2)
  2440. {
  2441. xmlChar *str = NULL, *msg = NULL;
  2442. xmlSchemaTypeType facetType;
  2443. int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
  2444. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2445. if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
  2446. facetType = XML_SCHEMA_FACET_ENUMERATION;
  2447. /*
  2448. * If enumerations are validated, one must not expect the
  2449. * facet to be given.
  2450. */
  2451. } else
  2452. facetType = facet->type;
  2453. msg = xmlStrcat(msg, BAD_CAST "[");
  2454. msg = xmlStrcat(msg, BAD_CAST "facet '");
  2455. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
  2456. msg = xmlStrcat(msg, BAD_CAST "'] ");
  2457. if (message == NULL) {
  2458. /*
  2459. * Use a default message.
  2460. */
  2461. if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
  2462. (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
  2463. (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
  2464. char len[25], actLen[25];
  2465. /* FIXME, TODO: What is the max expected string length of the
  2466. * this value?
  2467. */
  2468. if (nodeType == XML_ATTRIBUTE_NODE)
  2469. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
  2470. else
  2471. msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
  2472. snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
  2473. snprintf(actLen, 24, "%lu", length);
  2474. if (facetType == XML_SCHEMA_FACET_LENGTH)
  2475. msg = xmlStrcat(msg,
  2476. BAD_CAST "this differs from the allowed length of '%s'.\n");
  2477. else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
  2478. msg = xmlStrcat(msg,
  2479. BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
  2480. else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
  2481. msg = xmlStrcat(msg,
  2482. BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
  2483. if (nodeType == XML_ATTRIBUTE_NODE)
  2484. xmlSchemaErr3(actxt, error, node, (const char *) msg,
  2485. value, (const xmlChar *) actLen, (const xmlChar *) len);
  2486. else
  2487. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2488. (const xmlChar *) actLen, (const xmlChar *) len);
  2489. } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
  2490. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
  2491. "of the set {%s}.\n");
  2492. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2493. xmlSchemaFormatFacetEnumSet(actxt, &str, type));
  2494. } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
  2495. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
  2496. "by the pattern '%s'.\n");
  2497. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2498. facet->value);
  2499. } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
  2500. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
  2501. "minimum value allowed ('%s').\n");
  2502. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2503. facet->value);
  2504. } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
  2505. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
  2506. "maximum value allowed ('%s').\n");
  2507. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2508. facet->value);
  2509. } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
  2510. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
  2511. "'%s'.\n");
  2512. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2513. facet->value);
  2514. } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
  2515. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
  2516. "'%s'.\n");
  2517. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2518. facet->value);
  2519. } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
  2520. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
  2521. "digits than are allowed ('%s').\n");
  2522. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2523. facet->value);
  2524. } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
  2525. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
  2526. "digits than are allowed ('%s').\n");
  2527. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2528. facet->value);
  2529. } else if (nodeType == XML_ATTRIBUTE_NODE) {
  2530. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
  2531. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2532. } else {
  2533. msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
  2534. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2535. }
  2536. } else {
  2537. msg = xmlStrcat(msg, (const xmlChar *) message);
  2538. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2539. xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
  2540. }
  2541. FREE_AND_NULL(str)
  2542. xmlFree(msg);
  2543. }
  2544. #define VERROR(err, type, msg) \
  2545. xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
  2546. #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
  2547. #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
  2548. #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
  2549. #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
  2550. /**
  2551. * xmlSchemaPMissingAttrErr:
  2552. * @ctxt: the schema validation context
  2553. * @ownerItem: the owner as a schema object
  2554. * @ownerElem: the owner as an element node
  2555. * @node: the parent element node of the missing attribute node
  2556. * @type: the corresponding type of the attribute node
  2557. *
  2558. * Reports an illegal attribute.
  2559. */
  2560. static void
  2561. xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2562. xmlParserErrors error,
  2563. xmlSchemaBasicItemPtr ownerItem,
  2564. xmlNodePtr ownerElem,
  2565. const char *name,
  2566. const char *message)
  2567. {
  2568. xmlChar *des = NULL;
  2569. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2570. if (message != NULL)
  2571. xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
  2572. else
  2573. xmlSchemaPErr(ctxt, ownerElem, error,
  2574. "%s: The attribute '%s' is required but missing.\n",
  2575. BAD_CAST des, BAD_CAST name);
  2576. FREE_AND_NULL(des);
  2577. }
  2578. /**
  2579. * xmlSchemaPResCompAttrErr:
  2580. * @ctxt: the schema validation context
  2581. * @error: the error code
  2582. * @ownerItem: the owner as a schema object
  2583. * @ownerElem: the owner as an element node
  2584. * @name: the name of the attribute holding the QName
  2585. * @refName: the referenced local name
  2586. * @refURI: the referenced namespace URI
  2587. * @message: optional message
  2588. *
  2589. * Used to report QName attribute values that failed to resolve
  2590. * to schema components.
  2591. */
  2592. static void
  2593. xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2594. xmlParserErrors error,
  2595. xmlSchemaBasicItemPtr ownerItem,
  2596. xmlNodePtr ownerElem,
  2597. const char *name,
  2598. const xmlChar *refName,
  2599. const xmlChar *refURI,
  2600. xmlSchemaTypeType refType,
  2601. const char *refTypeStr)
  2602. {
  2603. xmlChar *des = NULL, *strA = NULL;
  2604. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2605. if (refTypeStr == NULL)
  2606. refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
  2607. xmlSchemaPErrExt(ctxt, ownerElem, error,
  2608. NULL, NULL, NULL,
  2609. "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
  2610. "%s.\n", BAD_CAST des, BAD_CAST name,
  2611. xmlSchemaFormatQName(&strA, refURI, refName),
  2612. BAD_CAST refTypeStr, NULL);
  2613. FREE_AND_NULL(des)
  2614. FREE_AND_NULL(strA)
  2615. }
  2616. /**
  2617. * xmlSchemaPCustomAttrErr:
  2618. * @ctxt: the schema parser context
  2619. * @error: the error code
  2620. * @ownerDes: the designation of the owner
  2621. * @ownerItem: the owner as a schema object
  2622. * @attr: the illegal attribute node
  2623. *
  2624. * Reports an illegal attribute during the parse.
  2625. */
  2626. static void
  2627. xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2628. xmlParserErrors error,
  2629. xmlChar **ownerDes,
  2630. xmlSchemaBasicItemPtr ownerItem,
  2631. xmlAttrPtr attr,
  2632. const char *msg)
  2633. {
  2634. xmlChar *des = NULL;
  2635. if (ownerDes == NULL)
  2636. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
  2637. else if (*ownerDes == NULL) {
  2638. xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
  2639. des = *ownerDes;
  2640. } else
  2641. des = *ownerDes;
  2642. if (attr == NULL) {
  2643. xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
  2644. "%s, attribute '%s': %s.\n",
  2645. BAD_CAST des, (const xmlChar *) "Unknown",
  2646. (const xmlChar *) msg, NULL, NULL);
  2647. } else {
  2648. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2649. "%s, attribute '%s': %s.\n",
  2650. BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
  2651. }
  2652. if (ownerDes == NULL)
  2653. FREE_AND_NULL(des);
  2654. }
  2655. /**
  2656. * xmlSchemaPIllegalAttrErr:
  2657. * @ctxt: the schema parser context
  2658. * @error: the error code
  2659. * @ownerItem: the attribute's owner item
  2660. * @attr: the illegal attribute node
  2661. *
  2662. * Reports an illegal attribute during the parse.
  2663. */
  2664. static void
  2665. xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2666. xmlParserErrors error,
  2667. xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
  2668. xmlAttrPtr attr)
  2669. {
  2670. xmlChar *strA = NULL, *strB = NULL;
  2671. xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
  2672. xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
  2673. "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
  2674. xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
  2675. NULL, NULL);
  2676. FREE_AND_NULL(strA);
  2677. FREE_AND_NULL(strB);
  2678. }
  2679. /**
  2680. * xmlSchemaPCustomErr:
  2681. * @ctxt: the schema parser context
  2682. * @error: the error code
  2683. * @itemDes: the designation of the schema item
  2684. * @item: the schema item
  2685. * @itemElem: the node of the schema item
  2686. * @message: the error message
  2687. * @str1: an optional param for the error message
  2688. * @str2: an optional param for the error message
  2689. * @str3: an optional param for the error message
  2690. *
  2691. * Reports an error during parsing.
  2692. */
  2693. static void LIBXML_ATTR_FORMAT(5,0)
  2694. xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
  2695. xmlParserErrors error,
  2696. xmlSchemaBasicItemPtr item,
  2697. xmlNodePtr itemElem,
  2698. const char *message,
  2699. const xmlChar *str1,
  2700. const xmlChar *str2,
  2701. const xmlChar *str3)
  2702. {
  2703. xmlChar *des = NULL, *msg = NULL;
  2704. xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
  2705. msg = xmlStrdup(BAD_CAST "%s: ");
  2706. msg = xmlStrcat(msg, (const xmlChar *) message);
  2707. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2708. if ((itemElem == NULL) && (item != NULL))
  2709. itemElem = WXS_ITEM_NODE(item);
  2710. xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
  2711. (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
  2712. FREE_AND_NULL(des);
  2713. FREE_AND_NULL(msg);
  2714. }
  2715. /**
  2716. * xmlSchemaPCustomErr:
  2717. * @ctxt: the schema parser context
  2718. * @error: the error code
  2719. * @itemDes: the designation of the schema item
  2720. * @item: the schema item
  2721. * @itemElem: the node of the schema item
  2722. * @message: the error message
  2723. * @str1: the optional param for the error message
  2724. *
  2725. * Reports an error during parsing.
  2726. */
  2727. static void LIBXML_ATTR_FORMAT(5,0)
  2728. xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
  2729. xmlParserErrors error,
  2730. xmlSchemaBasicItemPtr item,
  2731. xmlNodePtr itemElem,
  2732. const char *message,
  2733. const xmlChar *str1)
  2734. {
  2735. xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
  2736. str1, NULL, NULL);
  2737. }
  2738. /**
  2739. * xmlSchemaPAttrUseErr:
  2740. * @ctxt: the schema parser context
  2741. * @error: the error code
  2742. * @itemDes: the designation of the schema type
  2743. * @item: the schema type
  2744. * @itemElem: the node of the schema type
  2745. * @attr: the invalid schema attribute
  2746. * @message: the error message
  2747. * @str1: the optional param for the error message
  2748. *
  2749. * Reports an attribute use error during parsing.
  2750. */
  2751. static void LIBXML_ATTR_FORMAT(6,0)
  2752. xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
  2753. xmlParserErrors error,
  2754. xmlNodePtr node,
  2755. xmlSchemaBasicItemPtr ownerItem,
  2756. const xmlSchemaAttributeUsePtr attruse,
  2757. const char *message,
  2758. const xmlChar *str1, const xmlChar *str2,
  2759. const xmlChar *str3,const xmlChar *str4)
  2760. {
  2761. xmlChar *str = NULL, *msg = NULL;
  2762. xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
  2763. msg = xmlStrcat(msg, BAD_CAST ", ");
  2764. msg = xmlStrcat(msg,
  2765. BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
  2766. WXS_BASIC_CAST attruse, NULL));
  2767. FREE_AND_NULL(str);
  2768. msg = xmlStrcat(msg, BAD_CAST ": ");
  2769. msg = xmlStrcat(msg, (const xmlChar *) message);
  2770. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2771. xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
  2772. (const char *) msg, str1, str2, str3, str4);
  2773. xmlFree(msg);
  2774. }
  2775. /**
  2776. * xmlSchemaPIllegalFacetAtomicErr:
  2777. * @ctxt: the schema parser context
  2778. * @error: the error code
  2779. * @type: the schema type
  2780. * @baseType: the base type of type
  2781. * @facet: the illegal facet
  2782. *
  2783. * Reports an illegal facet for atomic simple types.
  2784. */
  2785. static void
  2786. xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
  2787. xmlParserErrors error,
  2788. xmlSchemaTypePtr type,
  2789. xmlSchemaTypePtr baseType,
  2790. xmlSchemaFacetPtr facet)
  2791. {
  2792. xmlChar *des = NULL, *strT = NULL;
  2793. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
  2794. xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
  2795. "%s: The facet '%s' is not allowed on types derived from the "
  2796. "type %s.\n",
  2797. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
  2798. xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
  2799. NULL, NULL);
  2800. FREE_AND_NULL(des);
  2801. FREE_AND_NULL(strT);
  2802. }
  2803. /**
  2804. * xmlSchemaPIllegalFacetListUnionErr:
  2805. * @ctxt: the schema parser context
  2806. * @error: the error code
  2807. * @itemDes: the designation of the schema item involved
  2808. * @item: the schema item involved
  2809. * @facet: the illegal facet
  2810. *
  2811. * Reports an illegal facet for <list> and <union>.
  2812. */
  2813. static void
  2814. xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
  2815. xmlParserErrors error,
  2816. xmlSchemaTypePtr type,
  2817. xmlSchemaFacetPtr facet)
  2818. {
  2819. xmlChar *des = NULL;
  2820. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
  2821. type->node);
  2822. xmlSchemaPErr(ctxt, type->node, error,
  2823. "%s: The facet '%s' is not allowed.\n",
  2824. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
  2825. FREE_AND_NULL(des);
  2826. }
  2827. /**
  2828. * xmlSchemaPMutualExclAttrErr:
  2829. * @ctxt: the schema validation context
  2830. * @error: the error code
  2831. * @elemDes: the designation of the parent element node
  2832. * @attr: the bad attribute node
  2833. * @type: the corresponding type of the attribute node
  2834. *
  2835. * Reports an illegal attribute.
  2836. */
  2837. static void
  2838. xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2839. xmlParserErrors error,
  2840. xmlSchemaBasicItemPtr ownerItem,
  2841. xmlAttrPtr attr,
  2842. const char *name1,
  2843. const char *name2)
  2844. {
  2845. xmlChar *des = NULL;
  2846. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
  2847. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2848. "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
  2849. BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
  2850. FREE_AND_NULL(des);
  2851. }
  2852. /**
  2853. * xmlSchemaPSimpleTypeErr:
  2854. * @ctxt: the schema validation context
  2855. * @error: the error code
  2856. * @type: the type specifier
  2857. * @ownerItem: the schema object if existent
  2858. * @node: the validated node
  2859. * @value: the validated value
  2860. *
  2861. * Reports a simple type validation error.
  2862. * TODO: Should this report the value of an element as well?
  2863. */
  2864. static void LIBXML_ATTR_FORMAT(8,0)
  2865. xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
  2866. xmlParserErrors error,
  2867. xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
  2868. xmlNodePtr node,
  2869. xmlSchemaTypePtr type,
  2870. const char *expected,
  2871. const xmlChar *value,
  2872. const char *message,
  2873. const xmlChar *str1,
  2874. const xmlChar *str2)
  2875. {
  2876. xmlChar *msg = NULL;
  2877. xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
  2878. if (message == NULL) {
  2879. /*
  2880. * Use default messages.
  2881. */
  2882. if (type != NULL) {
  2883. if (node->type == XML_ATTRIBUTE_NODE)
  2884. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2885. else
  2886. msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
  2887. "valid value of ");
  2888. if (! xmlSchemaIsGlobalItem(type))
  2889. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2890. else
  2891. msg = xmlStrcat(msg, BAD_CAST "the ");
  2892. if (WXS_IS_ATOMIC(type))
  2893. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2894. else if (WXS_IS_LIST(type))
  2895. msg = xmlStrcat(msg, BAD_CAST "list type");
  2896. else if (WXS_IS_UNION(type))
  2897. msg = xmlStrcat(msg, BAD_CAST "union type");
  2898. if (xmlSchemaIsGlobalItem(type)) {
  2899. xmlChar *str = NULL;
  2900. msg = xmlStrcat(msg, BAD_CAST " '");
  2901. if (type->builtInType != 0) {
  2902. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2903. str = xmlStrdup(type->name);
  2904. } else {
  2905. const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
  2906. if (!str)
  2907. str = xmlStrdup(qName);
  2908. }
  2909. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2910. msg = xmlStrcat(msg, BAD_CAST "'.");
  2911. FREE_AND_NULL(str);
  2912. }
  2913. } else {
  2914. if (node->type == XML_ATTRIBUTE_NODE)
  2915. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
  2916. else
  2917. msg = xmlStrcat(msg, BAD_CAST "The character content is not "
  2918. "valid.");
  2919. }
  2920. if (expected) {
  2921. xmlChar *expectedEscaped = xmlCharStrdup(expected);
  2922. msg = xmlStrcat(msg, BAD_CAST " Expected is '");
  2923. msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
  2924. FREE_AND_NULL(expectedEscaped);
  2925. msg = xmlStrcat(msg, BAD_CAST "'.\n");
  2926. } else
  2927. msg = xmlStrcat(msg, BAD_CAST "\n");
  2928. if (node->type == XML_ATTRIBUTE_NODE)
  2929. xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
  2930. else
  2931. xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
  2932. } else {
  2933. msg = xmlStrcat(msg, BAD_CAST message);
  2934. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2935. xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
  2936. (const char*) msg, str1, str2, NULL, NULL, NULL);
  2937. }
  2938. /* Cleanup. */
  2939. FREE_AND_NULL(msg)
  2940. }
  2941. /**
  2942. * xmlSchemaPContentErr:
  2943. * @ctxt: the schema parser context
  2944. * @error: the error code
  2945. * @ownerItem: the owner item of the holder of the content
  2946. * @ownerElem: the node of the holder of the content
  2947. * @child: the invalid child node
  2948. * @message: the optional error message
  2949. * @content: the optional string describing the correct content
  2950. *
  2951. * Reports an error concerning the content of a schema element.
  2952. */
  2953. static void
  2954. xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
  2955. xmlParserErrors error,
  2956. xmlSchemaBasicItemPtr ownerItem,
  2957. xmlNodePtr ownerElem,
  2958. xmlNodePtr child,
  2959. const char *message,
  2960. const char *content)
  2961. {
  2962. xmlChar *des = NULL;
  2963. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2964. if (message != NULL)
  2965. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2966. "%s: %s.\n",
  2967. BAD_CAST des, BAD_CAST message);
  2968. else {
  2969. if (content != NULL) {
  2970. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2971. "%s: The content is not valid. Expected is %s.\n",
  2972. BAD_CAST des, BAD_CAST content);
  2973. } else {
  2974. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2975. "%s: The content is not valid.\n",
  2976. BAD_CAST des, NULL);
  2977. }
  2978. }
  2979. FREE_AND_NULL(des)
  2980. }
  2981. /************************************************************************
  2982. * *
  2983. * Streamable error functions *
  2984. * *
  2985. ************************************************************************/
  2986. /************************************************************************
  2987. * *
  2988. * Validation helper functions *
  2989. * *
  2990. ************************************************************************/
  2991. /************************************************************************
  2992. * *
  2993. * Allocation functions *
  2994. * *
  2995. ************************************************************************/
  2996. /**
  2997. * xmlSchemaNewSchemaForParserCtxt:
  2998. * @ctxt: a schema validation context
  2999. *
  3000. * Allocate a new Schema structure.
  3001. *
  3002. * Returns the newly allocated structure or NULL in case or error
  3003. */
  3004. static xmlSchemaPtr
  3005. xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
  3006. {
  3007. xmlSchemaPtr ret;
  3008. ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
  3009. if (ret == NULL) {
  3010. xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
  3011. return (NULL);
  3012. }
  3013. memset(ret, 0, sizeof(xmlSchema));
  3014. ret->dict = ctxt->dict;
  3015. xmlDictReference(ret->dict);
  3016. return (ret);
  3017. }
  3018. /**
  3019. * xmlSchemaNewFacet:
  3020. *
  3021. * Allocate a new Facet structure.
  3022. *
  3023. * Returns the newly allocated structure or NULL in case or error
  3024. */
  3025. xmlSchemaFacetPtr
  3026. xmlSchemaNewFacet(void)
  3027. {
  3028. xmlSchemaFacetPtr ret;
  3029. ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
  3030. if (ret == NULL) {
  3031. return (NULL);
  3032. }
  3033. memset(ret, 0, sizeof(xmlSchemaFacet));
  3034. return (ret);
  3035. }
  3036. /**
  3037. * xmlSchemaNewAnnot:
  3038. * @ctxt: a schema validation context
  3039. * @node: a node
  3040. *
  3041. * Allocate a new annotation structure.
  3042. *
  3043. * Returns the newly allocated structure or NULL in case or error
  3044. */
  3045. static xmlSchemaAnnotPtr
  3046. xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  3047. {
  3048. xmlSchemaAnnotPtr ret;
  3049. ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
  3050. if (ret == NULL) {
  3051. xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
  3052. return (NULL);
  3053. }
  3054. memset(ret, 0, sizeof(xmlSchemaAnnot));
  3055. ret->content = node;
  3056. return (ret);
  3057. }
  3058. static xmlSchemaItemListPtr
  3059. xmlSchemaItemListCreate(void)
  3060. {
  3061. xmlSchemaItemListPtr ret;
  3062. ret = xmlMalloc(sizeof(xmlSchemaItemList));
  3063. if (ret == NULL) {
  3064. xmlSchemaPErrMemory(NULL,
  3065. "allocating an item list structure", NULL);
  3066. return (NULL);
  3067. }
  3068. memset(ret, 0, sizeof(xmlSchemaItemList));
  3069. return (ret);
  3070. }
  3071. static void
  3072. xmlSchemaItemListClear(xmlSchemaItemListPtr list)
  3073. {
  3074. if (list->items != NULL) {
  3075. xmlFree(list->items);
  3076. list->items = NULL;
  3077. }
  3078. list->nbItems = 0;
  3079. list->sizeItems = 0;
  3080. }
  3081. static int
  3082. xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
  3083. {
  3084. if (list->items == NULL) {
  3085. list->items = (void **) xmlMalloc(
  3086. 20 * sizeof(void *));
  3087. if (list->items == NULL) {
  3088. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3089. return(-1);
  3090. }
  3091. list->sizeItems = 20;
  3092. } else if (list->sizeItems <= list->nbItems) {
  3093. list->sizeItems *= 2;
  3094. list->items = (void **) xmlRealloc(list->items,
  3095. list->sizeItems * sizeof(void *));
  3096. if (list->items == NULL) {
  3097. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3098. list->sizeItems = 0;
  3099. return(-1);
  3100. }
  3101. }
  3102. list->items[list->nbItems++] = item;
  3103. return(0);
  3104. }
  3105. static int
  3106. xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
  3107. int initialSize,
  3108. void *item)
  3109. {
  3110. if (list->items == NULL) {
  3111. if (initialSize <= 0)
  3112. initialSize = 1;
  3113. list->items = (void **) xmlMalloc(
  3114. initialSize * sizeof(void *));
  3115. if (list->items == NULL) {
  3116. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3117. return(-1);
  3118. }
  3119. list->sizeItems = initialSize;
  3120. } else if (list->sizeItems <= list->nbItems) {
  3121. list->sizeItems *= 2;
  3122. list->items = (void **) xmlRealloc(list->items,
  3123. list->sizeItems * sizeof(void *));
  3124. if (list->items == NULL) {
  3125. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3126. list->sizeItems = 0;
  3127. return(-1);
  3128. }
  3129. }
  3130. list->items[list->nbItems++] = item;
  3131. return(0);
  3132. }
  3133. static int
  3134. xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
  3135. {
  3136. if (list->items == NULL) {
  3137. list->items = (void **) xmlMalloc(
  3138. 20 * sizeof(void *));
  3139. if (list->items == NULL) {
  3140. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3141. return(-1);
  3142. }
  3143. list->sizeItems = 20;
  3144. } else if (list->sizeItems <= list->nbItems) {
  3145. list->sizeItems *= 2;
  3146. list->items = (void **) xmlRealloc(list->items,
  3147. list->sizeItems * sizeof(void *));
  3148. if (list->items == NULL) {
  3149. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3150. list->sizeItems = 0;
  3151. return(-1);
  3152. }
  3153. }
  3154. /*
  3155. * Just append if the index is greater/equal than the item count.
  3156. */
  3157. if (idx >= list->nbItems) {
  3158. list->items[list->nbItems++] = item;
  3159. } else {
  3160. int i;
  3161. for (i = list->nbItems; i > idx; i--)
  3162. list->items[i] = list->items[i-1];
  3163. list->items[idx] = item;
  3164. list->nbItems++;
  3165. }
  3166. return(0);
  3167. }
  3168. #if 0 /* enable if ever needed */
  3169. static int
  3170. xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
  3171. int initialSize,
  3172. void *item,
  3173. int idx)
  3174. {
  3175. if (list->items == NULL) {
  3176. if (initialSize <= 0)
  3177. initialSize = 1;
  3178. list->items = (void **) xmlMalloc(
  3179. initialSize * sizeof(void *));
  3180. if (list->items == NULL) {
  3181. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3182. return(-1);
  3183. }
  3184. list->sizeItems = initialSize;
  3185. } else if (list->sizeItems <= list->nbItems) {
  3186. list->sizeItems *= 2;
  3187. list->items = (void **) xmlRealloc(list->items,
  3188. list->sizeItems * sizeof(void *));
  3189. if (list->items == NULL) {
  3190. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3191. list->sizeItems = 0;
  3192. return(-1);
  3193. }
  3194. }
  3195. /*
  3196. * Just append if the index is greater/equal than the item count.
  3197. */
  3198. if (idx >= list->nbItems) {
  3199. list->items[list->nbItems++] = item;
  3200. } else {
  3201. int i;
  3202. for (i = list->nbItems; i > idx; i--)
  3203. list->items[i] = list->items[i-1];
  3204. list->items[idx] = item;
  3205. list->nbItems++;
  3206. }
  3207. return(0);
  3208. }
  3209. #endif
  3210. static int
  3211. xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
  3212. {
  3213. int i;
  3214. if ((list->items == NULL) || (idx >= list->nbItems)) {
  3215. xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
  3216. "index error.\n");
  3217. return(-1);
  3218. }
  3219. if (list->nbItems == 1) {
  3220. /* TODO: Really free the list? */
  3221. xmlFree(list->items);
  3222. list->items = NULL;
  3223. list->nbItems = 0;
  3224. list->sizeItems = 0;
  3225. } else if (list->nbItems -1 == idx) {
  3226. list->nbItems--;
  3227. } else {
  3228. for (i = idx; i < list->nbItems -1; i++)
  3229. list->items[i] = list->items[i+1];
  3230. list->nbItems--;
  3231. }
  3232. return(0);
  3233. }
  3234. /**
  3235. * xmlSchemaItemListFree:
  3236. * @annot: a schema type structure
  3237. *
  3238. * Deallocate a annotation structure
  3239. */
  3240. static void
  3241. xmlSchemaItemListFree(xmlSchemaItemListPtr list)
  3242. {
  3243. if (list == NULL)
  3244. return;
  3245. if (list->items != NULL)
  3246. xmlFree(list->items);
  3247. xmlFree(list);
  3248. }
  3249. static void
  3250. xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
  3251. {
  3252. if (bucket == NULL)
  3253. return;
  3254. if (bucket->globals != NULL) {
  3255. xmlSchemaComponentListFree(bucket->globals);
  3256. xmlSchemaItemListFree(bucket->globals);
  3257. }
  3258. if (bucket->locals != NULL) {
  3259. xmlSchemaComponentListFree(bucket->locals);
  3260. xmlSchemaItemListFree(bucket->locals);
  3261. }
  3262. if (bucket->relations != NULL) {
  3263. xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
  3264. do {
  3265. prev = cur;
  3266. cur = cur->next;
  3267. xmlFree(prev);
  3268. } while (cur != NULL);
  3269. }
  3270. if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
  3271. xmlFreeDoc(bucket->doc);
  3272. }
  3273. if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
  3274. if (WXS_IMPBUCKET(bucket)->schema != NULL)
  3275. xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
  3276. }
  3277. xmlFree(bucket);
  3278. }
  3279. static void
  3280. xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
  3281. {
  3282. xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
  3283. }
  3284. static xmlSchemaBucketPtr
  3285. xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
  3286. int type, const xmlChar *targetNamespace)
  3287. {
  3288. xmlSchemaBucketPtr ret;
  3289. int size;
  3290. xmlSchemaPtr mainSchema;
  3291. if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
  3292. PERROR_INT("xmlSchemaBucketCreate",
  3293. "no main schema on constructor");
  3294. return(NULL);
  3295. }
  3296. mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
  3297. /* Create the schema bucket. */
  3298. if (WXS_IS_BUCKET_INCREDEF(type))
  3299. size = sizeof(xmlSchemaInclude);
  3300. else
  3301. size = sizeof(xmlSchemaImport);
  3302. ret = (xmlSchemaBucketPtr) xmlMalloc(size);
  3303. if (ret == NULL) {
  3304. xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
  3305. return(NULL);
  3306. }
  3307. memset(ret, 0, size);
  3308. ret->targetNamespace = targetNamespace;
  3309. ret->type = type;
  3310. ret->globals = xmlSchemaItemListCreate();
  3311. if (ret->globals == NULL) {
  3312. xmlFree(ret);
  3313. return(NULL);
  3314. }
  3315. ret->locals = xmlSchemaItemListCreate();
  3316. if (ret->locals == NULL) {
  3317. xmlFree(ret);
  3318. return(NULL);
  3319. }
  3320. /*
  3321. * The following will assure that only the first bucket is marked as
  3322. * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
  3323. * For each following import buckets an xmlSchema will be created.
  3324. * An xmlSchema will be created for every distinct targetNamespace.
  3325. * We assign the targetNamespace to the schemata here.
  3326. */
  3327. if (! WXS_HAS_BUCKETS(pctxt)) {
  3328. if (WXS_IS_BUCKET_INCREDEF(type)) {
  3329. PERROR_INT("xmlSchemaBucketCreate",
  3330. "first bucket but it's an include or redefine");
  3331. xmlSchemaBucketFree(ret);
  3332. return(NULL);
  3333. }
  3334. /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
  3335. ret->type = XML_SCHEMA_SCHEMA_MAIN;
  3336. /* Point to the *main* schema. */
  3337. WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
  3338. WXS_IMPBUCKET(ret)->schema = mainSchema;
  3339. /*
  3340. * Ensure that the main schema gets a targetNamespace.
  3341. */
  3342. mainSchema->targetNamespace = targetNamespace;
  3343. } else {
  3344. if (type == XML_SCHEMA_SCHEMA_MAIN) {
  3345. PERROR_INT("xmlSchemaBucketCreate",
  3346. "main bucket but it's not the first one");
  3347. xmlSchemaBucketFree(ret);
  3348. return(NULL);
  3349. } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
  3350. /*
  3351. * Create a schema for imports and assign the
  3352. * targetNamespace.
  3353. */
  3354. WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
  3355. if (WXS_IMPBUCKET(ret)->schema == NULL) {
  3356. xmlSchemaBucketFree(ret);
  3357. return(NULL);
  3358. }
  3359. WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
  3360. }
  3361. }
  3362. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  3363. int res;
  3364. /*
  3365. * Imports go into the "schemasImports" slot of the main *schema*.
  3366. * Note that we create an import entry for the main schema as well; i.e.,
  3367. * even if there's only one schema, we'll get an import.
  3368. */
  3369. if (mainSchema->schemasImports == NULL) {
  3370. mainSchema->schemasImports = xmlHashCreateDict(5,
  3371. WXS_CONSTRUCTOR(pctxt)->dict);
  3372. if (mainSchema->schemasImports == NULL) {
  3373. xmlSchemaBucketFree(ret);
  3374. return(NULL);
  3375. }
  3376. }
  3377. if (targetNamespace == NULL)
  3378. res = xmlHashAddEntry(mainSchema->schemasImports,
  3379. XML_SCHEMAS_NO_NAMESPACE, ret);
  3380. else
  3381. res = xmlHashAddEntry(mainSchema->schemasImports,
  3382. targetNamespace, ret);
  3383. if (res != 0) {
  3384. PERROR_INT("xmlSchemaBucketCreate",
  3385. "failed to add the schema bucket to the hash");
  3386. xmlSchemaBucketFree(ret);
  3387. return(NULL);
  3388. }
  3389. } else {
  3390. /* Set the @ownerImport of an include bucket. */
  3391. if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
  3392. WXS_INCBUCKET(ret)->ownerImport =
  3393. WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
  3394. else
  3395. WXS_INCBUCKET(ret)->ownerImport =
  3396. WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
  3397. /* Includes got into the "includes" slot of the *main* schema. */
  3398. if (mainSchema->includes == NULL) {
  3399. mainSchema->includes = xmlSchemaItemListCreate();
  3400. if (mainSchema->includes == NULL) {
  3401. xmlSchemaBucketFree(ret);
  3402. return(NULL);
  3403. }
  3404. }
  3405. xmlSchemaItemListAdd(mainSchema->includes, ret);
  3406. }
  3407. /*
  3408. * Add to list of all buckets; this is used for lookup
  3409. * during schema construction time only.
  3410. */
  3411. if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
  3412. return(NULL);
  3413. return(ret);
  3414. }
  3415. static int
  3416. xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
  3417. {
  3418. if (*list == NULL) {
  3419. *list = xmlSchemaItemListCreate();
  3420. if (*list == NULL)
  3421. return(-1);
  3422. }
  3423. xmlSchemaItemListAddSize(*list, initialSize, item);
  3424. return(0);
  3425. }
  3426. /**
  3427. * xmlSchemaFreeAnnot:
  3428. * @annot: a schema type structure
  3429. *
  3430. * Deallocate a annotation structure
  3431. */
  3432. static void
  3433. xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
  3434. {
  3435. if (annot == NULL)
  3436. return;
  3437. if (annot->next == NULL) {
  3438. xmlFree(annot);
  3439. } else {
  3440. xmlSchemaAnnotPtr prev;
  3441. do {
  3442. prev = annot;
  3443. annot = annot->next;
  3444. xmlFree(prev);
  3445. } while (annot != NULL);
  3446. }
  3447. }
  3448. /**
  3449. * xmlSchemaFreeNotation:
  3450. * @schema: a schema notation structure
  3451. *
  3452. * Deallocate a Schema Notation structure.
  3453. */
  3454. static void
  3455. xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
  3456. {
  3457. if (nota == NULL)
  3458. return;
  3459. xmlFree(nota);
  3460. }
  3461. /**
  3462. * xmlSchemaFreeAttribute:
  3463. * @attr: an attribute declaration
  3464. *
  3465. * Deallocates an attribute declaration structure.
  3466. */
  3467. static void
  3468. xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
  3469. {
  3470. if (attr == NULL)
  3471. return;
  3472. if (attr->annot != NULL)
  3473. xmlSchemaFreeAnnot(attr->annot);
  3474. if (attr->defVal != NULL)
  3475. xmlSchemaFreeValue(attr->defVal);
  3476. xmlFree(attr);
  3477. }
  3478. /**
  3479. * xmlSchemaFreeAttributeUse:
  3480. * @use: an attribute use
  3481. *
  3482. * Deallocates an attribute use structure.
  3483. */
  3484. static void
  3485. xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
  3486. {
  3487. if (use == NULL)
  3488. return;
  3489. if (use->annot != NULL)
  3490. xmlSchemaFreeAnnot(use->annot);
  3491. if (use->defVal != NULL)
  3492. xmlSchemaFreeValue(use->defVal);
  3493. xmlFree(use);
  3494. }
  3495. /**
  3496. * xmlSchemaFreeAttributeUseProhib:
  3497. * @prohib: an attribute use prohibition
  3498. *
  3499. * Deallocates an attribute use structure.
  3500. */
  3501. static void
  3502. xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
  3503. {
  3504. if (prohib == NULL)
  3505. return;
  3506. xmlFree(prohib);
  3507. }
  3508. /**
  3509. * xmlSchemaFreeWildcardNsSet:
  3510. * set: a schema wildcard namespace
  3511. *
  3512. * Deallocates a list of wildcard constraint structures.
  3513. */
  3514. static void
  3515. xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
  3516. {
  3517. xmlSchemaWildcardNsPtr next;
  3518. while (set != NULL) {
  3519. next = set->next;
  3520. xmlFree(set);
  3521. set = next;
  3522. }
  3523. }
  3524. /**
  3525. * xmlSchemaFreeWildcard:
  3526. * @wildcard: a wildcard structure
  3527. *
  3528. * Deallocates a wildcard structure.
  3529. */
  3530. void
  3531. xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
  3532. {
  3533. if (wildcard == NULL)
  3534. return;
  3535. if (wildcard->annot != NULL)
  3536. xmlSchemaFreeAnnot(wildcard->annot);
  3537. if (wildcard->nsSet != NULL)
  3538. xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
  3539. if (wildcard->negNsSet != NULL)
  3540. xmlFree(wildcard->negNsSet);
  3541. xmlFree(wildcard);
  3542. }
  3543. /**
  3544. * xmlSchemaFreeAttributeGroup:
  3545. * @schema: a schema attribute group structure
  3546. *
  3547. * Deallocate a Schema Attribute Group structure.
  3548. */
  3549. static void
  3550. xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
  3551. {
  3552. if (attrGr == NULL)
  3553. return;
  3554. if (attrGr->annot != NULL)
  3555. xmlSchemaFreeAnnot(attrGr->annot);
  3556. if (attrGr->attrUses != NULL)
  3557. xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
  3558. xmlFree(attrGr);
  3559. }
  3560. /**
  3561. * xmlSchemaFreeQNameRef:
  3562. * @item: a QName reference structure
  3563. *
  3564. * Deallocatea a QName reference structure.
  3565. */
  3566. static void
  3567. xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
  3568. {
  3569. xmlFree(item);
  3570. }
  3571. /**
  3572. * xmlSchemaFreeTypeLinkList:
  3573. * @alink: a type link
  3574. *
  3575. * Deallocate a list of types.
  3576. */
  3577. static void
  3578. xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
  3579. {
  3580. xmlSchemaTypeLinkPtr next;
  3581. while (link != NULL) {
  3582. next = link->next;
  3583. xmlFree(link);
  3584. link = next;
  3585. }
  3586. }
  3587. static void
  3588. xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
  3589. {
  3590. xmlSchemaIDCStateObjPtr next;
  3591. while (sto != NULL) {
  3592. next = sto->next;
  3593. if (sto->history != NULL)
  3594. xmlFree(sto->history);
  3595. if (sto->xpathCtxt != NULL)
  3596. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  3597. xmlFree(sto);
  3598. sto = next;
  3599. }
  3600. }
  3601. /**
  3602. * xmlSchemaFreeIDC:
  3603. * @idc: a identity-constraint definition
  3604. *
  3605. * Deallocates an identity-constraint definition.
  3606. */
  3607. static void
  3608. xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
  3609. {
  3610. xmlSchemaIDCSelectPtr cur, prev;
  3611. if (idcDef == NULL)
  3612. return;
  3613. if (idcDef->annot != NULL)
  3614. xmlSchemaFreeAnnot(idcDef->annot);
  3615. /* Selector */
  3616. if (idcDef->selector != NULL) {
  3617. if (idcDef->selector->xpathComp != NULL)
  3618. xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
  3619. xmlFree(idcDef->selector);
  3620. }
  3621. /* Fields */
  3622. if (idcDef->fields != NULL) {
  3623. cur = idcDef->fields;
  3624. do {
  3625. prev = cur;
  3626. cur = cur->next;
  3627. if (prev->xpathComp != NULL)
  3628. xmlFreePattern((xmlPatternPtr) prev->xpathComp);
  3629. xmlFree(prev);
  3630. } while (cur != NULL);
  3631. }
  3632. xmlFree(idcDef);
  3633. }
  3634. /**
  3635. * xmlSchemaFreeElement:
  3636. * @schema: a schema element structure
  3637. *
  3638. * Deallocate a Schema Element structure.
  3639. */
  3640. static void
  3641. xmlSchemaFreeElement(xmlSchemaElementPtr elem)
  3642. {
  3643. if (elem == NULL)
  3644. return;
  3645. if (elem->annot != NULL)
  3646. xmlSchemaFreeAnnot(elem->annot);
  3647. if (elem->contModel != NULL)
  3648. xmlRegFreeRegexp(elem->contModel);
  3649. if (elem->defVal != NULL)
  3650. xmlSchemaFreeValue(elem->defVal);
  3651. xmlFree(elem);
  3652. }
  3653. /**
  3654. * xmlSchemaFreeFacet:
  3655. * @facet: a schema facet structure
  3656. *
  3657. * Deallocate a Schema Facet structure.
  3658. */
  3659. void
  3660. xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
  3661. {
  3662. if (facet == NULL)
  3663. return;
  3664. if (facet->val != NULL)
  3665. xmlSchemaFreeValue(facet->val);
  3666. if (facet->regexp != NULL)
  3667. xmlRegFreeRegexp(facet->regexp);
  3668. if (facet->annot != NULL)
  3669. xmlSchemaFreeAnnot(facet->annot);
  3670. xmlFree(facet);
  3671. }
  3672. /**
  3673. * xmlSchemaFreeType:
  3674. * @type: a schema type structure
  3675. *
  3676. * Deallocate a Schema Type structure.
  3677. */
  3678. void
  3679. xmlSchemaFreeType(xmlSchemaTypePtr type)
  3680. {
  3681. if (type == NULL)
  3682. return;
  3683. if (type->annot != NULL)
  3684. xmlSchemaFreeAnnot(type->annot);
  3685. if (type->facets != NULL) {
  3686. xmlSchemaFacetPtr facet, next;
  3687. facet = type->facets;
  3688. while (facet != NULL) {
  3689. next = facet->next;
  3690. xmlSchemaFreeFacet(facet);
  3691. facet = next;
  3692. }
  3693. }
  3694. if (type->attrUses != NULL)
  3695. xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
  3696. if (type->memberTypes != NULL)
  3697. xmlSchemaFreeTypeLinkList(type->memberTypes);
  3698. if (type->facetSet != NULL) {
  3699. xmlSchemaFacetLinkPtr next, link;
  3700. link = type->facetSet;
  3701. do {
  3702. next = link->next;
  3703. xmlFree(link);
  3704. link = next;
  3705. } while (link != NULL);
  3706. }
  3707. if (type->contModel != NULL)
  3708. xmlRegFreeRegexp(type->contModel);
  3709. xmlFree(type);
  3710. }
  3711. /**
  3712. * xmlSchemaFreeModelGroupDef:
  3713. * @item: a schema model group definition
  3714. *
  3715. * Deallocates a schema model group definition.
  3716. */
  3717. static void
  3718. xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
  3719. {
  3720. if (item->annot != NULL)
  3721. xmlSchemaFreeAnnot(item->annot);
  3722. xmlFree(item);
  3723. }
  3724. /**
  3725. * xmlSchemaFreeModelGroup:
  3726. * @item: a schema model group
  3727. *
  3728. * Deallocates a schema model group structure.
  3729. */
  3730. static void
  3731. xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
  3732. {
  3733. if (item->annot != NULL)
  3734. xmlSchemaFreeAnnot(item->annot);
  3735. xmlFree(item);
  3736. }
  3737. static void
  3738. xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
  3739. {
  3740. if ((list == NULL) || (list->nbItems == 0))
  3741. return;
  3742. {
  3743. xmlSchemaTreeItemPtr item;
  3744. xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
  3745. int i;
  3746. for (i = 0; i < list->nbItems; i++) {
  3747. item = items[i];
  3748. if (item == NULL)
  3749. continue;
  3750. switch (item->type) {
  3751. case XML_SCHEMA_TYPE_SIMPLE:
  3752. case XML_SCHEMA_TYPE_COMPLEX:
  3753. xmlSchemaFreeType((xmlSchemaTypePtr) item);
  3754. break;
  3755. case XML_SCHEMA_TYPE_ATTRIBUTE:
  3756. xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
  3757. break;
  3758. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  3759. xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
  3760. break;
  3761. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  3762. xmlSchemaFreeAttributeUseProhib(
  3763. (xmlSchemaAttributeUseProhibPtr) item);
  3764. break;
  3765. case XML_SCHEMA_TYPE_ELEMENT:
  3766. xmlSchemaFreeElement((xmlSchemaElementPtr) item);
  3767. break;
  3768. case XML_SCHEMA_TYPE_PARTICLE:
  3769. if (item->annot != NULL)
  3770. xmlSchemaFreeAnnot(item->annot);
  3771. xmlFree(item);
  3772. break;
  3773. case XML_SCHEMA_TYPE_SEQUENCE:
  3774. case XML_SCHEMA_TYPE_CHOICE:
  3775. case XML_SCHEMA_TYPE_ALL:
  3776. xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
  3777. break;
  3778. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  3779. xmlSchemaFreeAttributeGroup(
  3780. (xmlSchemaAttributeGroupPtr) item);
  3781. break;
  3782. case XML_SCHEMA_TYPE_GROUP:
  3783. xmlSchemaFreeModelGroupDef(
  3784. (xmlSchemaModelGroupDefPtr) item);
  3785. break;
  3786. case XML_SCHEMA_TYPE_ANY:
  3787. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  3788. xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
  3789. break;
  3790. case XML_SCHEMA_TYPE_IDC_KEY:
  3791. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  3792. case XML_SCHEMA_TYPE_IDC_KEYREF:
  3793. xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
  3794. break;
  3795. case XML_SCHEMA_TYPE_NOTATION:
  3796. xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
  3797. break;
  3798. case XML_SCHEMA_EXTRA_QNAMEREF:
  3799. xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
  3800. break;
  3801. default: {
  3802. /* TODO: This should never be hit. */
  3803. xmlSchemaPSimpleInternalErr(NULL,
  3804. "Internal error: xmlSchemaComponentListFree, "
  3805. "unexpected component type '%s'\n",
  3806. (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
  3807. }
  3808. break;
  3809. }
  3810. }
  3811. list->nbItems = 0;
  3812. }
  3813. }
  3814. /**
  3815. * xmlSchemaFree:
  3816. * @schema: a schema structure
  3817. *
  3818. * Deallocate a Schema structure.
  3819. */
  3820. void
  3821. xmlSchemaFree(xmlSchemaPtr schema)
  3822. {
  3823. if (schema == NULL)
  3824. return;
  3825. /* @volatiles is not used anymore :-/ */
  3826. if (schema->volatiles != NULL)
  3827. TODO
  3828. /*
  3829. * Note that those slots are not responsible for freeing
  3830. * schema components anymore; this will now be done by
  3831. * the schema buckets.
  3832. */
  3833. if (schema->notaDecl != NULL)
  3834. xmlHashFree(schema->notaDecl, NULL);
  3835. if (schema->attrDecl != NULL)
  3836. xmlHashFree(schema->attrDecl, NULL);
  3837. if (schema->attrgrpDecl != NULL)
  3838. xmlHashFree(schema->attrgrpDecl, NULL);
  3839. if (schema->elemDecl != NULL)
  3840. xmlHashFree(schema->elemDecl, NULL);
  3841. if (schema->typeDecl != NULL)
  3842. xmlHashFree(schema->typeDecl, NULL);
  3843. if (schema->groupDecl != NULL)
  3844. xmlHashFree(schema->groupDecl, NULL);
  3845. if (schema->idcDef != NULL)
  3846. xmlHashFree(schema->idcDef, NULL);
  3847. if (schema->schemasImports != NULL)
  3848. xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
  3849. if (schema->includes != NULL) {
  3850. xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
  3851. int i;
  3852. for (i = 0; i < list->nbItems; i++) {
  3853. xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
  3854. }
  3855. xmlSchemaItemListFree(list);
  3856. }
  3857. if (schema->annot != NULL)
  3858. xmlSchemaFreeAnnot(schema->annot);
  3859. /* Never free the doc here, since this will be done by the buckets. */
  3860. xmlDictFree(schema->dict);
  3861. xmlFree(schema);
  3862. }
  3863. /************************************************************************
  3864. * *
  3865. * Debug functions *
  3866. * *
  3867. ************************************************************************/
  3868. #ifdef LIBXML_OUTPUT_ENABLED
  3869. static void
  3870. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
  3871. /**
  3872. * xmlSchemaElementDump:
  3873. * @elem: an element
  3874. * @output: the file output
  3875. *
  3876. * Dump the element
  3877. */
  3878. static void
  3879. xmlSchemaElementDump(void *payload, void *data,
  3880. const xmlChar * name ATTRIBUTE_UNUSED,
  3881. const xmlChar * namespace ATTRIBUTE_UNUSED,
  3882. const xmlChar * context ATTRIBUTE_UNUSED)
  3883. {
  3884. xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
  3885. FILE *output = (FILE *) data;
  3886. if (elem == NULL)
  3887. return;
  3888. fprintf(output, "Element");
  3889. if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
  3890. fprintf(output, " (global)");
  3891. fprintf(output, ": '%s' ", elem->name);
  3892. if (namespace != NULL)
  3893. fprintf(output, "ns '%s'", namespace);
  3894. fprintf(output, "\n");
  3895. #if 0
  3896. if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
  3897. fprintf(output, " min %d ", elem->minOccurs);
  3898. if (elem->maxOccurs >= UNBOUNDED)
  3899. fprintf(output, "max: unbounded\n");
  3900. else if (elem->maxOccurs != 1)
  3901. fprintf(output, "max: %d\n", elem->maxOccurs);
  3902. else
  3903. fprintf(output, "\n");
  3904. }
  3905. #endif
  3906. /*
  3907. * Misc other properties.
  3908. */
  3909. if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
  3910. (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
  3911. (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
  3912. (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
  3913. fprintf(output, " props: ");
  3914. if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
  3915. fprintf(output, "[fixed] ");
  3916. if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
  3917. fprintf(output, "[default] ");
  3918. if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  3919. fprintf(output, "[abstract] ");
  3920. if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
  3921. fprintf(output, "[nillable] ");
  3922. fprintf(output, "\n");
  3923. }
  3924. /*
  3925. * Default/fixed value.
  3926. */
  3927. if (elem->value != NULL)
  3928. fprintf(output, " value: '%s'\n", elem->value);
  3929. /*
  3930. * Type.
  3931. */
  3932. if (elem->namedType != NULL) {
  3933. fprintf(output, " type: '%s' ", elem->namedType);
  3934. if (elem->namedTypeNs != NULL)
  3935. fprintf(output, "ns '%s'\n", elem->namedTypeNs);
  3936. else
  3937. fprintf(output, "\n");
  3938. } else if (elem->subtypes != NULL) {
  3939. /*
  3940. * Dump local types.
  3941. */
  3942. xmlSchemaTypeDump(elem->subtypes, output);
  3943. }
  3944. /*
  3945. * Substitution group.
  3946. */
  3947. if (elem->substGroup != NULL) {
  3948. fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
  3949. if (elem->substGroupNs != NULL)
  3950. fprintf(output, "ns '%s'\n", elem->substGroupNs);
  3951. else
  3952. fprintf(output, "\n");
  3953. }
  3954. }
  3955. /**
  3956. * xmlSchemaAnnotDump:
  3957. * @output: the file output
  3958. * @annot: a annotation
  3959. *
  3960. * Dump the annotation
  3961. */
  3962. static void
  3963. xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
  3964. {
  3965. xmlChar *content;
  3966. if (annot == NULL)
  3967. return;
  3968. content = xmlNodeGetContent(annot->content);
  3969. if (content != NULL) {
  3970. fprintf(output, " Annot: %s\n", content);
  3971. xmlFree(content);
  3972. } else
  3973. fprintf(output, " Annot: empty\n");
  3974. }
  3975. /**
  3976. * xmlSchemaContentModelDump:
  3977. * @particle: the schema particle
  3978. * @output: the file output
  3979. * @depth: the depth used for indentation
  3980. *
  3981. * Dump a SchemaType structure
  3982. */
  3983. static void
  3984. xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
  3985. {
  3986. xmlChar *str = NULL;
  3987. xmlSchemaTreeItemPtr term;
  3988. char shift[100];
  3989. int i;
  3990. if (particle == NULL)
  3991. return;
  3992. for (i = 0;((i < depth) && (i < 25));i++)
  3993. shift[2 * i] = shift[2 * i + 1] = ' ';
  3994. shift[2 * i] = shift[2 * i + 1] = 0;
  3995. fprintf(output, "%s", shift);
  3996. if (particle->children == NULL) {
  3997. fprintf(output, "MISSING particle term\n");
  3998. return;
  3999. }
  4000. term = particle->children;
  4001. if (term == NULL) {
  4002. fprintf(output, "(NULL)");
  4003. } else {
  4004. switch (term->type) {
  4005. case XML_SCHEMA_TYPE_ELEMENT:
  4006. fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
  4007. ((xmlSchemaElementPtr)term)->targetNamespace,
  4008. ((xmlSchemaElementPtr)term)->name));
  4009. FREE_AND_NULL(str);
  4010. break;
  4011. case XML_SCHEMA_TYPE_SEQUENCE:
  4012. fprintf(output, "SEQUENCE");
  4013. break;
  4014. case XML_SCHEMA_TYPE_CHOICE:
  4015. fprintf(output, "CHOICE");
  4016. break;
  4017. case XML_SCHEMA_TYPE_ALL:
  4018. fprintf(output, "ALL");
  4019. break;
  4020. case XML_SCHEMA_TYPE_ANY:
  4021. fprintf(output, "ANY");
  4022. break;
  4023. default:
  4024. fprintf(output, "UNKNOWN\n");
  4025. return;
  4026. }
  4027. }
  4028. if (particle->minOccurs != 1)
  4029. fprintf(output, " min: %d", particle->minOccurs);
  4030. if (particle->maxOccurs >= UNBOUNDED)
  4031. fprintf(output, " max: unbounded");
  4032. else if (particle->maxOccurs != 1)
  4033. fprintf(output, " max: %d", particle->maxOccurs);
  4034. fprintf(output, "\n");
  4035. if (term &&
  4036. ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  4037. (term->type == XML_SCHEMA_TYPE_CHOICE) ||
  4038. (term->type == XML_SCHEMA_TYPE_ALL)) &&
  4039. (term->children != NULL)) {
  4040. xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
  4041. output, depth +1);
  4042. }
  4043. if (particle->next != NULL)
  4044. xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
  4045. output, depth);
  4046. }
  4047. /**
  4048. * xmlSchemaAttrUsesDump:
  4049. * @uses: attribute uses list
  4050. * @output: the file output
  4051. *
  4052. * Dumps a list of attribute use components.
  4053. */
  4054. static void
  4055. xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
  4056. {
  4057. xmlSchemaAttributeUsePtr use;
  4058. xmlSchemaAttributeUseProhibPtr prohib;
  4059. xmlSchemaQNameRefPtr ref;
  4060. const xmlChar *name, *tns;
  4061. xmlChar *str = NULL;
  4062. int i;
  4063. if ((uses == NULL) || (uses->nbItems == 0))
  4064. return;
  4065. fprintf(output, " attributes:\n");
  4066. for (i = 0; i < uses->nbItems; i++) {
  4067. use = uses->items[i];
  4068. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  4069. fprintf(output, " [prohibition] ");
  4070. prohib = (xmlSchemaAttributeUseProhibPtr) use;
  4071. name = prohib->name;
  4072. tns = prohib->targetNamespace;
  4073. } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
  4074. fprintf(output, " [reference] ");
  4075. ref = (xmlSchemaQNameRefPtr) use;
  4076. name = ref->name;
  4077. tns = ref->targetNamespace;
  4078. } else {
  4079. fprintf(output, " [use] ");
  4080. name = WXS_ATTRUSE_DECL_NAME(use);
  4081. tns = WXS_ATTRUSE_DECL_TNS(use);
  4082. }
  4083. fprintf(output, "'%s'\n",
  4084. (const char *) xmlSchemaFormatQName(&str, tns, name));
  4085. FREE_AND_NULL(str);
  4086. }
  4087. }
  4088. /**
  4089. * xmlSchemaTypeDump:
  4090. * @output: the file output
  4091. * @type: a type structure
  4092. *
  4093. * Dump a SchemaType structure
  4094. */
  4095. static void
  4096. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
  4097. {
  4098. if (type == NULL) {
  4099. fprintf(output, "Type: NULL\n");
  4100. return;
  4101. }
  4102. fprintf(output, "Type: ");
  4103. if (type->name != NULL)
  4104. fprintf(output, "'%s' ", type->name);
  4105. else
  4106. fprintf(output, "(no name) ");
  4107. if (type->targetNamespace != NULL)
  4108. fprintf(output, "ns '%s' ", type->targetNamespace);
  4109. switch (type->type) {
  4110. case XML_SCHEMA_TYPE_BASIC:
  4111. fprintf(output, "[basic] ");
  4112. break;
  4113. case XML_SCHEMA_TYPE_SIMPLE:
  4114. fprintf(output, "[simple] ");
  4115. break;
  4116. case XML_SCHEMA_TYPE_COMPLEX:
  4117. fprintf(output, "[complex] ");
  4118. break;
  4119. case XML_SCHEMA_TYPE_SEQUENCE:
  4120. fprintf(output, "[sequence] ");
  4121. break;
  4122. case XML_SCHEMA_TYPE_CHOICE:
  4123. fprintf(output, "[choice] ");
  4124. break;
  4125. case XML_SCHEMA_TYPE_ALL:
  4126. fprintf(output, "[all] ");
  4127. break;
  4128. case XML_SCHEMA_TYPE_UR:
  4129. fprintf(output, "[ur] ");
  4130. break;
  4131. case XML_SCHEMA_TYPE_RESTRICTION:
  4132. fprintf(output, "[restriction] ");
  4133. break;
  4134. case XML_SCHEMA_TYPE_EXTENSION:
  4135. fprintf(output, "[extension] ");
  4136. break;
  4137. default:
  4138. fprintf(output, "[unknown type %d] ", type->type);
  4139. break;
  4140. }
  4141. fprintf(output, "content: ");
  4142. switch (type->contentType) {
  4143. case XML_SCHEMA_CONTENT_UNKNOWN:
  4144. fprintf(output, "[unknown] ");
  4145. break;
  4146. case XML_SCHEMA_CONTENT_EMPTY:
  4147. fprintf(output, "[empty] ");
  4148. break;
  4149. case XML_SCHEMA_CONTENT_ELEMENTS:
  4150. fprintf(output, "[element] ");
  4151. break;
  4152. case XML_SCHEMA_CONTENT_MIXED:
  4153. fprintf(output, "[mixed] ");
  4154. break;
  4155. case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
  4156. /* not used. */
  4157. break;
  4158. case XML_SCHEMA_CONTENT_BASIC:
  4159. fprintf(output, "[basic] ");
  4160. break;
  4161. case XML_SCHEMA_CONTENT_SIMPLE:
  4162. fprintf(output, "[simple] ");
  4163. break;
  4164. case XML_SCHEMA_CONTENT_ANY:
  4165. fprintf(output, "[any] ");
  4166. break;
  4167. }
  4168. fprintf(output, "\n");
  4169. if (type->base != NULL) {
  4170. fprintf(output, " base type: '%s'", type->base);
  4171. if (type->baseNs != NULL)
  4172. fprintf(output, " ns '%s'\n", type->baseNs);
  4173. else
  4174. fprintf(output, "\n");
  4175. }
  4176. if (type->attrUses != NULL)
  4177. xmlSchemaAttrUsesDump(type->attrUses, output);
  4178. if (type->annot != NULL)
  4179. xmlSchemaAnnotDump(output, type->annot);
  4180. #ifdef DUMP_CONTENT_MODEL
  4181. if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
  4182. (type->subtypes != NULL)) {
  4183. xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
  4184. output, 1);
  4185. }
  4186. #endif
  4187. }
  4188. static void
  4189. xmlSchemaTypeDumpEntry(void *type, void *output,
  4190. const xmlChar *name ATTRIBUTE_UNUSED)
  4191. {
  4192. xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
  4193. }
  4194. /**
  4195. * xmlSchemaDump:
  4196. * @output: the file output
  4197. * @schema: a schema structure
  4198. *
  4199. * Dump a Schema structure.
  4200. */
  4201. void
  4202. xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
  4203. {
  4204. if (output == NULL)
  4205. return;
  4206. if (schema == NULL) {
  4207. fprintf(output, "Schemas: NULL\n");
  4208. return;
  4209. }
  4210. fprintf(output, "Schemas: ");
  4211. if (schema->name != NULL)
  4212. fprintf(output, "%s, ", schema->name);
  4213. else
  4214. fprintf(output, "no name, ");
  4215. if (schema->targetNamespace != NULL)
  4216. fprintf(output, "%s", (const char *) schema->targetNamespace);
  4217. else
  4218. fprintf(output, "no target namespace");
  4219. fprintf(output, "\n");
  4220. if (schema->annot != NULL)
  4221. xmlSchemaAnnotDump(output, schema->annot);
  4222. xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
  4223. xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
  4224. }
  4225. #ifdef DEBUG_IDC_NODE_TABLE
  4226. /**
  4227. * xmlSchemaDebugDumpIDCTable:
  4228. * @vctxt: the WXS validation context
  4229. *
  4230. * Displays the current IDC table for debug purposes.
  4231. */
  4232. static void
  4233. xmlSchemaDebugDumpIDCTable(FILE * output,
  4234. const xmlChar *namespaceName,
  4235. const xmlChar *localName,
  4236. xmlSchemaPSVIIDCBindingPtr bind)
  4237. {
  4238. xmlChar *str = NULL;
  4239. const xmlChar *value;
  4240. xmlSchemaPSVIIDCNodePtr tab;
  4241. xmlSchemaPSVIIDCKeyPtr key;
  4242. int i, j, res;
  4243. fprintf(output, "IDC: TABLES on '%s'\n",
  4244. xmlSchemaFormatQName(&str, namespaceName, localName));
  4245. FREE_AND_NULL(str)
  4246. if (bind == NULL)
  4247. return;
  4248. do {
  4249. fprintf(output, "IDC: BINDING '%s' (%d)\n",
  4250. xmlSchemaGetComponentQName(&str,
  4251. bind->definition), bind->nbNodes);
  4252. FREE_AND_NULL(str)
  4253. for (i = 0; i < bind->nbNodes; i++) {
  4254. tab = bind->nodeTable[i];
  4255. fprintf(output, " ( ");
  4256. for (j = 0; j < bind->definition->nbFields; j++) {
  4257. key = tab->keys[j];
  4258. if ((key != NULL) && (key->val != NULL)) {
  4259. res = xmlSchemaGetCanonValue(key->val, &value);
  4260. if (res >= 0)
  4261. fprintf(output, "'%s' ", value);
  4262. else
  4263. fprintf(output, "CANON-VALUE-FAILED ");
  4264. if (res == 0)
  4265. FREE_AND_NULL(value)
  4266. } else if (key != NULL)
  4267. fprintf(output, "(no val), ");
  4268. else
  4269. fprintf(output, "(key missing), ");
  4270. }
  4271. fprintf(output, ")\n");
  4272. }
  4273. if (bind->dupls && bind->dupls->nbItems) {
  4274. fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems);
  4275. for (i = 0; i < bind->dupls->nbItems; i++) {
  4276. tab = bind->dupls->items[i];
  4277. fprintf(output, " ( ");
  4278. for (j = 0; j < bind->definition->nbFields; j++) {
  4279. key = tab->keys[j];
  4280. if ((key != NULL) && (key->val != NULL)) {
  4281. res = xmlSchemaGetCanonValue(key->val, &value);
  4282. if (res >= 0)
  4283. fprintf(output, "'%s' ", value);
  4284. else
  4285. fprintf(output, "CANON-VALUE-FAILED ");
  4286. if (res == 0)
  4287. FREE_AND_NULL(value)
  4288. } else if (key != NULL)
  4289. fprintf(output, "(no val), ");
  4290. else
  4291. fprintf(output, "(key missing), ");
  4292. }
  4293. fprintf(output, ")\n");
  4294. }
  4295. }
  4296. bind = bind->next;
  4297. } while (bind != NULL);
  4298. }
  4299. #endif /* DEBUG_IDC */
  4300. #endif /* LIBXML_OUTPUT_ENABLED */
  4301. /************************************************************************
  4302. * *
  4303. * Utilities *
  4304. * *
  4305. ************************************************************************/
  4306. /**
  4307. * xmlSchemaGetPropNode:
  4308. * @node: the element node
  4309. * @name: the name of the attribute
  4310. *
  4311. * Seeks an attribute with a name of @name in
  4312. * no namespace.
  4313. *
  4314. * Returns the attribute or NULL if not present.
  4315. */
  4316. static xmlAttrPtr
  4317. xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
  4318. {
  4319. xmlAttrPtr prop;
  4320. if ((node == NULL) || (name == NULL))
  4321. return(NULL);
  4322. prop = node->properties;
  4323. while (prop != NULL) {
  4324. if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
  4325. return(prop);
  4326. prop = prop->next;
  4327. }
  4328. return (NULL);
  4329. }
  4330. /**
  4331. * xmlSchemaGetPropNodeNs:
  4332. * @node: the element node
  4333. * @uri: the uri
  4334. * @name: the name of the attribute
  4335. *
  4336. * Seeks an attribute with a local name of @name and
  4337. * a namespace URI of @uri.
  4338. *
  4339. * Returns the attribute or NULL if not present.
  4340. */
  4341. static xmlAttrPtr
  4342. xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
  4343. {
  4344. xmlAttrPtr prop;
  4345. if ((node == NULL) || (name == NULL))
  4346. return(NULL);
  4347. prop = node->properties;
  4348. while (prop != NULL) {
  4349. if ((prop->ns != NULL) &&
  4350. xmlStrEqual(prop->name, BAD_CAST name) &&
  4351. xmlStrEqual(prop->ns->href, BAD_CAST uri))
  4352. return(prop);
  4353. prop = prop->next;
  4354. }
  4355. return (NULL);
  4356. }
  4357. static const xmlChar *
  4358. xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  4359. {
  4360. xmlChar *val;
  4361. const xmlChar *ret;
  4362. val = xmlNodeGetContent(node);
  4363. if (val == NULL)
  4364. val = xmlStrdup((xmlChar *)"");
  4365. ret = xmlDictLookup(ctxt->dict, val, -1);
  4366. xmlFree(val);
  4367. return(ret);
  4368. }
  4369. static const xmlChar *
  4370. xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
  4371. {
  4372. return((const xmlChar*) xmlNodeGetContent(node));
  4373. }
  4374. /**
  4375. * xmlSchemaGetProp:
  4376. * @ctxt: the parser context
  4377. * @node: the node
  4378. * @name: the property name
  4379. *
  4380. * Read a attribute value and internalize the string
  4381. *
  4382. * Returns the string or NULL if not present.
  4383. */
  4384. static const xmlChar *
  4385. xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  4386. const char *name)
  4387. {
  4388. xmlChar *val;
  4389. const xmlChar *ret;
  4390. val = xmlGetNoNsProp(node, BAD_CAST name);
  4391. if (val == NULL)
  4392. return(NULL);
  4393. ret = xmlDictLookup(ctxt->dict, val, -1);
  4394. xmlFree(val);
  4395. return(ret);
  4396. }
  4397. /************************************************************************
  4398. * *
  4399. * Parsing functions *
  4400. * *
  4401. ************************************************************************/
  4402. #define WXS_FIND_GLOBAL_ITEM(slot) \
  4403. if (xmlStrEqual(nsName, schema->targetNamespace)) { \
  4404. ret = xmlHashLookup(schema->slot, name); \
  4405. if (ret != NULL) goto exit; \
  4406. } \
  4407. if (xmlHashSize(schema->schemasImports) > 1) { \
  4408. xmlSchemaImportPtr import; \
  4409. if (nsName == NULL) \
  4410. import = xmlHashLookup(schema->schemasImports, \
  4411. XML_SCHEMAS_NO_NAMESPACE); \
  4412. else \
  4413. import = xmlHashLookup(schema->schemasImports, nsName); \
  4414. if (import == NULL) \
  4415. goto exit; \
  4416. ret = xmlHashLookup(import->schema->slot, name); \
  4417. }
  4418. /**
  4419. * xmlSchemaGetElem:
  4420. * @schema: the schema context
  4421. * @name: the element name
  4422. * @ns: the element namespace
  4423. *
  4424. * Lookup a global element declaration in the schema.
  4425. *
  4426. * Returns the element declaration or NULL if not found.
  4427. */
  4428. static xmlSchemaElementPtr
  4429. xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
  4430. const xmlChar * nsName)
  4431. {
  4432. xmlSchemaElementPtr ret = NULL;
  4433. if ((name == NULL) || (schema == NULL))
  4434. return(NULL);
  4435. if (schema != NULL) {
  4436. WXS_FIND_GLOBAL_ITEM(elemDecl)
  4437. }
  4438. exit:
  4439. #ifdef DEBUG
  4440. if (ret == NULL) {
  4441. if (nsName == NULL)
  4442. fprintf(stderr, "Unable to lookup element decl. %s", name);
  4443. else
  4444. fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
  4445. nsName);
  4446. }
  4447. #endif
  4448. return (ret);
  4449. }
  4450. /**
  4451. * xmlSchemaGetType:
  4452. * @schema: the main schema
  4453. * @name: the type's name
  4454. * nsName: the type's namespace
  4455. *
  4456. * Lookup a type in the schemas or the predefined types
  4457. *
  4458. * Returns the group definition or NULL if not found.
  4459. */
  4460. static xmlSchemaTypePtr
  4461. xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
  4462. const xmlChar * nsName)
  4463. {
  4464. xmlSchemaTypePtr ret = NULL;
  4465. if (name == NULL)
  4466. return (NULL);
  4467. /* First try the built-in types. */
  4468. if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
  4469. ret = xmlSchemaGetPredefinedType(name, nsName);
  4470. if (ret != NULL)
  4471. goto exit;
  4472. /*
  4473. * Note that we try the parsed schemas as well here
  4474. * since one might have parsed the S4S, which contain more
  4475. * than the built-in types.
  4476. * TODO: Can we optimize this?
  4477. */
  4478. }
  4479. if (schema != NULL) {
  4480. WXS_FIND_GLOBAL_ITEM(typeDecl)
  4481. }
  4482. exit:
  4483. #ifdef DEBUG
  4484. if (ret == NULL) {
  4485. if (nsName == NULL)
  4486. fprintf(stderr, "Unable to lookup type %s", name);
  4487. else
  4488. fprintf(stderr, "Unable to lookup type %s:%s", name,
  4489. nsName);
  4490. }
  4491. #endif
  4492. return (ret);
  4493. }
  4494. /**
  4495. * xmlSchemaGetAttributeDecl:
  4496. * @schema: the context of the schema
  4497. * @name: the name of the attribute
  4498. * @ns: the target namespace of the attribute
  4499. *
  4500. * Lookup a an attribute in the schema or imported schemas
  4501. *
  4502. * Returns the attribute declaration or NULL if not found.
  4503. */
  4504. static xmlSchemaAttributePtr
  4505. xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
  4506. const xmlChar * nsName)
  4507. {
  4508. xmlSchemaAttributePtr ret = NULL;
  4509. if ((name == NULL) || (schema == NULL))
  4510. return (NULL);
  4511. if (schema != NULL) {
  4512. WXS_FIND_GLOBAL_ITEM(attrDecl)
  4513. }
  4514. exit:
  4515. #ifdef DEBUG
  4516. if (ret == NULL) {
  4517. if (nsName == NULL)
  4518. fprintf(stderr, "Unable to lookup attribute %s", name);
  4519. else
  4520. fprintf(stderr, "Unable to lookup attribute %s:%s", name,
  4521. nsName);
  4522. }
  4523. #endif
  4524. return (ret);
  4525. }
  4526. /**
  4527. * xmlSchemaGetAttributeGroup:
  4528. * @schema: the context of the schema
  4529. * @name: the name of the attribute group
  4530. * @ns: the target namespace of the attribute group
  4531. *
  4532. * Lookup a an attribute group in the schema or imported schemas
  4533. *
  4534. * Returns the attribute group definition or NULL if not found.
  4535. */
  4536. static xmlSchemaAttributeGroupPtr
  4537. xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
  4538. const xmlChar * nsName)
  4539. {
  4540. xmlSchemaAttributeGroupPtr ret = NULL;
  4541. if ((name == NULL) || (schema == NULL))
  4542. return (NULL);
  4543. if (schema != NULL) {
  4544. WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
  4545. }
  4546. exit:
  4547. /* TODO:
  4548. if ((ret != NULL) && (ret->redef != NULL)) {
  4549. * Return the last redefinition. *
  4550. ret = ret->redef;
  4551. }
  4552. */
  4553. #ifdef DEBUG
  4554. if (ret == NULL) {
  4555. if (nsName == NULL)
  4556. fprintf(stderr, "Unable to lookup attribute group %s", name);
  4557. else
  4558. fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
  4559. nsName);
  4560. }
  4561. #endif
  4562. return (ret);
  4563. }
  4564. /**
  4565. * xmlSchemaGetGroup:
  4566. * @schema: the context of the schema
  4567. * @name: the name of the group
  4568. * @ns: the target namespace of the group
  4569. *
  4570. * Lookup a group in the schema or imported schemas
  4571. *
  4572. * Returns the group definition or NULL if not found.
  4573. */
  4574. static xmlSchemaModelGroupDefPtr
  4575. xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
  4576. const xmlChar * nsName)
  4577. {
  4578. xmlSchemaModelGroupDefPtr ret = NULL;
  4579. if ((name == NULL) || (schema == NULL))
  4580. return (NULL);
  4581. if (schema != NULL) {
  4582. WXS_FIND_GLOBAL_ITEM(groupDecl)
  4583. }
  4584. exit:
  4585. #ifdef DEBUG
  4586. if (ret == NULL) {
  4587. if (nsName == NULL)
  4588. fprintf(stderr, "Unable to lookup group %s", name);
  4589. else
  4590. fprintf(stderr, "Unable to lookup group %s:%s", name,
  4591. nsName);
  4592. }
  4593. #endif
  4594. return (ret);
  4595. }
  4596. static xmlSchemaNotationPtr
  4597. xmlSchemaGetNotation(xmlSchemaPtr schema,
  4598. const xmlChar *name,
  4599. const xmlChar *nsName)
  4600. {
  4601. xmlSchemaNotationPtr ret = NULL;
  4602. if ((name == NULL) || (schema == NULL))
  4603. return (NULL);
  4604. if (schema != NULL) {
  4605. WXS_FIND_GLOBAL_ITEM(notaDecl)
  4606. }
  4607. exit:
  4608. return (ret);
  4609. }
  4610. static xmlSchemaIDCPtr
  4611. xmlSchemaGetIDC(xmlSchemaPtr schema,
  4612. const xmlChar *name,
  4613. const xmlChar *nsName)
  4614. {
  4615. xmlSchemaIDCPtr ret = NULL;
  4616. if ((name == NULL) || (schema == NULL))
  4617. return (NULL);
  4618. if (schema != NULL) {
  4619. WXS_FIND_GLOBAL_ITEM(idcDef)
  4620. }
  4621. exit:
  4622. return (ret);
  4623. }
  4624. /**
  4625. * xmlSchemaGetNamedComponent:
  4626. * @schema: the schema
  4627. * @name: the name of the group
  4628. * @ns: the target namespace of the group
  4629. *
  4630. * Lookup a group in the schema or imported schemas
  4631. *
  4632. * Returns the group definition or NULL if not found.
  4633. */
  4634. static xmlSchemaBasicItemPtr
  4635. xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
  4636. xmlSchemaTypeType itemType,
  4637. const xmlChar *name,
  4638. const xmlChar *targetNs)
  4639. {
  4640. switch (itemType) {
  4641. case XML_SCHEMA_TYPE_GROUP:
  4642. return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
  4643. name, targetNs));
  4644. case XML_SCHEMA_TYPE_ELEMENT:
  4645. return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
  4646. name, targetNs));
  4647. default:
  4648. TODO
  4649. return (NULL);
  4650. }
  4651. }
  4652. /************************************************************************
  4653. * *
  4654. * Parsing functions *
  4655. * *
  4656. ************************************************************************/
  4657. #define IS_BLANK_NODE(n) \
  4658. (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
  4659. /**
  4660. * xmlSchemaIsBlank:
  4661. * @str: a string
  4662. * @len: the length of the string or -1
  4663. *
  4664. * Check if a string is ignorable
  4665. *
  4666. * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
  4667. */
  4668. static int
  4669. xmlSchemaIsBlank(xmlChar * str, int len)
  4670. {
  4671. if (str == NULL)
  4672. return (1);
  4673. if (len < 0) {
  4674. while (*str != 0) {
  4675. if (!(IS_BLANK_CH(*str)))
  4676. return (0);
  4677. str++;
  4678. }
  4679. } else while ((*str != 0) && (len != 0)) {
  4680. if (!(IS_BLANK_CH(*str)))
  4681. return (0);
  4682. str++;
  4683. len--;
  4684. }
  4685. return (1);
  4686. }
  4687. #define WXS_COMP_NAME(c, t) ((t) (c))->name
  4688. #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
  4689. /*
  4690. * xmlSchemaFindRedefCompInGraph:
  4691. * ATTENTION TODO: This uses pointer comp. for strings.
  4692. */
  4693. static xmlSchemaBasicItemPtr
  4694. xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
  4695. xmlSchemaTypeType type,
  4696. const xmlChar *name,
  4697. const xmlChar *nsName)
  4698. {
  4699. xmlSchemaBasicItemPtr ret;
  4700. int i;
  4701. if ((bucket == NULL) || (name == NULL))
  4702. return(NULL);
  4703. if ((bucket->globals == NULL) ||
  4704. (bucket->globals->nbItems == 0))
  4705. goto subschemas;
  4706. /*
  4707. * Search in global components.
  4708. */
  4709. for (i = 0; i < bucket->globals->nbItems; i++) {
  4710. ret = bucket->globals->items[i];
  4711. if (ret->type == type) {
  4712. switch (type) {
  4713. case XML_SCHEMA_TYPE_COMPLEX:
  4714. case XML_SCHEMA_TYPE_SIMPLE:
  4715. if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
  4716. (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
  4717. nsName))
  4718. {
  4719. return(ret);
  4720. }
  4721. break;
  4722. case XML_SCHEMA_TYPE_GROUP:
  4723. if ((WXS_COMP_NAME(ret,
  4724. xmlSchemaModelGroupDefPtr) == name) &&
  4725. (WXS_COMP_TNS(ret,
  4726. xmlSchemaModelGroupDefPtr) == nsName))
  4727. {
  4728. return(ret);
  4729. }
  4730. break;
  4731. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  4732. if ((WXS_COMP_NAME(ret,
  4733. xmlSchemaAttributeGroupPtr) == name) &&
  4734. (WXS_COMP_TNS(ret,
  4735. xmlSchemaAttributeGroupPtr) == nsName))
  4736. {
  4737. return(ret);
  4738. }
  4739. break;
  4740. default:
  4741. /* Should not be hit. */
  4742. return(NULL);
  4743. }
  4744. }
  4745. }
  4746. subschemas:
  4747. /*
  4748. * Process imported/included schemas.
  4749. */
  4750. if (bucket->relations != NULL) {
  4751. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  4752. /*
  4753. * TODO: Marking the bucket will not avoid multiple searches
  4754. * in the same schema, but avoids at least circularity.
  4755. */
  4756. bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
  4757. do {
  4758. if ((rel->bucket != NULL) &&
  4759. ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
  4760. ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
  4761. type, name, nsName);
  4762. if (ret != NULL)
  4763. return(ret);
  4764. }
  4765. rel = rel->next;
  4766. } while (rel != NULL);
  4767. bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
  4768. }
  4769. return(NULL);
  4770. }
  4771. /**
  4772. * xmlSchemaAddNotation:
  4773. * @ctxt: a schema parser context
  4774. * @schema: the schema being built
  4775. * @name: the item name
  4776. *
  4777. * Add an XML schema annotation declaration
  4778. * *WARNING* this interface is highly subject to change
  4779. *
  4780. * Returns the new structure or NULL in case of error
  4781. */
  4782. static xmlSchemaNotationPtr
  4783. xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4784. const xmlChar *name, const xmlChar *nsName,
  4785. xmlNodePtr node ATTRIBUTE_UNUSED)
  4786. {
  4787. xmlSchemaNotationPtr ret = NULL;
  4788. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  4789. return (NULL);
  4790. ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
  4791. if (ret == NULL) {
  4792. xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
  4793. return (NULL);
  4794. }
  4795. memset(ret, 0, sizeof(xmlSchemaNotation));
  4796. ret->type = XML_SCHEMA_TYPE_NOTATION;
  4797. ret->name = name;
  4798. ret->targetNamespace = nsName;
  4799. /* TODO: do we need the node to be set?
  4800. * ret->node = node;*/
  4801. WXS_ADD_GLOBAL(ctxt, ret);
  4802. return (ret);
  4803. }
  4804. /**
  4805. * xmlSchemaAddAttribute:
  4806. * @ctxt: a schema parser context
  4807. * @schema: the schema being built
  4808. * @name: the item name
  4809. * @namespace: the namespace
  4810. *
  4811. * Add an XML schema Attribute declaration
  4812. * *WARNING* this interface is highly subject to change
  4813. *
  4814. * Returns the new structure or NULL in case of error
  4815. */
  4816. static xmlSchemaAttributePtr
  4817. xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4818. const xmlChar * name, const xmlChar * nsName,
  4819. xmlNodePtr node, int topLevel)
  4820. {
  4821. xmlSchemaAttributePtr ret = NULL;
  4822. if ((ctxt == NULL) || (schema == NULL))
  4823. return (NULL);
  4824. ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
  4825. if (ret == NULL) {
  4826. xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
  4827. return (NULL);
  4828. }
  4829. memset(ret, 0, sizeof(xmlSchemaAttribute));
  4830. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
  4831. ret->node = node;
  4832. ret->name = name;
  4833. ret->targetNamespace = nsName;
  4834. if (topLevel)
  4835. WXS_ADD_GLOBAL(ctxt, ret);
  4836. else
  4837. WXS_ADD_LOCAL(ctxt, ret);
  4838. WXS_ADD_PENDING(ctxt, ret);
  4839. return (ret);
  4840. }
  4841. /**
  4842. * xmlSchemaAddAttributeUse:
  4843. * @ctxt: a schema parser context
  4844. * @schema: the schema being built
  4845. * @name: the item name
  4846. * @namespace: the namespace
  4847. *
  4848. * Add an XML schema Attribute declaration
  4849. * *WARNING* this interface is highly subject to change
  4850. *
  4851. * Returns the new structure or NULL in case of error
  4852. */
  4853. static xmlSchemaAttributeUsePtr
  4854. xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
  4855. xmlNodePtr node)
  4856. {
  4857. xmlSchemaAttributeUsePtr ret = NULL;
  4858. if (pctxt == NULL)
  4859. return (NULL);
  4860. ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
  4861. if (ret == NULL) {
  4862. xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
  4863. return (NULL);
  4864. }
  4865. memset(ret, 0, sizeof(xmlSchemaAttributeUse));
  4866. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
  4867. ret->node = node;
  4868. WXS_ADD_LOCAL(pctxt, ret);
  4869. return (ret);
  4870. }
  4871. /*
  4872. * xmlSchemaAddRedef:
  4873. *
  4874. * Adds a redefinition information. This is used at a later stage to:
  4875. * resolve references to the redefined components and to check constraints.
  4876. */
  4877. static xmlSchemaRedefPtr
  4878. xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
  4879. xmlSchemaBucketPtr targetBucket,
  4880. void *item,
  4881. const xmlChar *refName,
  4882. const xmlChar *refTargetNs)
  4883. {
  4884. xmlSchemaRedefPtr ret;
  4885. ret = (xmlSchemaRedefPtr)
  4886. xmlMalloc(sizeof(xmlSchemaRedef));
  4887. if (ret == NULL) {
  4888. xmlSchemaPErrMemory(pctxt,
  4889. "allocating redefinition info", NULL);
  4890. return (NULL);
  4891. }
  4892. memset(ret, 0, sizeof(xmlSchemaRedef));
  4893. ret->item = item;
  4894. ret->targetBucket = targetBucket;
  4895. ret->refName = refName;
  4896. ret->refTargetNs = refTargetNs;
  4897. if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
  4898. WXS_CONSTRUCTOR(pctxt)->redefs = ret;
  4899. else
  4900. WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
  4901. WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
  4902. return (ret);
  4903. }
  4904. /**
  4905. * xmlSchemaAddAttributeGroupDefinition:
  4906. * @ctxt: a schema parser context
  4907. * @schema: the schema being built
  4908. * @name: the item name
  4909. * @nsName: the target namespace
  4910. * @node: the corresponding node
  4911. *
  4912. * Add an XML schema Attribute Group definition.
  4913. *
  4914. * Returns the new structure or NULL in case of error
  4915. */
  4916. static xmlSchemaAttributeGroupPtr
  4917. xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  4918. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  4919. const xmlChar *name,
  4920. const xmlChar *nsName,
  4921. xmlNodePtr node)
  4922. {
  4923. xmlSchemaAttributeGroupPtr ret = NULL;
  4924. if ((pctxt == NULL) || (name == NULL))
  4925. return (NULL);
  4926. ret = (xmlSchemaAttributeGroupPtr)
  4927. xmlMalloc(sizeof(xmlSchemaAttributeGroup));
  4928. if (ret == NULL) {
  4929. xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
  4930. return (NULL);
  4931. }
  4932. memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
  4933. ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
  4934. ret->name = name;
  4935. ret->targetNamespace = nsName;
  4936. ret->node = node;
  4937. /* TODO: Remove the flag. */
  4938. ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
  4939. if (pctxt->isRedefine) {
  4940. pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
  4941. ret, name, nsName);
  4942. if (pctxt->redef == NULL) {
  4943. xmlFree(ret);
  4944. return(NULL);
  4945. }
  4946. pctxt->redefCounter = 0;
  4947. }
  4948. WXS_ADD_GLOBAL(pctxt, ret);
  4949. WXS_ADD_PENDING(pctxt, ret);
  4950. return (ret);
  4951. }
  4952. /**
  4953. * xmlSchemaAddElement:
  4954. * @ctxt: a schema parser context
  4955. * @schema: the schema being built
  4956. * @name: the type name
  4957. * @namespace: the type namespace
  4958. *
  4959. * Add an XML schema Element declaration
  4960. * *WARNING* this interface is highly subject to change
  4961. *
  4962. * Returns the new structure or NULL in case of error
  4963. */
  4964. static xmlSchemaElementPtr
  4965. xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
  4966. const xmlChar * name, const xmlChar * nsName,
  4967. xmlNodePtr node, int topLevel)
  4968. {
  4969. xmlSchemaElementPtr ret = NULL;
  4970. if ((ctxt == NULL) || (name == NULL))
  4971. return (NULL);
  4972. ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
  4973. if (ret == NULL) {
  4974. xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
  4975. return (NULL);
  4976. }
  4977. memset(ret, 0, sizeof(xmlSchemaElement));
  4978. ret->type = XML_SCHEMA_TYPE_ELEMENT;
  4979. ret->name = name;
  4980. ret->targetNamespace = nsName;
  4981. ret->node = node;
  4982. if (topLevel)
  4983. WXS_ADD_GLOBAL(ctxt, ret);
  4984. else
  4985. WXS_ADD_LOCAL(ctxt, ret);
  4986. WXS_ADD_PENDING(ctxt, ret);
  4987. return (ret);
  4988. }
  4989. /**
  4990. * xmlSchemaAddType:
  4991. * @ctxt: a schema parser context
  4992. * @schema: the schema being built
  4993. * @name: the item name
  4994. * @namespace: the namespace
  4995. *
  4996. * Add an XML schema item
  4997. * *WARNING* this interface is highly subject to change
  4998. *
  4999. * Returns the new structure or NULL in case of error
  5000. */
  5001. static xmlSchemaTypePtr
  5002. xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5003. xmlSchemaTypeType type,
  5004. const xmlChar * name, const xmlChar * nsName,
  5005. xmlNodePtr node, int topLevel)
  5006. {
  5007. xmlSchemaTypePtr ret = NULL;
  5008. if ((ctxt == NULL) || (schema == NULL))
  5009. return (NULL);
  5010. ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
  5011. if (ret == NULL) {
  5012. xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
  5013. return (NULL);
  5014. }
  5015. memset(ret, 0, sizeof(xmlSchemaType));
  5016. ret->type = type;
  5017. ret->name = name;
  5018. ret->targetNamespace = nsName;
  5019. ret->node = node;
  5020. if (topLevel) {
  5021. if (ctxt->isRedefine) {
  5022. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  5023. ret, name, nsName);
  5024. if (ctxt->redef == NULL) {
  5025. xmlFree(ret);
  5026. return(NULL);
  5027. }
  5028. ctxt->redefCounter = 0;
  5029. }
  5030. WXS_ADD_GLOBAL(ctxt, ret);
  5031. } else
  5032. WXS_ADD_LOCAL(ctxt, ret);
  5033. WXS_ADD_PENDING(ctxt, ret);
  5034. return (ret);
  5035. }
  5036. static xmlSchemaQNameRefPtr
  5037. xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
  5038. xmlSchemaTypeType refType,
  5039. const xmlChar *refName,
  5040. const xmlChar *refNs)
  5041. {
  5042. xmlSchemaQNameRefPtr ret;
  5043. ret = (xmlSchemaQNameRefPtr)
  5044. xmlMalloc(sizeof(xmlSchemaQNameRef));
  5045. if (ret == NULL) {
  5046. xmlSchemaPErrMemory(pctxt,
  5047. "allocating QName reference item", NULL);
  5048. return (NULL);
  5049. }
  5050. ret->node = NULL;
  5051. ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
  5052. ret->name = refName;
  5053. ret->targetNamespace = refNs;
  5054. ret->item = NULL;
  5055. ret->itemType = refType;
  5056. /*
  5057. * Store the reference item in the schema.
  5058. */
  5059. WXS_ADD_LOCAL(pctxt, ret);
  5060. return (ret);
  5061. }
  5062. static xmlSchemaAttributeUseProhibPtr
  5063. xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
  5064. {
  5065. xmlSchemaAttributeUseProhibPtr ret;
  5066. ret = (xmlSchemaAttributeUseProhibPtr)
  5067. xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
  5068. if (ret == NULL) {
  5069. xmlSchemaPErrMemory(pctxt,
  5070. "allocating attribute use prohibition", NULL);
  5071. return (NULL);
  5072. }
  5073. memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
  5074. ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
  5075. WXS_ADD_LOCAL(pctxt, ret);
  5076. return (ret);
  5077. }
  5078. /**
  5079. * xmlSchemaAddModelGroup:
  5080. * @ctxt: a schema parser context
  5081. * @schema: the schema being built
  5082. * @type: the "compositor" type of the model group
  5083. * @node: the node in the schema doc
  5084. *
  5085. * Adds a schema model group
  5086. * *WARNING* this interface is highly subject to change
  5087. *
  5088. * Returns the new structure or NULL in case of error
  5089. */
  5090. static xmlSchemaModelGroupPtr
  5091. xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
  5092. xmlSchemaPtr schema,
  5093. xmlSchemaTypeType type,
  5094. xmlNodePtr node)
  5095. {
  5096. xmlSchemaModelGroupPtr ret = NULL;
  5097. if ((ctxt == NULL) || (schema == NULL))
  5098. return (NULL);
  5099. ret = (xmlSchemaModelGroupPtr)
  5100. xmlMalloc(sizeof(xmlSchemaModelGroup));
  5101. if (ret == NULL) {
  5102. xmlSchemaPErrMemory(ctxt, "allocating model group component",
  5103. NULL);
  5104. return (NULL);
  5105. }
  5106. memset(ret, 0, sizeof(xmlSchemaModelGroup));
  5107. ret->type = type;
  5108. ret->node = node;
  5109. WXS_ADD_LOCAL(ctxt, ret);
  5110. if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
  5111. (type == XML_SCHEMA_TYPE_CHOICE))
  5112. WXS_ADD_PENDING(ctxt, ret);
  5113. return (ret);
  5114. }
  5115. /**
  5116. * xmlSchemaAddParticle:
  5117. * @ctxt: a schema parser context
  5118. * @schema: the schema being built
  5119. * @node: the corresponding node in the schema doc
  5120. * @min: the minOccurs
  5121. * @max: the maxOccurs
  5122. *
  5123. * Adds an XML schema particle component.
  5124. * *WARNING* this interface is highly subject to change
  5125. *
  5126. * Returns the new structure or NULL in case of error
  5127. */
  5128. static xmlSchemaParticlePtr
  5129. xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
  5130. xmlNodePtr node, int min, int max)
  5131. {
  5132. xmlSchemaParticlePtr ret = NULL;
  5133. if (ctxt == NULL)
  5134. return (NULL);
  5135. #ifdef DEBUG
  5136. fprintf(stderr, "Adding particle component\n");
  5137. #endif
  5138. ret = (xmlSchemaParticlePtr)
  5139. xmlMalloc(sizeof(xmlSchemaParticle));
  5140. if (ret == NULL) {
  5141. xmlSchemaPErrMemory(ctxt, "allocating particle component",
  5142. NULL);
  5143. return (NULL);
  5144. }
  5145. ret->type = XML_SCHEMA_TYPE_PARTICLE;
  5146. ret->annot = NULL;
  5147. ret->node = node;
  5148. ret->minOccurs = min;
  5149. ret->maxOccurs = max;
  5150. ret->next = NULL;
  5151. ret->children = NULL;
  5152. WXS_ADD_LOCAL(ctxt, ret);
  5153. /*
  5154. * Note that addition to pending components will be done locally
  5155. * to the specific parsing function, since the most particles
  5156. * need not to be fixed up (i.e. the reference to be resolved).
  5157. * REMOVED: WXS_ADD_PENDING(ctxt, ret);
  5158. */
  5159. return (ret);
  5160. }
  5161. /**
  5162. * xmlSchemaAddModelGroupDefinition:
  5163. * @ctxt: a schema validation context
  5164. * @schema: the schema being built
  5165. * @name: the group name
  5166. *
  5167. * Add an XML schema Group definition
  5168. *
  5169. * Returns the new structure or NULL in case of error
  5170. */
  5171. static xmlSchemaModelGroupDefPtr
  5172. xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  5173. xmlSchemaPtr schema,
  5174. const xmlChar *name,
  5175. const xmlChar *nsName,
  5176. xmlNodePtr node)
  5177. {
  5178. xmlSchemaModelGroupDefPtr ret = NULL;
  5179. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5180. return (NULL);
  5181. ret = (xmlSchemaModelGroupDefPtr)
  5182. xmlMalloc(sizeof(xmlSchemaModelGroupDef));
  5183. if (ret == NULL) {
  5184. xmlSchemaPErrMemory(ctxt, "adding group", NULL);
  5185. return (NULL);
  5186. }
  5187. memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
  5188. ret->name = name;
  5189. ret->type = XML_SCHEMA_TYPE_GROUP;
  5190. ret->node = node;
  5191. ret->targetNamespace = nsName;
  5192. if (ctxt->isRedefine) {
  5193. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  5194. ret, name, nsName);
  5195. if (ctxt->redef == NULL) {
  5196. xmlFree(ret);
  5197. return(NULL);
  5198. }
  5199. ctxt->redefCounter = 0;
  5200. }
  5201. WXS_ADD_GLOBAL(ctxt, ret);
  5202. WXS_ADD_PENDING(ctxt, ret);
  5203. return (ret);
  5204. }
  5205. /**
  5206. * xmlSchemaNewWildcardNs:
  5207. * @ctxt: a schema validation context
  5208. *
  5209. * Creates a new wildcard namespace constraint.
  5210. *
  5211. * Returns the new structure or NULL in case of error
  5212. */
  5213. static xmlSchemaWildcardNsPtr
  5214. xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
  5215. {
  5216. xmlSchemaWildcardNsPtr ret;
  5217. ret = (xmlSchemaWildcardNsPtr)
  5218. xmlMalloc(sizeof(xmlSchemaWildcardNs));
  5219. if (ret == NULL) {
  5220. xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
  5221. return (NULL);
  5222. }
  5223. ret->value = NULL;
  5224. ret->next = NULL;
  5225. return (ret);
  5226. }
  5227. static xmlSchemaIDCPtr
  5228. xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5229. const xmlChar *name, const xmlChar *nsName,
  5230. int category, xmlNodePtr node)
  5231. {
  5232. xmlSchemaIDCPtr ret = NULL;
  5233. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5234. return (NULL);
  5235. ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
  5236. if (ret == NULL) {
  5237. xmlSchemaPErrMemory(ctxt,
  5238. "allocating an identity-constraint definition", NULL);
  5239. return (NULL);
  5240. }
  5241. memset(ret, 0, sizeof(xmlSchemaIDC));
  5242. /* The target namespace of the parent element declaration. */
  5243. ret->targetNamespace = nsName;
  5244. ret->name = name;
  5245. ret->type = category;
  5246. ret->node = node;
  5247. WXS_ADD_GLOBAL(ctxt, ret);
  5248. /*
  5249. * Only keyrefs need to be fixup up.
  5250. */
  5251. if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
  5252. WXS_ADD_PENDING(ctxt, ret);
  5253. return (ret);
  5254. }
  5255. /**
  5256. * xmlSchemaAddWildcard:
  5257. * @ctxt: a schema validation context
  5258. * @schema: a schema
  5259. *
  5260. * Adds a wildcard.
  5261. * It corresponds to a xsd:anyAttribute and xsd:any.
  5262. *
  5263. * Returns the new structure or NULL in case of error
  5264. */
  5265. static xmlSchemaWildcardPtr
  5266. xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5267. xmlSchemaTypeType type, xmlNodePtr node)
  5268. {
  5269. xmlSchemaWildcardPtr ret = NULL;
  5270. if ((ctxt == NULL) || (schema == NULL))
  5271. return (NULL);
  5272. ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
  5273. if (ret == NULL) {
  5274. xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
  5275. return (NULL);
  5276. }
  5277. memset(ret, 0, sizeof(xmlSchemaWildcard));
  5278. ret->type = type;
  5279. ret->node = node;
  5280. WXS_ADD_LOCAL(ctxt, ret);
  5281. return (ret);
  5282. }
  5283. static void
  5284. xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
  5285. {
  5286. if (group == NULL)
  5287. return;
  5288. if (group->members != NULL)
  5289. xmlSchemaItemListFree(group->members);
  5290. xmlFree(group);
  5291. }
  5292. static void
  5293. xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
  5294. {
  5295. xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
  5296. }
  5297. static xmlSchemaSubstGroupPtr
  5298. xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
  5299. xmlSchemaElementPtr head)
  5300. {
  5301. xmlSchemaSubstGroupPtr ret;
  5302. /* Init subst group hash. */
  5303. if (WXS_SUBST_GROUPS(pctxt) == NULL) {
  5304. WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
  5305. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5306. return(NULL);
  5307. }
  5308. /* Create a new substitution group. */
  5309. ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
  5310. if (ret == NULL) {
  5311. xmlSchemaPErrMemory(NULL,
  5312. "allocating a substitution group container", NULL);
  5313. return(NULL);
  5314. }
  5315. memset(ret, 0, sizeof(xmlSchemaSubstGroup));
  5316. ret->head = head;
  5317. /* Create list of members. */
  5318. ret->members = xmlSchemaItemListCreate();
  5319. if (ret->members == NULL) {
  5320. xmlSchemaSubstGroupFree(ret);
  5321. return(NULL);
  5322. }
  5323. /* Add subst group to hash. */
  5324. if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
  5325. head->name, head->targetNamespace, ret) != 0) {
  5326. PERROR_INT("xmlSchemaSubstGroupAdd",
  5327. "failed to add a new substitution container");
  5328. xmlSchemaSubstGroupFree(ret);
  5329. return(NULL);
  5330. }
  5331. return(ret);
  5332. }
  5333. static xmlSchemaSubstGroupPtr
  5334. xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
  5335. xmlSchemaElementPtr head)
  5336. {
  5337. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5338. return(NULL);
  5339. return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
  5340. head->name, head->targetNamespace));
  5341. }
  5342. /**
  5343. * xmlSchemaAddElementSubstitutionMember:
  5344. * @pctxt: a schema parser context
  5345. * @head: the head of the substitution group
  5346. * @member: the new member of the substitution group
  5347. *
  5348. * Allocate a new annotation structure.
  5349. *
  5350. * Returns the newly allocated structure or NULL in case or error
  5351. */
  5352. static int
  5353. xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
  5354. xmlSchemaElementPtr head,
  5355. xmlSchemaElementPtr member)
  5356. {
  5357. xmlSchemaSubstGroupPtr substGroup = NULL;
  5358. if ((pctxt == NULL) || (head == NULL) || (member == NULL))
  5359. return (-1);
  5360. substGroup = xmlSchemaSubstGroupGet(pctxt, head);
  5361. if (substGroup == NULL)
  5362. substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
  5363. if (substGroup == NULL)
  5364. return(-1);
  5365. if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
  5366. return(-1);
  5367. return(0);
  5368. }
  5369. /************************************************************************
  5370. * *
  5371. * Utilities for parsing *
  5372. * *
  5373. ************************************************************************/
  5374. /**
  5375. * xmlSchemaPValAttrNodeQNameValue:
  5376. * @ctxt: a schema parser context
  5377. * @schema: the schema context
  5378. * @ownerItem: the parent as a schema object
  5379. * @value: the QName value
  5380. * @uri: the resulting namespace URI if found
  5381. * @local: the resulting local part if found, the attribute value otherwise
  5382. *
  5383. * Extracts the local name and the URI of a QName value and validates it.
  5384. * This one is intended to be used on attribute values that
  5385. * should resolve to schema components.
  5386. *
  5387. * Returns 0, in case the QName is valid, a positive error code
  5388. * if not valid and -1 if an internal error occurs.
  5389. */
  5390. static int
  5391. xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
  5392. xmlSchemaPtr schema,
  5393. xmlSchemaBasicItemPtr ownerItem,
  5394. xmlAttrPtr attr,
  5395. const xmlChar *value,
  5396. const xmlChar **uri,
  5397. const xmlChar **local)
  5398. {
  5399. const xmlChar *pref;
  5400. xmlNsPtr ns;
  5401. int len, ret;
  5402. *uri = NULL;
  5403. *local = NULL;
  5404. ret = xmlValidateQName(value, 1);
  5405. if (ret > 0) {
  5406. xmlSchemaPSimpleTypeErr(ctxt,
  5407. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5408. ownerItem, (xmlNodePtr) attr,
  5409. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  5410. NULL, value, NULL, NULL, NULL);
  5411. *local = value;
  5412. return (ctxt->err);
  5413. } else if (ret < 0)
  5414. return (-1);
  5415. if (!strchr((char *) value, ':')) {
  5416. ns = xmlSearchNs(attr->doc, attr->parent, NULL);
  5417. if (ns)
  5418. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5419. else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
  5420. /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
  5421. * parser context. */
  5422. /*
  5423. * This one takes care of included schemas with no
  5424. * target namespace.
  5425. */
  5426. *uri = ctxt->targetNamespace;
  5427. }
  5428. *local = xmlDictLookup(ctxt->dict, value, -1);
  5429. return (0);
  5430. }
  5431. /*
  5432. * At this point xmlSplitQName3 has to return a local name.
  5433. */
  5434. *local = xmlSplitQName3(value, &len);
  5435. *local = xmlDictLookup(ctxt->dict, *local, -1);
  5436. pref = xmlDictLookup(ctxt->dict, value, len);
  5437. ns = xmlSearchNs(attr->doc, attr->parent, pref);
  5438. if (ns == NULL) {
  5439. xmlSchemaPSimpleTypeErr(ctxt,
  5440. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5441. ownerItem, (xmlNodePtr) attr,
  5442. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
  5443. "The value '%s' of simple type 'xs:QName' has no "
  5444. "corresponding namespace declaration in scope", value, NULL);
  5445. return (ctxt->err);
  5446. } else {
  5447. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5448. }
  5449. return (0);
  5450. }
  5451. /**
  5452. * xmlSchemaPValAttrNodeQName:
  5453. * @ctxt: a schema parser context
  5454. * @schema: the schema context
  5455. * @ownerItem: the owner as a schema object
  5456. * @attr: the attribute node
  5457. * @uri: the resulting namespace URI if found
  5458. * @local: the resulting local part if found, the attribute value otherwise
  5459. *
  5460. * Extracts and validates the QName of an attribute value.
  5461. * This one is intended to be used on attribute values that
  5462. * should resolve to schema components.
  5463. *
  5464. * Returns 0, in case the QName is valid, a positive error code
  5465. * if not valid and -1 if an internal error occurs.
  5466. */
  5467. static int
  5468. xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
  5469. xmlSchemaPtr schema,
  5470. xmlSchemaBasicItemPtr ownerItem,
  5471. xmlAttrPtr attr,
  5472. const xmlChar **uri,
  5473. const xmlChar **local)
  5474. {
  5475. const xmlChar *value;
  5476. value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5477. return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  5478. ownerItem, attr, value, uri, local));
  5479. }
  5480. /**
  5481. * xmlSchemaPValAttrQName:
  5482. * @ctxt: a schema parser context
  5483. * @schema: the schema context
  5484. * @ownerItem: the owner as a schema object
  5485. * @ownerElem: the parent node of the attribute
  5486. * @name: the name of the attribute
  5487. * @uri: the resulting namespace URI if found
  5488. * @local: the resulting local part if found, the attribute value otherwise
  5489. *
  5490. * Extracts and validates the QName of an attribute value.
  5491. *
  5492. * Returns 0, in case the QName is valid, a positive error code
  5493. * if not valid and -1 if an internal error occurs.
  5494. */
  5495. static int
  5496. xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
  5497. xmlSchemaPtr schema,
  5498. xmlSchemaBasicItemPtr ownerItem,
  5499. xmlNodePtr ownerElem,
  5500. const char *name,
  5501. const xmlChar **uri,
  5502. const xmlChar **local)
  5503. {
  5504. xmlAttrPtr attr;
  5505. attr = xmlSchemaGetPropNode(ownerElem, name);
  5506. if (attr == NULL) {
  5507. *local = NULL;
  5508. *uri = NULL;
  5509. return (0);
  5510. }
  5511. return (xmlSchemaPValAttrNodeQName(ctxt, schema,
  5512. ownerItem, attr, uri, local));
  5513. }
  5514. /**
  5515. * xmlSchemaPValAttrID:
  5516. * @ctxt: a schema parser context
  5517. *
  5518. * Extracts and validates the ID of an attribute value.
  5519. *
  5520. * Returns 0, in case the ID is valid, a positive error code
  5521. * if not valid and -1 if an internal error occurs.
  5522. */
  5523. static int
  5524. xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
  5525. {
  5526. int ret;
  5527. const xmlChar *value;
  5528. if (attr == NULL)
  5529. return(0);
  5530. value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
  5531. ret = xmlValidateNCName(value, 1);
  5532. if (ret == 0) {
  5533. /*
  5534. * NOTE: the IDness might have already be declared in the DTD
  5535. */
  5536. if (attr->atype != XML_ATTRIBUTE_ID) {
  5537. xmlIDPtr res;
  5538. xmlChar *strip;
  5539. /*
  5540. * TODO: Use xmlSchemaStrip here; it's not exported at this
  5541. * moment.
  5542. */
  5543. strip = xmlSchemaCollapseString(value);
  5544. if (strip != NULL) {
  5545. xmlFree((xmlChar *) value);
  5546. value = strip;
  5547. }
  5548. res = xmlAddID(NULL, attr->doc, value, attr);
  5549. if (res == NULL) {
  5550. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5551. xmlSchemaPSimpleTypeErr(ctxt,
  5552. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5553. NULL, (xmlNodePtr) attr,
  5554. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5555. NULL, NULL, "Duplicate value '%s' of simple "
  5556. "type 'xs:ID'", value, NULL);
  5557. } else
  5558. attr->atype = XML_ATTRIBUTE_ID;
  5559. }
  5560. } else if (ret > 0) {
  5561. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5562. xmlSchemaPSimpleTypeErr(ctxt,
  5563. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5564. NULL, (xmlNodePtr) attr,
  5565. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5566. NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
  5567. "not a valid 'xs:NCName'",
  5568. value, NULL);
  5569. }
  5570. if (value != NULL)
  5571. xmlFree((xmlChar *)value);
  5572. return (ret);
  5573. }
  5574. static int
  5575. xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
  5576. xmlNodePtr ownerElem,
  5577. const xmlChar *name)
  5578. {
  5579. xmlAttrPtr attr;
  5580. attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
  5581. if (attr == NULL)
  5582. return(0);
  5583. return(xmlSchemaPValAttrNodeID(ctxt, attr));
  5584. }
  5585. /**
  5586. * xmlGetMaxOccurs:
  5587. * @ctxt: a schema validation context
  5588. * @node: a subtree containing XML Schema information
  5589. *
  5590. * Get the maxOccurs property
  5591. *
  5592. * Returns the default if not found, or the value
  5593. */
  5594. static int
  5595. xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5596. int min, int max, int def, const char *expected)
  5597. {
  5598. const xmlChar *val, *cur;
  5599. int ret = 0;
  5600. xmlAttrPtr attr;
  5601. attr = xmlSchemaGetPropNode(node, "maxOccurs");
  5602. if (attr == NULL)
  5603. return (def);
  5604. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5605. if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
  5606. if (max != UNBOUNDED) {
  5607. xmlSchemaPSimpleTypeErr(ctxt,
  5608. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5609. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5610. NULL, (xmlNodePtr) attr, NULL, expected,
  5611. val, NULL, NULL, NULL);
  5612. return (def);
  5613. } else
  5614. return (UNBOUNDED); /* encoding it with -1 might be another option */
  5615. }
  5616. cur = val;
  5617. while (IS_BLANK_CH(*cur))
  5618. cur++;
  5619. if (*cur == 0) {
  5620. xmlSchemaPSimpleTypeErr(ctxt,
  5621. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5622. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5623. NULL, (xmlNodePtr) attr, NULL, expected,
  5624. val, NULL, NULL, NULL);
  5625. return (def);
  5626. }
  5627. while ((*cur >= '0') && (*cur <= '9')) {
  5628. if (ret > INT_MAX / 10) {
  5629. ret = INT_MAX;
  5630. } else {
  5631. int digit = *cur - '0';
  5632. ret *= 10;
  5633. if (ret > INT_MAX - digit)
  5634. ret = INT_MAX;
  5635. else
  5636. ret += digit;
  5637. }
  5638. cur++;
  5639. }
  5640. while (IS_BLANK_CH(*cur))
  5641. cur++;
  5642. /*
  5643. * TODO: Restrict the maximal value to Integer.
  5644. */
  5645. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5646. xmlSchemaPSimpleTypeErr(ctxt,
  5647. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5648. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5649. NULL, (xmlNodePtr) attr, NULL, expected,
  5650. val, NULL, NULL, NULL);
  5651. return (def);
  5652. }
  5653. return (ret);
  5654. }
  5655. /**
  5656. * xmlGetMinOccurs:
  5657. * @ctxt: a schema validation context
  5658. * @node: a subtree containing XML Schema information
  5659. *
  5660. * Get the minOccurs property
  5661. *
  5662. * Returns the default if not found, or the value
  5663. */
  5664. static int
  5665. xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5666. int min, int max, int def, const char *expected)
  5667. {
  5668. const xmlChar *val, *cur;
  5669. int ret = 0;
  5670. xmlAttrPtr attr;
  5671. attr = xmlSchemaGetPropNode(node, "minOccurs");
  5672. if (attr == NULL)
  5673. return (def);
  5674. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5675. cur = val;
  5676. while (IS_BLANK_CH(*cur))
  5677. cur++;
  5678. if (*cur == 0) {
  5679. xmlSchemaPSimpleTypeErr(ctxt,
  5680. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5681. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5682. NULL, (xmlNodePtr) attr, NULL, expected,
  5683. val, NULL, NULL, NULL);
  5684. return (def);
  5685. }
  5686. while ((*cur >= '0') && (*cur <= '9')) {
  5687. if (ret > INT_MAX / 10) {
  5688. ret = INT_MAX;
  5689. } else {
  5690. int digit = *cur - '0';
  5691. ret *= 10;
  5692. if (ret > INT_MAX - digit)
  5693. ret = INT_MAX;
  5694. else
  5695. ret += digit;
  5696. }
  5697. cur++;
  5698. }
  5699. while (IS_BLANK_CH(*cur))
  5700. cur++;
  5701. /*
  5702. * TODO: Restrict the maximal value to Integer.
  5703. */
  5704. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5705. xmlSchemaPSimpleTypeErr(ctxt,
  5706. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5707. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5708. NULL, (xmlNodePtr) attr, NULL, expected,
  5709. val, NULL, NULL, NULL);
  5710. return (def);
  5711. }
  5712. return (ret);
  5713. }
  5714. /**
  5715. * xmlSchemaPGetBoolNodeValue:
  5716. * @ctxt: a schema validation context
  5717. * @ownerItem: the owner as a schema item
  5718. * @node: the node holding the value
  5719. *
  5720. * Converts a boolean string value into 1 or 0.
  5721. *
  5722. * Returns 0 or 1.
  5723. */
  5724. static int
  5725. xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
  5726. xmlSchemaBasicItemPtr ownerItem,
  5727. xmlNodePtr node)
  5728. {
  5729. xmlChar *value = NULL;
  5730. int res = 0;
  5731. value = xmlNodeGetContent(node);
  5732. /*
  5733. * 3.2.2.1 Lexical representation
  5734. * An instance of a datatype that is defined as `boolean`
  5735. * can have the following legal literals {true, false, 1, 0}.
  5736. */
  5737. if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
  5738. res = 1;
  5739. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
  5740. res = 0;
  5741. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
  5742. res = 1;
  5743. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
  5744. res = 0;
  5745. else {
  5746. xmlSchemaPSimpleTypeErr(ctxt,
  5747. XML_SCHEMAP_INVALID_BOOLEAN,
  5748. ownerItem, node,
  5749. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5750. NULL, BAD_CAST value,
  5751. NULL, NULL, NULL);
  5752. }
  5753. if (value != NULL)
  5754. xmlFree(value);
  5755. return (res);
  5756. }
  5757. /**
  5758. * xmlGetBooleanProp:
  5759. * @ctxt: a schema validation context
  5760. * @node: a subtree containing XML Schema information
  5761. * @name: the attribute name
  5762. * @def: the default value
  5763. *
  5764. * Evaluate if a boolean property is set
  5765. *
  5766. * Returns the default if not found, 0 if found to be false,
  5767. * 1 if found to be true
  5768. */
  5769. static int
  5770. xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
  5771. xmlNodePtr node,
  5772. const char *name, int def)
  5773. {
  5774. const xmlChar *val;
  5775. val = xmlSchemaGetProp(ctxt, node, name);
  5776. if (val == NULL)
  5777. return (def);
  5778. /*
  5779. * 3.2.2.1 Lexical representation
  5780. * An instance of a datatype that is defined as `boolean`
  5781. * can have the following legal literals {true, false, 1, 0}.
  5782. */
  5783. if (xmlStrEqual(val, BAD_CAST "true"))
  5784. def = 1;
  5785. else if (xmlStrEqual(val, BAD_CAST "false"))
  5786. def = 0;
  5787. else if (xmlStrEqual(val, BAD_CAST "1"))
  5788. def = 1;
  5789. else if (xmlStrEqual(val, BAD_CAST "0"))
  5790. def = 0;
  5791. else {
  5792. xmlSchemaPSimpleTypeErr(ctxt,
  5793. XML_SCHEMAP_INVALID_BOOLEAN,
  5794. NULL,
  5795. (xmlNodePtr) xmlSchemaGetPropNode(node, name),
  5796. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5797. NULL, val, NULL, NULL, NULL);
  5798. }
  5799. return (def);
  5800. }
  5801. /************************************************************************
  5802. * *
  5803. * Schema extraction from an Infoset *
  5804. * *
  5805. ************************************************************************/
  5806. static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
  5807. ctxt, xmlSchemaPtr schema,
  5808. xmlNodePtr node,
  5809. int topLevel);
  5810. static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
  5811. ctxt,
  5812. xmlSchemaPtr schema,
  5813. xmlNodePtr node,
  5814. int topLevel);
  5815. static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
  5816. ctxt,
  5817. xmlSchemaPtr schema,
  5818. xmlNodePtr node,
  5819. xmlSchemaTypeType parentType);
  5820. static xmlSchemaBasicItemPtr
  5821. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  5822. xmlSchemaPtr schema,
  5823. xmlNodePtr node,
  5824. xmlSchemaItemListPtr uses,
  5825. int parentType);
  5826. static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
  5827. xmlSchemaPtr schema,
  5828. xmlNodePtr node);
  5829. static xmlSchemaWildcardPtr
  5830. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  5831. xmlSchemaPtr schema, xmlNodePtr node);
  5832. /**
  5833. * xmlSchemaPValAttrNodeValue:
  5834. *
  5835. * @pctxt: a schema parser context
  5836. * @ownerItem: the schema object owner if existent
  5837. * @attr: the schema attribute node being validated
  5838. * @value: the value
  5839. * @type: the built-in type to be validated against
  5840. *
  5841. * Validates a value against the given built-in type.
  5842. * This one is intended to be used internally for validation
  5843. * of schema attribute values during parsing of the schema.
  5844. *
  5845. * Returns 0 if the value is valid, a positive error code
  5846. * number otherwise and -1 in case of an internal or API error.
  5847. */
  5848. static int
  5849. xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
  5850. xmlSchemaBasicItemPtr ownerItem,
  5851. xmlAttrPtr attr,
  5852. const xmlChar *value,
  5853. xmlSchemaTypePtr type)
  5854. {
  5855. int ret = 0;
  5856. /*
  5857. * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
  5858. * one is really meant to be used internally, so better not.
  5859. */
  5860. if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
  5861. return (-1);
  5862. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5863. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5864. "the given type is not a built-in type");
  5865. return (-1);
  5866. }
  5867. switch (type->builtInType) {
  5868. case XML_SCHEMAS_NCNAME:
  5869. case XML_SCHEMAS_QNAME:
  5870. case XML_SCHEMAS_ANYURI:
  5871. case XML_SCHEMAS_TOKEN:
  5872. case XML_SCHEMAS_LANGUAGE:
  5873. ret = xmlSchemaValPredefTypeNode(type, value, NULL,
  5874. (xmlNodePtr) attr);
  5875. break;
  5876. default: {
  5877. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5878. "validation using the given type is not supported while "
  5879. "parsing a schema");
  5880. return (-1);
  5881. }
  5882. }
  5883. /*
  5884. * TODO: Should we use the S4S error codes instead?
  5885. */
  5886. if (ret < 0) {
  5887. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5888. "failed to validate a schema attribute value");
  5889. return (-1);
  5890. } else if (ret > 0) {
  5891. if (WXS_IS_LIST(type))
  5892. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  5893. else
  5894. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  5895. xmlSchemaPSimpleTypeErr(pctxt,
  5896. ret, ownerItem, (xmlNodePtr) attr,
  5897. type, NULL, value, NULL, NULL, NULL);
  5898. }
  5899. return (ret);
  5900. }
  5901. /**
  5902. * xmlSchemaPValAttrNode:
  5903. *
  5904. * @ctxt: a schema parser context
  5905. * @ownerItem: the schema object owner if existent
  5906. * @attr: the schema attribute node being validated
  5907. * @type: the built-in type to be validated against
  5908. * @value: the resulting value if any
  5909. *
  5910. * Extracts and validates a value against the given built-in type.
  5911. * This one is intended to be used internally for validation
  5912. * of schema attribute values during parsing of the schema.
  5913. *
  5914. * Returns 0 if the value is valid, a positive error code
  5915. * number otherwise and -1 in case of an internal or API error.
  5916. */
  5917. static int
  5918. xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
  5919. xmlSchemaBasicItemPtr ownerItem,
  5920. xmlAttrPtr attr,
  5921. xmlSchemaTypePtr type,
  5922. const xmlChar **value)
  5923. {
  5924. const xmlChar *val;
  5925. if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
  5926. return (-1);
  5927. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5928. if (value != NULL)
  5929. *value = val;
  5930. return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
  5931. val, type));
  5932. }
  5933. /**
  5934. * xmlSchemaPValAttr:
  5935. *
  5936. * @ctxt: a schema parser context
  5937. * @node: the element node of the attribute
  5938. * @ownerItem: the schema object owner if existent
  5939. * @ownerElem: the owner element node
  5940. * @name: the name of the schema attribute node
  5941. * @type: the built-in type to be validated against
  5942. * @value: the resulting value if any
  5943. *
  5944. * Extracts and validates a value against the given built-in type.
  5945. * This one is intended to be used internally for validation
  5946. * of schema attribute values during parsing of the schema.
  5947. *
  5948. * Returns 0 if the value is valid, a positive error code
  5949. * number otherwise and -1 in case of an internal or API error.
  5950. */
  5951. static int
  5952. xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
  5953. xmlSchemaBasicItemPtr ownerItem,
  5954. xmlNodePtr ownerElem,
  5955. const char *name,
  5956. xmlSchemaTypePtr type,
  5957. const xmlChar **value)
  5958. {
  5959. xmlAttrPtr attr;
  5960. if ((ctxt == NULL) || (type == NULL)) {
  5961. if (value != NULL)
  5962. *value = NULL;
  5963. return (-1);
  5964. }
  5965. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5966. if (value != NULL)
  5967. *value = NULL;
  5968. xmlSchemaPErr(ctxt, ownerElem,
  5969. XML_SCHEMAP_INTERNAL,
  5970. "Internal error: xmlSchemaPValAttr, the given "
  5971. "type '%s' is not a built-in type.\n",
  5972. type->name, NULL);
  5973. return (-1);
  5974. }
  5975. attr = xmlSchemaGetPropNode(ownerElem, name);
  5976. if (attr == NULL) {
  5977. if (value != NULL)
  5978. *value = NULL;
  5979. return (0);
  5980. }
  5981. return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
  5982. type, value));
  5983. }
  5984. static int
  5985. xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
  5986. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  5987. xmlNodePtr node,
  5988. xmlAttrPtr attr,
  5989. const xmlChar *namespaceName)
  5990. {
  5991. /* TODO: Pointer comparison instead? */
  5992. if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
  5993. return (0);
  5994. if (xmlStrEqual(xmlSchemaNs, namespaceName))
  5995. return (0);
  5996. /*
  5997. * Check if the referenced namespace was <import>ed.
  5998. */
  5999. if (WXS_BUCKET(pctxt)->relations != NULL) {
  6000. xmlSchemaSchemaRelationPtr rel;
  6001. rel = WXS_BUCKET(pctxt)->relations;
  6002. do {
  6003. if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
  6004. xmlStrEqual(namespaceName, rel->importNamespace))
  6005. return (0);
  6006. rel = rel->next;
  6007. } while (rel != NULL);
  6008. }
  6009. /*
  6010. * No matching <import>ed namespace found.
  6011. */
  6012. {
  6013. xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
  6014. if (namespaceName == NULL)
  6015. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6016. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  6017. "References from this schema to components in no "
  6018. "namespace are not allowed, since not indicated by an "
  6019. "import statement", NULL, NULL);
  6020. else
  6021. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6022. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  6023. "References from this schema to components in the "
  6024. "namespace '%s' are not allowed, since not indicated by an "
  6025. "import statement", namespaceName, NULL);
  6026. }
  6027. return (XML_SCHEMAP_SRC_RESOLVE);
  6028. }
  6029. /**
  6030. * xmlSchemaParseLocalAttributes:
  6031. * @ctxt: a schema validation context
  6032. * @schema: the schema being built
  6033. * @node: a subtree containing XML Schema information
  6034. * @type: the hosting type where the attributes will be anchored
  6035. *
  6036. * Parses attribute uses and attribute declarations and
  6037. * attribute group references.
  6038. */
  6039. static int
  6040. xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6041. xmlNodePtr *child, xmlSchemaItemListPtr *list,
  6042. int parentType, int *hasRefs)
  6043. {
  6044. void *item;
  6045. while ((IS_SCHEMA((*child), "attribute")) ||
  6046. (IS_SCHEMA((*child), "attributeGroup"))) {
  6047. if (IS_SCHEMA((*child), "attribute")) {
  6048. item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
  6049. *list, parentType);
  6050. } else {
  6051. item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
  6052. if ((item != NULL) && (hasRefs != NULL))
  6053. *hasRefs = 1;
  6054. }
  6055. if (item != NULL) {
  6056. if (*list == NULL) {
  6057. /* TODO: Customize grow factor. */
  6058. *list = xmlSchemaItemListCreate();
  6059. if (*list == NULL)
  6060. return(-1);
  6061. }
  6062. if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
  6063. return(-1);
  6064. }
  6065. *child = (*child)->next;
  6066. }
  6067. return (0);
  6068. }
  6069. /**
  6070. * xmlSchemaParseAnnotation:
  6071. * @ctxt: a schema validation context
  6072. * @schema: the schema being built
  6073. * @node: a subtree containing XML Schema information
  6074. *
  6075. * parse a XML schema Attribute declaration
  6076. * *WARNING* this interface is highly subject to change
  6077. *
  6078. * Returns -1 in case of error, 0 if the declaration is improper and
  6079. * 1 in case of success.
  6080. */
  6081. static xmlSchemaAnnotPtr
  6082. xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
  6083. {
  6084. xmlSchemaAnnotPtr ret;
  6085. xmlNodePtr child = NULL;
  6086. xmlAttrPtr attr;
  6087. int barked = 0;
  6088. /*
  6089. * INFO: S4S completed.
  6090. */
  6091. /*
  6092. * id = ID
  6093. * {any attributes with non-schema namespace . . .}>
  6094. * Content: (appinfo | documentation)*
  6095. */
  6096. if ((ctxt == NULL) || (node == NULL))
  6097. return (NULL);
  6098. if (needed)
  6099. ret = xmlSchemaNewAnnot(ctxt, node);
  6100. else
  6101. ret = NULL;
  6102. attr = node->properties;
  6103. while (attr != NULL) {
  6104. if (((attr->ns == NULL) &&
  6105. (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
  6106. ((attr->ns != NULL) &&
  6107. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  6108. xmlSchemaPIllegalAttrErr(ctxt,
  6109. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6110. }
  6111. attr = attr->next;
  6112. }
  6113. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6114. /*
  6115. * And now for the children...
  6116. */
  6117. child = node->children;
  6118. while (child != NULL) {
  6119. if (IS_SCHEMA(child, "appinfo")) {
  6120. /* TODO: make available the content of "appinfo". */
  6121. /*
  6122. * source = anyURI
  6123. * {any attributes with non-schema namespace . . .}>
  6124. * Content: ({any})*
  6125. */
  6126. attr = child->properties;
  6127. while (attr != NULL) {
  6128. if (((attr->ns == NULL) &&
  6129. (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
  6130. ((attr->ns != NULL) &&
  6131. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  6132. xmlSchemaPIllegalAttrErr(ctxt,
  6133. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6134. }
  6135. attr = attr->next;
  6136. }
  6137. xmlSchemaPValAttr(ctxt, NULL, child, "source",
  6138. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  6139. child = child->next;
  6140. } else if (IS_SCHEMA(child, "documentation")) {
  6141. /* TODO: make available the content of "documentation". */
  6142. /*
  6143. * source = anyURI
  6144. * {any attributes with non-schema namespace . . .}>
  6145. * Content: ({any})*
  6146. */
  6147. attr = child->properties;
  6148. while (attr != NULL) {
  6149. if (attr->ns == NULL) {
  6150. if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
  6151. xmlSchemaPIllegalAttrErr(ctxt,
  6152. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6153. }
  6154. } else {
  6155. if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
  6156. (xmlStrEqual(attr->name, BAD_CAST "lang") &&
  6157. (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
  6158. xmlSchemaPIllegalAttrErr(ctxt,
  6159. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6160. }
  6161. }
  6162. attr = attr->next;
  6163. }
  6164. /*
  6165. * Attribute "xml:lang".
  6166. */
  6167. attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
  6168. if (attr != NULL)
  6169. xmlSchemaPValAttrNode(ctxt, NULL, attr,
  6170. xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
  6171. child = child->next;
  6172. } else {
  6173. if (!barked)
  6174. xmlSchemaPContentErr(ctxt,
  6175. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6176. NULL, node, child, NULL, "(appinfo | documentation)*");
  6177. barked = 1;
  6178. child = child->next;
  6179. }
  6180. }
  6181. return (ret);
  6182. }
  6183. /**
  6184. * xmlSchemaParseFacet:
  6185. * @ctxt: a schema validation context
  6186. * @schema: the schema being built
  6187. * @node: a subtree containing XML Schema information
  6188. *
  6189. * parse a XML schema Facet declaration
  6190. * *WARNING* this interface is highly subject to change
  6191. *
  6192. * Returns the new type structure or NULL in case of error
  6193. */
  6194. static xmlSchemaFacetPtr
  6195. xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6196. xmlNodePtr node)
  6197. {
  6198. xmlSchemaFacetPtr facet;
  6199. xmlNodePtr child = NULL;
  6200. const xmlChar *value;
  6201. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6202. return (NULL);
  6203. facet = xmlSchemaNewFacet();
  6204. if (facet == NULL) {
  6205. xmlSchemaPErrMemory(ctxt, "allocating facet", node);
  6206. return (NULL);
  6207. }
  6208. facet->node = node;
  6209. value = xmlSchemaGetProp(ctxt, node, "value");
  6210. if (value == NULL) {
  6211. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
  6212. "Facet %s has no value\n", node->name, NULL);
  6213. xmlSchemaFreeFacet(facet);
  6214. return (NULL);
  6215. }
  6216. if (IS_SCHEMA(node, "minInclusive")) {
  6217. facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
  6218. } else if (IS_SCHEMA(node, "minExclusive")) {
  6219. facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
  6220. } else if (IS_SCHEMA(node, "maxInclusive")) {
  6221. facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
  6222. } else if (IS_SCHEMA(node, "maxExclusive")) {
  6223. facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
  6224. } else if (IS_SCHEMA(node, "totalDigits")) {
  6225. facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
  6226. } else if (IS_SCHEMA(node, "fractionDigits")) {
  6227. facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
  6228. } else if (IS_SCHEMA(node, "pattern")) {
  6229. facet->type = XML_SCHEMA_FACET_PATTERN;
  6230. } else if (IS_SCHEMA(node, "enumeration")) {
  6231. facet->type = XML_SCHEMA_FACET_ENUMERATION;
  6232. } else if (IS_SCHEMA(node, "whiteSpace")) {
  6233. facet->type = XML_SCHEMA_FACET_WHITESPACE;
  6234. } else if (IS_SCHEMA(node, "length")) {
  6235. facet->type = XML_SCHEMA_FACET_LENGTH;
  6236. } else if (IS_SCHEMA(node, "maxLength")) {
  6237. facet->type = XML_SCHEMA_FACET_MAXLENGTH;
  6238. } else if (IS_SCHEMA(node, "minLength")) {
  6239. facet->type = XML_SCHEMA_FACET_MINLENGTH;
  6240. } else {
  6241. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
  6242. "Unknown facet type %s\n", node->name, NULL);
  6243. xmlSchemaFreeFacet(facet);
  6244. return (NULL);
  6245. }
  6246. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6247. facet->value = value;
  6248. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  6249. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  6250. const xmlChar *fixed;
  6251. fixed = xmlSchemaGetProp(ctxt, node, "fixed");
  6252. if (fixed != NULL) {
  6253. if (xmlStrEqual(fixed, BAD_CAST "true"))
  6254. facet->fixed = 1;
  6255. }
  6256. }
  6257. child = node->children;
  6258. if (IS_SCHEMA(child, "annotation")) {
  6259. facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6260. child = child->next;
  6261. }
  6262. if (child != NULL) {
  6263. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
  6264. "Facet %s has unexpected child content\n",
  6265. node->name, NULL);
  6266. }
  6267. return (facet);
  6268. }
  6269. /**
  6270. * xmlSchemaParseWildcardNs:
  6271. * @ctxt: a schema parser context
  6272. * @wildc: the wildcard, already created
  6273. * @node: a subtree containing XML Schema information
  6274. *
  6275. * Parses the attribute "processContents" and "namespace"
  6276. * of a xsd:anyAttribute and xsd:any.
  6277. * *WARNING* this interface is highly subject to change
  6278. *
  6279. * Returns 0 if everything goes fine, a positive error code
  6280. * if something is not valid and -1 if an internal error occurs.
  6281. */
  6282. static int
  6283. xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
  6284. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  6285. xmlSchemaWildcardPtr wildc,
  6286. xmlNodePtr node)
  6287. {
  6288. const xmlChar *pc, *ns, *dictnsItem;
  6289. int ret = 0;
  6290. xmlChar *nsItem;
  6291. xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
  6292. xmlAttrPtr attr;
  6293. pc = xmlSchemaGetProp(ctxt, node, "processContents");
  6294. if ((pc == NULL)
  6295. || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
  6296. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6297. } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
  6298. wildc->processContents = XML_SCHEMAS_ANY_SKIP;
  6299. } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
  6300. wildc->processContents = XML_SCHEMAS_ANY_LAX;
  6301. } else {
  6302. xmlSchemaPSimpleTypeErr(ctxt,
  6303. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6304. NULL, node,
  6305. NULL, "(strict | skip | lax)", pc,
  6306. NULL, NULL, NULL);
  6307. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6308. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  6309. }
  6310. /*
  6311. * Build the namespace constraints.
  6312. */
  6313. attr = xmlSchemaGetPropNode(node, "namespace");
  6314. ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  6315. if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
  6316. wildc->any = 1;
  6317. else if (xmlStrEqual(ns, BAD_CAST "##other")) {
  6318. wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  6319. if (wildc->negNsSet == NULL) {
  6320. return (-1);
  6321. }
  6322. wildc->negNsSet->value = ctxt->targetNamespace;
  6323. } else {
  6324. const xmlChar *end, *cur;
  6325. cur = ns;
  6326. do {
  6327. while (IS_BLANK_CH(*cur))
  6328. cur++;
  6329. end = cur;
  6330. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  6331. end++;
  6332. if (end == cur)
  6333. break;
  6334. nsItem = xmlStrndup(cur, end - cur);
  6335. if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
  6336. (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
  6337. xmlSchemaPSimpleTypeErr(ctxt,
  6338. XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
  6339. NULL, (xmlNodePtr) attr,
  6340. NULL,
  6341. "((##any | ##other) | List of (xs:anyURI | "
  6342. "(##targetNamespace | ##local)))",
  6343. nsItem, NULL, NULL, NULL);
  6344. ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
  6345. } else {
  6346. if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
  6347. dictnsItem = ctxt->targetNamespace;
  6348. } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
  6349. dictnsItem = NULL;
  6350. } else {
  6351. /*
  6352. * Validate the item (anyURI).
  6353. */
  6354. xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
  6355. nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
  6356. dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
  6357. }
  6358. /*
  6359. * Avoid duplicate namespaces.
  6360. */
  6361. tmp = wildc->nsSet;
  6362. while (tmp != NULL) {
  6363. if (dictnsItem == tmp->value)
  6364. break;
  6365. tmp = tmp->next;
  6366. }
  6367. if (tmp == NULL) {
  6368. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  6369. if (tmp == NULL) {
  6370. xmlFree(nsItem);
  6371. return (-1);
  6372. }
  6373. tmp->value = dictnsItem;
  6374. tmp->next = NULL;
  6375. if (wildc->nsSet == NULL)
  6376. wildc->nsSet = tmp;
  6377. else if (lastNs != NULL)
  6378. lastNs->next = tmp;
  6379. lastNs = tmp;
  6380. }
  6381. }
  6382. xmlFree(nsItem);
  6383. cur = end;
  6384. } while (*cur != 0);
  6385. }
  6386. return (ret);
  6387. }
  6388. static int
  6389. xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
  6390. xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
  6391. xmlNodePtr node,
  6392. int minOccurs,
  6393. int maxOccurs) {
  6394. if ((maxOccurs == 0) && ( minOccurs == 0))
  6395. return (0);
  6396. if (maxOccurs != UNBOUNDED) {
  6397. /*
  6398. * TODO: Maybe we should better not create the particle,
  6399. * if min/max is invalid, since it could confuse the build of the
  6400. * content model.
  6401. */
  6402. /*
  6403. * 3.9.6 Schema Component Constraint: Particle Correct
  6404. *
  6405. */
  6406. if (maxOccurs < 1) {
  6407. /*
  6408. * 2.2 {max occurs} must be greater than or equal to 1.
  6409. */
  6410. xmlSchemaPCustomAttrErr(ctxt,
  6411. XML_SCHEMAP_P_PROPS_CORRECT_2_2,
  6412. NULL, NULL,
  6413. xmlSchemaGetPropNode(node, "maxOccurs"),
  6414. "The value must be greater than or equal to 1");
  6415. return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
  6416. } else if (minOccurs > maxOccurs) {
  6417. /*
  6418. * 2.1 {min occurs} must not be greater than {max occurs}.
  6419. */
  6420. xmlSchemaPCustomAttrErr(ctxt,
  6421. XML_SCHEMAP_P_PROPS_CORRECT_2_1,
  6422. NULL, NULL,
  6423. xmlSchemaGetPropNode(node, "minOccurs"),
  6424. "The value must not be greater than the value of 'maxOccurs'");
  6425. return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
  6426. }
  6427. }
  6428. return (0);
  6429. }
  6430. /**
  6431. * xmlSchemaParseAny:
  6432. * @ctxt: a schema validation context
  6433. * @schema: the schema being built
  6434. * @node: a subtree containing XML Schema information
  6435. *
  6436. * Parsea a XML schema <any> element. A particle and wildcard
  6437. * will be created (except if minOccurs==maxOccurs==0, in this case
  6438. * nothing will be created).
  6439. * *WARNING* this interface is highly subject to change
  6440. *
  6441. * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
  6442. */
  6443. static xmlSchemaParticlePtr
  6444. xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6445. xmlNodePtr node)
  6446. {
  6447. xmlSchemaParticlePtr particle;
  6448. xmlNodePtr child = NULL;
  6449. xmlSchemaWildcardPtr wild;
  6450. int min, max;
  6451. xmlAttrPtr attr;
  6452. xmlSchemaAnnotPtr annot = NULL;
  6453. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6454. return (NULL);
  6455. /*
  6456. * Check for illegal attributes.
  6457. */
  6458. attr = node->properties;
  6459. while (attr != NULL) {
  6460. if (attr->ns == NULL) {
  6461. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6462. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  6463. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  6464. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6465. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6466. xmlSchemaPIllegalAttrErr(ctxt,
  6467. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6468. }
  6469. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6470. xmlSchemaPIllegalAttrErr(ctxt,
  6471. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6472. }
  6473. attr = attr->next;
  6474. }
  6475. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6476. /*
  6477. * minOccurs/maxOccurs.
  6478. */
  6479. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  6480. "(xs:nonNegativeInteger | unbounded)");
  6481. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
  6482. "xs:nonNegativeInteger");
  6483. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  6484. /*
  6485. * Create & parse the wildcard.
  6486. */
  6487. wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
  6488. if (wild == NULL)
  6489. return (NULL);
  6490. xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
  6491. /*
  6492. * And now for the children...
  6493. */
  6494. child = node->children;
  6495. if (IS_SCHEMA(child, "annotation")) {
  6496. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6497. child = child->next;
  6498. }
  6499. if (child != NULL) {
  6500. xmlSchemaPContentErr(ctxt,
  6501. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6502. NULL, node, child,
  6503. NULL, "(annotation?)");
  6504. }
  6505. /*
  6506. * No component if minOccurs==maxOccurs==0.
  6507. */
  6508. if ((min == 0) && (max == 0)) {
  6509. /* Don't free the wildcard, since it's already on the list. */
  6510. return (NULL);
  6511. }
  6512. /*
  6513. * Create the particle.
  6514. */
  6515. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  6516. if (particle == NULL)
  6517. return (NULL);
  6518. particle->annot = annot;
  6519. particle->children = (xmlSchemaTreeItemPtr) wild;
  6520. return (particle);
  6521. }
  6522. /**
  6523. * xmlSchemaParseNotation:
  6524. * @ctxt: a schema validation context
  6525. * @schema: the schema being built
  6526. * @node: a subtree containing XML Schema information
  6527. *
  6528. * parse a XML schema Notation declaration
  6529. *
  6530. * Returns the new structure or NULL in case of error
  6531. */
  6532. static xmlSchemaNotationPtr
  6533. xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6534. xmlNodePtr node)
  6535. {
  6536. const xmlChar *name;
  6537. xmlSchemaNotationPtr ret;
  6538. xmlNodePtr child = NULL;
  6539. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6540. return (NULL);
  6541. name = xmlSchemaGetProp(ctxt, node, "name");
  6542. if (name == NULL) {
  6543. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
  6544. "Notation has no name\n", NULL, NULL);
  6545. return (NULL);
  6546. }
  6547. ret = xmlSchemaAddNotation(ctxt, schema, name,
  6548. ctxt->targetNamespace, node);
  6549. if (ret == NULL)
  6550. return (NULL);
  6551. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6552. child = node->children;
  6553. if (IS_SCHEMA(child, "annotation")) {
  6554. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6555. child = child->next;
  6556. }
  6557. if (child != NULL) {
  6558. xmlSchemaPContentErr(ctxt,
  6559. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6560. NULL, node, child,
  6561. NULL, "(annotation?)");
  6562. }
  6563. return (ret);
  6564. }
  6565. /**
  6566. * xmlSchemaParseAnyAttribute:
  6567. * @ctxt: a schema validation context
  6568. * @schema: the schema being built
  6569. * @node: a subtree containing XML Schema information
  6570. *
  6571. * parse a XML schema AnyAttribute declaration
  6572. * *WARNING* this interface is highly subject to change
  6573. *
  6574. * Returns a wildcard or NULL.
  6575. */
  6576. static xmlSchemaWildcardPtr
  6577. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  6578. xmlSchemaPtr schema, xmlNodePtr node)
  6579. {
  6580. xmlSchemaWildcardPtr ret;
  6581. xmlNodePtr child = NULL;
  6582. xmlAttrPtr attr;
  6583. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6584. return (NULL);
  6585. ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  6586. node);
  6587. if (ret == NULL) {
  6588. return (NULL);
  6589. }
  6590. /*
  6591. * Check for illegal attributes.
  6592. */
  6593. attr = node->properties;
  6594. while (attr != NULL) {
  6595. if (attr->ns == NULL) {
  6596. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6597. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6598. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6599. xmlSchemaPIllegalAttrErr(ctxt,
  6600. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6601. }
  6602. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6603. xmlSchemaPIllegalAttrErr(ctxt,
  6604. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6605. }
  6606. attr = attr->next;
  6607. }
  6608. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6609. /*
  6610. * Parse the namespace list.
  6611. */
  6612. if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
  6613. return (NULL);
  6614. /*
  6615. * And now for the children...
  6616. */
  6617. child = node->children;
  6618. if (IS_SCHEMA(child, "annotation")) {
  6619. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6620. child = child->next;
  6621. }
  6622. if (child != NULL) {
  6623. xmlSchemaPContentErr(ctxt,
  6624. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6625. NULL, node, child,
  6626. NULL, "(annotation?)");
  6627. }
  6628. return (ret);
  6629. }
  6630. /**
  6631. * xmlSchemaParseAttribute:
  6632. * @ctxt: a schema validation context
  6633. * @schema: the schema being built
  6634. * @node: a subtree containing XML Schema information
  6635. *
  6636. * parse a XML schema Attribute declaration
  6637. * *WARNING* this interface is highly subject to change
  6638. *
  6639. * Returns the attribute declaration.
  6640. */
  6641. static xmlSchemaBasicItemPtr
  6642. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  6643. xmlSchemaPtr schema,
  6644. xmlNodePtr node,
  6645. xmlSchemaItemListPtr uses,
  6646. int parentType)
  6647. {
  6648. const xmlChar *attrValue, *name = NULL, *ns = NULL;
  6649. xmlSchemaAttributeUsePtr use = NULL;
  6650. xmlNodePtr child = NULL;
  6651. xmlAttrPtr attr;
  6652. const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
  6653. int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6654. int nberrors, hasForm = 0, defValueType = 0;
  6655. #define WXS_ATTR_DEF_VAL_DEFAULT 1
  6656. #define WXS_ATTR_DEF_VAL_FIXED 2
  6657. /*
  6658. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  6659. */
  6660. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  6661. return (NULL);
  6662. attr = xmlSchemaGetPropNode(node, "ref");
  6663. if (attr != NULL) {
  6664. if (xmlSchemaPValAttrNodeQName(pctxt, schema,
  6665. NULL, attr, &tmpNs, &tmpName) != 0) {
  6666. return (NULL);
  6667. }
  6668. if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
  6669. return(NULL);
  6670. isRef = 1;
  6671. }
  6672. nberrors = pctxt->nberrors;
  6673. /*
  6674. * Check for illegal attributes.
  6675. */
  6676. attr = node->properties;
  6677. while (attr != NULL) {
  6678. if (attr->ns == NULL) {
  6679. if (isRef) {
  6680. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6681. xmlSchemaPValAttrNodeID(pctxt, attr);
  6682. goto attr_next;
  6683. } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
  6684. goto attr_next;
  6685. }
  6686. } else {
  6687. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  6688. goto attr_next;
  6689. } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6690. xmlSchemaPValAttrNodeID(pctxt, attr);
  6691. goto attr_next;
  6692. } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
  6693. xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
  6694. attr, &tmpNs, &tmpName);
  6695. goto attr_next;
  6696. } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
  6697. /*
  6698. * Evaluate the target namespace
  6699. */
  6700. hasForm = 1;
  6701. attrValue = xmlSchemaGetNodeContent(pctxt,
  6702. (xmlNodePtr) attr);
  6703. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  6704. ns = pctxt->targetNamespace;
  6705. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
  6706. {
  6707. xmlSchemaPSimpleTypeErr(pctxt,
  6708. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6709. NULL, (xmlNodePtr) attr,
  6710. NULL, "(qualified | unqualified)",
  6711. attrValue, NULL, NULL, NULL);
  6712. }
  6713. goto attr_next;
  6714. }
  6715. }
  6716. if (xmlStrEqual(attr->name, BAD_CAST "use")) {
  6717. attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6718. /* TODO: Maybe we need to normalize the value beforehand. */
  6719. if (xmlStrEqual(attrValue, BAD_CAST "optional"))
  6720. occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6721. else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
  6722. occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
  6723. else if (xmlStrEqual(attrValue, BAD_CAST "required"))
  6724. occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
  6725. else {
  6726. xmlSchemaPSimpleTypeErr(pctxt,
  6727. XML_SCHEMAP_INVALID_ATTR_USE,
  6728. NULL, (xmlNodePtr) attr,
  6729. NULL, "(optional | prohibited | required)",
  6730. attrValue, NULL, NULL, NULL);
  6731. }
  6732. goto attr_next;
  6733. } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
  6734. /*
  6735. * 3.2.3 : 1
  6736. * default and fixed must not both be present.
  6737. */
  6738. if (defValue) {
  6739. xmlSchemaPMutualExclAttrErr(pctxt,
  6740. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6741. NULL, attr, "default", "fixed");
  6742. } else {
  6743. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6744. defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
  6745. }
  6746. goto attr_next;
  6747. } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
  6748. /*
  6749. * 3.2.3 : 1
  6750. * default and fixed must not both be present.
  6751. */
  6752. if (defValue) {
  6753. xmlSchemaPMutualExclAttrErr(pctxt,
  6754. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6755. NULL, attr, "default", "fixed");
  6756. } else {
  6757. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6758. defValueType = WXS_ATTR_DEF_VAL_FIXED;
  6759. }
  6760. goto attr_next;
  6761. }
  6762. } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
  6763. goto attr_next;
  6764. xmlSchemaPIllegalAttrErr(pctxt,
  6765. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6766. attr_next:
  6767. attr = attr->next;
  6768. }
  6769. /*
  6770. * 3.2.3 : 2
  6771. * If default and use are both present, use must have
  6772. * the actual value optional.
  6773. */
  6774. if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
  6775. (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
  6776. xmlSchemaPSimpleTypeErr(pctxt,
  6777. XML_SCHEMAP_SRC_ATTRIBUTE_2,
  6778. NULL, node, NULL,
  6779. "(optional | prohibited | required)", NULL,
  6780. "The value of the attribute 'use' must be 'optional' "
  6781. "if the attribute 'default' is present",
  6782. NULL, NULL);
  6783. }
  6784. /*
  6785. * We want correct attributes.
  6786. */
  6787. if (nberrors != pctxt->nberrors)
  6788. return(NULL);
  6789. if (! isRef) {
  6790. xmlSchemaAttributePtr attrDecl;
  6791. /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
  6792. if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
  6793. ns = pctxt->targetNamespace;
  6794. /*
  6795. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  6796. * TODO: Move this to the component layer.
  6797. */
  6798. if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
  6799. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6800. XML_SCHEMAP_NO_XSI,
  6801. node, NULL,
  6802. "The target namespace must not match '%s'",
  6803. xmlSchemaInstanceNs, NULL);
  6804. }
  6805. attr = xmlSchemaGetPropNode(node, "name");
  6806. if (attr == NULL) {
  6807. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  6808. NULL, node, "name", NULL);
  6809. return (NULL);
  6810. }
  6811. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  6812. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  6813. return (NULL);
  6814. }
  6815. /*
  6816. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  6817. * TODO: Move this to the component layer.
  6818. */
  6819. if (xmlStrEqual(name, BAD_CAST "xmlns")) {
  6820. xmlSchemaPSimpleTypeErr(pctxt,
  6821. XML_SCHEMAP_NO_XMLNS,
  6822. NULL, (xmlNodePtr) attr,
  6823. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  6824. "The value of the attribute must not match 'xmlns'",
  6825. NULL, NULL);
  6826. return (NULL);
  6827. }
  6828. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
  6829. goto check_children;
  6830. /*
  6831. * Create the attribute use component.
  6832. */
  6833. use = xmlSchemaAddAttributeUse(pctxt, node);
  6834. if (use == NULL)
  6835. return(NULL);
  6836. use->occurs = occurs;
  6837. /*
  6838. * Create the attribute declaration.
  6839. */
  6840. attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
  6841. if (attrDecl == NULL)
  6842. return (NULL);
  6843. if (tmpName != NULL) {
  6844. attrDecl->typeName = tmpName;
  6845. attrDecl->typeNs = tmpNs;
  6846. }
  6847. use->attrDecl = attrDecl;
  6848. /*
  6849. * Value constraint.
  6850. */
  6851. if (defValue != NULL) {
  6852. attrDecl->defValue = defValue;
  6853. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6854. attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
  6855. }
  6856. } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6857. xmlSchemaQNameRefPtr ref;
  6858. /*
  6859. * Create the attribute use component.
  6860. */
  6861. use = xmlSchemaAddAttributeUse(pctxt, node);
  6862. if (use == NULL)
  6863. return(NULL);
  6864. /*
  6865. * We need to resolve the reference at later stage.
  6866. */
  6867. WXS_ADD_PENDING(pctxt, use);
  6868. use->occurs = occurs;
  6869. /*
  6870. * Create a QName reference to the attribute declaration.
  6871. */
  6872. ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
  6873. tmpName, tmpNs);
  6874. if (ref == NULL)
  6875. return(NULL);
  6876. /*
  6877. * Assign the reference. This will be substituted for the
  6878. * referenced attribute declaration when the QName is resolved.
  6879. */
  6880. use->attrDecl = WXS_ATTR_CAST ref;
  6881. /*
  6882. * Value constraint.
  6883. */
  6884. if (defValue != NULL)
  6885. use->defValue = defValue;
  6886. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6887. use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
  6888. }
  6889. check_children:
  6890. /*
  6891. * And now for the children...
  6892. */
  6893. child = node->children;
  6894. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6895. xmlSchemaAttributeUseProhibPtr prohib;
  6896. if (IS_SCHEMA(child, "annotation")) {
  6897. xmlSchemaParseAnnotation(pctxt, child, 0);
  6898. child = child->next;
  6899. }
  6900. if (child != NULL) {
  6901. xmlSchemaPContentErr(pctxt,
  6902. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6903. NULL, node, child, NULL,
  6904. "(annotation?)");
  6905. }
  6906. /*
  6907. * Check for pointlessness of attribute prohibitions.
  6908. */
  6909. if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
  6910. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6911. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6912. node, NULL,
  6913. "Skipping attribute use prohibition, since it is "
  6914. "pointless inside an <attributeGroup>",
  6915. NULL, NULL, NULL);
  6916. return(NULL);
  6917. } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
  6918. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6919. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6920. node, NULL,
  6921. "Skipping attribute use prohibition, since it is "
  6922. "pointless when extending a type",
  6923. NULL, NULL, NULL);
  6924. return(NULL);
  6925. }
  6926. if (! isRef) {
  6927. tmpName = name;
  6928. tmpNs = ns;
  6929. }
  6930. /*
  6931. * Check for duplicate attribute prohibitions.
  6932. */
  6933. if (uses) {
  6934. int i;
  6935. for (i = 0; i < uses->nbItems; i++) {
  6936. use = uses->items[i];
  6937. if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
  6938. (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
  6939. (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
  6940. {
  6941. xmlChar *str = NULL;
  6942. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6943. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6944. node, NULL,
  6945. "Skipping duplicate attribute use prohibition '%s'",
  6946. xmlSchemaFormatQName(&str, tmpNs, tmpName),
  6947. NULL, NULL);
  6948. FREE_AND_NULL(str)
  6949. return(NULL);
  6950. }
  6951. }
  6952. }
  6953. /*
  6954. * Create the attribute prohibition helper component.
  6955. */
  6956. prohib = xmlSchemaAddAttributeUseProhib(pctxt);
  6957. if (prohib == NULL)
  6958. return(NULL);
  6959. prohib->node = node;
  6960. prohib->name = tmpName;
  6961. prohib->targetNamespace = tmpNs;
  6962. if (isRef) {
  6963. /*
  6964. * We need at least to resolve to the attribute declaration.
  6965. */
  6966. WXS_ADD_PENDING(pctxt, prohib);
  6967. }
  6968. return(WXS_BASIC_CAST prohib);
  6969. } else {
  6970. if (IS_SCHEMA(child, "annotation")) {
  6971. /*
  6972. * TODO: Should this go into the attr decl?
  6973. */
  6974. use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  6975. child = child->next;
  6976. }
  6977. if (isRef) {
  6978. if (child != NULL) {
  6979. if (IS_SCHEMA(child, "simpleType"))
  6980. /*
  6981. * 3.2.3 : 3.2
  6982. * If ref is present, then all of <simpleType>,
  6983. * form and type must be absent.
  6984. */
  6985. xmlSchemaPContentErr(pctxt,
  6986. XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
  6987. NULL, node, child, NULL,
  6988. "(annotation?)");
  6989. else
  6990. xmlSchemaPContentErr(pctxt,
  6991. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6992. NULL, node, child, NULL,
  6993. "(annotation?)");
  6994. }
  6995. } else {
  6996. if (IS_SCHEMA(child, "simpleType")) {
  6997. if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
  6998. /*
  6999. * 3.2.3 : 4
  7000. * type and <simpleType> must not both be present.
  7001. */
  7002. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  7003. NULL, node, child,
  7004. "The attribute 'type' and the <simpleType> child "
  7005. "are mutually exclusive", NULL);
  7006. } else
  7007. WXS_ATTRUSE_TYPEDEF(use) =
  7008. xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  7009. child = child->next;
  7010. }
  7011. if (child != NULL)
  7012. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7013. NULL, node, child, NULL,
  7014. "(annotation?, simpleType?)");
  7015. }
  7016. }
  7017. return (WXS_BASIC_CAST use);
  7018. }
  7019. static xmlSchemaAttributePtr
  7020. xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
  7021. xmlSchemaPtr schema,
  7022. xmlNodePtr node)
  7023. {
  7024. const xmlChar *attrValue;
  7025. xmlSchemaAttributePtr ret;
  7026. xmlNodePtr child = NULL;
  7027. xmlAttrPtr attr;
  7028. /*
  7029. * Note that the w3c spec assumes the schema to be validated with schema
  7030. * for schemas beforehand.
  7031. *
  7032. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  7033. */
  7034. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7035. return (NULL);
  7036. /*
  7037. * 3.2.3 : 3.1
  7038. * One of ref or name must be present, but not both
  7039. */
  7040. attr = xmlSchemaGetPropNode(node, "name");
  7041. if (attr == NULL) {
  7042. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  7043. NULL, node, "name", NULL);
  7044. return (NULL);
  7045. }
  7046. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  7047. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
  7048. return (NULL);
  7049. }
  7050. /*
  7051. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  7052. * TODO: Move this to the component layer.
  7053. */
  7054. if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
  7055. xmlSchemaPSimpleTypeErr(pctxt,
  7056. XML_SCHEMAP_NO_XMLNS,
  7057. NULL, (xmlNodePtr) attr,
  7058. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  7059. "The value of the attribute must not match 'xmlns'",
  7060. NULL, NULL);
  7061. return (NULL);
  7062. }
  7063. /*
  7064. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  7065. * TODO: Move this to the component layer.
  7066. * Or better leave it here and add it to the component layer
  7067. * if we have a schema construction API.
  7068. */
  7069. if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
  7070. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  7071. XML_SCHEMAP_NO_XSI, node, NULL,
  7072. "The target namespace must not match '%s'",
  7073. xmlSchemaInstanceNs, NULL);
  7074. }
  7075. ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
  7076. pctxt->targetNamespace, node, 1);
  7077. if (ret == NULL)
  7078. return (NULL);
  7079. ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
  7080. /*
  7081. * Check for illegal attributes.
  7082. */
  7083. attr = node->properties;
  7084. while (attr != NULL) {
  7085. if (attr->ns == NULL) {
  7086. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7087. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  7088. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  7089. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7090. (!xmlStrEqual(attr->name, BAD_CAST "type")))
  7091. {
  7092. xmlSchemaPIllegalAttrErr(pctxt,
  7093. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7094. }
  7095. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7096. xmlSchemaPIllegalAttrErr(pctxt,
  7097. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7098. }
  7099. attr = attr->next;
  7100. }
  7101. xmlSchemaPValAttrQName(pctxt, schema, NULL,
  7102. node, "type", &ret->typeNs, &ret->typeName);
  7103. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7104. /*
  7105. * Attribute "fixed".
  7106. */
  7107. ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
  7108. if (ret->defValue != NULL)
  7109. ret->flags |= XML_SCHEMAS_ATTR_FIXED;
  7110. /*
  7111. * Attribute "default".
  7112. */
  7113. attr = xmlSchemaGetPropNode(node, "default");
  7114. if (attr != NULL) {
  7115. /*
  7116. * 3.2.3 : 1
  7117. * default and fixed must not both be present.
  7118. */
  7119. if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
  7120. xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
  7121. WXS_BASIC_CAST ret, attr, "default", "fixed");
  7122. } else
  7123. ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  7124. }
  7125. /*
  7126. * And now for the children...
  7127. */
  7128. child = node->children;
  7129. if (IS_SCHEMA(child, "annotation")) {
  7130. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7131. child = child->next;
  7132. }
  7133. if (IS_SCHEMA(child, "simpleType")) {
  7134. if (ret->typeName != NULL) {
  7135. /*
  7136. * 3.2.3 : 4
  7137. * type and <simpleType> must not both be present.
  7138. */
  7139. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  7140. NULL, node, child,
  7141. "The attribute 'type' and the <simpleType> child "
  7142. "are mutually exclusive", NULL);
  7143. } else
  7144. ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  7145. child = child->next;
  7146. }
  7147. if (child != NULL)
  7148. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7149. NULL, node, child, NULL,
  7150. "(annotation?, simpleType?)");
  7151. return (ret);
  7152. }
  7153. /**
  7154. * xmlSchemaParseAttributeGroupRef:
  7155. * @ctxt: a schema validation context
  7156. * @schema: the schema being built
  7157. * @node: a subtree containing XML Schema information
  7158. *
  7159. * Parse an attribute group definition reference.
  7160. * Note that a reference to an attribute group does not
  7161. * correspond to any component at all.
  7162. * *WARNING* this interface is highly subject to change
  7163. *
  7164. * Returns the attribute group or NULL in case of error.
  7165. */
  7166. static xmlSchemaQNameRefPtr
  7167. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  7168. xmlSchemaPtr schema,
  7169. xmlNodePtr node)
  7170. {
  7171. xmlSchemaQNameRefPtr ret;
  7172. xmlNodePtr child = NULL;
  7173. xmlAttrPtr attr;
  7174. const xmlChar *refNs = NULL, *ref = NULL;
  7175. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7176. return (NULL);
  7177. attr = xmlSchemaGetPropNode(node, "ref");
  7178. if (attr == NULL) {
  7179. xmlSchemaPMissingAttrErr(pctxt,
  7180. XML_SCHEMAP_S4S_ATTR_MISSING,
  7181. NULL, node, "ref", NULL);
  7182. return (NULL);
  7183. }
  7184. xmlSchemaPValAttrNodeQName(pctxt, schema,
  7185. NULL, attr, &refNs, &ref);
  7186. if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
  7187. return(NULL);
  7188. /*
  7189. * Check for illegal attributes.
  7190. */
  7191. attr = node->properties;
  7192. while (attr != NULL) {
  7193. if (attr->ns == NULL) {
  7194. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  7195. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7196. {
  7197. xmlSchemaPIllegalAttrErr(pctxt,
  7198. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7199. }
  7200. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7201. xmlSchemaPIllegalAttrErr(pctxt,
  7202. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7203. }
  7204. attr = attr->next;
  7205. }
  7206. /* Attribute ID */
  7207. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7208. /*
  7209. * And now for the children...
  7210. */
  7211. child = node->children;
  7212. if (IS_SCHEMA(child, "annotation")) {
  7213. /*
  7214. * TODO: We do not have a place to store the annotation, do we?
  7215. */
  7216. xmlSchemaParseAnnotation(pctxt, child, 0);
  7217. child = child->next;
  7218. }
  7219. if (child != NULL) {
  7220. xmlSchemaPContentErr(pctxt,
  7221. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7222. NULL, node, child, NULL,
  7223. "(annotation?)");
  7224. }
  7225. /*
  7226. * Handle attribute group redefinitions.
  7227. */
  7228. if (pctxt->isRedefine && pctxt->redef &&
  7229. (pctxt->redef->item->type ==
  7230. XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  7231. (ref == pctxt->redef->refName) &&
  7232. (refNs == pctxt->redef->refTargetNs))
  7233. {
  7234. /*
  7235. * SPEC src-redefine:
  7236. * (7.1) "If it has an <attributeGroup> among its contents
  7237. * the `actual value` of whose ref [attribute] is the same
  7238. * as the `actual value` of its own name attribute plus
  7239. * target namespace, then it must have exactly one such group."
  7240. */
  7241. if (pctxt->redefCounter != 0) {
  7242. xmlChar *str = NULL;
  7243. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  7244. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  7245. "The redefining attribute group definition "
  7246. "'%s' must not contain more than one "
  7247. "reference to the redefined definition",
  7248. xmlSchemaFormatQName(&str, refNs, ref), NULL);
  7249. FREE_AND_NULL(str);
  7250. return(NULL);
  7251. }
  7252. pctxt->redefCounter++;
  7253. /*
  7254. * URGENT TODO: How to ensure that the reference will not be
  7255. * handled by the normal component resolution mechanism?
  7256. */
  7257. ret = xmlSchemaNewQNameRef(pctxt,
  7258. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7259. if (ret == NULL)
  7260. return(NULL);
  7261. ret->node = node;
  7262. pctxt->redef->reference = WXS_BASIC_CAST ret;
  7263. } else {
  7264. /*
  7265. * Create a QName-reference helper component. We will substitute this
  7266. * component for the attribute uses of the referenced attribute group
  7267. * definition.
  7268. */
  7269. ret = xmlSchemaNewQNameRef(pctxt,
  7270. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7271. if (ret == NULL)
  7272. return(NULL);
  7273. ret->node = node;
  7274. /* Add to pending items, to be able to resolve the reference. */
  7275. WXS_ADD_PENDING(pctxt, ret);
  7276. }
  7277. return (ret);
  7278. }
  7279. /**
  7280. * xmlSchemaParseAttributeGroupDefinition:
  7281. * @pctxt: a schema validation context
  7282. * @schema: the schema being built
  7283. * @node: a subtree containing XML Schema information
  7284. *
  7285. * parse a XML schema Attribute Group declaration
  7286. * *WARNING* this interface is highly subject to change
  7287. *
  7288. * Returns the attribute group definition or NULL in case of error.
  7289. */
  7290. static xmlSchemaAttributeGroupPtr
  7291. xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  7292. xmlSchemaPtr schema,
  7293. xmlNodePtr node)
  7294. {
  7295. const xmlChar *name;
  7296. xmlSchemaAttributeGroupPtr ret;
  7297. xmlNodePtr child = NULL;
  7298. xmlAttrPtr attr;
  7299. int hasRefs = 0;
  7300. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7301. return (NULL);
  7302. attr = xmlSchemaGetPropNode(node, "name");
  7303. if (attr == NULL) {
  7304. xmlSchemaPMissingAttrErr(pctxt,
  7305. XML_SCHEMAP_S4S_ATTR_MISSING,
  7306. NULL, node, "name", NULL);
  7307. return (NULL);
  7308. }
  7309. /*
  7310. * The name is crucial, exit if invalid.
  7311. */
  7312. if (xmlSchemaPValAttrNode(pctxt,
  7313. NULL, attr,
  7314. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7315. return (NULL);
  7316. }
  7317. ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
  7318. name, pctxt->targetNamespace, node);
  7319. if (ret == NULL)
  7320. return (NULL);
  7321. /*
  7322. * Check for illegal attributes.
  7323. */
  7324. attr = node->properties;
  7325. while (attr != NULL) {
  7326. if (attr->ns == NULL) {
  7327. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7328. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7329. {
  7330. xmlSchemaPIllegalAttrErr(pctxt,
  7331. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7332. }
  7333. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7334. xmlSchemaPIllegalAttrErr(pctxt,
  7335. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7336. }
  7337. attr = attr->next;
  7338. }
  7339. /* Attribute ID */
  7340. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7341. /*
  7342. * And now for the children...
  7343. */
  7344. child = node->children;
  7345. if (IS_SCHEMA(child, "annotation")) {
  7346. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7347. child = child->next;
  7348. }
  7349. /*
  7350. * Parse contained attribute decls/refs.
  7351. */
  7352. if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
  7353. (xmlSchemaItemListPtr *) &(ret->attrUses),
  7354. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
  7355. return(NULL);
  7356. if (hasRefs)
  7357. ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
  7358. /*
  7359. * Parse the attribute wildcard.
  7360. */
  7361. if (IS_SCHEMA(child, "anyAttribute")) {
  7362. ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
  7363. schema, child);
  7364. child = child->next;
  7365. }
  7366. if (child != NULL) {
  7367. xmlSchemaPContentErr(pctxt,
  7368. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7369. NULL, node, child, NULL,
  7370. "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
  7371. }
  7372. return (ret);
  7373. }
  7374. /**
  7375. * xmlSchemaPValAttrFormDefault:
  7376. * @value: the value
  7377. * @flags: the flags to be modified
  7378. * @flagQualified: the specific flag for "qualified"
  7379. *
  7380. * Returns 0 if the value is valid, 1 otherwise.
  7381. */
  7382. static int
  7383. xmlSchemaPValAttrFormDefault(const xmlChar *value,
  7384. int *flags,
  7385. int flagQualified)
  7386. {
  7387. if (xmlStrEqual(value, BAD_CAST "qualified")) {
  7388. if ((*flags & flagQualified) == 0)
  7389. *flags |= flagQualified;
  7390. } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
  7391. return (1);
  7392. return (0);
  7393. }
  7394. /**
  7395. * xmlSchemaPValAttrBlockFinal:
  7396. * @value: the value
  7397. * @flags: the flags to be modified
  7398. * @flagAll: the specific flag for "#all"
  7399. * @flagExtension: the specific flag for "extension"
  7400. * @flagRestriction: the specific flag for "restriction"
  7401. * @flagSubstitution: the specific flag for "substitution"
  7402. * @flagList: the specific flag for "list"
  7403. * @flagUnion: the specific flag for "union"
  7404. *
  7405. * Validates the value of the attribute "final" and "block". The value
  7406. * is converted into the specified flag values and returned in @flags.
  7407. *
  7408. * Returns 0 if the value is valid, 1 otherwise.
  7409. */
  7410. static int
  7411. xmlSchemaPValAttrBlockFinal(const xmlChar *value,
  7412. int *flags,
  7413. int flagAll,
  7414. int flagExtension,
  7415. int flagRestriction,
  7416. int flagSubstitution,
  7417. int flagList,
  7418. int flagUnion)
  7419. {
  7420. int ret = 0;
  7421. /*
  7422. * TODO: This does not check for duplicate entries.
  7423. */
  7424. if ((flags == NULL) || (value == NULL))
  7425. return (-1);
  7426. if (value[0] == 0)
  7427. return (0);
  7428. if (xmlStrEqual(value, BAD_CAST "#all")) {
  7429. if (flagAll != -1)
  7430. *flags |= flagAll;
  7431. else {
  7432. if (flagExtension != -1)
  7433. *flags |= flagExtension;
  7434. if (flagRestriction != -1)
  7435. *flags |= flagRestriction;
  7436. if (flagSubstitution != -1)
  7437. *flags |= flagSubstitution;
  7438. if (flagList != -1)
  7439. *flags |= flagList;
  7440. if (flagUnion != -1)
  7441. *flags |= flagUnion;
  7442. }
  7443. } else {
  7444. const xmlChar *end, *cur = value;
  7445. xmlChar *item;
  7446. do {
  7447. while (IS_BLANK_CH(*cur))
  7448. cur++;
  7449. end = cur;
  7450. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  7451. end++;
  7452. if (end == cur)
  7453. break;
  7454. item = xmlStrndup(cur, end - cur);
  7455. if (xmlStrEqual(item, BAD_CAST "extension")) {
  7456. if (flagExtension != -1) {
  7457. if ((*flags & flagExtension) == 0)
  7458. *flags |= flagExtension;
  7459. } else
  7460. ret = 1;
  7461. } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
  7462. if (flagRestriction != -1) {
  7463. if ((*flags & flagRestriction) == 0)
  7464. *flags |= flagRestriction;
  7465. } else
  7466. ret = 1;
  7467. } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
  7468. if (flagSubstitution != -1) {
  7469. if ((*flags & flagSubstitution) == 0)
  7470. *flags |= flagSubstitution;
  7471. } else
  7472. ret = 1;
  7473. } else if (xmlStrEqual(item, BAD_CAST "list")) {
  7474. if (flagList != -1) {
  7475. if ((*flags & flagList) == 0)
  7476. *flags |= flagList;
  7477. } else
  7478. ret = 1;
  7479. } else if (xmlStrEqual(item, BAD_CAST "union")) {
  7480. if (flagUnion != -1) {
  7481. if ((*flags & flagUnion) == 0)
  7482. *flags |= flagUnion;
  7483. } else
  7484. ret = 1;
  7485. } else
  7486. ret = 1;
  7487. if (item != NULL)
  7488. xmlFree(item);
  7489. cur = end;
  7490. } while ((ret == 0) && (*cur != 0));
  7491. }
  7492. return (ret);
  7493. }
  7494. static int
  7495. xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
  7496. xmlSchemaIDCPtr idc,
  7497. xmlSchemaIDCSelectPtr selector,
  7498. xmlAttrPtr attr,
  7499. int isField)
  7500. {
  7501. xmlNodePtr node;
  7502. /*
  7503. * c-selector-xpath:
  7504. * Schema Component Constraint: Selector Value OK
  7505. *
  7506. * TODO: 1 The {selector} must be a valid XPath expression, as defined
  7507. * in [XPath].
  7508. */
  7509. if (selector == NULL) {
  7510. xmlSchemaPErr(ctxt, idc->node,
  7511. XML_SCHEMAP_INTERNAL,
  7512. "Internal error: xmlSchemaCheckCSelectorXPath, "
  7513. "the selector is not specified.\n", NULL, NULL);
  7514. return (-1);
  7515. }
  7516. if (attr == NULL)
  7517. node = idc->node;
  7518. else
  7519. node = (xmlNodePtr) attr;
  7520. if (selector->xpath == NULL) {
  7521. xmlSchemaPCustomErr(ctxt,
  7522. /* TODO: Adjust error code. */
  7523. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7524. NULL, node,
  7525. "The XPath expression of the selector is not valid", NULL);
  7526. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7527. } else {
  7528. const xmlChar **nsArray = NULL;
  7529. xmlNsPtr *nsList = NULL;
  7530. /*
  7531. * Compile the XPath expression.
  7532. */
  7533. /*
  7534. * TODO: We need the array of in-scope namespaces for compilation.
  7535. * TODO: Call xmlPatterncompile with different options for selector/
  7536. * field.
  7537. */
  7538. if (attr == NULL)
  7539. nsList = NULL;
  7540. else
  7541. nsList = xmlGetNsList(attr->doc, attr->parent);
  7542. /*
  7543. * Build an array of prefixes and namespaces.
  7544. */
  7545. if (nsList != NULL) {
  7546. int i, count = 0;
  7547. for (i = 0; nsList[i] != NULL; i++)
  7548. count++;
  7549. nsArray = (const xmlChar **) xmlMalloc(
  7550. (count * 2 + 1) * sizeof(const xmlChar *));
  7551. if (nsArray == NULL) {
  7552. xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
  7553. NULL);
  7554. xmlFree(nsList);
  7555. return (-1);
  7556. }
  7557. for (i = 0; i < count; i++) {
  7558. nsArray[2 * i] = nsList[i]->href;
  7559. nsArray[2 * i + 1] = nsList[i]->prefix;
  7560. }
  7561. nsArray[count * 2] = NULL;
  7562. xmlFree(nsList);
  7563. }
  7564. /*
  7565. * TODO: Differentiate between "selector" and "field".
  7566. */
  7567. if (isField)
  7568. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7569. NULL, XML_PATTERN_XSFIELD, nsArray);
  7570. else
  7571. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7572. NULL, XML_PATTERN_XSSEL, nsArray);
  7573. if (nsArray != NULL)
  7574. xmlFree((xmlChar **) nsArray);
  7575. if (selector->xpathComp == NULL) {
  7576. xmlSchemaPCustomErr(ctxt,
  7577. /* TODO: Adjust error code? */
  7578. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7579. NULL, node,
  7580. "The XPath expression '%s' could not be "
  7581. "compiled", selector->xpath);
  7582. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7583. }
  7584. }
  7585. return (0);
  7586. }
  7587. #define ADD_ANNOTATION(annot) \
  7588. xmlSchemaAnnotPtr cur = item->annot; \
  7589. if (item->annot == NULL) { \
  7590. item->annot = annot; \
  7591. return (annot); \
  7592. } \
  7593. cur = item->annot; \
  7594. if (cur->next != NULL) { \
  7595. cur = cur->next; \
  7596. } \
  7597. cur->next = annot;
  7598. /**
  7599. * xmlSchemaAssignAnnotation:
  7600. * @item: the schema component
  7601. * @annot: the annotation
  7602. *
  7603. * Adds the annotation to the given schema component.
  7604. *
  7605. * Returns the given annotation.
  7606. */
  7607. static xmlSchemaAnnotPtr
  7608. xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
  7609. xmlSchemaAnnotPtr annot)
  7610. {
  7611. if ((annItem == NULL) || (annot == NULL))
  7612. return (NULL);
  7613. switch (annItem->type) {
  7614. case XML_SCHEMA_TYPE_ELEMENT: {
  7615. xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
  7616. ADD_ANNOTATION(annot)
  7617. }
  7618. break;
  7619. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  7620. xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
  7621. ADD_ANNOTATION(annot)
  7622. }
  7623. break;
  7624. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  7625. case XML_SCHEMA_TYPE_ANY: {
  7626. xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
  7627. ADD_ANNOTATION(annot)
  7628. }
  7629. break;
  7630. case XML_SCHEMA_TYPE_PARTICLE:
  7631. case XML_SCHEMA_TYPE_IDC_KEY:
  7632. case XML_SCHEMA_TYPE_IDC_KEYREF:
  7633. case XML_SCHEMA_TYPE_IDC_UNIQUE: {
  7634. xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
  7635. ADD_ANNOTATION(annot)
  7636. }
  7637. break;
  7638. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
  7639. xmlSchemaAttributeGroupPtr item =
  7640. (xmlSchemaAttributeGroupPtr) annItem;
  7641. ADD_ANNOTATION(annot)
  7642. }
  7643. break;
  7644. case XML_SCHEMA_TYPE_NOTATION: {
  7645. xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
  7646. ADD_ANNOTATION(annot)
  7647. }
  7648. break;
  7649. case XML_SCHEMA_FACET_MININCLUSIVE:
  7650. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  7651. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  7652. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  7653. case XML_SCHEMA_FACET_TOTALDIGITS:
  7654. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  7655. case XML_SCHEMA_FACET_PATTERN:
  7656. case XML_SCHEMA_FACET_ENUMERATION:
  7657. case XML_SCHEMA_FACET_WHITESPACE:
  7658. case XML_SCHEMA_FACET_LENGTH:
  7659. case XML_SCHEMA_FACET_MAXLENGTH:
  7660. case XML_SCHEMA_FACET_MINLENGTH: {
  7661. xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
  7662. ADD_ANNOTATION(annot)
  7663. }
  7664. break;
  7665. case XML_SCHEMA_TYPE_SIMPLE:
  7666. case XML_SCHEMA_TYPE_COMPLEX: {
  7667. xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
  7668. ADD_ANNOTATION(annot)
  7669. }
  7670. break;
  7671. case XML_SCHEMA_TYPE_GROUP: {
  7672. xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
  7673. ADD_ANNOTATION(annot)
  7674. }
  7675. break;
  7676. case XML_SCHEMA_TYPE_SEQUENCE:
  7677. case XML_SCHEMA_TYPE_CHOICE:
  7678. case XML_SCHEMA_TYPE_ALL: {
  7679. xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
  7680. ADD_ANNOTATION(annot)
  7681. }
  7682. break;
  7683. default:
  7684. xmlSchemaPCustomErr(NULL,
  7685. XML_SCHEMAP_INTERNAL,
  7686. NULL, NULL,
  7687. "Internal error: xmlSchemaAddAnnotation, "
  7688. "The item is not a annotated schema component", NULL);
  7689. break;
  7690. }
  7691. return (annot);
  7692. }
  7693. /**
  7694. * xmlSchemaParseIDCSelectorAndField:
  7695. * @ctxt: a schema validation context
  7696. * @schema: the schema being built
  7697. * @node: a subtree containing XML Schema information
  7698. *
  7699. * Parses a XML Schema identity-constraint definition's
  7700. * <selector> and <field> elements.
  7701. *
  7702. * Returns the parsed identity-constraint definition.
  7703. */
  7704. static xmlSchemaIDCSelectPtr
  7705. xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
  7706. xmlSchemaIDCPtr idc,
  7707. xmlNodePtr node,
  7708. int isField)
  7709. {
  7710. xmlSchemaIDCSelectPtr item;
  7711. xmlNodePtr child = NULL;
  7712. xmlAttrPtr attr;
  7713. /*
  7714. * Check for illegal attributes.
  7715. */
  7716. attr = node->properties;
  7717. while (attr != NULL) {
  7718. if (attr->ns == NULL) {
  7719. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7720. (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
  7721. xmlSchemaPIllegalAttrErr(ctxt,
  7722. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7723. }
  7724. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7725. xmlSchemaPIllegalAttrErr(ctxt,
  7726. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7727. }
  7728. attr = attr->next;
  7729. }
  7730. /*
  7731. * Create the item.
  7732. */
  7733. item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
  7734. if (item == NULL) {
  7735. xmlSchemaPErrMemory(ctxt,
  7736. "allocating a 'selector' of an identity-constraint definition",
  7737. NULL);
  7738. return (NULL);
  7739. }
  7740. memset(item, 0, sizeof(xmlSchemaIDCSelect));
  7741. /*
  7742. * Attribute "xpath" (mandatory).
  7743. */
  7744. attr = xmlSchemaGetPropNode(node, "xpath");
  7745. if (attr == NULL) {
  7746. xmlSchemaPMissingAttrErr(ctxt,
  7747. XML_SCHEMAP_S4S_ATTR_MISSING,
  7748. NULL, node,
  7749. "name", NULL);
  7750. } else {
  7751. item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  7752. /*
  7753. * URGENT TODO: "field"s have an other syntax than "selector"s.
  7754. */
  7755. if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
  7756. isField) == -1) {
  7757. xmlSchemaPErr(ctxt,
  7758. (xmlNodePtr) attr,
  7759. XML_SCHEMAP_INTERNAL,
  7760. "Internal error: xmlSchemaParseIDCSelectorAndField, "
  7761. "validating the XPath expression of a IDC selector.\n",
  7762. NULL, NULL);
  7763. }
  7764. }
  7765. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7766. /*
  7767. * And now for the children...
  7768. */
  7769. child = node->children;
  7770. if (IS_SCHEMA(child, "annotation")) {
  7771. /*
  7772. * Add the annotation to the parent IDC.
  7773. */
  7774. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
  7775. xmlSchemaParseAnnotation(ctxt, child, 1));
  7776. child = child->next;
  7777. }
  7778. if (child != NULL) {
  7779. xmlSchemaPContentErr(ctxt,
  7780. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7781. NULL, node, child,
  7782. NULL, "(annotation?)");
  7783. }
  7784. return (item);
  7785. }
  7786. /**
  7787. * xmlSchemaParseIDC:
  7788. * @ctxt: a schema validation context
  7789. * @schema: the schema being built
  7790. * @node: a subtree containing XML Schema information
  7791. *
  7792. * Parses a XML Schema identity-constraint definition.
  7793. *
  7794. * Returns the parsed identity-constraint definition.
  7795. */
  7796. static xmlSchemaIDCPtr
  7797. xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
  7798. xmlSchemaPtr schema,
  7799. xmlNodePtr node,
  7800. xmlSchemaTypeType idcCategory,
  7801. const xmlChar *targetNamespace)
  7802. {
  7803. xmlSchemaIDCPtr item = NULL;
  7804. xmlNodePtr child = NULL;
  7805. xmlAttrPtr attr;
  7806. const xmlChar *name = NULL;
  7807. xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
  7808. /*
  7809. * Check for illegal attributes.
  7810. */
  7811. attr = node->properties;
  7812. while (attr != NULL) {
  7813. if (attr->ns == NULL) {
  7814. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7815. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7816. ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
  7817. (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
  7818. xmlSchemaPIllegalAttrErr(ctxt,
  7819. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7820. }
  7821. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7822. xmlSchemaPIllegalAttrErr(ctxt,
  7823. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7824. }
  7825. attr = attr->next;
  7826. }
  7827. /*
  7828. * Attribute "name" (mandatory).
  7829. */
  7830. attr = xmlSchemaGetPropNode(node, "name");
  7831. if (attr == NULL) {
  7832. xmlSchemaPMissingAttrErr(ctxt,
  7833. XML_SCHEMAP_S4S_ATTR_MISSING,
  7834. NULL, node,
  7835. "name", NULL);
  7836. return (NULL);
  7837. } else if (xmlSchemaPValAttrNode(ctxt,
  7838. NULL, attr,
  7839. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7840. return (NULL);
  7841. }
  7842. /* Create the component. */
  7843. item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
  7844. idcCategory, node);
  7845. if (item == NULL)
  7846. return(NULL);
  7847. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7848. if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
  7849. /*
  7850. * Attribute "refer" (mandatory).
  7851. */
  7852. attr = xmlSchemaGetPropNode(node, "refer");
  7853. if (attr == NULL) {
  7854. xmlSchemaPMissingAttrErr(ctxt,
  7855. XML_SCHEMAP_S4S_ATTR_MISSING,
  7856. NULL, node,
  7857. "refer", NULL);
  7858. } else {
  7859. /*
  7860. * Create a reference item.
  7861. */
  7862. item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
  7863. NULL, NULL);
  7864. if (item->ref == NULL)
  7865. return (NULL);
  7866. xmlSchemaPValAttrNodeQName(ctxt, schema,
  7867. NULL, attr,
  7868. &(item->ref->targetNamespace),
  7869. &(item->ref->name));
  7870. xmlSchemaCheckReference(ctxt, schema, node, attr,
  7871. item->ref->targetNamespace);
  7872. }
  7873. }
  7874. /*
  7875. * And now for the children...
  7876. */
  7877. child = node->children;
  7878. if (IS_SCHEMA(child, "annotation")) {
  7879. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7880. child = child->next;
  7881. }
  7882. if (child == NULL) {
  7883. xmlSchemaPContentErr(ctxt,
  7884. XML_SCHEMAP_S4S_ELEM_MISSING,
  7885. NULL, node, child,
  7886. "A child element is missing",
  7887. "(annotation?, (selector, field+))");
  7888. }
  7889. /*
  7890. * Child element <selector>.
  7891. */
  7892. if (IS_SCHEMA(child, "selector")) {
  7893. item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
  7894. item, child, 0);
  7895. child = child->next;
  7896. /*
  7897. * Child elements <field>.
  7898. */
  7899. if (IS_SCHEMA(child, "field")) {
  7900. do {
  7901. field = xmlSchemaParseIDCSelectorAndField(ctxt,
  7902. item, child, 1);
  7903. if (field != NULL) {
  7904. field->index = item->nbFields;
  7905. item->nbFields++;
  7906. if (lastField != NULL)
  7907. lastField->next = field;
  7908. else
  7909. item->fields = field;
  7910. lastField = field;
  7911. }
  7912. child = child->next;
  7913. } while (IS_SCHEMA(child, "field"));
  7914. } else {
  7915. xmlSchemaPContentErr(ctxt,
  7916. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7917. NULL, node, child,
  7918. NULL, "(annotation?, (selector, field+))");
  7919. }
  7920. }
  7921. if (child != NULL) {
  7922. xmlSchemaPContentErr(ctxt,
  7923. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7924. NULL, node, child,
  7925. NULL, "(annotation?, (selector, field+))");
  7926. }
  7927. return (item);
  7928. }
  7929. /**
  7930. * xmlSchemaParseElement:
  7931. * @ctxt: a schema validation context
  7932. * @schema: the schema being built
  7933. * @node: a subtree containing XML Schema information
  7934. * @topLevel: indicates if this is global declaration
  7935. *
  7936. * Parses a XML schema element declaration.
  7937. * *WARNING* this interface is highly subject to change
  7938. *
  7939. * Returns the element declaration or a particle; NULL in case
  7940. * of an error or if the particle has minOccurs==maxOccurs==0.
  7941. */
  7942. static xmlSchemaBasicItemPtr
  7943. xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  7944. xmlNodePtr node, int *isElemRef, int topLevel)
  7945. {
  7946. xmlSchemaElementPtr decl = NULL;
  7947. xmlSchemaParticlePtr particle = NULL;
  7948. xmlSchemaAnnotPtr annot = NULL;
  7949. xmlNodePtr child = NULL;
  7950. xmlAttrPtr attr, nameAttr;
  7951. int min, max, isRef = 0;
  7952. xmlChar *des = NULL;
  7953. /* 3.3.3 Constraints on XML Representations of Element Declarations */
  7954. /* TODO: Complete implementation of 3.3.6 */
  7955. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  7956. return (NULL);
  7957. if (isElemRef != NULL)
  7958. *isElemRef = 0;
  7959. /*
  7960. * If we get a "ref" attribute on a local <element> we will assume it's
  7961. * a reference - even if there's a "name" attribute; this seems to be more
  7962. * robust.
  7963. */
  7964. nameAttr = xmlSchemaGetPropNode(node, "name");
  7965. attr = xmlSchemaGetPropNode(node, "ref");
  7966. if ((topLevel) || (attr == NULL)) {
  7967. if (nameAttr == NULL) {
  7968. xmlSchemaPMissingAttrErr(ctxt,
  7969. XML_SCHEMAP_S4S_ATTR_MISSING,
  7970. NULL, node, "name", NULL);
  7971. return (NULL);
  7972. }
  7973. } else
  7974. isRef = 1;
  7975. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7976. child = node->children;
  7977. if (IS_SCHEMA(child, "annotation")) {
  7978. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7979. child = child->next;
  7980. }
  7981. /*
  7982. * Skip particle part if a global declaration.
  7983. */
  7984. if (topLevel)
  7985. goto declaration_part;
  7986. /*
  7987. * The particle part ==================================================
  7988. */
  7989. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  7990. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
  7991. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  7992. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  7993. if (particle == NULL)
  7994. goto return_null;
  7995. /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
  7996. if (isRef) {
  7997. const xmlChar *refNs = NULL, *ref = NULL;
  7998. xmlSchemaQNameRefPtr refer = NULL;
  7999. /*
  8000. * The reference part =============================================
  8001. */
  8002. if (isElemRef != NULL)
  8003. *isElemRef = 1;
  8004. xmlSchemaPValAttrNodeQName(ctxt, schema,
  8005. NULL, attr, &refNs, &ref);
  8006. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  8007. /*
  8008. * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
  8009. */
  8010. if (nameAttr != NULL) {
  8011. xmlSchemaPMutualExclAttrErr(ctxt,
  8012. XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
  8013. }
  8014. /*
  8015. * Check for illegal attributes.
  8016. */
  8017. attr = node->properties;
  8018. while (attr != NULL) {
  8019. if (attr->ns == NULL) {
  8020. if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
  8021. xmlStrEqual(attr->name, BAD_CAST "name") ||
  8022. xmlStrEqual(attr->name, BAD_CAST "id") ||
  8023. xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
  8024. xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
  8025. {
  8026. attr = attr->next;
  8027. continue;
  8028. } else {
  8029. /* SPEC (3.3.3 : 2.2) */
  8030. xmlSchemaPCustomAttrErr(ctxt,
  8031. XML_SCHEMAP_SRC_ELEMENT_2_2,
  8032. NULL, NULL, attr,
  8033. "Only the attributes 'minOccurs', 'maxOccurs' and "
  8034. "'id' are allowed in addition to 'ref'");
  8035. break;
  8036. }
  8037. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8038. xmlSchemaPIllegalAttrErr(ctxt,
  8039. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8040. }
  8041. attr = attr->next;
  8042. }
  8043. /*
  8044. * No children except <annotation> expected.
  8045. */
  8046. if (child != NULL) {
  8047. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8048. NULL, node, child, NULL, "(annotation?)");
  8049. }
  8050. if ((min == 0) && (max == 0))
  8051. goto return_null;
  8052. /*
  8053. * Create the reference item and attach it to the particle.
  8054. */
  8055. refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
  8056. ref, refNs);
  8057. if (refer == NULL)
  8058. goto return_null;
  8059. particle->children = (xmlSchemaTreeItemPtr) refer;
  8060. particle->annot = annot;
  8061. /*
  8062. * Add the particle to pending components, since the reference
  8063. * need to be resolved.
  8064. */
  8065. WXS_ADD_PENDING(ctxt, particle);
  8066. return ((xmlSchemaBasicItemPtr) particle);
  8067. }
  8068. /*
  8069. * The declaration part ===============================================
  8070. */
  8071. declaration_part:
  8072. {
  8073. const xmlChar *ns = NULL, *fixed, *name, *attrValue;
  8074. xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
  8075. if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
  8076. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
  8077. goto return_null;
  8078. /*
  8079. * Evaluate the target namespace.
  8080. */
  8081. if (topLevel) {
  8082. ns = ctxt->targetNamespace;
  8083. } else {
  8084. attr = xmlSchemaGetPropNode(node, "form");
  8085. if (attr != NULL) {
  8086. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8087. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  8088. ns = ctxt->targetNamespace;
  8089. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
  8090. xmlSchemaPSimpleTypeErr(ctxt,
  8091. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8092. NULL, (xmlNodePtr) attr,
  8093. NULL, "(qualified | unqualified)",
  8094. attrValue, NULL, NULL, NULL);
  8095. }
  8096. } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  8097. ns = ctxt->targetNamespace;
  8098. }
  8099. decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
  8100. if (decl == NULL) {
  8101. goto return_null;
  8102. }
  8103. /*
  8104. * Check for illegal attributes.
  8105. */
  8106. attr = node->properties;
  8107. while (attr != NULL) {
  8108. if (attr->ns == NULL) {
  8109. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8110. (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
  8111. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8112. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  8113. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  8114. (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
  8115. (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
  8116. {
  8117. if (topLevel == 0) {
  8118. if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  8119. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8120. (!xmlStrEqual(attr->name, BAD_CAST "form")))
  8121. {
  8122. xmlSchemaPIllegalAttrErr(ctxt,
  8123. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8124. }
  8125. } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
  8126. (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
  8127. (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
  8128. xmlSchemaPIllegalAttrErr(ctxt,
  8129. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8130. }
  8131. }
  8132. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8133. xmlSchemaPIllegalAttrErr(ctxt,
  8134. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8135. }
  8136. attr = attr->next;
  8137. }
  8138. /*
  8139. * Extract/validate attributes.
  8140. */
  8141. if (topLevel) {
  8142. /*
  8143. * Process top attributes of global element declarations here.
  8144. */
  8145. decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
  8146. decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
  8147. xmlSchemaPValAttrQName(ctxt, schema,
  8148. NULL, node, "substitutionGroup",
  8149. &(decl->substGroupNs), &(decl->substGroup));
  8150. if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
  8151. decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
  8152. /*
  8153. * Attribute "final".
  8154. */
  8155. attr = xmlSchemaGetPropNode(node, "final");
  8156. if (attr == NULL) {
  8157. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  8158. decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
  8159. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8160. decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
  8161. } else {
  8162. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8163. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8164. -1,
  8165. XML_SCHEMAS_ELEM_FINAL_EXTENSION,
  8166. XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
  8167. xmlSchemaPSimpleTypeErr(ctxt,
  8168. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8169. NULL, (xmlNodePtr) attr,
  8170. NULL, "(#all | List of (extension | restriction))",
  8171. attrValue, NULL, NULL, NULL);
  8172. }
  8173. }
  8174. }
  8175. /*
  8176. * Attribute "block".
  8177. */
  8178. attr = xmlSchemaGetPropNode(node, "block");
  8179. if (attr == NULL) {
  8180. /*
  8181. * Apply default "block" values.
  8182. */
  8183. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  8184. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
  8185. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  8186. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
  8187. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  8188. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
  8189. } else {
  8190. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8191. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8192. -1,
  8193. XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
  8194. XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
  8195. XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
  8196. xmlSchemaPSimpleTypeErr(ctxt,
  8197. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8198. NULL, (xmlNodePtr) attr,
  8199. NULL, "(#all | List of (extension | "
  8200. "restriction | substitution))", attrValue,
  8201. NULL, NULL, NULL);
  8202. }
  8203. }
  8204. if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
  8205. decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
  8206. attr = xmlSchemaGetPropNode(node, "type");
  8207. if (attr != NULL) {
  8208. xmlSchemaPValAttrNodeQName(ctxt, schema,
  8209. NULL, attr,
  8210. &(decl->namedTypeNs), &(decl->namedType));
  8211. xmlSchemaCheckReference(ctxt, schema, node,
  8212. attr, decl->namedTypeNs);
  8213. }
  8214. decl->value = xmlSchemaGetProp(ctxt, node, "default");
  8215. attr = xmlSchemaGetPropNode(node, "fixed");
  8216. if (attr != NULL) {
  8217. fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8218. if (decl->value != NULL) {
  8219. /*
  8220. * 3.3.3 : 1
  8221. * default and fixed must not both be present.
  8222. */
  8223. xmlSchemaPMutualExclAttrErr(ctxt,
  8224. XML_SCHEMAP_SRC_ELEMENT_1,
  8225. NULL, attr, "default", "fixed");
  8226. } else {
  8227. decl->flags |= XML_SCHEMAS_ELEM_FIXED;
  8228. decl->value = fixed;
  8229. }
  8230. }
  8231. /*
  8232. * And now for the children...
  8233. */
  8234. if (IS_SCHEMA(child, "complexType")) {
  8235. /*
  8236. * 3.3.3 : 3
  8237. * "type" and either <simpleType> or <complexType> are mutually
  8238. * exclusive
  8239. */
  8240. if (decl->namedType != NULL) {
  8241. xmlSchemaPContentErr(ctxt,
  8242. XML_SCHEMAP_SRC_ELEMENT_3,
  8243. NULL, node, child,
  8244. "The attribute 'type' and the <complexType> child are "
  8245. "mutually exclusive", NULL);
  8246. } else
  8247. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
  8248. child = child->next;
  8249. } else if (IS_SCHEMA(child, "simpleType")) {
  8250. /*
  8251. * 3.3.3 : 3
  8252. * "type" and either <simpleType> or <complexType> are
  8253. * mutually exclusive
  8254. */
  8255. if (decl->namedType != NULL) {
  8256. xmlSchemaPContentErr(ctxt,
  8257. XML_SCHEMAP_SRC_ELEMENT_3,
  8258. NULL, node, child,
  8259. "The attribute 'type' and the <simpleType> child are "
  8260. "mutually exclusive", NULL);
  8261. } else
  8262. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8263. child = child->next;
  8264. }
  8265. while ((IS_SCHEMA(child, "unique")) ||
  8266. (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
  8267. if (IS_SCHEMA(child, "unique")) {
  8268. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8269. XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
  8270. } else if (IS_SCHEMA(child, "key")) {
  8271. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8272. XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
  8273. } else if (IS_SCHEMA(child, "keyref")) {
  8274. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8275. XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
  8276. }
  8277. if (lastIDC != NULL)
  8278. lastIDC->next = curIDC;
  8279. else
  8280. decl->idcs = (void *) curIDC;
  8281. lastIDC = curIDC;
  8282. child = child->next;
  8283. }
  8284. if (child != NULL) {
  8285. xmlSchemaPContentErr(ctxt,
  8286. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8287. NULL, node, child,
  8288. NULL, "(annotation?, ((simpleType | complexType)?, "
  8289. "(unique | key | keyref)*))");
  8290. }
  8291. decl->annot = annot;
  8292. }
  8293. /*
  8294. * NOTE: Element Declaration Representation OK 4. will be checked at a
  8295. * different layer.
  8296. */
  8297. FREE_AND_NULL(des)
  8298. if (topLevel)
  8299. return ((xmlSchemaBasicItemPtr) decl);
  8300. else {
  8301. particle->children = (xmlSchemaTreeItemPtr) decl;
  8302. return ((xmlSchemaBasicItemPtr) particle);
  8303. }
  8304. return_null:
  8305. FREE_AND_NULL(des);
  8306. if (annot != NULL) {
  8307. if (particle != NULL)
  8308. particle->annot = NULL;
  8309. if (decl != NULL)
  8310. decl->annot = NULL;
  8311. xmlSchemaFreeAnnot(annot);
  8312. }
  8313. return (NULL);
  8314. }
  8315. /**
  8316. * xmlSchemaParseUnion:
  8317. * @ctxt: a schema validation context
  8318. * @schema: the schema being built
  8319. * @node: a subtree containing XML Schema information
  8320. *
  8321. * parse a XML schema Union definition
  8322. * *WARNING* this interface is highly subject to change
  8323. *
  8324. * Returns -1 in case of internal error, 0 in case of success and a positive
  8325. * error code otherwise.
  8326. */
  8327. static int
  8328. xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8329. xmlNodePtr node)
  8330. {
  8331. xmlSchemaTypePtr type;
  8332. xmlNodePtr child = NULL;
  8333. xmlAttrPtr attr;
  8334. const xmlChar *cur = NULL;
  8335. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8336. return (-1);
  8337. /* Not a component, don't create it. */
  8338. type = ctxt->ctxtType;
  8339. /*
  8340. * Mark the simple type as being of variety "union".
  8341. */
  8342. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  8343. /*
  8344. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8345. * then the `simple ur-type definition`."
  8346. */
  8347. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8348. /*
  8349. * Check for illegal attributes.
  8350. */
  8351. attr = node->properties;
  8352. while (attr != NULL) {
  8353. if (attr->ns == NULL) {
  8354. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8355. (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
  8356. xmlSchemaPIllegalAttrErr(ctxt,
  8357. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8358. }
  8359. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8360. xmlSchemaPIllegalAttrErr(ctxt,
  8361. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8362. }
  8363. attr = attr->next;
  8364. }
  8365. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8366. /*
  8367. * Attribute "memberTypes". This is a list of QNames.
  8368. * TODO: Check the value to contain anything.
  8369. */
  8370. attr = xmlSchemaGetPropNode(node, "memberTypes");
  8371. if (attr != NULL) {
  8372. const xmlChar *end;
  8373. xmlChar *tmp;
  8374. const xmlChar *localName, *nsName;
  8375. xmlSchemaTypeLinkPtr link, lastLink = NULL;
  8376. xmlSchemaQNameRefPtr ref;
  8377. cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8378. type->base = cur;
  8379. do {
  8380. while (IS_BLANK_CH(*cur))
  8381. cur++;
  8382. end = cur;
  8383. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  8384. end++;
  8385. if (end == cur)
  8386. break;
  8387. tmp = xmlStrndup(cur, end - cur);
  8388. if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  8389. NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
  8390. /*
  8391. * Create the member type link.
  8392. */
  8393. link = (xmlSchemaTypeLinkPtr)
  8394. xmlMalloc(sizeof(xmlSchemaTypeLink));
  8395. if (link == NULL) {
  8396. xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
  8397. "allocating a type link", NULL);
  8398. return (-1);
  8399. }
  8400. link->type = NULL;
  8401. link->next = NULL;
  8402. if (lastLink == NULL)
  8403. type->memberTypes = link;
  8404. else
  8405. lastLink->next = link;
  8406. lastLink = link;
  8407. /*
  8408. * Create a reference item.
  8409. */
  8410. ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
  8411. localName, nsName);
  8412. if (ref == NULL) {
  8413. FREE_AND_NULL(tmp)
  8414. return (-1);
  8415. }
  8416. /*
  8417. * Assign the reference to the link, it will be resolved
  8418. * later during fixup of the union simple type.
  8419. */
  8420. link->type = (xmlSchemaTypePtr) ref;
  8421. }
  8422. FREE_AND_NULL(tmp)
  8423. cur = end;
  8424. } while (*cur != 0);
  8425. }
  8426. /*
  8427. * And now for the children...
  8428. */
  8429. child = node->children;
  8430. if (IS_SCHEMA(child, "annotation")) {
  8431. /*
  8432. * Add the annotation to the simple type ancestor.
  8433. */
  8434. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8435. xmlSchemaParseAnnotation(ctxt, child, 1));
  8436. child = child->next;
  8437. }
  8438. if (IS_SCHEMA(child, "simpleType")) {
  8439. xmlSchemaTypePtr subtype, last = NULL;
  8440. /*
  8441. * Anchor the member types in the "subtypes" field of the
  8442. * simple type.
  8443. */
  8444. while (IS_SCHEMA(child, "simpleType")) {
  8445. subtype = (xmlSchemaTypePtr)
  8446. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8447. if (subtype != NULL) {
  8448. if (last == NULL) {
  8449. type->subtypes = subtype;
  8450. last = subtype;
  8451. } else {
  8452. last->next = subtype;
  8453. last = subtype;
  8454. }
  8455. last->next = NULL;
  8456. }
  8457. child = child->next;
  8458. }
  8459. }
  8460. if (child != NULL) {
  8461. xmlSchemaPContentErr(ctxt,
  8462. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8463. NULL, node, child, NULL, "(annotation?, simpleType*)");
  8464. }
  8465. if ((attr == NULL) && (type->subtypes == NULL)) {
  8466. /*
  8467. * src-union-memberTypes-or-simpleTypes
  8468. * Either the memberTypes [attribute] of the <union> element must
  8469. * be non-empty or there must be at least one simpleType [child].
  8470. */
  8471. xmlSchemaPCustomErr(ctxt,
  8472. XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
  8473. NULL, node,
  8474. "Either the attribute 'memberTypes' or "
  8475. "at least one <simpleType> child must be present", NULL);
  8476. }
  8477. return (0);
  8478. }
  8479. /**
  8480. * xmlSchemaParseList:
  8481. * @ctxt: a schema validation context
  8482. * @schema: the schema being built
  8483. * @node: a subtree containing XML Schema information
  8484. *
  8485. * parse a XML schema List definition
  8486. * *WARNING* this interface is highly subject to change
  8487. *
  8488. * Returns -1 in case of error, 0 if the declaration is improper and
  8489. * 1 in case of success.
  8490. */
  8491. static xmlSchemaTypePtr
  8492. xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8493. xmlNodePtr node)
  8494. {
  8495. xmlSchemaTypePtr type;
  8496. xmlNodePtr child = NULL;
  8497. xmlAttrPtr attr;
  8498. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8499. return (NULL);
  8500. /* Not a component, don't create it. */
  8501. type = ctxt->ctxtType;
  8502. /*
  8503. * Mark the type as being of variety "list".
  8504. */
  8505. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  8506. /*
  8507. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8508. * then the `simple ur-type definition`."
  8509. */
  8510. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8511. /*
  8512. * Check for illegal attributes.
  8513. */
  8514. attr = node->properties;
  8515. while (attr != NULL) {
  8516. if (attr->ns == NULL) {
  8517. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8518. (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
  8519. xmlSchemaPIllegalAttrErr(ctxt,
  8520. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8521. }
  8522. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8523. xmlSchemaPIllegalAttrErr(ctxt,
  8524. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8525. }
  8526. attr = attr->next;
  8527. }
  8528. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8529. /*
  8530. * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
  8531. * fields for holding the reference to the itemType.
  8532. *
  8533. * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
  8534. * the "ref" fields.
  8535. */
  8536. xmlSchemaPValAttrQName(ctxt, schema, NULL,
  8537. node, "itemType", &(type->baseNs), &(type->base));
  8538. /*
  8539. * And now for the children...
  8540. */
  8541. child = node->children;
  8542. if (IS_SCHEMA(child, "annotation")) {
  8543. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8544. xmlSchemaParseAnnotation(ctxt, child, 1));
  8545. child = child->next;
  8546. }
  8547. if (IS_SCHEMA(child, "simpleType")) {
  8548. /*
  8549. * src-list-itemType-or-simpleType
  8550. * Either the itemType [attribute] or the <simpleType> [child] of
  8551. * the <list> element must be present, but not both.
  8552. */
  8553. if (type->base != NULL) {
  8554. xmlSchemaPCustomErr(ctxt,
  8555. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8556. NULL, node,
  8557. "The attribute 'itemType' and the <simpleType> child "
  8558. "are mutually exclusive", NULL);
  8559. } else {
  8560. type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8561. }
  8562. child = child->next;
  8563. } else if (type->base == NULL) {
  8564. xmlSchemaPCustomErr(ctxt,
  8565. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8566. NULL, node,
  8567. "Either the attribute 'itemType' or the <simpleType> child "
  8568. "must be present", NULL);
  8569. }
  8570. if (child != NULL) {
  8571. xmlSchemaPContentErr(ctxt,
  8572. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8573. NULL, node, child, NULL, "(annotation?, simpleType?)");
  8574. }
  8575. if ((type->base == NULL) &&
  8576. (type->subtypes == NULL) &&
  8577. (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
  8578. xmlSchemaPCustomErr(ctxt,
  8579. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8580. NULL, node,
  8581. "Either the attribute 'itemType' or the <simpleType> child "
  8582. "must be present", NULL);
  8583. }
  8584. return (NULL);
  8585. }
  8586. /**
  8587. * xmlSchemaParseSimpleType:
  8588. * @ctxt: a schema validation context
  8589. * @schema: the schema being built
  8590. * @node: a subtree containing XML Schema information
  8591. *
  8592. * parse a XML schema Simple Type definition
  8593. * *WARNING* this interface is highly subject to change
  8594. *
  8595. * Returns -1 in case of error, 0 if the declaration is improper and
  8596. * 1 in case of success.
  8597. */
  8598. static xmlSchemaTypePtr
  8599. xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8600. xmlNodePtr node, int topLevel)
  8601. {
  8602. xmlSchemaTypePtr type, oldCtxtType;
  8603. xmlNodePtr child = NULL;
  8604. const xmlChar *attrValue = NULL;
  8605. xmlAttrPtr attr;
  8606. int hasRestriction = 0;
  8607. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8608. return (NULL);
  8609. if (topLevel) {
  8610. attr = xmlSchemaGetPropNode(node, "name");
  8611. if (attr == NULL) {
  8612. xmlSchemaPMissingAttrErr(ctxt,
  8613. XML_SCHEMAP_S4S_ATTR_MISSING,
  8614. NULL, node,
  8615. "name", NULL);
  8616. return (NULL);
  8617. } else {
  8618. if (xmlSchemaPValAttrNode(ctxt,
  8619. NULL, attr,
  8620. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
  8621. return (NULL);
  8622. /*
  8623. * Skip built-in types.
  8624. */
  8625. if (ctxt->isS4S) {
  8626. xmlSchemaTypePtr biType;
  8627. if (ctxt->isRedefine) {
  8628. /*
  8629. * REDEFINE: Disallow redefinition of built-in-types.
  8630. * TODO: It seems that the spec does not say anything
  8631. * about this case.
  8632. */
  8633. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8634. NULL, node,
  8635. "Redefinition of built-in simple types is not "
  8636. "supported", NULL);
  8637. return(NULL);
  8638. }
  8639. biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
  8640. if (biType != NULL)
  8641. return (biType);
  8642. }
  8643. }
  8644. }
  8645. /*
  8646. * TargetNamespace:
  8647. * SPEC "The `actual value` of the targetNamespace [attribute]
  8648. * of the <schema> ancestor element information item if present,
  8649. * otherwise `absent`.
  8650. */
  8651. if (topLevel == 0) {
  8652. #ifdef ENABLE_NAMED_LOCALS
  8653. char buf[40];
  8654. #endif
  8655. /*
  8656. * Parse as local simple type definition.
  8657. */
  8658. #ifdef ENABLE_NAMED_LOCALS
  8659. snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
  8660. type = xmlSchemaAddType(ctxt, schema,
  8661. XML_SCHEMA_TYPE_SIMPLE,
  8662. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  8663. ctxt->targetNamespace, node, 0);
  8664. #else
  8665. type = xmlSchemaAddType(ctxt, schema,
  8666. XML_SCHEMA_TYPE_SIMPLE,
  8667. NULL, ctxt->targetNamespace, node, 0);
  8668. #endif
  8669. if (type == NULL)
  8670. return (NULL);
  8671. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8672. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8673. /*
  8674. * Check for illegal attributes.
  8675. */
  8676. attr = node->properties;
  8677. while (attr != NULL) {
  8678. if (attr->ns == NULL) {
  8679. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  8680. xmlSchemaPIllegalAttrErr(ctxt,
  8681. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8682. }
  8683. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8684. xmlSchemaPIllegalAttrErr(ctxt,
  8685. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8686. }
  8687. attr = attr->next;
  8688. }
  8689. } else {
  8690. /*
  8691. * Parse as global simple type definition.
  8692. *
  8693. * Note that attrValue is the value of the attribute "name" here.
  8694. */
  8695. type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
  8696. attrValue, ctxt->targetNamespace, node, 1);
  8697. if (type == NULL)
  8698. return (NULL);
  8699. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8700. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8701. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  8702. /*
  8703. * Check for illegal attributes.
  8704. */
  8705. attr = node->properties;
  8706. while (attr != NULL) {
  8707. if (attr->ns == NULL) {
  8708. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8709. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8710. (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
  8711. xmlSchemaPIllegalAttrErr(ctxt,
  8712. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8713. }
  8714. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8715. xmlSchemaPIllegalAttrErr(ctxt,
  8716. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8717. }
  8718. attr = attr->next;
  8719. }
  8720. /*
  8721. * Attribute "final".
  8722. */
  8723. attr = xmlSchemaGetPropNode(node, "final");
  8724. if (attr == NULL) {
  8725. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8726. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  8727. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  8728. type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
  8729. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  8730. type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
  8731. } else {
  8732. attrValue = xmlSchemaGetProp(ctxt, node, "final");
  8733. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  8734. -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
  8735. XML_SCHEMAS_TYPE_FINAL_LIST,
  8736. XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
  8737. xmlSchemaPSimpleTypeErr(ctxt,
  8738. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8739. WXS_BASIC_CAST type, (xmlNodePtr) attr,
  8740. NULL, "(#all | List of (list | union | restriction)",
  8741. attrValue, NULL, NULL, NULL);
  8742. }
  8743. }
  8744. }
  8745. type->targetNamespace = ctxt->targetNamespace;
  8746. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8747. /*
  8748. * And now for the children...
  8749. */
  8750. oldCtxtType = ctxt->ctxtType;
  8751. ctxt->ctxtType = type;
  8752. child = node->children;
  8753. if (IS_SCHEMA(child, "annotation")) {
  8754. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8755. child = child->next;
  8756. }
  8757. if (child == NULL) {
  8758. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
  8759. NULL, node, child, NULL,
  8760. "(annotation?, (restriction | list | union))");
  8761. } else if (IS_SCHEMA(child, "restriction")) {
  8762. xmlSchemaParseRestriction(ctxt, schema, child,
  8763. XML_SCHEMA_TYPE_SIMPLE);
  8764. hasRestriction = 1;
  8765. child = child->next;
  8766. } else if (IS_SCHEMA(child, "list")) {
  8767. xmlSchemaParseList(ctxt, schema, child);
  8768. child = child->next;
  8769. } else if (IS_SCHEMA(child, "union")) {
  8770. xmlSchemaParseUnion(ctxt, schema, child);
  8771. child = child->next;
  8772. }
  8773. if (child != NULL) {
  8774. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8775. NULL, node, child, NULL,
  8776. "(annotation?, (restriction | list | union))");
  8777. }
  8778. /*
  8779. * REDEFINE: SPEC src-redefine (5)
  8780. * "Within the [children], each <simpleType> must have a
  8781. * <restriction> among its [children] ... the `actual value` of whose
  8782. * base [attribute] must be the same as the `actual value` of its own
  8783. * name attribute plus target namespace;"
  8784. */
  8785. if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
  8786. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8787. NULL, node, "This is a redefinition, thus the "
  8788. "<simpleType> must have a <restriction> child", NULL);
  8789. }
  8790. ctxt->ctxtType = oldCtxtType;
  8791. return (type);
  8792. }
  8793. /**
  8794. * xmlSchemaParseModelGroupDefRef:
  8795. * @ctxt: the parser context
  8796. * @schema: the schema being built
  8797. * @node: the node
  8798. *
  8799. * Parses a reference to a model group definition.
  8800. *
  8801. * We will return a particle component with a qname-component or
  8802. * NULL in case of an error.
  8803. */
  8804. static xmlSchemaTreeItemPtr
  8805. xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
  8806. xmlSchemaPtr schema,
  8807. xmlNodePtr node)
  8808. {
  8809. xmlSchemaParticlePtr item;
  8810. xmlNodePtr child = NULL;
  8811. xmlAttrPtr attr;
  8812. const xmlChar *ref = NULL, *refNs = NULL;
  8813. int min, max;
  8814. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8815. return (NULL);
  8816. attr = xmlSchemaGetPropNode(node, "ref");
  8817. if (attr == NULL) {
  8818. xmlSchemaPMissingAttrErr(ctxt,
  8819. XML_SCHEMAP_S4S_ATTR_MISSING,
  8820. NULL, node, "ref", NULL);
  8821. return (NULL);
  8822. } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
  8823. attr, &refNs, &ref) != 0) {
  8824. return (NULL);
  8825. }
  8826. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  8827. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  8828. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  8829. "(xs:nonNegativeInteger | unbounded)");
  8830. /*
  8831. * Check for illegal attributes.
  8832. */
  8833. attr = node->properties;
  8834. while (attr != NULL) {
  8835. if (attr->ns == NULL) {
  8836. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  8837. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8838. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8839. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
  8840. xmlSchemaPIllegalAttrErr(ctxt,
  8841. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8842. }
  8843. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8844. xmlSchemaPIllegalAttrErr(ctxt,
  8845. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8846. }
  8847. attr = attr->next;
  8848. }
  8849. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8850. item = xmlSchemaAddParticle(ctxt, node, min, max);
  8851. if (item == NULL)
  8852. return (NULL);
  8853. /*
  8854. * Create a qname-reference and set as the term; it will be substituted
  8855. * for the model group after the reference has been resolved.
  8856. */
  8857. item->children = (xmlSchemaTreeItemPtr)
  8858. xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
  8859. xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
  8860. /*
  8861. * And now for the children...
  8862. */
  8863. child = node->children;
  8864. /* TODO: Is annotation even allowed for a model group reference? */
  8865. if (IS_SCHEMA(child, "annotation")) {
  8866. /*
  8867. * TODO: What to do exactly with the annotation?
  8868. */
  8869. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8870. child = child->next;
  8871. }
  8872. if (child != NULL) {
  8873. xmlSchemaPContentErr(ctxt,
  8874. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8875. NULL, node, child, NULL,
  8876. "(annotation?)");
  8877. }
  8878. /*
  8879. * Corresponds to no component at all if minOccurs==maxOccurs==0.
  8880. */
  8881. if ((min == 0) && (max == 0))
  8882. return (NULL);
  8883. return ((xmlSchemaTreeItemPtr) item);
  8884. }
  8885. /**
  8886. * xmlSchemaParseModelGroupDefinition:
  8887. * @ctxt: a schema validation context
  8888. * @schema: the schema being built
  8889. * @node: a subtree containing XML Schema information
  8890. *
  8891. * Parses a XML schema model group definition.
  8892. *
  8893. * Note that the constraint src-redefine (6.2) can't be applied until
  8894. * references have been resolved. So we will do this at the
  8895. * component fixup level.
  8896. *
  8897. * *WARNING* this interface is highly subject to change
  8898. *
  8899. * Returns -1 in case of error, 0 if the declaration is improper and
  8900. * 1 in case of success.
  8901. */
  8902. static xmlSchemaModelGroupDefPtr
  8903. xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  8904. xmlSchemaPtr schema,
  8905. xmlNodePtr node)
  8906. {
  8907. xmlSchemaModelGroupDefPtr item;
  8908. xmlNodePtr child = NULL;
  8909. xmlAttrPtr attr;
  8910. const xmlChar *name;
  8911. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8912. return (NULL);
  8913. attr = xmlSchemaGetPropNode(node, "name");
  8914. if (attr == NULL) {
  8915. xmlSchemaPMissingAttrErr(ctxt,
  8916. XML_SCHEMAP_S4S_ATTR_MISSING,
  8917. NULL, node,
  8918. "name", NULL);
  8919. return (NULL);
  8920. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  8921. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  8922. return (NULL);
  8923. }
  8924. item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
  8925. ctxt->targetNamespace, node);
  8926. if (item == NULL)
  8927. return (NULL);
  8928. /*
  8929. * Check for illegal attributes.
  8930. */
  8931. attr = node->properties;
  8932. while (attr != NULL) {
  8933. if (attr->ns == NULL) {
  8934. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8935. (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  8936. xmlSchemaPIllegalAttrErr(ctxt,
  8937. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8938. }
  8939. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8940. xmlSchemaPIllegalAttrErr(ctxt,
  8941. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8942. }
  8943. attr = attr->next;
  8944. }
  8945. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8946. /*
  8947. * And now for the children...
  8948. */
  8949. child = node->children;
  8950. if (IS_SCHEMA(child, "annotation")) {
  8951. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8952. child = child->next;
  8953. }
  8954. if (IS_SCHEMA(child, "all")) {
  8955. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8956. XML_SCHEMA_TYPE_ALL, 0);
  8957. child = child->next;
  8958. } else if (IS_SCHEMA(child, "choice")) {
  8959. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8960. XML_SCHEMA_TYPE_CHOICE, 0);
  8961. child = child->next;
  8962. } else if (IS_SCHEMA(child, "sequence")) {
  8963. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8964. XML_SCHEMA_TYPE_SEQUENCE, 0);
  8965. child = child->next;
  8966. }
  8967. if (child != NULL) {
  8968. xmlSchemaPContentErr(ctxt,
  8969. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8970. NULL, node, child, NULL,
  8971. "(annotation?, (all | choice | sequence)?)");
  8972. }
  8973. return (item);
  8974. }
  8975. /**
  8976. * xmlSchemaCleanupDoc:
  8977. * @ctxt: a schema validation context
  8978. * @node: the root of the document.
  8979. *
  8980. * removes unwanted nodes in a schemas document tree
  8981. */
  8982. static void
  8983. xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
  8984. {
  8985. xmlNodePtr delete, cur;
  8986. if ((ctxt == NULL) || (root == NULL)) return;
  8987. /*
  8988. * Remove all the blank text nodes
  8989. */
  8990. delete = NULL;
  8991. cur = root;
  8992. while (cur != NULL) {
  8993. if (delete != NULL) {
  8994. xmlUnlinkNode(delete);
  8995. xmlFreeNode(delete);
  8996. delete = NULL;
  8997. }
  8998. if (cur->type == XML_TEXT_NODE) {
  8999. if (IS_BLANK_NODE(cur)) {
  9000. if (xmlNodeGetSpacePreserve(cur) != 1) {
  9001. delete = cur;
  9002. }
  9003. }
  9004. } else if ((cur->type != XML_ELEMENT_NODE) &&
  9005. (cur->type != XML_CDATA_SECTION_NODE)) {
  9006. delete = cur;
  9007. goto skip_children;
  9008. }
  9009. /*
  9010. * Skip to next node
  9011. */
  9012. if (cur->children != NULL) {
  9013. if ((cur->children->type != XML_ENTITY_DECL) &&
  9014. (cur->children->type != XML_ENTITY_REF_NODE) &&
  9015. (cur->children->type != XML_ENTITY_NODE)) {
  9016. cur = cur->children;
  9017. continue;
  9018. }
  9019. }
  9020. skip_children:
  9021. if (cur->next != NULL) {
  9022. cur = cur->next;
  9023. continue;
  9024. }
  9025. do {
  9026. cur = cur->parent;
  9027. if (cur == NULL)
  9028. break;
  9029. if (cur == root) {
  9030. cur = NULL;
  9031. break;
  9032. }
  9033. if (cur->next != NULL) {
  9034. cur = cur->next;
  9035. break;
  9036. }
  9037. } while (cur != NULL);
  9038. }
  9039. if (delete != NULL) {
  9040. xmlUnlinkNode(delete);
  9041. xmlFreeNode(delete);
  9042. delete = NULL;
  9043. }
  9044. }
  9045. static void
  9046. xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
  9047. {
  9048. if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  9049. schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
  9050. if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
  9051. schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
  9052. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  9053. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
  9054. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  9055. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
  9056. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  9057. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
  9058. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  9059. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
  9060. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  9061. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
  9062. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  9063. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
  9064. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  9065. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
  9066. }
  9067. static int
  9068. xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
  9069. xmlSchemaPtr schema,
  9070. xmlNodePtr node)
  9071. {
  9072. xmlAttrPtr attr;
  9073. const xmlChar *val;
  9074. int res = 0, oldErrs = ctxt->nberrors;
  9075. /*
  9076. * Those flags should be moved to the parser context flags,
  9077. * since they are not visible at the component level. I.e.
  9078. * they are used if processing schema *documents* only.
  9079. */
  9080. res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  9081. HFAILURE;
  9082. /*
  9083. * Since the version is of type xs:token, we won't bother to
  9084. * check it.
  9085. */
  9086. /* REMOVED:
  9087. attr = xmlSchemaGetPropNode(node, "version");
  9088. if (attr != NULL) {
  9089. res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
  9090. xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
  9091. HFAILURE;
  9092. }
  9093. */
  9094. attr = xmlSchemaGetPropNode(node, "targetNamespace");
  9095. if (attr != NULL) {
  9096. res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
  9097. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  9098. HFAILURE;
  9099. if (res != 0) {
  9100. ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  9101. goto exit;
  9102. }
  9103. }
  9104. attr = xmlSchemaGetPropNode(node, "elementFormDefault");
  9105. if (attr != NULL) {
  9106. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9107. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9108. XML_SCHEMAS_QUALIF_ELEM);
  9109. HFAILURE;
  9110. if (res != 0) {
  9111. xmlSchemaPSimpleTypeErr(ctxt,
  9112. XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
  9113. NULL, (xmlNodePtr) attr, NULL,
  9114. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9115. }
  9116. }
  9117. attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
  9118. if (attr != NULL) {
  9119. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9120. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9121. XML_SCHEMAS_QUALIF_ATTR);
  9122. HFAILURE;
  9123. if (res != 0) {
  9124. xmlSchemaPSimpleTypeErr(ctxt,
  9125. XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
  9126. NULL, (xmlNodePtr) attr, NULL,
  9127. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9128. }
  9129. }
  9130. attr = xmlSchemaGetPropNode(node, "finalDefault");
  9131. if (attr != NULL) {
  9132. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9133. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9134. XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
  9135. XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
  9136. -1,
  9137. XML_SCHEMAS_FINAL_DEFAULT_LIST,
  9138. XML_SCHEMAS_FINAL_DEFAULT_UNION);
  9139. HFAILURE;
  9140. if (res != 0) {
  9141. xmlSchemaPSimpleTypeErr(ctxt,
  9142. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9143. NULL, (xmlNodePtr) attr, NULL,
  9144. "(#all | List of (extension | restriction | list | union))",
  9145. val, NULL, NULL, NULL);
  9146. }
  9147. }
  9148. attr = xmlSchemaGetPropNode(node, "blockDefault");
  9149. if (attr != NULL) {
  9150. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9151. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9152. XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
  9153. XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
  9154. XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
  9155. HFAILURE;
  9156. if (res != 0) {
  9157. xmlSchemaPSimpleTypeErr(ctxt,
  9158. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9159. NULL, (xmlNodePtr) attr, NULL,
  9160. "(#all | List of (extension | restriction | substitution))",
  9161. val, NULL, NULL, NULL);
  9162. }
  9163. }
  9164. exit:
  9165. if (oldErrs != ctxt->nberrors)
  9166. res = ctxt->err;
  9167. return(res);
  9168. exit_failure:
  9169. return(-1);
  9170. }
  9171. /**
  9172. * xmlSchemaParseSchemaTopLevel:
  9173. * @ctxt: a schema validation context
  9174. * @schema: the schemas
  9175. * @nodes: the list of top level nodes
  9176. *
  9177. * Returns the internal XML Schema structure built from the resource or
  9178. * NULL in case of error
  9179. */
  9180. static int
  9181. xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
  9182. xmlSchemaPtr schema, xmlNodePtr nodes)
  9183. {
  9184. xmlNodePtr child;
  9185. xmlSchemaAnnotPtr annot;
  9186. int res = 0, oldErrs, tmpOldErrs;
  9187. if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
  9188. return(-1);
  9189. oldErrs = ctxt->nberrors;
  9190. child = nodes;
  9191. while ((IS_SCHEMA(child, "include")) ||
  9192. (IS_SCHEMA(child, "import")) ||
  9193. (IS_SCHEMA(child, "redefine")) ||
  9194. (IS_SCHEMA(child, "annotation"))) {
  9195. if (IS_SCHEMA(child, "annotation")) {
  9196. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9197. if (schema->annot == NULL)
  9198. schema->annot = annot;
  9199. else
  9200. xmlSchemaFreeAnnot(annot);
  9201. } else if (IS_SCHEMA(child, "import")) {
  9202. tmpOldErrs = ctxt->nberrors;
  9203. res = xmlSchemaParseImport(ctxt, schema, child);
  9204. HFAILURE;
  9205. HSTOP(ctxt);
  9206. if (tmpOldErrs != ctxt->nberrors)
  9207. goto exit;
  9208. } else if (IS_SCHEMA(child, "include")) {
  9209. tmpOldErrs = ctxt->nberrors;
  9210. res = xmlSchemaParseInclude(ctxt, schema, child);
  9211. HFAILURE;
  9212. HSTOP(ctxt);
  9213. if (tmpOldErrs != ctxt->nberrors)
  9214. goto exit;
  9215. } else if (IS_SCHEMA(child, "redefine")) {
  9216. tmpOldErrs = ctxt->nberrors;
  9217. res = xmlSchemaParseRedefine(ctxt, schema, child);
  9218. HFAILURE;
  9219. HSTOP(ctxt);
  9220. if (tmpOldErrs != ctxt->nberrors)
  9221. goto exit;
  9222. }
  9223. child = child->next;
  9224. }
  9225. /*
  9226. * URGENT TODO: Change the functions to return int results.
  9227. * We need especially to catch internal errors.
  9228. */
  9229. while (child != NULL) {
  9230. if (IS_SCHEMA(child, "complexType")) {
  9231. xmlSchemaParseComplexType(ctxt, schema, child, 1);
  9232. child = child->next;
  9233. } else if (IS_SCHEMA(child, "simpleType")) {
  9234. xmlSchemaParseSimpleType(ctxt, schema, child, 1);
  9235. child = child->next;
  9236. } else if (IS_SCHEMA(child, "element")) {
  9237. xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
  9238. child = child->next;
  9239. } else if (IS_SCHEMA(child, "attribute")) {
  9240. xmlSchemaParseGlobalAttribute(ctxt, schema, child);
  9241. child = child->next;
  9242. } else if (IS_SCHEMA(child, "attributeGroup")) {
  9243. xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
  9244. child = child->next;
  9245. } else if (IS_SCHEMA(child, "group")) {
  9246. xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
  9247. child = child->next;
  9248. } else if (IS_SCHEMA(child, "notation")) {
  9249. xmlSchemaParseNotation(ctxt, schema, child);
  9250. child = child->next;
  9251. } else {
  9252. xmlSchemaPContentErr(ctxt,
  9253. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  9254. NULL, child->parent, child,
  9255. NULL, "((include | import | redefine | annotation)*, "
  9256. "(((simpleType | complexType | group | attributeGroup) "
  9257. "| element | attribute | notation), annotation*)*)");
  9258. child = child->next;
  9259. }
  9260. while (IS_SCHEMA(child, "annotation")) {
  9261. /*
  9262. * TODO: We should add all annotations.
  9263. */
  9264. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9265. if (schema->annot == NULL)
  9266. schema->annot = annot;
  9267. else
  9268. xmlSchemaFreeAnnot(annot);
  9269. child = child->next;
  9270. }
  9271. }
  9272. exit:
  9273. ctxt->ctxtType = NULL;
  9274. if (oldErrs != ctxt->nberrors)
  9275. res = ctxt->err;
  9276. return(res);
  9277. exit_failure:
  9278. return(-1);
  9279. }
  9280. static xmlSchemaSchemaRelationPtr
  9281. xmlSchemaSchemaRelationCreate(void)
  9282. {
  9283. xmlSchemaSchemaRelationPtr ret;
  9284. ret = (xmlSchemaSchemaRelationPtr)
  9285. xmlMalloc(sizeof(xmlSchemaSchemaRelation));
  9286. if (ret == NULL) {
  9287. xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
  9288. return(NULL);
  9289. }
  9290. memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
  9291. return(ret);
  9292. }
  9293. #if 0
  9294. static void
  9295. xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
  9296. {
  9297. xmlFree(rel);
  9298. }
  9299. #endif
  9300. static void
  9301. xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
  9302. {
  9303. xmlSchemaRedefPtr prev;
  9304. while (redef != NULL) {
  9305. prev = redef;
  9306. redef = redef->next;
  9307. xmlFree(prev);
  9308. }
  9309. }
  9310. static void
  9311. xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
  9312. {
  9313. /*
  9314. * After the construction context has been freed, there will be
  9315. * no schema graph available any more. Only the schema buckets
  9316. * will stay alive, which are put into the "schemasImports" and
  9317. * "includes" slots of the xmlSchema.
  9318. */
  9319. if (con->buckets != NULL)
  9320. xmlSchemaItemListFree(con->buckets);
  9321. if (con->pending != NULL)
  9322. xmlSchemaItemListFree(con->pending);
  9323. if (con->substGroups != NULL)
  9324. xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
  9325. if (con->redefs != NULL)
  9326. xmlSchemaRedefListFree(con->redefs);
  9327. if (con->dict != NULL)
  9328. xmlDictFree(con->dict);
  9329. xmlFree(con);
  9330. }
  9331. static xmlSchemaConstructionCtxtPtr
  9332. xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
  9333. {
  9334. xmlSchemaConstructionCtxtPtr ret;
  9335. ret = (xmlSchemaConstructionCtxtPtr)
  9336. xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
  9337. if (ret == NULL) {
  9338. xmlSchemaPErrMemory(NULL,
  9339. "allocating schema construction context", NULL);
  9340. return (NULL);
  9341. }
  9342. memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
  9343. ret->buckets = xmlSchemaItemListCreate();
  9344. if (ret->buckets == NULL) {
  9345. xmlSchemaPErrMemory(NULL,
  9346. "allocating list of schema buckets", NULL);
  9347. xmlFree(ret);
  9348. return (NULL);
  9349. }
  9350. ret->pending = xmlSchemaItemListCreate();
  9351. if (ret->pending == NULL) {
  9352. xmlSchemaPErrMemory(NULL,
  9353. "allocating list of pending global components", NULL);
  9354. xmlSchemaConstructionCtxtFree(ret);
  9355. return (NULL);
  9356. }
  9357. ret->dict = dict;
  9358. xmlDictReference(dict);
  9359. return(ret);
  9360. }
  9361. static xmlSchemaParserCtxtPtr
  9362. xmlSchemaParserCtxtCreate(void)
  9363. {
  9364. xmlSchemaParserCtxtPtr ret;
  9365. ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
  9366. if (ret == NULL) {
  9367. xmlSchemaPErrMemory(NULL, "allocating schema parser context",
  9368. NULL);
  9369. return (NULL);
  9370. }
  9371. memset(ret, 0, sizeof(xmlSchemaParserCtxt));
  9372. ret->type = XML_SCHEMA_CTXT_PARSER;
  9373. ret->attrProhibs = xmlSchemaItemListCreate();
  9374. if (ret->attrProhibs == NULL) {
  9375. xmlFree(ret);
  9376. return(NULL);
  9377. }
  9378. return(ret);
  9379. }
  9380. /**
  9381. * xmlSchemaNewParserCtxtUseDict:
  9382. * @URL: the location of the schema
  9383. * @dict: the dictionary to be used
  9384. *
  9385. * Create an XML Schemas parse context for that file/resource expected
  9386. * to contain an XML Schemas file.
  9387. *
  9388. * Returns the parser context or NULL in case of error
  9389. */
  9390. static xmlSchemaParserCtxtPtr
  9391. xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
  9392. {
  9393. xmlSchemaParserCtxtPtr ret;
  9394. ret = xmlSchemaParserCtxtCreate();
  9395. if (ret == NULL)
  9396. return (NULL);
  9397. ret->dict = dict;
  9398. xmlDictReference(dict);
  9399. if (URL != NULL)
  9400. ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
  9401. return (ret);
  9402. }
  9403. static int
  9404. xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
  9405. {
  9406. if (vctxt->pctxt == NULL) {
  9407. if (vctxt->schema != NULL)
  9408. vctxt->pctxt =
  9409. xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
  9410. else
  9411. vctxt->pctxt = xmlSchemaNewParserCtxt("*");
  9412. if (vctxt->pctxt == NULL) {
  9413. VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
  9414. "failed to create a temp. parser context");
  9415. return (-1);
  9416. }
  9417. /* TODO: Pass user data. */
  9418. xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
  9419. vctxt->warning, vctxt->errCtxt);
  9420. xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
  9421. vctxt->errCtxt);
  9422. }
  9423. return (0);
  9424. }
  9425. /**
  9426. * xmlSchemaGetSchemaBucket:
  9427. * @pctxt: the schema parser context
  9428. * @schemaLocation: the URI of the schema document
  9429. *
  9430. * Returns a schema bucket if it was already parsed.
  9431. *
  9432. * Returns a schema bucket if it was already parsed from
  9433. * @schemaLocation, NULL otherwise.
  9434. */
  9435. static xmlSchemaBucketPtr
  9436. xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9437. const xmlChar *schemaLocation)
  9438. {
  9439. xmlSchemaBucketPtr cur;
  9440. xmlSchemaItemListPtr list;
  9441. list = pctxt->constructor->buckets;
  9442. if (list->nbItems == 0)
  9443. return(NULL);
  9444. else {
  9445. int i;
  9446. for (i = 0; i < list->nbItems; i++) {
  9447. cur = (xmlSchemaBucketPtr) list->items[i];
  9448. /* Pointer comparison! */
  9449. if (cur->schemaLocation == schemaLocation)
  9450. return(cur);
  9451. }
  9452. }
  9453. return(NULL);
  9454. }
  9455. static xmlSchemaBucketPtr
  9456. xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9457. const xmlChar *schemaLocation,
  9458. const xmlChar *targetNamespace)
  9459. {
  9460. xmlSchemaBucketPtr cur;
  9461. xmlSchemaItemListPtr list;
  9462. list = pctxt->constructor->buckets;
  9463. if (list->nbItems == 0)
  9464. return(NULL);
  9465. else {
  9466. int i;
  9467. for (i = 0; i < list->nbItems; i++) {
  9468. cur = (xmlSchemaBucketPtr) list->items[i];
  9469. /* Pointer comparison! */
  9470. if ((cur->origTargetNamespace == NULL) &&
  9471. (cur->schemaLocation == schemaLocation) &&
  9472. (cur->targetNamespace == targetNamespace))
  9473. return(cur);
  9474. }
  9475. }
  9476. return(NULL);
  9477. }
  9478. #define IS_BAD_SCHEMA_DOC(b) \
  9479. (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
  9480. static xmlSchemaBucketPtr
  9481. xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
  9482. const xmlChar *targetNamespace,
  9483. int imported)
  9484. {
  9485. xmlSchemaBucketPtr cur;
  9486. xmlSchemaItemListPtr list;
  9487. list = pctxt->constructor->buckets;
  9488. if (list->nbItems == 0)
  9489. return(NULL);
  9490. else {
  9491. int i;
  9492. for (i = 0; i < list->nbItems; i++) {
  9493. cur = (xmlSchemaBucketPtr) list->items[i];
  9494. if ((! IS_BAD_SCHEMA_DOC(cur)) &&
  9495. (cur->origTargetNamespace == targetNamespace) &&
  9496. ((imported && cur->imported) ||
  9497. ((!imported) && (!cur->imported))))
  9498. return(cur);
  9499. }
  9500. }
  9501. return(NULL);
  9502. }
  9503. static int
  9504. xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
  9505. xmlSchemaPtr schema,
  9506. xmlSchemaBucketPtr bucket)
  9507. {
  9508. int oldFlags;
  9509. xmlDocPtr oldDoc;
  9510. xmlNodePtr node;
  9511. int ret, oldErrs;
  9512. xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
  9513. /*
  9514. * Save old values; reset the *main* schema.
  9515. * URGENT TODO: This is not good; move the per-document information
  9516. * to the parser. Get rid of passing the main schema to the
  9517. * parsing functions.
  9518. */
  9519. oldFlags = schema->flags;
  9520. oldDoc = schema->doc;
  9521. if (schema->flags != 0)
  9522. xmlSchemaClearSchemaDefaults(schema);
  9523. schema->doc = bucket->doc;
  9524. pctxt->schema = schema;
  9525. /*
  9526. * Keep the current target namespace on the parser *not* on the
  9527. * main schema.
  9528. */
  9529. pctxt->targetNamespace = bucket->targetNamespace;
  9530. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  9531. if ((bucket->targetNamespace != NULL) &&
  9532. xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
  9533. /*
  9534. * We are parsing the schema for schemas!
  9535. */
  9536. pctxt->isS4S = 1;
  9537. }
  9538. /* Mark it as parsed, even if parsing fails. */
  9539. bucket->parsed++;
  9540. /* Compile the schema doc. */
  9541. node = xmlDocGetRootElement(bucket->doc);
  9542. ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
  9543. if (ret != 0)
  9544. goto exit;
  9545. /* An empty schema; just get out. */
  9546. if (node->children == NULL)
  9547. goto exit;
  9548. oldErrs = pctxt->nberrors;
  9549. ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
  9550. if (ret != 0)
  9551. goto exit;
  9552. /*
  9553. * TODO: Not nice, but I'm not 100% sure we will get always an error
  9554. * as a result of the above functions; so better rely on pctxt->err
  9555. * as well.
  9556. */
  9557. if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
  9558. ret = pctxt->err;
  9559. goto exit;
  9560. }
  9561. exit:
  9562. WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
  9563. /* Restore schema values. */
  9564. schema->doc = oldDoc;
  9565. schema->flags = oldFlags;
  9566. return(ret);
  9567. }
  9568. static int
  9569. xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
  9570. xmlSchemaPtr schema,
  9571. xmlSchemaBucketPtr bucket)
  9572. {
  9573. xmlSchemaParserCtxtPtr newpctxt;
  9574. int res = 0;
  9575. if (bucket == NULL)
  9576. return(0);
  9577. if (bucket->parsed) {
  9578. PERROR_INT("xmlSchemaParseNewDoc",
  9579. "reparsing a schema doc");
  9580. return(-1);
  9581. }
  9582. if (bucket->doc == NULL) {
  9583. PERROR_INT("xmlSchemaParseNewDoc",
  9584. "parsing a schema doc, but there's no doc");
  9585. return(-1);
  9586. }
  9587. if (pctxt->constructor == NULL) {
  9588. PERROR_INT("xmlSchemaParseNewDoc",
  9589. "no constructor");
  9590. return(-1);
  9591. }
  9592. /* Create and init the temporary parser context. */
  9593. newpctxt = xmlSchemaNewParserCtxtUseDict(
  9594. (const char *) bucket->schemaLocation, pctxt->dict);
  9595. if (newpctxt == NULL)
  9596. return(-1);
  9597. newpctxt->constructor = pctxt->constructor;
  9598. /*
  9599. * TODO: Can we avoid that the parser knows about the main schema?
  9600. * It would be better if he knows about the current schema bucket
  9601. * only.
  9602. */
  9603. newpctxt->schema = schema;
  9604. xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
  9605. pctxt->errCtxt);
  9606. xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
  9607. pctxt->errCtxt);
  9608. newpctxt->counter = pctxt->counter;
  9609. res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
  9610. /* Channel back errors and cleanup the temporary parser context. */
  9611. if (res != 0)
  9612. pctxt->err = res;
  9613. pctxt->nberrors += newpctxt->nberrors;
  9614. pctxt->counter = newpctxt->counter;
  9615. newpctxt->constructor = NULL;
  9616. /* Free the parser context. */
  9617. xmlSchemaFreeParserCtxt(newpctxt);
  9618. return(res);
  9619. }
  9620. static void
  9621. xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
  9622. xmlSchemaSchemaRelationPtr rel)
  9623. {
  9624. xmlSchemaSchemaRelationPtr cur = bucket->relations;
  9625. if (cur == NULL) {
  9626. bucket->relations = rel;
  9627. return;
  9628. }
  9629. while (cur->next != NULL)
  9630. cur = cur->next;
  9631. cur->next = rel;
  9632. }
  9633. static const xmlChar *
  9634. xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
  9635. xmlNodePtr ctxtNode)
  9636. {
  9637. /*
  9638. * Build an absolute location URI.
  9639. */
  9640. if (location != NULL) {
  9641. if (ctxtNode == NULL)
  9642. return(location);
  9643. else {
  9644. xmlChar *base, *URI;
  9645. const xmlChar *ret = NULL;
  9646. base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
  9647. if (base == NULL) {
  9648. URI = xmlBuildURI(location, ctxtNode->doc->URL);
  9649. } else {
  9650. URI = xmlBuildURI(location, base);
  9651. xmlFree(base);
  9652. }
  9653. if (URI != NULL) {
  9654. ret = xmlDictLookup(dict, URI, -1);
  9655. xmlFree(URI);
  9656. return(ret);
  9657. }
  9658. }
  9659. }
  9660. return(NULL);
  9661. }
  9662. /**
  9663. * xmlSchemaAddSchemaDoc:
  9664. * @pctxt: a schema validation context
  9665. * @schema: the schema being built
  9666. * @node: a subtree containing XML Schema information
  9667. *
  9668. * Parse an included (and to-be-redefined) XML schema document.
  9669. *
  9670. * Returns 0 on success, a positive error code on errors and
  9671. * -1 in case of an internal or API error.
  9672. */
  9673. static int
  9674. xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
  9675. int type, /* import or include or redefine */
  9676. const xmlChar *schemaLocation,
  9677. xmlDocPtr schemaDoc,
  9678. const char *schemaBuffer,
  9679. int schemaBufferLen,
  9680. xmlNodePtr invokingNode,
  9681. const xmlChar *sourceTargetNamespace,
  9682. const xmlChar *importNamespace,
  9683. xmlSchemaBucketPtr *bucket)
  9684. {
  9685. const xmlChar *targetNamespace = NULL;
  9686. xmlSchemaSchemaRelationPtr relation = NULL;
  9687. xmlDocPtr doc = NULL;
  9688. int res = 0, err = 0, located = 0, preserveDoc = 0;
  9689. xmlSchemaBucketPtr bkt = NULL;
  9690. if (bucket != NULL)
  9691. *bucket = NULL;
  9692. switch (type) {
  9693. case XML_SCHEMA_SCHEMA_IMPORT:
  9694. case XML_SCHEMA_SCHEMA_MAIN:
  9695. err = XML_SCHEMAP_SRC_IMPORT;
  9696. break;
  9697. case XML_SCHEMA_SCHEMA_INCLUDE:
  9698. err = XML_SCHEMAP_SRC_INCLUDE;
  9699. break;
  9700. case XML_SCHEMA_SCHEMA_REDEFINE:
  9701. err = XML_SCHEMAP_SRC_REDEFINE;
  9702. break;
  9703. }
  9704. /* Special handling for the main schema:
  9705. * skip the location and relation logic and just parse the doc.
  9706. * We need just a bucket to be returned in this case.
  9707. */
  9708. if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
  9709. goto doc_load;
  9710. /* Note that we expect the location to be an absolute URI. */
  9711. if (schemaLocation != NULL) {
  9712. bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
  9713. if ((bkt != NULL) &&
  9714. (pctxt->constructor->bucket == bkt)) {
  9715. /* Report self-imports/inclusions/redefinitions. */
  9716. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9717. invokingNode, NULL,
  9718. "The schema must not import/include/redefine itself",
  9719. NULL, NULL);
  9720. goto exit;
  9721. }
  9722. }
  9723. /*
  9724. * Create a relation for the graph of schemas.
  9725. */
  9726. relation = xmlSchemaSchemaRelationCreate();
  9727. if (relation == NULL)
  9728. return(-1);
  9729. xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
  9730. relation);
  9731. relation->type = type;
  9732. /*
  9733. * Save the namespace import information.
  9734. */
  9735. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9736. relation->importNamespace = importNamespace;
  9737. if (schemaLocation == NULL) {
  9738. /*
  9739. * No location; this is just an import of the namespace.
  9740. * Note that we don't assign a bucket to the relation
  9741. * in this case.
  9742. */
  9743. goto exit;
  9744. }
  9745. targetNamespace = importNamespace;
  9746. }
  9747. /* Did we already fetch the doc? */
  9748. if (bkt != NULL) {
  9749. if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
  9750. /*
  9751. * We included/redefined and then try to import a schema,
  9752. * but the new location provided for import was different.
  9753. */
  9754. if (schemaLocation == NULL)
  9755. schemaLocation = BAD_CAST "in_memory_buffer";
  9756. if (!xmlStrEqual(schemaLocation,
  9757. bkt->schemaLocation)) {
  9758. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9759. invokingNode, NULL,
  9760. "The schema document '%s' cannot be imported, since "
  9761. "it was already included or redefined",
  9762. schemaLocation, NULL);
  9763. goto exit;
  9764. }
  9765. } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
  9766. /*
  9767. * We imported and then try to include/redefine a schema,
  9768. * but the new location provided for the include/redefine
  9769. * was different.
  9770. */
  9771. if (schemaLocation == NULL)
  9772. schemaLocation = BAD_CAST "in_memory_buffer";
  9773. if (!xmlStrEqual(schemaLocation,
  9774. bkt->schemaLocation)) {
  9775. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9776. invokingNode, NULL,
  9777. "The schema document '%s' cannot be included or "
  9778. "redefined, since it was already imported",
  9779. schemaLocation, NULL);
  9780. goto exit;
  9781. }
  9782. }
  9783. }
  9784. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9785. /*
  9786. * Given that the schemaLocation [attribute] is only a hint, it is open
  9787. * to applications to ignore all but the first <import> for a given
  9788. * namespace, regardless of the `actual value` of schemaLocation, but
  9789. * such a strategy risks missing useful information when new
  9790. * schemaLocations are offered.
  9791. *
  9792. * We will use the first <import> that comes with a location.
  9793. * Further <import>s *with* a location, will result in an error.
  9794. * TODO: Better would be to just report a warning here, but
  9795. * we'll try it this way until someone complains.
  9796. *
  9797. * Schema Document Location Strategy:
  9798. * 3 Based on the namespace name, identify an existing schema document,
  9799. * either as a resource which is an XML document or a <schema> element
  9800. * information item, in some local schema repository;
  9801. * 5 Attempt to resolve the namespace name to locate such a resource.
  9802. *
  9803. * NOTE: (3) and (5) are not supported.
  9804. */
  9805. if (bkt != NULL) {
  9806. relation->bucket = bkt;
  9807. goto exit;
  9808. }
  9809. bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
  9810. importNamespace, 1);
  9811. if (bkt != NULL) {
  9812. relation->bucket = bkt;
  9813. if (bkt->schemaLocation == NULL) {
  9814. /* First given location of the schema; load the doc. */
  9815. bkt->schemaLocation = schemaLocation;
  9816. } else {
  9817. if (!xmlStrEqual(schemaLocation,
  9818. bkt->schemaLocation)) {
  9819. /*
  9820. * Additional location given; just skip it.
  9821. * URGENT TODO: We should report a warning here.
  9822. * res = XML_SCHEMAP_SRC_IMPORT;
  9823. */
  9824. if (schemaLocation == NULL)
  9825. schemaLocation = BAD_CAST "in_memory_buffer";
  9826. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  9827. XML_SCHEMAP_WARN_SKIP_SCHEMA,
  9828. invokingNode, NULL,
  9829. "Skipping import of schema located at '%s' for the "
  9830. "namespace '%s', since this namespace was already "
  9831. "imported with the schema located at '%s'",
  9832. schemaLocation, importNamespace, bkt->schemaLocation);
  9833. }
  9834. goto exit;
  9835. }
  9836. }
  9837. /*
  9838. * No bucket + first location: load the doc and create a
  9839. * bucket.
  9840. */
  9841. } else {
  9842. /* <include> and <redefine> */
  9843. if (bkt != NULL) {
  9844. if ((bkt->origTargetNamespace == NULL) &&
  9845. (bkt->targetNamespace != sourceTargetNamespace)) {
  9846. xmlSchemaBucketPtr chamel;
  9847. /*
  9848. * Chameleon include/redefine: skip loading only if it was
  9849. * already build for the targetNamespace of the including
  9850. * schema.
  9851. */
  9852. /*
  9853. * URGENT TODO: If the schema is a chameleon-include then copy
  9854. * the components into the including schema and modify the
  9855. * targetNamespace of those components, do nothing otherwise.
  9856. * NOTE: This is currently worked-around by compiling the
  9857. * chameleon for every distinct including targetNamespace; thus
  9858. * not performant at the moment.
  9859. * TODO: Check when the namespace in wildcards for chameleons
  9860. * needs to be converted: before we built wildcard intersections
  9861. * or after.
  9862. * Answer: after!
  9863. */
  9864. chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
  9865. schemaLocation, sourceTargetNamespace);
  9866. if (chamel != NULL) {
  9867. /* A fitting chameleon was already parsed; NOP. */
  9868. relation->bucket = chamel;
  9869. goto exit;
  9870. }
  9871. /*
  9872. * We need to parse the chameleon again for a different
  9873. * targetNamespace.
  9874. * CHAMELEON TODO: Optimize this by only parsing the
  9875. * chameleon once, and then copying the components to
  9876. * the new targetNamespace.
  9877. */
  9878. bkt = NULL;
  9879. } else {
  9880. relation->bucket = bkt;
  9881. goto exit;
  9882. }
  9883. }
  9884. }
  9885. if ((bkt != NULL) && (bkt->doc != NULL)) {
  9886. PERROR_INT("xmlSchemaAddSchemaDoc",
  9887. "trying to load a schema doc, but a doc is already "
  9888. "assigned to the schema bucket");
  9889. goto exit_failure;
  9890. }
  9891. doc_load:
  9892. /*
  9893. * Load the document.
  9894. */
  9895. if (schemaDoc != NULL) {
  9896. doc = schemaDoc;
  9897. /* Don' free this one, since it was provided by the caller. */
  9898. preserveDoc = 1;
  9899. /* TODO: Does the context or the doc hold the location? */
  9900. if (schemaDoc->URL != NULL)
  9901. schemaLocation = xmlDictLookup(pctxt->dict,
  9902. schemaDoc->URL, -1);
  9903. else
  9904. schemaLocation = BAD_CAST "in_memory_buffer";
  9905. } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
  9906. xmlParserCtxtPtr parserCtxt;
  9907. parserCtxt = xmlNewParserCtxt();
  9908. if (parserCtxt == NULL) {
  9909. xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
  9910. "allocating a parser context", NULL);
  9911. goto exit_failure;
  9912. }
  9913. if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
  9914. /*
  9915. * TODO: Do we have to burden the schema parser dict with all
  9916. * the content of the schema doc?
  9917. */
  9918. xmlDictFree(parserCtxt->dict);
  9919. parserCtxt->dict = pctxt->dict;
  9920. xmlDictReference(parserCtxt->dict);
  9921. }
  9922. if (schemaLocation != NULL) {
  9923. /* Parse from file. */
  9924. doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
  9925. NULL, SCHEMAS_PARSE_OPTIONS);
  9926. } else if (schemaBuffer != NULL) {
  9927. /* Parse from memory buffer. */
  9928. doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
  9929. NULL, NULL, SCHEMAS_PARSE_OPTIONS);
  9930. schemaLocation = BAD_CAST "in_memory_buffer";
  9931. if (doc != NULL)
  9932. doc->URL = xmlStrdup(schemaLocation);
  9933. }
  9934. /*
  9935. * For <import>:
  9936. * 2.1 The referent is (a fragment of) a resource which is an
  9937. * XML document (see clause 1.1), which in turn corresponds to
  9938. * a <schema> element information item in a well-formed information
  9939. * set, which in turn corresponds to a valid schema.
  9940. * TODO: (2.1) fragments of XML documents are not supported.
  9941. *
  9942. * 2.2 The referent is a <schema> element information item in
  9943. * a well-formed information set, which in turn corresponds
  9944. * to a valid schema.
  9945. * TODO: (2.2) is not supported.
  9946. */
  9947. if (doc == NULL) {
  9948. xmlErrorPtr lerr;
  9949. lerr = xmlGetLastError();
  9950. /*
  9951. * Check if this a parser error, or if the document could
  9952. * just not be located.
  9953. * TODO: Try to find specific error codes to react only on
  9954. * localisation failures.
  9955. */
  9956. if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
  9957. /*
  9958. * We assume a parser error here.
  9959. */
  9960. located = 1;
  9961. /* TODO: Error code ?? */
  9962. res = XML_SCHEMAP_SRC_IMPORT_2_1;
  9963. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  9964. invokingNode, NULL,
  9965. "Failed to parse the XML resource '%s'",
  9966. schemaLocation, NULL);
  9967. }
  9968. }
  9969. xmlFreeParserCtxt(parserCtxt);
  9970. if ((doc == NULL) && located)
  9971. goto exit_error;
  9972. } else {
  9973. xmlSchemaPErr(pctxt, NULL,
  9974. XML_SCHEMAP_NOTHING_TO_PARSE,
  9975. "No information for parsing was provided with the "
  9976. "given schema parser context.\n",
  9977. NULL, NULL);
  9978. goto exit_failure;
  9979. }
  9980. /*
  9981. * Preprocess the document.
  9982. */
  9983. if (doc != NULL) {
  9984. xmlNodePtr docElem = NULL;
  9985. located = 1;
  9986. docElem = xmlDocGetRootElement(doc);
  9987. if (docElem == NULL) {
  9988. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
  9989. invokingNode, NULL,
  9990. "The document '%s' has no document element",
  9991. schemaLocation, NULL);
  9992. goto exit_error;
  9993. }
  9994. /*
  9995. * Remove all the blank text nodes.
  9996. */
  9997. xmlSchemaCleanupDoc(pctxt, docElem);
  9998. /*
  9999. * Check the schema's top level element.
  10000. */
  10001. if (!IS_SCHEMA(docElem, "schema")) {
  10002. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
  10003. invokingNode, NULL,
  10004. "The XML document '%s' is not a schema document",
  10005. schemaLocation, NULL);
  10006. goto exit_error;
  10007. }
  10008. /*
  10009. * Note that we don't apply a type check for the
  10010. * targetNamespace value here.
  10011. */
  10012. targetNamespace = xmlSchemaGetProp(pctxt, docElem,
  10013. "targetNamespace");
  10014. }
  10015. /* after_doc_loading: */
  10016. if ((bkt == NULL) && located) {
  10017. /* Only create a bucket if the schema was located. */
  10018. bkt = xmlSchemaBucketCreate(pctxt, type,
  10019. targetNamespace);
  10020. if (bkt == NULL)
  10021. goto exit_failure;
  10022. }
  10023. if (bkt != NULL) {
  10024. bkt->schemaLocation = schemaLocation;
  10025. bkt->located = located;
  10026. if (doc != NULL) {
  10027. bkt->doc = doc;
  10028. bkt->targetNamespace = targetNamespace;
  10029. bkt->origTargetNamespace = targetNamespace;
  10030. if (preserveDoc)
  10031. bkt->preserveDoc = 1;
  10032. }
  10033. if (WXS_IS_BUCKET_IMPMAIN(type))
  10034. bkt->imported++;
  10035. /*
  10036. * Add it to the graph of schemas.
  10037. */
  10038. if (relation != NULL)
  10039. relation->bucket = bkt;
  10040. }
  10041. exit:
  10042. /*
  10043. * Return the bucket explicitly; this is needed for the
  10044. * main schema.
  10045. */
  10046. if (bucket != NULL)
  10047. *bucket = bkt;
  10048. return (0);
  10049. exit_error:
  10050. if ((doc != NULL) && (! preserveDoc)) {
  10051. xmlFreeDoc(doc);
  10052. if (bkt != NULL)
  10053. bkt->doc = NULL;
  10054. }
  10055. return(pctxt->err);
  10056. exit_failure:
  10057. if ((doc != NULL) && (! preserveDoc)) {
  10058. xmlFreeDoc(doc);
  10059. if (bkt != NULL)
  10060. bkt->doc = NULL;
  10061. }
  10062. return (-1);
  10063. }
  10064. /**
  10065. * xmlSchemaParseImport:
  10066. * @ctxt: a schema validation context
  10067. * @schema: the schema being built
  10068. * @node: a subtree containing XML Schema information
  10069. *
  10070. * parse a XML schema Import definition
  10071. * *WARNING* this interface is highly subject to change
  10072. *
  10073. * Returns 0 in case of success, a positive error code if
  10074. * not valid and -1 in case of an internal error.
  10075. */
  10076. static int
  10077. xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10078. xmlNodePtr node)
  10079. {
  10080. xmlNodePtr child;
  10081. const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
  10082. const xmlChar *thisTargetNamespace;
  10083. xmlAttrPtr attr;
  10084. int ret = 0;
  10085. xmlSchemaBucketPtr bucket = NULL;
  10086. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  10087. return (-1);
  10088. /*
  10089. * Check for illegal attributes.
  10090. */
  10091. attr = node->properties;
  10092. while (attr != NULL) {
  10093. if (attr->ns == NULL) {
  10094. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10095. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  10096. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  10097. xmlSchemaPIllegalAttrErr(pctxt,
  10098. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10099. }
  10100. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10101. xmlSchemaPIllegalAttrErr(pctxt,
  10102. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10103. }
  10104. attr = attr->next;
  10105. }
  10106. /*
  10107. * Extract and validate attributes.
  10108. */
  10109. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10110. "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10111. &namespaceName) != 0) {
  10112. xmlSchemaPSimpleTypeErr(pctxt,
  10113. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10114. NULL, node,
  10115. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10116. NULL, namespaceName, NULL, NULL, NULL);
  10117. return (pctxt->err);
  10118. }
  10119. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10120. "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10121. &schemaLocation) != 0) {
  10122. xmlSchemaPSimpleTypeErr(pctxt,
  10123. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10124. NULL, node,
  10125. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10126. NULL, schemaLocation, NULL, NULL, NULL);
  10127. return (pctxt->err);
  10128. }
  10129. /*
  10130. * And now for the children...
  10131. */
  10132. child = node->children;
  10133. if (IS_SCHEMA(child, "annotation")) {
  10134. /*
  10135. * the annotation here is simply discarded ...
  10136. * TODO: really?
  10137. */
  10138. child = child->next;
  10139. }
  10140. if (child != NULL) {
  10141. xmlSchemaPContentErr(pctxt,
  10142. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10143. NULL, node, child, NULL,
  10144. "(annotation?)");
  10145. }
  10146. /*
  10147. * Apply additional constraints.
  10148. *
  10149. * Note that it is important to use the original @targetNamespace
  10150. * (or none at all), to rule out imports of schemas _with_ a
  10151. * @targetNamespace if the importing schema is a chameleon schema
  10152. * (with no @targetNamespace).
  10153. */
  10154. thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
  10155. if (namespaceName != NULL) {
  10156. /*
  10157. * 1.1 If the namespace [attribute] is present, then its `actual value`
  10158. * must not match the `actual value` of the enclosing <schema>'s
  10159. * targetNamespace [attribute].
  10160. */
  10161. if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
  10162. xmlSchemaPCustomErr(pctxt,
  10163. XML_SCHEMAP_SRC_IMPORT_1_1,
  10164. NULL, node,
  10165. "The value of the attribute 'namespace' must not match "
  10166. "the target namespace '%s' of the importing schema",
  10167. thisTargetNamespace);
  10168. return (pctxt->err);
  10169. }
  10170. } else {
  10171. /*
  10172. * 1.2 If the namespace [attribute] is not present, then the enclosing
  10173. * <schema> must have a targetNamespace [attribute].
  10174. */
  10175. if (thisTargetNamespace == NULL) {
  10176. xmlSchemaPCustomErr(pctxt,
  10177. XML_SCHEMAP_SRC_IMPORT_1_2,
  10178. NULL, node,
  10179. "The attribute 'namespace' must be existent if "
  10180. "the importing schema has no target namespace",
  10181. NULL);
  10182. return (pctxt->err);
  10183. }
  10184. }
  10185. /*
  10186. * Locate and acquire the schema document.
  10187. */
  10188. if (schemaLocation != NULL)
  10189. schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  10190. schemaLocation, node);
  10191. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  10192. schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
  10193. namespaceName, &bucket);
  10194. if (ret != 0)
  10195. return(ret);
  10196. /*
  10197. * For <import>: "It is *not* an error for the application
  10198. * schema reference strategy to fail."
  10199. * So just don't parse if no schema document was found.
  10200. * Note that we will get no bucket if the schema could not be
  10201. * located or if there was no schemaLocation.
  10202. */
  10203. if ((bucket == NULL) && (schemaLocation != NULL)) {
  10204. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  10205. XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
  10206. node, NULL,
  10207. "Failed to locate a schema at location '%s'. "
  10208. "Skipping the import", schemaLocation, NULL, NULL);
  10209. }
  10210. if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
  10211. ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10212. }
  10213. return (ret);
  10214. }
  10215. static int
  10216. xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
  10217. xmlSchemaPtr schema,
  10218. xmlNodePtr node,
  10219. xmlChar **schemaLocation,
  10220. int type)
  10221. {
  10222. xmlAttrPtr attr;
  10223. if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
  10224. (schemaLocation == NULL))
  10225. return (-1);
  10226. *schemaLocation = NULL;
  10227. /*
  10228. * Check for illegal attributes.
  10229. * Applies for both <include> and <redefine>.
  10230. */
  10231. attr = node->properties;
  10232. while (attr != NULL) {
  10233. if (attr->ns == NULL) {
  10234. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10235. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  10236. xmlSchemaPIllegalAttrErr(pctxt,
  10237. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10238. }
  10239. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10240. xmlSchemaPIllegalAttrErr(pctxt,
  10241. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10242. }
  10243. attr = attr->next;
  10244. }
  10245. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  10246. /*
  10247. * Preliminary step, extract the URI-Reference and make an URI
  10248. * from the base.
  10249. */
  10250. /*
  10251. * Attribute "schemaLocation" is mandatory.
  10252. */
  10253. attr = xmlSchemaGetPropNode(node, "schemaLocation");
  10254. if (attr != NULL) {
  10255. xmlChar *base = NULL;
  10256. xmlChar *uri = NULL;
  10257. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  10258. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10259. (const xmlChar **) schemaLocation) != 0)
  10260. goto exit_error;
  10261. base = xmlNodeGetBase(node->doc, node);
  10262. if (base == NULL) {
  10263. uri = xmlBuildURI(*schemaLocation, node->doc->URL);
  10264. } else {
  10265. uri = xmlBuildURI(*schemaLocation, base);
  10266. xmlFree(base);
  10267. }
  10268. if (uri == NULL) {
  10269. PERROR_INT("xmlSchemaParseIncludeOrRedefine",
  10270. "could not build an URI from the schemaLocation")
  10271. goto exit_failure;
  10272. }
  10273. (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
  10274. xmlFree(uri);
  10275. } else {
  10276. xmlSchemaPMissingAttrErr(pctxt,
  10277. XML_SCHEMAP_S4S_ATTR_MISSING,
  10278. NULL, node, "schemaLocation", NULL);
  10279. goto exit_error;
  10280. }
  10281. /*
  10282. * Report self-inclusion and self-redefinition.
  10283. */
  10284. if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
  10285. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10286. xmlSchemaPCustomErr(pctxt,
  10287. XML_SCHEMAP_SRC_REDEFINE,
  10288. NULL, node,
  10289. "The schema document '%s' cannot redefine itself.",
  10290. *schemaLocation);
  10291. } else {
  10292. xmlSchemaPCustomErr(pctxt,
  10293. XML_SCHEMAP_SRC_INCLUDE,
  10294. NULL, node,
  10295. "The schema document '%s' cannot include itself.",
  10296. *schemaLocation);
  10297. }
  10298. goto exit_error;
  10299. }
  10300. return(0);
  10301. exit_error:
  10302. return(pctxt->err);
  10303. exit_failure:
  10304. return(-1);
  10305. }
  10306. static int
  10307. xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
  10308. xmlSchemaPtr schema,
  10309. xmlNodePtr node,
  10310. int type)
  10311. {
  10312. xmlNodePtr child = NULL;
  10313. const xmlChar *schemaLocation = NULL;
  10314. int res = 0; /* hasRedefinitions = 0 */
  10315. int isChameleon = 0, wasChameleon = 0;
  10316. xmlSchemaBucketPtr bucket = NULL;
  10317. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  10318. return (-1);
  10319. /*
  10320. * Parse attributes. Note that the returned schemaLocation will
  10321. * be already converted to an absolute URI.
  10322. */
  10323. res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
  10324. node, (xmlChar **) (&schemaLocation), type);
  10325. if (res != 0)
  10326. return(res);
  10327. /*
  10328. * Load and add the schema document.
  10329. */
  10330. res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
  10331. NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
  10332. if (res != 0)
  10333. return(res);
  10334. /*
  10335. * If we get no schema bucket back, then this means that the schema
  10336. * document could not be located or was broken XML or was not
  10337. * a schema document.
  10338. */
  10339. if ((bucket == NULL) || (bucket->doc == NULL)) {
  10340. if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
  10341. /*
  10342. * WARNING for <include>:
  10343. * We will raise an error if the schema cannot be located
  10344. * for inclusions, since the that was the feedback from the
  10345. * schema people. I.e. the following spec piece will *not* be
  10346. * satisfied:
  10347. * SPEC src-include: "It is not an error for the `actual value` of the
  10348. * schemaLocation [attribute] to fail to resolve it all, in which
  10349. * case no corresponding inclusion is performed.
  10350. * So do we need a warning report here?"
  10351. */
  10352. res = XML_SCHEMAP_SRC_INCLUDE;
  10353. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10354. node, NULL,
  10355. "Failed to load the document '%s' for inclusion",
  10356. schemaLocation, NULL);
  10357. } else {
  10358. /*
  10359. * NOTE: This was changed to raise an error even if no redefinitions
  10360. * are specified.
  10361. *
  10362. * SPEC src-redefine (1)
  10363. * "If there are any element information items among the [children]
  10364. * other than <annotation> then the `actual value` of the
  10365. * schemaLocation [attribute] must successfully resolve."
  10366. * TODO: Ask the WG if a the location has always to resolve
  10367. * here as well!
  10368. */
  10369. res = XML_SCHEMAP_SRC_REDEFINE;
  10370. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10371. node, NULL,
  10372. "Failed to load the document '%s' for redefinition",
  10373. schemaLocation, NULL);
  10374. }
  10375. } else {
  10376. /*
  10377. * Check targetNamespace sanity before parsing the new schema.
  10378. * TODO: Note that we won't check further content if the
  10379. * targetNamespace was bad.
  10380. */
  10381. if (bucket->origTargetNamespace != NULL) {
  10382. /*
  10383. * SPEC src-include (2.1)
  10384. * "SII has a targetNamespace [attribute], and its `actual
  10385. * value` is identical to the `actual value` of the targetNamespace
  10386. * [attribute] of SII' (which must have such an [attribute])."
  10387. */
  10388. if (pctxt->targetNamespace == NULL) {
  10389. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  10390. XML_SCHEMAP_SRC_INCLUDE,
  10391. node, NULL,
  10392. "The target namespace of the included/redefined schema "
  10393. "'%s' has to be absent, since the including/redefining "
  10394. "schema has no target namespace",
  10395. schemaLocation, NULL);
  10396. goto exit_error;
  10397. } else if (!xmlStrEqual(bucket->origTargetNamespace,
  10398. pctxt->targetNamespace)) {
  10399. /* TODO: Change error function. */
  10400. xmlSchemaPCustomErrExt(pctxt,
  10401. XML_SCHEMAP_SRC_INCLUDE,
  10402. NULL, node,
  10403. "The target namespace '%s' of the included/redefined "
  10404. "schema '%s' differs from '%s' of the "
  10405. "including/redefining schema",
  10406. bucket->origTargetNamespace, schemaLocation,
  10407. pctxt->targetNamespace);
  10408. goto exit_error;
  10409. }
  10410. } else if (pctxt->targetNamespace != NULL) {
  10411. /*
  10412. * Chameleons: the original target namespace will
  10413. * differ from the resulting namespace.
  10414. */
  10415. isChameleon = 1;
  10416. if (bucket->parsed &&
  10417. bucket->origTargetNamespace != NULL) {
  10418. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  10419. XML_SCHEMAP_SRC_INCLUDE,
  10420. node, NULL,
  10421. "The target namespace of the included/redefined schema "
  10422. "'%s' has to be absent or the same as the "
  10423. "including/redefining schema's target namespace",
  10424. schemaLocation, NULL);
  10425. goto exit_error;
  10426. }
  10427. bucket->targetNamespace = pctxt->targetNamespace;
  10428. }
  10429. }
  10430. /*
  10431. * Parse the schema.
  10432. */
  10433. if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
  10434. if (isChameleon) {
  10435. /* TODO: Get rid of this flag on the schema itself. */
  10436. if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
  10437. schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10438. } else
  10439. wasChameleon = 1;
  10440. }
  10441. xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10442. /* Restore chameleon flag. */
  10443. if (isChameleon && (!wasChameleon))
  10444. schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10445. }
  10446. /*
  10447. * And now for the children...
  10448. */
  10449. child = node->children;
  10450. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10451. /*
  10452. * Parse (simpleType | complexType | group | attributeGroup))*
  10453. */
  10454. pctxt->redefined = bucket;
  10455. /*
  10456. * How to proceed if the redefined schema was not located?
  10457. */
  10458. pctxt->isRedefine = 1;
  10459. while (IS_SCHEMA(child, "annotation") ||
  10460. IS_SCHEMA(child, "simpleType") ||
  10461. IS_SCHEMA(child, "complexType") ||
  10462. IS_SCHEMA(child, "group") ||
  10463. IS_SCHEMA(child, "attributeGroup")) {
  10464. if (IS_SCHEMA(child, "annotation")) {
  10465. /*
  10466. * TODO: discard or not?
  10467. */
  10468. } else if (IS_SCHEMA(child, "simpleType")) {
  10469. xmlSchemaParseSimpleType(pctxt, schema, child, 1);
  10470. } else if (IS_SCHEMA(child, "complexType")) {
  10471. xmlSchemaParseComplexType(pctxt, schema, child, 1);
  10472. /* hasRedefinitions = 1; */
  10473. } else if (IS_SCHEMA(child, "group")) {
  10474. /* hasRedefinitions = 1; */
  10475. xmlSchemaParseModelGroupDefinition(pctxt,
  10476. schema, child);
  10477. } else if (IS_SCHEMA(child, "attributeGroup")) {
  10478. /* hasRedefinitions = 1; */
  10479. xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
  10480. child);
  10481. }
  10482. child = child->next;
  10483. }
  10484. pctxt->redefined = NULL;
  10485. pctxt->isRedefine = 0;
  10486. } else {
  10487. if (IS_SCHEMA(child, "annotation")) {
  10488. /*
  10489. * TODO: discard or not?
  10490. */
  10491. child = child->next;
  10492. }
  10493. }
  10494. if (child != NULL) {
  10495. res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
  10496. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10497. xmlSchemaPContentErr(pctxt, res,
  10498. NULL, node, child, NULL,
  10499. "(annotation | (simpleType | complexType | group | attributeGroup))*");
  10500. } else {
  10501. xmlSchemaPContentErr(pctxt, res,
  10502. NULL, node, child, NULL,
  10503. "(annotation?)");
  10504. }
  10505. }
  10506. return(res);
  10507. exit_error:
  10508. return(pctxt->err);
  10509. }
  10510. static int
  10511. xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10512. xmlNodePtr node)
  10513. {
  10514. int res;
  10515. #ifndef ENABLE_REDEFINE
  10516. TODO
  10517. return(0);
  10518. #endif
  10519. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10520. XML_SCHEMA_SCHEMA_REDEFINE);
  10521. if (res != 0)
  10522. return(res);
  10523. return(0);
  10524. }
  10525. static int
  10526. xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10527. xmlNodePtr node)
  10528. {
  10529. int res;
  10530. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10531. XML_SCHEMA_SCHEMA_INCLUDE);
  10532. if (res != 0)
  10533. return(res);
  10534. return(0);
  10535. }
  10536. /**
  10537. * xmlSchemaParseModelGroup:
  10538. * @ctxt: a schema validation context
  10539. * @schema: the schema being built
  10540. * @node: a subtree containing XML Schema information
  10541. * @type: the "compositor" type
  10542. * @particleNeeded: if a a model group with a particle
  10543. *
  10544. * parse a XML schema Sequence definition.
  10545. * Applies parts of:
  10546. * Schema Representation Constraint:
  10547. * Redefinition Constraints and Semantics (src-redefine)
  10548. * (6.1), (6.1.1), (6.1.2)
  10549. *
  10550. * Schema Component Constraint:
  10551. * All Group Limited (cos-all-limited) (2)
  10552. * TODO: Actually this should go to component-level checks,
  10553. * but is done here due to performance. Move it to an other layer
  10554. * is schema construction via an API is implemented.
  10555. *
  10556. * *WARNING* this interface is highly subject to change
  10557. *
  10558. * Returns -1 in case of error, 0 if the declaration is improper and
  10559. * 1 in case of success.
  10560. */
  10561. static xmlSchemaTreeItemPtr
  10562. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10563. xmlNodePtr node, xmlSchemaTypeType type,
  10564. int withParticle)
  10565. {
  10566. xmlSchemaModelGroupPtr item;
  10567. xmlSchemaParticlePtr particle = NULL;
  10568. xmlNodePtr child = NULL;
  10569. xmlAttrPtr attr;
  10570. int min = 1, max = 1, isElemRef, hasRefs = 0;
  10571. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10572. return (NULL);
  10573. /*
  10574. * Create a model group with the given compositor.
  10575. */
  10576. item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
  10577. if (item == NULL)
  10578. return (NULL);
  10579. if (withParticle) {
  10580. if (type == XML_SCHEMA_TYPE_ALL) {
  10581. min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
  10582. max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
  10583. } else {
  10584. /* choice + sequence */
  10585. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  10586. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  10587. "(xs:nonNegativeInteger | unbounded)");
  10588. }
  10589. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  10590. /*
  10591. * Create a particle
  10592. */
  10593. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  10594. if (particle == NULL)
  10595. return (NULL);
  10596. particle->children = (xmlSchemaTreeItemPtr) item;
  10597. /*
  10598. * Check for illegal attributes.
  10599. */
  10600. attr = node->properties;
  10601. while (attr != NULL) {
  10602. if (attr->ns == NULL) {
  10603. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10604. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  10605. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
  10606. xmlSchemaPIllegalAttrErr(ctxt,
  10607. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10608. }
  10609. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10610. xmlSchemaPIllegalAttrErr(ctxt,
  10611. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10612. }
  10613. attr = attr->next;
  10614. }
  10615. } else {
  10616. /*
  10617. * Check for illegal attributes.
  10618. */
  10619. attr = node->properties;
  10620. while (attr != NULL) {
  10621. if (attr->ns == NULL) {
  10622. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  10623. xmlSchemaPIllegalAttrErr(ctxt,
  10624. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10625. }
  10626. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10627. xmlSchemaPIllegalAttrErr(ctxt,
  10628. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10629. }
  10630. attr = attr->next;
  10631. }
  10632. }
  10633. /*
  10634. * Extract and validate attributes.
  10635. */
  10636. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10637. /*
  10638. * And now for the children...
  10639. */
  10640. child = node->children;
  10641. if (IS_SCHEMA(child, "annotation")) {
  10642. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  10643. child = child->next;
  10644. }
  10645. if (type == XML_SCHEMA_TYPE_ALL) {
  10646. xmlSchemaParticlePtr part, last = NULL;
  10647. while (IS_SCHEMA(child, "element")) {
  10648. part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
  10649. schema, child, &isElemRef, 0);
  10650. /*
  10651. * SPEC cos-all-limited (2)
  10652. * "The {max occurs} of all the particles in the {particles}
  10653. * of the ('all') group must be 0 or 1.
  10654. */
  10655. if (part != NULL) {
  10656. if (isElemRef)
  10657. hasRefs++;
  10658. if (part->minOccurs > 1) {
  10659. xmlSchemaPCustomErr(ctxt,
  10660. XML_SCHEMAP_COS_ALL_LIMITED,
  10661. NULL, child,
  10662. "Invalid value for minOccurs (must be 0 or 1)",
  10663. NULL);
  10664. /* Reset to 1. */
  10665. part->minOccurs = 1;
  10666. }
  10667. if (part->maxOccurs > 1) {
  10668. xmlSchemaPCustomErr(ctxt,
  10669. XML_SCHEMAP_COS_ALL_LIMITED,
  10670. NULL, child,
  10671. "Invalid value for maxOccurs (must be 0 or 1)",
  10672. NULL);
  10673. /* Reset to 1. */
  10674. part->maxOccurs = 1;
  10675. }
  10676. if (last == NULL)
  10677. item->children = (xmlSchemaTreeItemPtr) part;
  10678. else
  10679. last->next = (xmlSchemaTreeItemPtr) part;
  10680. last = part;
  10681. }
  10682. child = child->next;
  10683. }
  10684. if (child != NULL) {
  10685. xmlSchemaPContentErr(ctxt,
  10686. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10687. NULL, node, child, NULL,
  10688. "(annotation?, (annotation?, element*)");
  10689. }
  10690. } else {
  10691. /* choice + sequence */
  10692. xmlSchemaTreeItemPtr part = NULL, last = NULL;
  10693. while ((IS_SCHEMA(child, "element")) ||
  10694. (IS_SCHEMA(child, "group")) ||
  10695. (IS_SCHEMA(child, "any")) ||
  10696. (IS_SCHEMA(child, "choice")) ||
  10697. (IS_SCHEMA(child, "sequence"))) {
  10698. if (IS_SCHEMA(child, "element")) {
  10699. part = (xmlSchemaTreeItemPtr)
  10700. xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
  10701. if (part && isElemRef)
  10702. hasRefs++;
  10703. } else if (IS_SCHEMA(child, "group")) {
  10704. part =
  10705. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10706. if (part != NULL)
  10707. hasRefs++;
  10708. /*
  10709. * Handle redefinitions.
  10710. */
  10711. if (ctxt->isRedefine && ctxt->redef &&
  10712. (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
  10713. part && part->children)
  10714. {
  10715. if ((xmlSchemaGetQNameRefName(part->children) ==
  10716. ctxt->redef->refName) &&
  10717. (xmlSchemaGetQNameRefTargetNs(part->children) ==
  10718. ctxt->redef->refTargetNs))
  10719. {
  10720. /*
  10721. * SPEC src-redefine:
  10722. * (6.1) "If it has a <group> among its contents at
  10723. * some level the `actual value` of whose ref
  10724. * [attribute] is the same as the `actual value` of
  10725. * its own name attribute plus target namespace, then
  10726. * all of the following must be true:"
  10727. * (6.1.1) "It must have exactly one such group."
  10728. */
  10729. if (ctxt->redefCounter != 0) {
  10730. xmlChar *str = NULL;
  10731. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10732. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10733. "The redefining model group definition "
  10734. "'%s' must not contain more than one "
  10735. "reference to the redefined definition",
  10736. xmlSchemaFormatQName(&str,
  10737. ctxt->redef->refTargetNs,
  10738. ctxt->redef->refName),
  10739. NULL);
  10740. FREE_AND_NULL(str)
  10741. part = NULL;
  10742. } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
  10743. ((WXS_PARTICLE(part))->maxOccurs != 1))
  10744. {
  10745. xmlChar *str = NULL;
  10746. /*
  10747. * SPEC src-redefine:
  10748. * (6.1.2) "The `actual value` of both that
  10749. * group's minOccurs and maxOccurs [attribute]
  10750. * must be 1 (or `absent`).
  10751. */
  10752. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10753. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10754. "The redefining model group definition "
  10755. "'%s' must not contain a reference to the "
  10756. "redefined definition with a "
  10757. "maxOccurs/minOccurs other than 1",
  10758. xmlSchemaFormatQName(&str,
  10759. ctxt->redef->refTargetNs,
  10760. ctxt->redef->refName),
  10761. NULL);
  10762. FREE_AND_NULL(str)
  10763. part = NULL;
  10764. }
  10765. ctxt->redef->reference = WXS_BASIC_CAST part;
  10766. ctxt->redefCounter++;
  10767. }
  10768. }
  10769. } else if (IS_SCHEMA(child, "any")) {
  10770. part = (xmlSchemaTreeItemPtr)
  10771. xmlSchemaParseAny(ctxt, schema, child);
  10772. } else if (IS_SCHEMA(child, "choice")) {
  10773. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10774. XML_SCHEMA_TYPE_CHOICE, 1);
  10775. } else if (IS_SCHEMA(child, "sequence")) {
  10776. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10777. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10778. }
  10779. if (part != NULL) {
  10780. if (last == NULL)
  10781. item->children = part;
  10782. else
  10783. last->next = part;
  10784. last = part;
  10785. }
  10786. child = child->next;
  10787. }
  10788. if (child != NULL) {
  10789. xmlSchemaPContentErr(ctxt,
  10790. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10791. NULL, node, child, NULL,
  10792. "(annotation?, (element | group | choice | sequence | any)*)");
  10793. }
  10794. }
  10795. if ((max == 0) && (min == 0))
  10796. return (NULL);
  10797. if (hasRefs) {
  10798. /*
  10799. * We need to resolve references.
  10800. */
  10801. WXS_ADD_PENDING(ctxt, item);
  10802. }
  10803. if (withParticle)
  10804. return ((xmlSchemaTreeItemPtr) particle);
  10805. else
  10806. return ((xmlSchemaTreeItemPtr) item);
  10807. }
  10808. /**
  10809. * xmlSchemaParseRestriction:
  10810. * @ctxt: a schema validation context
  10811. * @schema: the schema being built
  10812. * @node: a subtree containing XML Schema information
  10813. *
  10814. * parse a XML schema Restriction definition
  10815. * *WARNING* this interface is highly subject to change
  10816. *
  10817. * Returns the type definition or NULL in case of error
  10818. */
  10819. static xmlSchemaTypePtr
  10820. xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10821. xmlNodePtr node, xmlSchemaTypeType parentType)
  10822. {
  10823. xmlSchemaTypePtr type;
  10824. xmlNodePtr child = NULL;
  10825. xmlAttrPtr attr;
  10826. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10827. return (NULL);
  10828. /* Not a component, don't create it. */
  10829. type = ctxt->ctxtType;
  10830. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  10831. /*
  10832. * Check for illegal attributes.
  10833. */
  10834. attr = node->properties;
  10835. while (attr != NULL) {
  10836. if (attr->ns == NULL) {
  10837. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10838. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  10839. xmlSchemaPIllegalAttrErr(ctxt,
  10840. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10841. }
  10842. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10843. xmlSchemaPIllegalAttrErr(ctxt,
  10844. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10845. }
  10846. attr = attr->next;
  10847. }
  10848. /*
  10849. * Extract and validate attributes.
  10850. */
  10851. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10852. /*
  10853. * Attribute
  10854. */
  10855. /*
  10856. * Extract the base type. The "base" attribute is mandatory if inside
  10857. * a complex type or if redefining.
  10858. *
  10859. * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
  10860. * among its [children]), the simple type definition which is
  10861. * the {content type} of the type definition `resolved` to by
  10862. * the `actual value` of the base [attribute]"
  10863. */
  10864. if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
  10865. &(type->baseNs), &(type->base)) == 0)
  10866. {
  10867. if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
  10868. xmlSchemaPMissingAttrErr(ctxt,
  10869. XML_SCHEMAP_S4S_ATTR_MISSING,
  10870. NULL, node, "base", NULL);
  10871. } else if ((ctxt->isRedefine) &&
  10872. (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
  10873. {
  10874. if (type->base == NULL) {
  10875. xmlSchemaPMissingAttrErr(ctxt,
  10876. XML_SCHEMAP_S4S_ATTR_MISSING,
  10877. NULL, node, "base", NULL);
  10878. } else if ((! xmlStrEqual(type->base, type->name)) ||
  10879. (! xmlStrEqual(type->baseNs, type->targetNamespace)))
  10880. {
  10881. xmlChar *str1 = NULL, *str2 = NULL;
  10882. /*
  10883. * REDEFINE: SPEC src-redefine (5)
  10884. * "Within the [children], each <simpleType> must have a
  10885. * <restriction> among its [children] ... the `actual value` of
  10886. * whose base [attribute] must be the same as the `actual value`
  10887. * of its own name attribute plus target namespace;"
  10888. */
  10889. xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  10890. NULL, node, "This is a redefinition, but the QName "
  10891. "value '%s' of the 'base' attribute does not match the "
  10892. "type's designation '%s'",
  10893. xmlSchemaFormatQName(&str1, type->baseNs, type->base),
  10894. xmlSchemaFormatQName(&str2, type->targetNamespace,
  10895. type->name), NULL);
  10896. FREE_AND_NULL(str1);
  10897. FREE_AND_NULL(str2);
  10898. /* Avoid confusion and erase the values. */
  10899. type->base = NULL;
  10900. type->baseNs = NULL;
  10901. }
  10902. }
  10903. }
  10904. /*
  10905. * And now for the children...
  10906. */
  10907. child = node->children;
  10908. if (IS_SCHEMA(child, "annotation")) {
  10909. /*
  10910. * Add the annotation to the simple type ancestor.
  10911. */
  10912. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  10913. xmlSchemaParseAnnotation(ctxt, child, 1));
  10914. child = child->next;
  10915. }
  10916. if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
  10917. /*
  10918. * Corresponds to <simpleType><restriction><simpleType>.
  10919. */
  10920. if (IS_SCHEMA(child, "simpleType")) {
  10921. if (type->base != NULL) {
  10922. /*
  10923. * src-restriction-base-or-simpleType
  10924. * Either the base [attribute] or the simpleType [child] of the
  10925. * <restriction> element must be present, but not both.
  10926. */
  10927. xmlSchemaPContentErr(ctxt,
  10928. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10929. NULL, node, child,
  10930. "The attribute 'base' and the <simpleType> child are "
  10931. "mutually exclusive", NULL);
  10932. } else {
  10933. type->baseType = (xmlSchemaTypePtr)
  10934. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10935. }
  10936. child = child->next;
  10937. } else if (type->base == NULL) {
  10938. xmlSchemaPContentErr(ctxt,
  10939. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10940. NULL, node, child,
  10941. "Either the attribute 'base' or a <simpleType> child "
  10942. "must be present", NULL);
  10943. }
  10944. } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  10945. /*
  10946. * Corresponds to <complexType><complexContent><restriction>...
  10947. * followed by:
  10948. *
  10949. * Model groups <all>, <choice> and <sequence>.
  10950. */
  10951. if (IS_SCHEMA(child, "all")) {
  10952. type->subtypes = (xmlSchemaTypePtr)
  10953. xmlSchemaParseModelGroup(ctxt, schema, child,
  10954. XML_SCHEMA_TYPE_ALL, 1);
  10955. child = child->next;
  10956. } else if (IS_SCHEMA(child, "choice")) {
  10957. type->subtypes = (xmlSchemaTypePtr)
  10958. xmlSchemaParseModelGroup(ctxt,
  10959. schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
  10960. child = child->next;
  10961. } else if (IS_SCHEMA(child, "sequence")) {
  10962. type->subtypes = (xmlSchemaTypePtr)
  10963. xmlSchemaParseModelGroup(ctxt, schema, child,
  10964. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10965. child = child->next;
  10966. /*
  10967. * Model group reference <group>.
  10968. */
  10969. } else if (IS_SCHEMA(child, "group")) {
  10970. type->subtypes = (xmlSchemaTypePtr)
  10971. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10972. /*
  10973. * Note that the reference will be resolved in
  10974. * xmlSchemaResolveTypeReferences();
  10975. */
  10976. child = child->next;
  10977. }
  10978. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  10979. /*
  10980. * Corresponds to <complexType><simpleContent><restriction>...
  10981. *
  10982. * "1.1 the simple type definition corresponding to the <simpleType>
  10983. * among the [children] of <restriction> if there is one;"
  10984. */
  10985. if (IS_SCHEMA(child, "simpleType")) {
  10986. /*
  10987. * We will store the to-be-restricted simple type in
  10988. * type->contentTypeDef *temporarily*.
  10989. */
  10990. type->contentTypeDef = (xmlSchemaTypePtr)
  10991. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10992. if ( type->contentTypeDef == NULL)
  10993. return (NULL);
  10994. child = child->next;
  10995. }
  10996. }
  10997. if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
  10998. (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
  10999. xmlSchemaFacetPtr facet, lastfacet = NULL;
  11000. /*
  11001. * Corresponds to <complexType><simpleContent><restriction>...
  11002. * <simpleType><restriction>...
  11003. */
  11004. /*
  11005. * Add the facets to the simple type ancestor.
  11006. */
  11007. /*
  11008. * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
  11009. * Simple Type Definition Schema Representation Constraint:
  11010. * *Single Facet Value*
  11011. */
  11012. while ((IS_SCHEMA(child, "minInclusive")) ||
  11013. (IS_SCHEMA(child, "minExclusive")) ||
  11014. (IS_SCHEMA(child, "maxInclusive")) ||
  11015. (IS_SCHEMA(child, "maxExclusive")) ||
  11016. (IS_SCHEMA(child, "totalDigits")) ||
  11017. (IS_SCHEMA(child, "fractionDigits")) ||
  11018. (IS_SCHEMA(child, "pattern")) ||
  11019. (IS_SCHEMA(child, "enumeration")) ||
  11020. (IS_SCHEMA(child, "whiteSpace")) ||
  11021. (IS_SCHEMA(child, "length")) ||
  11022. (IS_SCHEMA(child, "maxLength")) ||
  11023. (IS_SCHEMA(child, "minLength"))) {
  11024. facet = xmlSchemaParseFacet(ctxt, schema, child);
  11025. if (facet != NULL) {
  11026. if (lastfacet == NULL)
  11027. type->facets = facet;
  11028. else
  11029. lastfacet->next = facet;
  11030. lastfacet = facet;
  11031. lastfacet->next = NULL;
  11032. }
  11033. child = child->next;
  11034. }
  11035. /*
  11036. * Create links for derivation and validation.
  11037. */
  11038. if (type->facets != NULL) {
  11039. xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
  11040. facet = type->facets;
  11041. do {
  11042. facetLink = (xmlSchemaFacetLinkPtr)
  11043. xmlMalloc(sizeof(xmlSchemaFacetLink));
  11044. if (facetLink == NULL) {
  11045. xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
  11046. xmlFree(facetLink);
  11047. return (NULL);
  11048. }
  11049. facetLink->facet = facet;
  11050. facetLink->next = NULL;
  11051. if (lastFacetLink == NULL)
  11052. type->facetSet = facetLink;
  11053. else
  11054. lastFacetLink->next = facetLink;
  11055. lastFacetLink = facetLink;
  11056. facet = facet->next;
  11057. } while (facet != NULL);
  11058. }
  11059. }
  11060. if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
  11061. /*
  11062. * Attribute uses/declarations.
  11063. */
  11064. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11065. (xmlSchemaItemListPtr *) &(type->attrUses),
  11066. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  11067. return(NULL);
  11068. /*
  11069. * Attribute wildcard.
  11070. */
  11071. if (IS_SCHEMA(child, "anyAttribute")) {
  11072. type->attributeWildcard =
  11073. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11074. child = child->next;
  11075. }
  11076. }
  11077. if (child != NULL) {
  11078. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11079. xmlSchemaPContentErr(ctxt,
  11080. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11081. NULL, node, child, NULL,
  11082. "annotation?, (group | all | choice | sequence)?, "
  11083. "((attribute | attributeGroup)*, anyAttribute?))");
  11084. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  11085. xmlSchemaPContentErr(ctxt,
  11086. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11087. NULL, node, child, NULL,
  11088. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  11089. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  11090. "length | minLength | maxLength | enumeration | whiteSpace | "
  11091. "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
  11092. } else {
  11093. /* Simple type */
  11094. xmlSchemaPContentErr(ctxt,
  11095. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11096. NULL, node, child, NULL,
  11097. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  11098. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  11099. "length | minLength | maxLength | enumeration | whiteSpace | "
  11100. "pattern)*))");
  11101. }
  11102. }
  11103. return (NULL);
  11104. }
  11105. /**
  11106. * xmlSchemaParseExtension:
  11107. * @ctxt: a schema validation context
  11108. * @schema: the schema being built
  11109. * @node: a subtree containing XML Schema information
  11110. *
  11111. * Parses an <extension>, which is found inside a
  11112. * <simpleContent> or <complexContent>.
  11113. * *WARNING* this interface is highly subject to change.
  11114. *
  11115. * TODO: Returns the type definition or NULL in case of error
  11116. */
  11117. static xmlSchemaTypePtr
  11118. xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11119. xmlNodePtr node, xmlSchemaTypeType parentType)
  11120. {
  11121. xmlSchemaTypePtr type;
  11122. xmlNodePtr child = NULL;
  11123. xmlAttrPtr attr;
  11124. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11125. return (NULL);
  11126. /* Not a component, don't create it. */
  11127. type = ctxt->ctxtType;
  11128. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
  11129. /*
  11130. * Check for illegal attributes.
  11131. */
  11132. attr = node->properties;
  11133. while (attr != NULL) {
  11134. if (attr->ns == NULL) {
  11135. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11136. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  11137. xmlSchemaPIllegalAttrErr(ctxt,
  11138. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11139. }
  11140. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11141. xmlSchemaPIllegalAttrErr(ctxt,
  11142. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11143. }
  11144. attr = attr->next;
  11145. }
  11146. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11147. /*
  11148. * Attribute "base" - mandatory.
  11149. */
  11150. if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
  11151. "base", &(type->baseNs), &(type->base)) == 0) &&
  11152. (type->base == NULL)) {
  11153. xmlSchemaPMissingAttrErr(ctxt,
  11154. XML_SCHEMAP_S4S_ATTR_MISSING,
  11155. NULL, node, "base", NULL);
  11156. }
  11157. /*
  11158. * And now for the children...
  11159. */
  11160. child = node->children;
  11161. if (IS_SCHEMA(child, "annotation")) {
  11162. /*
  11163. * Add the annotation to the type ancestor.
  11164. */
  11165. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11166. xmlSchemaParseAnnotation(ctxt, child, 1));
  11167. child = child->next;
  11168. }
  11169. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11170. /*
  11171. * Corresponds to <complexType><complexContent><extension>... and:
  11172. *
  11173. * Model groups <all>, <choice>, <sequence> and <group>.
  11174. */
  11175. if (IS_SCHEMA(child, "all")) {
  11176. type->subtypes = (xmlSchemaTypePtr)
  11177. xmlSchemaParseModelGroup(ctxt, schema,
  11178. child, XML_SCHEMA_TYPE_ALL, 1);
  11179. child = child->next;
  11180. } else if (IS_SCHEMA(child, "choice")) {
  11181. type->subtypes = (xmlSchemaTypePtr)
  11182. xmlSchemaParseModelGroup(ctxt, schema,
  11183. child, XML_SCHEMA_TYPE_CHOICE, 1);
  11184. child = child->next;
  11185. } else if (IS_SCHEMA(child, "sequence")) {
  11186. type->subtypes = (xmlSchemaTypePtr)
  11187. xmlSchemaParseModelGroup(ctxt, schema,
  11188. child, XML_SCHEMA_TYPE_SEQUENCE, 1);
  11189. child = child->next;
  11190. } else if (IS_SCHEMA(child, "group")) {
  11191. type->subtypes = (xmlSchemaTypePtr)
  11192. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11193. /*
  11194. * Note that the reference will be resolved in
  11195. * xmlSchemaResolveTypeReferences();
  11196. */
  11197. child = child->next;
  11198. }
  11199. }
  11200. if (child != NULL) {
  11201. /*
  11202. * Attribute uses/declarations.
  11203. */
  11204. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11205. (xmlSchemaItemListPtr *) &(type->attrUses),
  11206. XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
  11207. return(NULL);
  11208. /*
  11209. * Attribute wildcard.
  11210. */
  11211. if (IS_SCHEMA(child, "anyAttribute")) {
  11212. ctxt->ctxtType->attributeWildcard =
  11213. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11214. child = child->next;
  11215. }
  11216. }
  11217. if (child != NULL) {
  11218. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11219. /* Complex content extension. */
  11220. xmlSchemaPContentErr(ctxt,
  11221. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11222. NULL, node, child, NULL,
  11223. "(annotation?, ((group | all | choice | sequence)?, "
  11224. "((attribute | attributeGroup)*, anyAttribute?)))");
  11225. } else {
  11226. /* Simple content extension. */
  11227. xmlSchemaPContentErr(ctxt,
  11228. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11229. NULL, node, child, NULL,
  11230. "(annotation?, ((attribute | attributeGroup)*, "
  11231. "anyAttribute?))");
  11232. }
  11233. }
  11234. return (NULL);
  11235. }
  11236. /**
  11237. * xmlSchemaParseSimpleContent:
  11238. * @ctxt: a schema validation context
  11239. * @schema: the schema being built
  11240. * @node: a subtree containing XML Schema information
  11241. *
  11242. * parse a XML schema SimpleContent definition
  11243. * *WARNING* this interface is highly subject to change
  11244. *
  11245. * Returns the type definition or NULL in case of error
  11246. */
  11247. static int
  11248. xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
  11249. xmlSchemaPtr schema, xmlNodePtr node,
  11250. int *hasRestrictionOrExtension)
  11251. {
  11252. xmlSchemaTypePtr type;
  11253. xmlNodePtr child = NULL;
  11254. xmlAttrPtr attr;
  11255. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11256. (hasRestrictionOrExtension == NULL))
  11257. return (-1);
  11258. *hasRestrictionOrExtension = 0;
  11259. /* Not a component, don't create it. */
  11260. type = ctxt->ctxtType;
  11261. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  11262. /*
  11263. * Check for illegal attributes.
  11264. */
  11265. attr = node->properties;
  11266. while (attr != NULL) {
  11267. if (attr->ns == NULL) {
  11268. if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  11269. xmlSchemaPIllegalAttrErr(ctxt,
  11270. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11271. }
  11272. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11273. xmlSchemaPIllegalAttrErr(ctxt,
  11274. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11275. }
  11276. attr = attr->next;
  11277. }
  11278. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11279. /*
  11280. * And now for the children...
  11281. */
  11282. child = node->children;
  11283. if (IS_SCHEMA(child, "annotation")) {
  11284. /*
  11285. * Add the annotation to the complex type ancestor.
  11286. */
  11287. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11288. xmlSchemaParseAnnotation(ctxt, child, 1));
  11289. child = child->next;
  11290. }
  11291. if (child == NULL) {
  11292. xmlSchemaPContentErr(ctxt,
  11293. XML_SCHEMAP_S4S_ELEM_MISSING,
  11294. NULL, node, NULL, NULL,
  11295. "(annotation?, (restriction | extension))");
  11296. }
  11297. if (child == NULL) {
  11298. xmlSchemaPContentErr(ctxt,
  11299. XML_SCHEMAP_S4S_ELEM_MISSING,
  11300. NULL, node, NULL, NULL,
  11301. "(annotation?, (restriction | extension))");
  11302. }
  11303. if (IS_SCHEMA(child, "restriction")) {
  11304. xmlSchemaParseRestriction(ctxt, schema, child,
  11305. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11306. (*hasRestrictionOrExtension) = 1;
  11307. child = child->next;
  11308. } else if (IS_SCHEMA(child, "extension")) {
  11309. xmlSchemaParseExtension(ctxt, schema, child,
  11310. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11311. (*hasRestrictionOrExtension) = 1;
  11312. child = child->next;
  11313. }
  11314. if (child != NULL) {
  11315. xmlSchemaPContentErr(ctxt,
  11316. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11317. NULL, node, child, NULL,
  11318. "(annotation?, (restriction | extension))");
  11319. }
  11320. return (0);
  11321. }
  11322. /**
  11323. * xmlSchemaParseComplexContent:
  11324. * @ctxt: a schema validation context
  11325. * @schema: the schema being built
  11326. * @node: a subtree containing XML Schema information
  11327. *
  11328. * parse a XML schema ComplexContent definition
  11329. * *WARNING* this interface is highly subject to change
  11330. *
  11331. * Returns the type definition or NULL in case of error
  11332. */
  11333. static int
  11334. xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
  11335. xmlSchemaPtr schema, xmlNodePtr node,
  11336. int *hasRestrictionOrExtension)
  11337. {
  11338. xmlSchemaTypePtr type;
  11339. xmlNodePtr child = NULL;
  11340. xmlAttrPtr attr;
  11341. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11342. (hasRestrictionOrExtension == NULL))
  11343. return (-1);
  11344. *hasRestrictionOrExtension = 0;
  11345. /* Not a component, don't create it. */
  11346. type = ctxt->ctxtType;
  11347. /*
  11348. * Check for illegal attributes.
  11349. */
  11350. attr = node->properties;
  11351. while (attr != NULL) {
  11352. if (attr->ns == NULL) {
  11353. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11354. (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
  11355. {
  11356. xmlSchemaPIllegalAttrErr(ctxt,
  11357. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11358. }
  11359. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11360. xmlSchemaPIllegalAttrErr(ctxt,
  11361. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11362. }
  11363. attr = attr->next;
  11364. }
  11365. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11366. /*
  11367. * Set the 'mixed' on the complex type ancestor.
  11368. */
  11369. if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
  11370. if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
  11371. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11372. }
  11373. child = node->children;
  11374. if (IS_SCHEMA(child, "annotation")) {
  11375. /*
  11376. * Add the annotation to the complex type ancestor.
  11377. */
  11378. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11379. xmlSchemaParseAnnotation(ctxt, child, 1));
  11380. child = child->next;
  11381. }
  11382. if (child == NULL) {
  11383. xmlSchemaPContentErr(ctxt,
  11384. XML_SCHEMAP_S4S_ELEM_MISSING,
  11385. NULL, node, NULL,
  11386. NULL, "(annotation?, (restriction | extension))");
  11387. }
  11388. if (child == NULL) {
  11389. xmlSchemaPContentErr(ctxt,
  11390. XML_SCHEMAP_S4S_ELEM_MISSING,
  11391. NULL, node, NULL,
  11392. NULL, "(annotation?, (restriction | extension))");
  11393. }
  11394. if (IS_SCHEMA(child, "restriction")) {
  11395. xmlSchemaParseRestriction(ctxt, schema, child,
  11396. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11397. (*hasRestrictionOrExtension) = 1;
  11398. child = child->next;
  11399. } else if (IS_SCHEMA(child, "extension")) {
  11400. xmlSchemaParseExtension(ctxt, schema, child,
  11401. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11402. (*hasRestrictionOrExtension) = 1;
  11403. child = child->next;
  11404. }
  11405. if (child != NULL) {
  11406. xmlSchemaPContentErr(ctxt,
  11407. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11408. NULL, node, child,
  11409. NULL, "(annotation?, (restriction | extension))");
  11410. }
  11411. return (0);
  11412. }
  11413. /**
  11414. * xmlSchemaParseComplexType:
  11415. * @ctxt: a schema validation context
  11416. * @schema: the schema being built
  11417. * @node: a subtree containing XML Schema information
  11418. *
  11419. * parse a XML schema Complex Type definition
  11420. * *WARNING* this interface is highly subject to change
  11421. *
  11422. * Returns the type definition or NULL in case of error
  11423. */
  11424. static xmlSchemaTypePtr
  11425. xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11426. xmlNodePtr node, int topLevel)
  11427. {
  11428. xmlSchemaTypePtr type, ctxtType;
  11429. xmlNodePtr child = NULL;
  11430. const xmlChar *name = NULL;
  11431. xmlAttrPtr attr;
  11432. const xmlChar *attrValue;
  11433. #ifdef ENABLE_NAMED_LOCALS
  11434. char buf[40];
  11435. #endif
  11436. int final = 0, block = 0, hasRestrictionOrExtension = 0;
  11437. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11438. return (NULL);
  11439. ctxtType = ctxt->ctxtType;
  11440. if (topLevel) {
  11441. attr = xmlSchemaGetPropNode(node, "name");
  11442. if (attr == NULL) {
  11443. xmlSchemaPMissingAttrErr(ctxt,
  11444. XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
  11445. return (NULL);
  11446. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  11447. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  11448. return (NULL);
  11449. }
  11450. }
  11451. if (topLevel == 0) {
  11452. /*
  11453. * Parse as local complex type definition.
  11454. */
  11455. #ifdef ENABLE_NAMED_LOCALS
  11456. snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
  11457. type = xmlSchemaAddType(ctxt, schema,
  11458. XML_SCHEMA_TYPE_COMPLEX,
  11459. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  11460. ctxt->targetNamespace, node, 0);
  11461. #else
  11462. type = xmlSchemaAddType(ctxt, schema,
  11463. XML_SCHEMA_TYPE_COMPLEX,
  11464. NULL, ctxt->targetNamespace, node, 0);
  11465. #endif
  11466. if (type == NULL)
  11467. return (NULL);
  11468. name = type->name;
  11469. type->node = node;
  11470. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11471. /*
  11472. * TODO: We need the target namespace.
  11473. */
  11474. } else {
  11475. /*
  11476. * Parse as global complex type definition.
  11477. */
  11478. type = xmlSchemaAddType(ctxt, schema,
  11479. XML_SCHEMA_TYPE_COMPLEX,
  11480. name, ctxt->targetNamespace, node, 1);
  11481. if (type == NULL)
  11482. return (NULL);
  11483. type->node = node;
  11484. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11485. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  11486. }
  11487. type->targetNamespace = ctxt->targetNamespace;
  11488. /*
  11489. * Handle attributes.
  11490. */
  11491. attr = node->properties;
  11492. while (attr != NULL) {
  11493. if (attr->ns == NULL) {
  11494. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  11495. /*
  11496. * Attribute "id".
  11497. */
  11498. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11499. } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
  11500. /*
  11501. * Attribute "mixed".
  11502. */
  11503. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11504. NULL, (xmlNodePtr) attr))
  11505. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11506. } else if (topLevel) {
  11507. /*
  11508. * Attributes of global complex type definitions.
  11509. */
  11510. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  11511. /* Pass. */
  11512. } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
  11513. /*
  11514. * Attribute "abstract".
  11515. */
  11516. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11517. NULL, (xmlNodePtr) attr))
  11518. type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
  11519. } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
  11520. /*
  11521. * Attribute "final".
  11522. */
  11523. attrValue = xmlSchemaGetNodeContent(ctxt,
  11524. (xmlNodePtr) attr);
  11525. if (xmlSchemaPValAttrBlockFinal(attrValue,
  11526. &(type->flags),
  11527. -1,
  11528. XML_SCHEMAS_TYPE_FINAL_EXTENSION,
  11529. XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
  11530. -1, -1, -1) != 0)
  11531. {
  11532. xmlSchemaPSimpleTypeErr(ctxt,
  11533. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11534. NULL, (xmlNodePtr) attr, NULL,
  11535. "(#all | List of (extension | restriction))",
  11536. attrValue, NULL, NULL, NULL);
  11537. } else
  11538. final = 1;
  11539. } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
  11540. /*
  11541. * Attribute "block".
  11542. */
  11543. attrValue = xmlSchemaGetNodeContent(ctxt,
  11544. (xmlNodePtr) attr);
  11545. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  11546. -1,
  11547. XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
  11548. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
  11549. -1, -1, -1) != 0) {
  11550. xmlSchemaPSimpleTypeErr(ctxt,
  11551. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11552. NULL, (xmlNodePtr) attr, NULL,
  11553. "(#all | List of (extension | restriction)) ",
  11554. attrValue, NULL, NULL, NULL);
  11555. } else
  11556. block = 1;
  11557. } else {
  11558. xmlSchemaPIllegalAttrErr(ctxt,
  11559. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11560. }
  11561. } else {
  11562. xmlSchemaPIllegalAttrErr(ctxt,
  11563. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11564. }
  11565. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11566. xmlSchemaPIllegalAttrErr(ctxt,
  11567. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11568. }
  11569. attr = attr->next;
  11570. }
  11571. if (! block) {
  11572. /*
  11573. * Apply default "block" values.
  11574. */
  11575. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  11576. type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  11577. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  11578. type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  11579. }
  11580. if (! final) {
  11581. /*
  11582. * Apply default "block" values.
  11583. */
  11584. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  11585. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  11586. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  11587. type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
  11588. }
  11589. /*
  11590. * And now for the children...
  11591. */
  11592. child = node->children;
  11593. if (IS_SCHEMA(child, "annotation")) {
  11594. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  11595. child = child->next;
  11596. }
  11597. ctxt->ctxtType = type;
  11598. if (IS_SCHEMA(child, "simpleContent")) {
  11599. /*
  11600. * <complexType><simpleContent>...
  11601. * 3.4.3 : 2.2
  11602. * Specifying mixed='true' when the <simpleContent>
  11603. * alternative is chosen has no effect
  11604. */
  11605. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  11606. type->flags ^= XML_SCHEMAS_TYPE_MIXED;
  11607. xmlSchemaParseSimpleContent(ctxt, schema, child,
  11608. &hasRestrictionOrExtension);
  11609. child = child->next;
  11610. } else if (IS_SCHEMA(child, "complexContent")) {
  11611. /*
  11612. * <complexType><complexContent>...
  11613. */
  11614. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  11615. xmlSchemaParseComplexContent(ctxt, schema, child,
  11616. &hasRestrictionOrExtension);
  11617. child = child->next;
  11618. } else {
  11619. /*
  11620. * E.g <complexType><sequence>... or <complexType><attribute>... etc.
  11621. *
  11622. * SPEC
  11623. * "...the third alternative (neither <simpleContent> nor
  11624. * <complexContent>) is chosen. This case is understood as shorthand
  11625. * for complex content restricting the `ur-type definition`, and the
  11626. * details of the mappings should be modified as necessary.
  11627. */
  11628. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  11629. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  11630. /*
  11631. * Parse model groups.
  11632. */
  11633. if (IS_SCHEMA(child, "all")) {
  11634. type->subtypes = (xmlSchemaTypePtr)
  11635. xmlSchemaParseModelGroup(ctxt, schema, child,
  11636. XML_SCHEMA_TYPE_ALL, 1);
  11637. child = child->next;
  11638. } else if (IS_SCHEMA(child, "choice")) {
  11639. type->subtypes = (xmlSchemaTypePtr)
  11640. xmlSchemaParseModelGroup(ctxt, schema, child,
  11641. XML_SCHEMA_TYPE_CHOICE, 1);
  11642. child = child->next;
  11643. } else if (IS_SCHEMA(child, "sequence")) {
  11644. type->subtypes = (xmlSchemaTypePtr)
  11645. xmlSchemaParseModelGroup(ctxt, schema, child,
  11646. XML_SCHEMA_TYPE_SEQUENCE, 1);
  11647. child = child->next;
  11648. } else if (IS_SCHEMA(child, "group")) {
  11649. type->subtypes = (xmlSchemaTypePtr)
  11650. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11651. /*
  11652. * Note that the reference will be resolved in
  11653. * xmlSchemaResolveTypeReferences();
  11654. */
  11655. child = child->next;
  11656. }
  11657. /*
  11658. * Parse attribute decls/refs.
  11659. */
  11660. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11661. (xmlSchemaItemListPtr *) &(type->attrUses),
  11662. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  11663. return(NULL);
  11664. /*
  11665. * Parse attribute wildcard.
  11666. */
  11667. if (IS_SCHEMA(child, "anyAttribute")) {
  11668. type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11669. child = child->next;
  11670. }
  11671. }
  11672. if (child != NULL) {
  11673. xmlSchemaPContentErr(ctxt,
  11674. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11675. NULL, node, child,
  11676. NULL, "(annotation?, (simpleContent | complexContent | "
  11677. "((group | all | choice | sequence)?, ((attribute | "
  11678. "attributeGroup)*, anyAttribute?))))");
  11679. }
  11680. /*
  11681. * REDEFINE: SPEC src-redefine (5)
  11682. */
  11683. if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
  11684. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  11685. NULL, node, "This is a redefinition, thus the "
  11686. "<complexType> must have a <restriction> or <extension> "
  11687. "grand-child", NULL);
  11688. }
  11689. ctxt->ctxtType = ctxtType;
  11690. return (type);
  11691. }
  11692. /************************************************************************
  11693. * *
  11694. * Validating using Schemas *
  11695. * *
  11696. ************************************************************************/
  11697. /************************************************************************
  11698. * *
  11699. * Reading/Writing Schemas *
  11700. * *
  11701. ************************************************************************/
  11702. #if 0 /* Will be enabled if it is clear what options are needed. */
  11703. /**
  11704. * xmlSchemaParserCtxtSetOptions:
  11705. * @ctxt: a schema parser context
  11706. * @options: a combination of xmlSchemaParserOption
  11707. *
  11708. * Sets the options to be used during the parse.
  11709. *
  11710. * Returns 0 in case of success, -1 in case of an
  11711. * API error.
  11712. */
  11713. static int
  11714. xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
  11715. int options)
  11716. {
  11717. int i;
  11718. if (ctxt == NULL)
  11719. return (-1);
  11720. /*
  11721. * WARNING: Change the start value if adding to the
  11722. * xmlSchemaParseOption.
  11723. */
  11724. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  11725. if (options & 1<<i) {
  11726. return (-1);
  11727. }
  11728. }
  11729. ctxt->options = options;
  11730. return (0);
  11731. }
  11732. /**
  11733. * xmlSchemaValidCtxtGetOptions:
  11734. * @ctxt: a schema parser context
  11735. *
  11736. * Returns the option combination of the parser context.
  11737. */
  11738. static int
  11739. xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
  11740. {
  11741. if (ctxt == NULL)
  11742. return (-1);
  11743. else
  11744. return (ctxt->options);
  11745. }
  11746. #endif
  11747. /**
  11748. * xmlSchemaNewParserCtxt:
  11749. * @URL: the location of the schema
  11750. *
  11751. * Create an XML Schemas parse context for that file/resource expected
  11752. * to contain an XML Schemas file.
  11753. *
  11754. * Returns the parser context or NULL in case of error
  11755. */
  11756. xmlSchemaParserCtxtPtr
  11757. xmlSchemaNewParserCtxt(const char *URL)
  11758. {
  11759. xmlSchemaParserCtxtPtr ret;
  11760. if (URL == NULL)
  11761. return (NULL);
  11762. ret = xmlSchemaParserCtxtCreate();
  11763. if (ret == NULL)
  11764. return(NULL);
  11765. ret->dict = xmlDictCreate();
  11766. ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
  11767. return (ret);
  11768. }
  11769. /**
  11770. * xmlSchemaNewMemParserCtxt:
  11771. * @buffer: a pointer to a char array containing the schemas
  11772. * @size: the size of the array
  11773. *
  11774. * Create an XML Schemas parse context for that memory buffer expected
  11775. * to contain an XML Schemas file.
  11776. *
  11777. * Returns the parser context or NULL in case of error
  11778. */
  11779. xmlSchemaParserCtxtPtr
  11780. xmlSchemaNewMemParserCtxt(const char *buffer, int size)
  11781. {
  11782. xmlSchemaParserCtxtPtr ret;
  11783. if ((buffer == NULL) || (size <= 0))
  11784. return (NULL);
  11785. ret = xmlSchemaParserCtxtCreate();
  11786. if (ret == NULL)
  11787. return(NULL);
  11788. ret->buffer = buffer;
  11789. ret->size = size;
  11790. ret->dict = xmlDictCreate();
  11791. return (ret);
  11792. }
  11793. /**
  11794. * xmlSchemaNewDocParserCtxt:
  11795. * @doc: a preparsed document tree
  11796. *
  11797. * Create an XML Schemas parse context for that document.
  11798. * NB. The document may be modified during the parsing process.
  11799. *
  11800. * Returns the parser context or NULL in case of error
  11801. */
  11802. xmlSchemaParserCtxtPtr
  11803. xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
  11804. {
  11805. xmlSchemaParserCtxtPtr ret;
  11806. if (doc == NULL)
  11807. return (NULL);
  11808. ret = xmlSchemaParserCtxtCreate();
  11809. if (ret == NULL)
  11810. return(NULL);
  11811. ret->doc = doc;
  11812. ret->dict = xmlDictCreate();
  11813. /* The application has responsibility for the document */
  11814. ret->preserve = 1;
  11815. return (ret);
  11816. }
  11817. /**
  11818. * xmlSchemaFreeParserCtxt:
  11819. * @ctxt: the schema parser context
  11820. *
  11821. * Free the resources associated to the schema parser context
  11822. */
  11823. void
  11824. xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
  11825. {
  11826. if (ctxt == NULL)
  11827. return;
  11828. if (ctxt->doc != NULL && !ctxt->preserve)
  11829. xmlFreeDoc(ctxt->doc);
  11830. if (ctxt->vctxt != NULL) {
  11831. xmlSchemaFreeValidCtxt(ctxt->vctxt);
  11832. }
  11833. if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
  11834. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  11835. ctxt->constructor = NULL;
  11836. ctxt->ownsConstructor = 0;
  11837. }
  11838. if (ctxt->attrProhibs != NULL)
  11839. xmlSchemaItemListFree(ctxt->attrProhibs);
  11840. xmlDictFree(ctxt->dict);
  11841. xmlFree(ctxt);
  11842. }
  11843. /************************************************************************
  11844. * *
  11845. * Building the content models *
  11846. * *
  11847. ************************************************************************/
  11848. /**
  11849. * xmlSchemaBuildContentModelForSubstGroup:
  11850. *
  11851. * Returns 1 if nillable, 0 otherwise
  11852. */
  11853. static int
  11854. xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
  11855. xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
  11856. {
  11857. xmlAutomataStatePtr start, tmp;
  11858. xmlSchemaElementPtr elemDecl, member;
  11859. xmlSchemaSubstGroupPtr substGroup;
  11860. int i;
  11861. int ret = 0;
  11862. elemDecl = (xmlSchemaElementPtr) particle->children;
  11863. /*
  11864. * Wrap the substitution group with a CHOICE.
  11865. */
  11866. start = pctxt->state;
  11867. if (end == NULL)
  11868. end = xmlAutomataNewState(pctxt->am);
  11869. substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
  11870. if (substGroup == NULL) {
  11871. xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
  11872. XML_SCHEMAP_INTERNAL,
  11873. "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
  11874. "declaration is marked having a subst. group but none "
  11875. "available.\n", elemDecl->name, NULL);
  11876. return(0);
  11877. }
  11878. if (counter >= 0) {
  11879. /*
  11880. * NOTE that we put the declaration in, even if it's abstract.
  11881. * However, an error will be raised during *validation* if an element
  11882. * information item shall be validated against an abstract element
  11883. * declaration.
  11884. */
  11885. tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
  11886. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11887. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11888. /*
  11889. * Add subst. group members.
  11890. */
  11891. for (i = 0; i < substGroup->members->nbItems; i++) {
  11892. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11893. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11894. member->name, member->targetNamespace, member);
  11895. }
  11896. } else if (particle->maxOccurs == 1) {
  11897. /*
  11898. * NOTE that we put the declaration in, even if it's abstract,
  11899. */
  11900. xmlAutomataNewEpsilon(pctxt->am,
  11901. xmlAutomataNewTransition2(pctxt->am,
  11902. start, NULL,
  11903. elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
  11904. /*
  11905. * Add subst. group members.
  11906. */
  11907. for (i = 0; i < substGroup->members->nbItems; i++) {
  11908. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11909. /*
  11910. * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
  11911. * was incorrectly used instead of xmlAutomataNewTransition2()
  11912. * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
  11913. * section in xmlSchemaBuildAContentModel() ).
  11914. * TODO: Check if xmlAutomataNewOnceTrans2() was instead
  11915. * intended for the above "counter" section originally. I.e.,
  11916. * check xs:all with subst-groups.
  11917. *
  11918. * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
  11919. * member->name, member->targetNamespace,
  11920. * 1, 1, member);
  11921. */
  11922. tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
  11923. member->name, member->targetNamespace, member);
  11924. xmlAutomataNewEpsilon(pctxt->am, tmp, end);
  11925. }
  11926. } else {
  11927. xmlAutomataStatePtr hop;
  11928. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  11929. UNBOUNDED : particle->maxOccurs - 1;
  11930. int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  11931. counter =
  11932. xmlAutomataNewCounter(pctxt->am, minOccurs,
  11933. maxOccurs);
  11934. hop = xmlAutomataNewState(pctxt->am);
  11935. xmlAutomataNewEpsilon(pctxt->am,
  11936. xmlAutomataNewTransition2(pctxt->am,
  11937. start, NULL,
  11938. elemDecl->name, elemDecl->targetNamespace, elemDecl),
  11939. hop);
  11940. /*
  11941. * Add subst. group members.
  11942. */
  11943. for (i = 0; i < substGroup->members->nbItems; i++) {
  11944. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11945. xmlAutomataNewEpsilon(pctxt->am,
  11946. xmlAutomataNewTransition2(pctxt->am,
  11947. start, NULL,
  11948. member->name, member->targetNamespace, member),
  11949. hop);
  11950. }
  11951. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  11952. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  11953. }
  11954. if (particle->minOccurs == 0) {
  11955. xmlAutomataNewEpsilon(pctxt->am, start, end);
  11956. ret = 1;
  11957. }
  11958. pctxt->state = end;
  11959. return(ret);
  11960. }
  11961. /**
  11962. * xmlSchemaBuildContentModelForElement:
  11963. *
  11964. * Returns 1 if nillable, 0 otherwise
  11965. */
  11966. static int
  11967. xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
  11968. xmlSchemaParticlePtr particle)
  11969. {
  11970. int ret = 0;
  11971. if (((xmlSchemaElementPtr) particle->children)->flags &
  11972. XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  11973. /*
  11974. * Substitution groups.
  11975. */
  11976. ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
  11977. } else {
  11978. xmlSchemaElementPtr elemDecl;
  11979. xmlAutomataStatePtr start;
  11980. elemDecl = (xmlSchemaElementPtr) particle->children;
  11981. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  11982. return(0);
  11983. if (particle->maxOccurs == 1) {
  11984. start = ctxt->state;
  11985. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11986. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11987. } else if ((particle->maxOccurs >= UNBOUNDED) &&
  11988. (particle->minOccurs < 2)) {
  11989. /* Special case. */
  11990. start = ctxt->state;
  11991. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11992. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11993. ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
  11994. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11995. } else {
  11996. int counter;
  11997. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  11998. UNBOUNDED : particle->maxOccurs - 1;
  11999. int minOccurs = particle->minOccurs < 1 ?
  12000. 0 : particle->minOccurs - 1;
  12001. start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
  12002. counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
  12003. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  12004. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  12005. xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
  12006. ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
  12007. NULL, counter);
  12008. }
  12009. if (particle->minOccurs == 0) {
  12010. xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
  12011. ret = 1;
  12012. }
  12013. }
  12014. return(ret);
  12015. }
  12016. /**
  12017. * xmlSchemaBuildAContentModel:
  12018. * @ctxt: the schema parser context
  12019. * @particle: the particle component
  12020. * @name: the complex type's name whose content is being built
  12021. *
  12022. * Create the automaton for the {content type} of a complex type.
  12023. *
  12024. * Returns 1 if the content is nillable, 0 otherwise
  12025. */
  12026. static int
  12027. xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
  12028. xmlSchemaParticlePtr particle)
  12029. {
  12030. int ret = 0, tmp2;
  12031. if (particle == NULL) {
  12032. PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
  12033. return(1);
  12034. }
  12035. if (particle->children == NULL) {
  12036. /*
  12037. * Just return in this case. A missing "term" of the particle
  12038. * might arise due to an invalid "term" component.
  12039. */
  12040. return(1);
  12041. }
  12042. switch (particle->children->type) {
  12043. case XML_SCHEMA_TYPE_ANY: {
  12044. xmlAutomataStatePtr start, end;
  12045. xmlSchemaWildcardPtr wild;
  12046. xmlSchemaWildcardNsPtr ns;
  12047. wild = (xmlSchemaWildcardPtr) particle->children;
  12048. start = pctxt->state;
  12049. end = xmlAutomataNewState(pctxt->am);
  12050. if (particle->maxOccurs == 1) {
  12051. if (wild->any == 1) {
  12052. /*
  12053. * We need to add both transitions:
  12054. *
  12055. * 1. the {"*", "*"} for elements in a namespace.
  12056. */
  12057. pctxt->state =
  12058. xmlAutomataNewTransition2(pctxt->am,
  12059. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  12060. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12061. /*
  12062. * 2. the {"*"} for elements in no namespace.
  12063. */
  12064. pctxt->state =
  12065. xmlAutomataNewTransition2(pctxt->am,
  12066. start, NULL, BAD_CAST "*", NULL, wild);
  12067. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12068. } else if (wild->nsSet != NULL) {
  12069. ns = wild->nsSet;
  12070. do {
  12071. pctxt->state = start;
  12072. pctxt->state = xmlAutomataNewTransition2(pctxt->am,
  12073. pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
  12074. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12075. ns = ns->next;
  12076. } while (ns != NULL);
  12077. } else if (wild->negNsSet != NULL) {
  12078. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  12079. start, end, BAD_CAST "*", wild->negNsSet->value,
  12080. wild);
  12081. }
  12082. } else {
  12083. int counter;
  12084. xmlAutomataStatePtr hop;
  12085. int maxOccurs =
  12086. particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
  12087. particle->maxOccurs - 1;
  12088. int minOccurs =
  12089. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  12090. counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  12091. hop = xmlAutomataNewState(pctxt->am);
  12092. if (wild->any == 1) {
  12093. pctxt->state =
  12094. xmlAutomataNewTransition2(pctxt->am,
  12095. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  12096. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12097. pctxt->state =
  12098. xmlAutomataNewTransition2(pctxt->am,
  12099. start, NULL, BAD_CAST "*", NULL, wild);
  12100. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12101. } else if (wild->nsSet != NULL) {
  12102. ns = wild->nsSet;
  12103. do {
  12104. pctxt->state =
  12105. xmlAutomataNewTransition2(pctxt->am,
  12106. start, NULL, BAD_CAST "*", ns->value, wild);
  12107. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12108. ns = ns->next;
  12109. } while (ns != NULL);
  12110. } else if (wild->negNsSet != NULL) {
  12111. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  12112. start, hop, BAD_CAST "*", wild->negNsSet->value,
  12113. wild);
  12114. }
  12115. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  12116. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12117. }
  12118. if (particle->minOccurs == 0) {
  12119. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12120. ret = 1;
  12121. }
  12122. pctxt->state = end;
  12123. break;
  12124. }
  12125. case XML_SCHEMA_TYPE_ELEMENT:
  12126. ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
  12127. break;
  12128. case XML_SCHEMA_TYPE_SEQUENCE:{
  12129. xmlSchemaTreeItemPtr sub;
  12130. ret = 1;
  12131. /*
  12132. * If max and min occurrences are default (1) then
  12133. * simply iterate over the particles of the <sequence>.
  12134. */
  12135. if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
  12136. sub = particle->children->children;
  12137. while (sub != NULL) {
  12138. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12139. (xmlSchemaParticlePtr) sub);
  12140. if (tmp2 != 1) ret = 0;
  12141. sub = sub->next;
  12142. }
  12143. } else {
  12144. xmlAutomataStatePtr oldstate = pctxt->state;
  12145. if (particle->maxOccurs >= UNBOUNDED) {
  12146. if (particle->minOccurs > 1) {
  12147. xmlAutomataStatePtr tmp;
  12148. int counter;
  12149. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12150. oldstate, NULL);
  12151. oldstate = pctxt->state;
  12152. counter = xmlAutomataNewCounter(pctxt->am,
  12153. particle->minOccurs - 1, UNBOUNDED);
  12154. sub = particle->children->children;
  12155. while (sub != NULL) {
  12156. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12157. (xmlSchemaParticlePtr) sub);
  12158. if (tmp2 != 1) ret = 0;
  12159. sub = sub->next;
  12160. }
  12161. tmp = pctxt->state;
  12162. xmlAutomataNewCountedTrans(pctxt->am, tmp,
  12163. oldstate, counter);
  12164. pctxt->state =
  12165. xmlAutomataNewCounterTrans(pctxt->am, tmp,
  12166. NULL, counter);
  12167. if (ret == 1)
  12168. xmlAutomataNewEpsilon(pctxt->am,
  12169. oldstate, pctxt->state);
  12170. } else {
  12171. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12172. oldstate, NULL);
  12173. oldstate = pctxt->state;
  12174. sub = particle->children->children;
  12175. while (sub != NULL) {
  12176. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12177. (xmlSchemaParticlePtr) sub);
  12178. if (tmp2 != 1) ret = 0;
  12179. sub = sub->next;
  12180. }
  12181. xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
  12182. oldstate);
  12183. /*
  12184. * epsilon needed to block previous trans from
  12185. * being allowed to enter back from another
  12186. * construct
  12187. */
  12188. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12189. pctxt->state, NULL);
  12190. if (particle->minOccurs == 0) {
  12191. xmlAutomataNewEpsilon(pctxt->am,
  12192. oldstate, pctxt->state);
  12193. ret = 1;
  12194. }
  12195. }
  12196. } else if ((particle->maxOccurs > 1)
  12197. || (particle->minOccurs > 1)) {
  12198. xmlAutomataStatePtr tmp;
  12199. int counter;
  12200. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12201. oldstate, NULL);
  12202. oldstate = pctxt->state;
  12203. counter = xmlAutomataNewCounter(pctxt->am,
  12204. particle->minOccurs - 1,
  12205. particle->maxOccurs - 1);
  12206. sub = particle->children->children;
  12207. while (sub != NULL) {
  12208. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12209. (xmlSchemaParticlePtr) sub);
  12210. if (tmp2 != 1) ret = 0;
  12211. sub = sub->next;
  12212. }
  12213. tmp = pctxt->state;
  12214. xmlAutomataNewCountedTrans(pctxt->am,
  12215. tmp, oldstate, counter);
  12216. pctxt->state =
  12217. xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
  12218. counter);
  12219. if ((particle->minOccurs == 0) || (ret == 1)) {
  12220. xmlAutomataNewEpsilon(pctxt->am,
  12221. oldstate, pctxt->state);
  12222. ret = 1;
  12223. }
  12224. } else {
  12225. sub = particle->children->children;
  12226. while (sub != NULL) {
  12227. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12228. (xmlSchemaParticlePtr) sub);
  12229. if (tmp2 != 1) ret = 0;
  12230. sub = sub->next;
  12231. }
  12232. /*
  12233. * epsilon needed to block previous trans from
  12234. * being allowed to enter back from another
  12235. * construct
  12236. */
  12237. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12238. pctxt->state, NULL);
  12239. if (particle->minOccurs == 0) {
  12240. xmlAutomataNewEpsilon(pctxt->am, oldstate,
  12241. pctxt->state);
  12242. ret = 1;
  12243. }
  12244. }
  12245. }
  12246. break;
  12247. }
  12248. case XML_SCHEMA_TYPE_CHOICE:{
  12249. xmlSchemaTreeItemPtr sub;
  12250. xmlAutomataStatePtr start, end;
  12251. ret = 0;
  12252. start = pctxt->state;
  12253. end = xmlAutomataNewState(pctxt->am);
  12254. /*
  12255. * iterate over the subtypes and remerge the end with an
  12256. * epsilon transition
  12257. */
  12258. if (particle->maxOccurs == 1) {
  12259. sub = particle->children->children;
  12260. while (sub != NULL) {
  12261. pctxt->state = start;
  12262. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12263. (xmlSchemaParticlePtr) sub);
  12264. if (tmp2 == 1) ret = 1;
  12265. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12266. sub = sub->next;
  12267. }
  12268. } else {
  12269. int counter;
  12270. xmlAutomataStatePtr hop, base;
  12271. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  12272. UNBOUNDED : particle->maxOccurs - 1;
  12273. int minOccurs =
  12274. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  12275. /*
  12276. * use a counter to keep track of the number of transitions
  12277. * which went through the choice.
  12278. */
  12279. counter =
  12280. xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  12281. hop = xmlAutomataNewState(pctxt->am);
  12282. base = xmlAutomataNewState(pctxt->am);
  12283. sub = particle->children->children;
  12284. while (sub != NULL) {
  12285. pctxt->state = base;
  12286. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12287. (xmlSchemaParticlePtr) sub);
  12288. if (tmp2 == 1) ret = 1;
  12289. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12290. sub = sub->next;
  12291. }
  12292. xmlAutomataNewEpsilon(pctxt->am, start, base);
  12293. xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
  12294. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12295. if (ret == 1)
  12296. xmlAutomataNewEpsilon(pctxt->am, base, end);
  12297. }
  12298. if (particle->minOccurs == 0) {
  12299. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12300. ret = 1;
  12301. }
  12302. pctxt->state = end;
  12303. break;
  12304. }
  12305. case XML_SCHEMA_TYPE_ALL:{
  12306. xmlAutomataStatePtr start, tmp;
  12307. xmlSchemaParticlePtr sub;
  12308. xmlSchemaElementPtr elemDecl;
  12309. ret = 1;
  12310. sub = (xmlSchemaParticlePtr) particle->children->children;
  12311. if (sub == NULL)
  12312. break;
  12313. ret = 0;
  12314. start = pctxt->state;
  12315. tmp = xmlAutomataNewState(pctxt->am);
  12316. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
  12317. pctxt->state = tmp;
  12318. while (sub != NULL) {
  12319. pctxt->state = tmp;
  12320. elemDecl = (xmlSchemaElementPtr) sub->children;
  12321. if (elemDecl == NULL) {
  12322. PERROR_INT("xmlSchemaBuildAContentModel",
  12323. "<element> particle has no term");
  12324. return(ret);
  12325. };
  12326. /*
  12327. * NOTE: The {max occurs} of all the particles in the
  12328. * {particles} of the group must be 0 or 1; this is
  12329. * already ensured during the parse of the content of
  12330. * <all>.
  12331. */
  12332. if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  12333. int counter;
  12334. /*
  12335. * This is an abstract group, we need to share
  12336. * the same counter for all the element transitions
  12337. * derived from the group
  12338. */
  12339. counter = xmlAutomataNewCounter(pctxt->am,
  12340. sub->minOccurs, sub->maxOccurs);
  12341. xmlSchemaBuildContentModelForSubstGroup(pctxt,
  12342. sub, counter, pctxt->state);
  12343. } else {
  12344. if ((sub->minOccurs == 1) &&
  12345. (sub->maxOccurs == 1)) {
  12346. xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
  12347. pctxt->state,
  12348. elemDecl->name,
  12349. elemDecl->targetNamespace,
  12350. 1, 1, elemDecl);
  12351. } else if ((sub->minOccurs == 0) &&
  12352. (sub->maxOccurs == 1)) {
  12353. xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
  12354. pctxt->state,
  12355. elemDecl->name,
  12356. elemDecl->targetNamespace,
  12357. 0,
  12358. 1,
  12359. elemDecl);
  12360. }
  12361. }
  12362. sub = (xmlSchemaParticlePtr) sub->next;
  12363. }
  12364. pctxt->state =
  12365. xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
  12366. if (particle->minOccurs == 0) {
  12367. xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
  12368. ret = 1;
  12369. }
  12370. break;
  12371. }
  12372. case XML_SCHEMA_TYPE_GROUP:
  12373. /*
  12374. * If we hit a model group definition, then this means that
  12375. * it was empty, thus was not substituted for the containing
  12376. * model group. Just do nothing in this case.
  12377. * TODO: But the group should be substituted and not occur at
  12378. * all in the content model at this point. Fix this.
  12379. */
  12380. ret = 1;
  12381. break;
  12382. default:
  12383. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  12384. "xmlSchemaBuildAContentModel",
  12385. "found unexpected term of type '%s' in content model",
  12386. WXS_ITEM_TYPE_NAME(particle->children), NULL);
  12387. return(ret);
  12388. }
  12389. return(ret);
  12390. }
  12391. /**
  12392. * xmlSchemaBuildContentModel:
  12393. * @ctxt: the schema parser context
  12394. * @type: the complex type definition
  12395. * @name: the element name
  12396. *
  12397. * Builds the content model of the complex type.
  12398. */
  12399. static void
  12400. xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
  12401. xmlSchemaParserCtxtPtr ctxt)
  12402. {
  12403. if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
  12404. (type->contModel != NULL) ||
  12405. ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
  12406. (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
  12407. return;
  12408. #ifdef DEBUG_CONTENT
  12409. xmlGenericError(xmlGenericErrorContext,
  12410. "Building content model for %s\n", name);
  12411. #endif
  12412. ctxt->am = NULL;
  12413. ctxt->am = xmlNewAutomata();
  12414. if (ctxt->am == NULL) {
  12415. xmlGenericError(xmlGenericErrorContext,
  12416. "Cannot create automata for complex type %s\n", type->name);
  12417. return;
  12418. }
  12419. ctxt->state = xmlAutomataGetInitState(ctxt->am);
  12420. /*
  12421. * Build the automaton.
  12422. */
  12423. xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
  12424. xmlAutomataSetFinalState(ctxt->am, ctxt->state);
  12425. type->contModel = xmlAutomataCompile(ctxt->am);
  12426. if (type->contModel == NULL) {
  12427. xmlSchemaPCustomErr(ctxt,
  12428. XML_SCHEMAP_INTERNAL,
  12429. WXS_BASIC_CAST type, type->node,
  12430. "Failed to compile the content model", NULL);
  12431. } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
  12432. xmlSchemaPCustomErr(ctxt,
  12433. XML_SCHEMAP_NOT_DETERMINISTIC,
  12434. /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
  12435. WXS_BASIC_CAST type, type->node,
  12436. "The content model is not determinist", NULL);
  12437. } else {
  12438. #ifdef DEBUG_CONTENT_REGEXP
  12439. xmlGenericError(xmlGenericErrorContext,
  12440. "Content model of %s:\n", type->name);
  12441. xmlRegexpPrint(stderr, type->contModel);
  12442. #endif
  12443. }
  12444. ctxt->state = NULL;
  12445. xmlFreeAutomata(ctxt->am);
  12446. ctxt->am = NULL;
  12447. }
  12448. /**
  12449. * xmlSchemaResolveElementReferences:
  12450. * @elem: the schema element context
  12451. * @ctxt: the schema parser context
  12452. *
  12453. * Resolves the references of an element declaration
  12454. * or particle, which has an element declaration as it's
  12455. * term.
  12456. */
  12457. static void
  12458. xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
  12459. xmlSchemaParserCtxtPtr ctxt)
  12460. {
  12461. if ((ctxt == NULL) || (elemDecl == NULL) ||
  12462. ((elemDecl != NULL) &&
  12463. (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
  12464. return;
  12465. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
  12466. if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
  12467. xmlSchemaTypePtr type;
  12468. /* (type definition) ... otherwise the type definition `resolved`
  12469. * to by the `actual value` of the type [attribute] ...
  12470. */
  12471. type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
  12472. elemDecl->namedTypeNs);
  12473. if (type == NULL) {
  12474. xmlSchemaPResCompAttrErr(ctxt,
  12475. XML_SCHEMAP_SRC_RESOLVE,
  12476. WXS_BASIC_CAST elemDecl, elemDecl->node,
  12477. "type", elemDecl->namedType, elemDecl->namedTypeNs,
  12478. XML_SCHEMA_TYPE_BASIC, "type definition");
  12479. } else
  12480. elemDecl->subtypes = type;
  12481. }
  12482. if (elemDecl->substGroup != NULL) {
  12483. xmlSchemaElementPtr substHead;
  12484. /*
  12485. * FIXME TODO: Do we need a new field in _xmlSchemaElement for
  12486. * substitutionGroup?
  12487. */
  12488. substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
  12489. elemDecl->substGroupNs);
  12490. if (substHead == NULL) {
  12491. xmlSchemaPResCompAttrErr(ctxt,
  12492. XML_SCHEMAP_SRC_RESOLVE,
  12493. WXS_BASIC_CAST elemDecl, NULL,
  12494. "substitutionGroup", elemDecl->substGroup,
  12495. elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
  12496. } else {
  12497. xmlSchemaResolveElementReferences(substHead, ctxt);
  12498. /*
  12499. * Set the "substitution group affiliation".
  12500. * NOTE that now we use the "refDecl" field for this.
  12501. */
  12502. WXS_SUBST_HEAD(elemDecl) = substHead;
  12503. /*
  12504. * The type definitions is set to:
  12505. * SPEC "...the {type definition} of the element
  12506. * declaration `resolved` to by the `actual value`
  12507. * of the substitutionGroup [attribute], if present"
  12508. */
  12509. if (elemDecl->subtypes == NULL)
  12510. elemDecl->subtypes = substHead->subtypes;
  12511. }
  12512. }
  12513. /*
  12514. * SPEC "The definition of anyType serves as the default type definition
  12515. * for element declarations whose XML representation does not specify one."
  12516. */
  12517. if ((elemDecl->subtypes == NULL) &&
  12518. (elemDecl->namedType == NULL) &&
  12519. (elemDecl->substGroup == NULL))
  12520. elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  12521. }
  12522. /**
  12523. * xmlSchemaResolveUnionMemberTypes:
  12524. * @ctxt: the schema parser context
  12525. * @type: the schema simple type definition
  12526. *
  12527. * Checks and builds the "member type definitions" property of the union
  12528. * simple type. This handles part (1), part (2) is done in
  12529. * xmlSchemaFinishMemberTypeDefinitionsProperty()
  12530. *
  12531. * Returns -1 in case of an internal error, 0 otherwise.
  12532. */
  12533. static int
  12534. xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
  12535. xmlSchemaTypePtr type)
  12536. {
  12537. xmlSchemaTypeLinkPtr link, lastLink, newLink;
  12538. xmlSchemaTypePtr memberType;
  12539. /*
  12540. * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
  12541. * define the explicit members as the type definitions `resolved`
  12542. * to by the items in the `actual value` of the memberTypes [attribute],
  12543. * if any, followed by the type definitions corresponding to the
  12544. * <simpleType>s among the [children] of <union>, if any."
  12545. */
  12546. /*
  12547. * Resolve references.
  12548. */
  12549. link = type->memberTypes;
  12550. lastLink = NULL;
  12551. while (link != NULL) {
  12552. const xmlChar *name, *nsName;
  12553. name = ((xmlSchemaQNameRefPtr) link->type)->name;
  12554. nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
  12555. memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
  12556. if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
  12557. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  12558. WXS_BASIC_CAST type, type->node, "memberTypes",
  12559. name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
  12560. /*
  12561. * Remove the member type link.
  12562. */
  12563. if (lastLink == NULL)
  12564. type->memberTypes = link->next;
  12565. else
  12566. lastLink->next = link->next;
  12567. newLink = link;
  12568. link = link->next;
  12569. xmlFree(newLink);
  12570. } else {
  12571. link->type = memberType;
  12572. lastLink = link;
  12573. link = link->next;
  12574. }
  12575. }
  12576. /*
  12577. * Add local simple types,
  12578. */
  12579. memberType = type->subtypes;
  12580. while (memberType != NULL) {
  12581. link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
  12582. if (link == NULL) {
  12583. xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
  12584. return (-1);
  12585. }
  12586. link->type = memberType;
  12587. link->next = NULL;
  12588. if (lastLink == NULL)
  12589. type->memberTypes = link;
  12590. else
  12591. lastLink->next = link;
  12592. lastLink = link;
  12593. memberType = memberType->next;
  12594. }
  12595. return (0);
  12596. }
  12597. /**
  12598. * xmlSchemaIsDerivedFromBuiltInType:
  12599. * @ctxt: the schema parser context
  12600. * @type: the type definition
  12601. * @valType: the value type
  12602. *
  12603. *
  12604. * Returns 1 if the type has the given value type, or
  12605. * is derived from such a type.
  12606. */
  12607. static int
  12608. xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12609. {
  12610. if (type == NULL)
  12611. return (0);
  12612. if (WXS_IS_COMPLEX(type))
  12613. return (0);
  12614. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12615. if (type->builtInType == valType)
  12616. return(1);
  12617. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12618. (type->builtInType == XML_SCHEMAS_ANYTYPE))
  12619. return (0);
  12620. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12621. }
  12622. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12623. }
  12624. #if 0
  12625. /**
  12626. * xmlSchemaIsDerivedFromBuiltInType:
  12627. * @ctxt: the schema parser context
  12628. * @type: the type definition
  12629. * @valType: the value type
  12630. *
  12631. *
  12632. * Returns 1 if the type has the given value type, or
  12633. * is derived from such a type.
  12634. */
  12635. static int
  12636. xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12637. {
  12638. if (type == NULL)
  12639. return (0);
  12640. if (WXS_IS_COMPLEX(type))
  12641. return (0);
  12642. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12643. if (type->builtInType == valType)
  12644. return(1);
  12645. return (0);
  12646. } else
  12647. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12648. return (0);
  12649. }
  12650. static xmlSchemaTypePtr
  12651. xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
  12652. {
  12653. if (type == NULL)
  12654. return (NULL);
  12655. if (WXS_IS_COMPLEX(type))
  12656. return (NULL);
  12657. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12658. return(type);
  12659. return(xmlSchemaQueryBuiltInType(type->subtypes));
  12660. }
  12661. #endif
  12662. /**
  12663. * xmlSchemaGetPrimitiveType:
  12664. * @type: the simpleType definition
  12665. *
  12666. * Returns the primitive type of the given type or
  12667. * NULL in case of error.
  12668. */
  12669. static xmlSchemaTypePtr
  12670. xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
  12671. {
  12672. while (type != NULL) {
  12673. /*
  12674. * Note that anySimpleType is actually not a primitive type
  12675. * but we need that here.
  12676. */
  12677. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12678. (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
  12679. return (type);
  12680. type = type->baseType;
  12681. }
  12682. return (NULL);
  12683. }
  12684. #if 0
  12685. /**
  12686. * xmlSchemaGetBuiltInTypeAncestor:
  12687. * @type: the simpleType definition
  12688. *
  12689. * Returns the primitive type of the given type or
  12690. * NULL in case of error.
  12691. */
  12692. static xmlSchemaTypePtr
  12693. xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
  12694. {
  12695. if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
  12696. return (0);
  12697. while (type != NULL) {
  12698. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12699. return (type);
  12700. type = type->baseType;
  12701. }
  12702. return (NULL);
  12703. }
  12704. #endif
  12705. /**
  12706. * xmlSchemaCloneWildcardNsConstraints:
  12707. * @ctxt: the schema parser context
  12708. * @dest: the destination wildcard
  12709. * @source: the source wildcard
  12710. *
  12711. * Clones the namespace constraints of source
  12712. * and assigns them to dest.
  12713. * Returns -1 on internal error, 0 otherwise.
  12714. */
  12715. static int
  12716. xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
  12717. xmlSchemaWildcardPtr dest,
  12718. xmlSchemaWildcardPtr source)
  12719. {
  12720. xmlSchemaWildcardNsPtr cur, tmp, last;
  12721. if ((source == NULL) || (dest == NULL))
  12722. return(-1);
  12723. dest->any = source->any;
  12724. cur = source->nsSet;
  12725. last = NULL;
  12726. while (cur != NULL) {
  12727. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12728. if (tmp == NULL)
  12729. return(-1);
  12730. tmp->value = cur->value;
  12731. if (last == NULL)
  12732. dest->nsSet = tmp;
  12733. else
  12734. last->next = tmp;
  12735. last = tmp;
  12736. cur = cur->next;
  12737. }
  12738. if (dest->negNsSet != NULL)
  12739. xmlSchemaFreeWildcardNsSet(dest->negNsSet);
  12740. if (source->negNsSet != NULL) {
  12741. dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12742. if (dest->negNsSet == NULL)
  12743. return(-1);
  12744. dest->negNsSet->value = source->negNsSet->value;
  12745. } else
  12746. dest->negNsSet = NULL;
  12747. return(0);
  12748. }
  12749. /**
  12750. * xmlSchemaUnionWildcards:
  12751. * @ctxt: the schema parser context
  12752. * @completeWild: the first wildcard
  12753. * @curWild: the second wildcard
  12754. *
  12755. * Unions the namespace constraints of the given wildcards.
  12756. * @completeWild will hold the resulting union.
  12757. * Returns a positive error code on failure, -1 in case of an
  12758. * internal error, 0 otherwise.
  12759. */
  12760. static int
  12761. xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
  12762. xmlSchemaWildcardPtr completeWild,
  12763. xmlSchemaWildcardPtr curWild)
  12764. {
  12765. xmlSchemaWildcardNsPtr cur, curB, tmp;
  12766. /*
  12767. * 1 If O1 and O2 are the same value, then that value must be the
  12768. * value.
  12769. */
  12770. if ((completeWild->any == curWild->any) &&
  12771. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  12772. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  12773. if ((completeWild->negNsSet == NULL) ||
  12774. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  12775. if (completeWild->nsSet != NULL) {
  12776. int found = 0;
  12777. /*
  12778. * Check equality of sets.
  12779. */
  12780. cur = completeWild->nsSet;
  12781. while (cur != NULL) {
  12782. found = 0;
  12783. curB = curWild->nsSet;
  12784. while (curB != NULL) {
  12785. if (cur->value == curB->value) {
  12786. found = 1;
  12787. break;
  12788. }
  12789. curB = curB->next;
  12790. }
  12791. if (!found)
  12792. break;
  12793. cur = cur->next;
  12794. }
  12795. if (found)
  12796. return(0);
  12797. } else
  12798. return(0);
  12799. }
  12800. }
  12801. /*
  12802. * 2 If either O1 or O2 is any, then any must be the value
  12803. */
  12804. if (completeWild->any != curWild->any) {
  12805. if (completeWild->any == 0) {
  12806. completeWild->any = 1;
  12807. if (completeWild->nsSet != NULL) {
  12808. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12809. completeWild->nsSet = NULL;
  12810. }
  12811. if (completeWild->negNsSet != NULL) {
  12812. xmlFree(completeWild->negNsSet);
  12813. completeWild->negNsSet = NULL;
  12814. }
  12815. }
  12816. return (0);
  12817. }
  12818. /*
  12819. * 3 If both O1 and O2 are sets of (namespace names or `absent`),
  12820. * then the union of those sets must be the value.
  12821. */
  12822. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  12823. int found;
  12824. xmlSchemaWildcardNsPtr start;
  12825. cur = curWild->nsSet;
  12826. start = completeWild->nsSet;
  12827. while (cur != NULL) {
  12828. found = 0;
  12829. curB = start;
  12830. while (curB != NULL) {
  12831. if (cur->value == curB->value) {
  12832. found = 1;
  12833. break;
  12834. }
  12835. curB = curB->next;
  12836. }
  12837. if (!found) {
  12838. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12839. if (tmp == NULL)
  12840. return (-1);
  12841. tmp->value = cur->value;
  12842. tmp->next = completeWild->nsSet;
  12843. completeWild->nsSet = tmp;
  12844. }
  12845. cur = cur->next;
  12846. }
  12847. return(0);
  12848. }
  12849. /*
  12850. * 4 If the two are negations of different values (namespace names
  12851. * or `absent`), then a pair of not and `absent` must be the value.
  12852. */
  12853. if ((completeWild->negNsSet != NULL) &&
  12854. (curWild->negNsSet != NULL) &&
  12855. (completeWild->negNsSet->value != curWild->negNsSet->value)) {
  12856. completeWild->negNsSet->value = NULL;
  12857. return(0);
  12858. }
  12859. /*
  12860. * 5.
  12861. */
  12862. if (((completeWild->negNsSet != NULL) &&
  12863. (completeWild->negNsSet->value != NULL) &&
  12864. (curWild->nsSet != NULL)) ||
  12865. ((curWild->negNsSet != NULL) &&
  12866. (curWild->negNsSet->value != NULL) &&
  12867. (completeWild->nsSet != NULL))) {
  12868. int nsFound, absentFound = 0;
  12869. if (completeWild->nsSet != NULL) {
  12870. cur = completeWild->nsSet;
  12871. curB = curWild->negNsSet;
  12872. } else {
  12873. cur = curWild->nsSet;
  12874. curB = completeWild->negNsSet;
  12875. }
  12876. nsFound = 0;
  12877. while (cur != NULL) {
  12878. if (cur->value == NULL)
  12879. absentFound = 1;
  12880. else if (cur->value == curB->value)
  12881. nsFound = 1;
  12882. if (nsFound && absentFound)
  12883. break;
  12884. cur = cur->next;
  12885. }
  12886. if (nsFound && absentFound) {
  12887. /*
  12888. * 5.1 If the set S includes both the negated namespace
  12889. * name and `absent`, then any must be the value.
  12890. */
  12891. completeWild->any = 1;
  12892. if (completeWild->nsSet != NULL) {
  12893. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12894. completeWild->nsSet = NULL;
  12895. }
  12896. if (completeWild->negNsSet != NULL) {
  12897. xmlFree(completeWild->negNsSet);
  12898. completeWild->negNsSet = NULL;
  12899. }
  12900. } else if (nsFound && (!absentFound)) {
  12901. /*
  12902. * 5.2 If the set S includes the negated namespace name
  12903. * but not `absent`, then a pair of not and `absent` must
  12904. * be the value.
  12905. */
  12906. if (completeWild->nsSet != NULL) {
  12907. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12908. completeWild->nsSet = NULL;
  12909. }
  12910. if (completeWild->negNsSet == NULL) {
  12911. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12912. if (completeWild->negNsSet == NULL)
  12913. return (-1);
  12914. }
  12915. completeWild->negNsSet->value = NULL;
  12916. } else if ((!nsFound) && absentFound) {
  12917. /*
  12918. * 5.3 If the set S includes `absent` but not the negated
  12919. * namespace name, then the union is not expressible.
  12920. */
  12921. xmlSchemaPErr(ctxt, completeWild->node,
  12922. XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
  12923. "The union of the wildcard is not expressible.\n",
  12924. NULL, NULL);
  12925. return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
  12926. } else if ((!nsFound) && (!absentFound)) {
  12927. /*
  12928. * 5.4 If the set S does not include either the negated namespace
  12929. * name or `absent`, then whichever of O1 or O2 is a pair of not
  12930. * and a namespace name must be the value.
  12931. */
  12932. if (completeWild->negNsSet == NULL) {
  12933. if (completeWild->nsSet != NULL) {
  12934. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12935. completeWild->nsSet = NULL;
  12936. }
  12937. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12938. if (completeWild->negNsSet == NULL)
  12939. return (-1);
  12940. completeWild->negNsSet->value = curWild->negNsSet->value;
  12941. }
  12942. }
  12943. return (0);
  12944. }
  12945. /*
  12946. * 6.
  12947. */
  12948. if (((completeWild->negNsSet != NULL) &&
  12949. (completeWild->negNsSet->value == NULL) &&
  12950. (curWild->nsSet != NULL)) ||
  12951. ((curWild->negNsSet != NULL) &&
  12952. (curWild->negNsSet->value == NULL) &&
  12953. (completeWild->nsSet != NULL))) {
  12954. if (completeWild->nsSet != NULL) {
  12955. cur = completeWild->nsSet;
  12956. } else {
  12957. cur = curWild->nsSet;
  12958. }
  12959. while (cur != NULL) {
  12960. if (cur->value == NULL) {
  12961. /*
  12962. * 6.1 If the set S includes `absent`, then any must be the
  12963. * value.
  12964. */
  12965. completeWild->any = 1;
  12966. if (completeWild->nsSet != NULL) {
  12967. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12968. completeWild->nsSet = NULL;
  12969. }
  12970. if (completeWild->negNsSet != NULL) {
  12971. xmlFree(completeWild->negNsSet);
  12972. completeWild->negNsSet = NULL;
  12973. }
  12974. return (0);
  12975. }
  12976. cur = cur->next;
  12977. }
  12978. if (completeWild->negNsSet == NULL) {
  12979. /*
  12980. * 6.2 If the set S does not include `absent`, then a pair of not
  12981. * and `absent` must be the value.
  12982. */
  12983. if (completeWild->nsSet != NULL) {
  12984. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12985. completeWild->nsSet = NULL;
  12986. }
  12987. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12988. if (completeWild->negNsSet == NULL)
  12989. return (-1);
  12990. completeWild->negNsSet->value = NULL;
  12991. }
  12992. return (0);
  12993. }
  12994. return (0);
  12995. }
  12996. /**
  12997. * xmlSchemaIntersectWildcards:
  12998. * @ctxt: the schema parser context
  12999. * @completeWild: the first wildcard
  13000. * @curWild: the second wildcard
  13001. *
  13002. * Intersects the namespace constraints of the given wildcards.
  13003. * @completeWild will hold the resulting intersection.
  13004. * Returns a positive error code on failure, -1 in case of an
  13005. * internal error, 0 otherwise.
  13006. */
  13007. static int
  13008. xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
  13009. xmlSchemaWildcardPtr completeWild,
  13010. xmlSchemaWildcardPtr curWild)
  13011. {
  13012. xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
  13013. /*
  13014. * 1 If O1 and O2 are the same value, then that value must be the
  13015. * value.
  13016. */
  13017. if ((completeWild->any == curWild->any) &&
  13018. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  13019. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  13020. if ((completeWild->negNsSet == NULL) ||
  13021. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  13022. if (completeWild->nsSet != NULL) {
  13023. int found = 0;
  13024. /*
  13025. * Check equality of sets.
  13026. */
  13027. cur = completeWild->nsSet;
  13028. while (cur != NULL) {
  13029. found = 0;
  13030. curB = curWild->nsSet;
  13031. while (curB != NULL) {
  13032. if (cur->value == curB->value) {
  13033. found = 1;
  13034. break;
  13035. }
  13036. curB = curB->next;
  13037. }
  13038. if (!found)
  13039. break;
  13040. cur = cur->next;
  13041. }
  13042. if (found)
  13043. return(0);
  13044. } else
  13045. return(0);
  13046. }
  13047. }
  13048. /*
  13049. * 2 If either O1 or O2 is any, then the other must be the value.
  13050. */
  13051. if ((completeWild->any != curWild->any) && (completeWild->any)) {
  13052. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  13053. return(-1);
  13054. return(0);
  13055. }
  13056. /*
  13057. * 3 If either O1 or O2 is a pair of not and a value (a namespace
  13058. * name or `absent`) and the other is a set of (namespace names or
  13059. * `absent`), then that set, minus the negated value if it was in
  13060. * the set, minus `absent` if it was in the set, must be the value.
  13061. */
  13062. if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
  13063. ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
  13064. const xmlChar *neg;
  13065. if (completeWild->nsSet == NULL) {
  13066. neg = completeWild->negNsSet->value;
  13067. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  13068. return(-1);
  13069. } else
  13070. neg = curWild->negNsSet->value;
  13071. /*
  13072. * Remove absent and negated.
  13073. */
  13074. prev = NULL;
  13075. cur = completeWild->nsSet;
  13076. while (cur != NULL) {
  13077. if (cur->value == NULL) {
  13078. if (prev == NULL)
  13079. completeWild->nsSet = cur->next;
  13080. else
  13081. prev->next = cur->next;
  13082. xmlFree(cur);
  13083. break;
  13084. }
  13085. prev = cur;
  13086. cur = cur->next;
  13087. }
  13088. if (neg != NULL) {
  13089. prev = NULL;
  13090. cur = completeWild->nsSet;
  13091. while (cur != NULL) {
  13092. if (cur->value == neg) {
  13093. if (prev == NULL)
  13094. completeWild->nsSet = cur->next;
  13095. else
  13096. prev->next = cur->next;
  13097. xmlFree(cur);
  13098. break;
  13099. }
  13100. prev = cur;
  13101. cur = cur->next;
  13102. }
  13103. }
  13104. return(0);
  13105. }
  13106. /*
  13107. * 4 If both O1 and O2 are sets of (namespace names or `absent`),
  13108. * then the intersection of those sets must be the value.
  13109. */
  13110. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  13111. int found;
  13112. cur = completeWild->nsSet;
  13113. prev = NULL;
  13114. while (cur != NULL) {
  13115. found = 0;
  13116. curB = curWild->nsSet;
  13117. while (curB != NULL) {
  13118. if (cur->value == curB->value) {
  13119. found = 1;
  13120. break;
  13121. }
  13122. curB = curB->next;
  13123. }
  13124. if (!found) {
  13125. if (prev == NULL)
  13126. completeWild->nsSet = cur->next;
  13127. else
  13128. prev->next = cur->next;
  13129. tmp = cur->next;
  13130. xmlFree(cur);
  13131. cur = tmp;
  13132. continue;
  13133. }
  13134. prev = cur;
  13135. cur = cur->next;
  13136. }
  13137. return(0);
  13138. }
  13139. /* 5 If the two are negations of different namespace names,
  13140. * then the intersection is not expressible
  13141. */
  13142. if ((completeWild->negNsSet != NULL) &&
  13143. (curWild->negNsSet != NULL) &&
  13144. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13145. (completeWild->negNsSet->value != NULL) &&
  13146. (curWild->negNsSet->value != NULL)) {
  13147. xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
  13148. "The intersection of the wildcard is not expressible.\n",
  13149. NULL, NULL);
  13150. return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
  13151. }
  13152. /*
  13153. * 6 If the one is a negation of a namespace name and the other
  13154. * is a negation of `absent`, then the one which is the negation
  13155. * of a namespace name must be the value.
  13156. */
  13157. if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
  13158. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13159. (completeWild->negNsSet->value == NULL)) {
  13160. completeWild->negNsSet->value = curWild->negNsSet->value;
  13161. }
  13162. return(0);
  13163. }
  13164. /**
  13165. * xmlSchemaIsWildcardNsConstraintSubset:
  13166. * @ctxt: the schema parser context
  13167. * @sub: the first wildcard
  13168. * @super: the second wildcard
  13169. *
  13170. * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
  13171. *
  13172. * Returns 0 if the namespace constraint of @sub is an intensional
  13173. * subset of @super, 1 otherwise.
  13174. */
  13175. static int
  13176. xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
  13177. xmlSchemaWildcardPtr super)
  13178. {
  13179. /*
  13180. * 1 super must be any.
  13181. */
  13182. if (super->any)
  13183. return (0);
  13184. /*
  13185. * 2.1 sub must be a pair of not and a namespace name or `absent`.
  13186. * 2.2 super must be a pair of not and the same value.
  13187. */
  13188. if ((sub->negNsSet != NULL) &&
  13189. (super->negNsSet != NULL) &&
  13190. (sub->negNsSet->value == super->negNsSet->value))
  13191. return (0);
  13192. /*
  13193. * 3.1 sub must be a set whose members are either namespace names or `absent`.
  13194. */
  13195. if (sub->nsSet != NULL) {
  13196. /*
  13197. * 3.2.1 super must be the same set or a superset thereof.
  13198. */
  13199. if (super->nsSet != NULL) {
  13200. xmlSchemaWildcardNsPtr cur, curB;
  13201. int found = 0;
  13202. cur = sub->nsSet;
  13203. while (cur != NULL) {
  13204. found = 0;
  13205. curB = super->nsSet;
  13206. while (curB != NULL) {
  13207. if (cur->value == curB->value) {
  13208. found = 1;
  13209. break;
  13210. }
  13211. curB = curB->next;
  13212. }
  13213. if (!found)
  13214. return (1);
  13215. cur = cur->next;
  13216. }
  13217. if (found)
  13218. return (0);
  13219. } else if (super->negNsSet != NULL) {
  13220. xmlSchemaWildcardNsPtr cur;
  13221. /*
  13222. * 3.2.2 super must be a pair of not and a namespace name or
  13223. * `absent` and that value must not be in sub's set.
  13224. */
  13225. cur = sub->nsSet;
  13226. while (cur != NULL) {
  13227. if (cur->value == super->negNsSet->value)
  13228. return (1);
  13229. cur = cur->next;
  13230. }
  13231. return (0);
  13232. }
  13233. }
  13234. return (1);
  13235. }
  13236. static int
  13237. xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
  13238. int *fixed,
  13239. const xmlChar **value,
  13240. xmlSchemaValPtr *val)
  13241. {
  13242. *fixed = 0;
  13243. *value = NULL;
  13244. if (val != 0)
  13245. *val = NULL;
  13246. if (attruse->defValue != NULL) {
  13247. *value = attruse->defValue;
  13248. if (val != NULL)
  13249. *val = attruse->defVal;
  13250. if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
  13251. *fixed = 1;
  13252. return(1);
  13253. } else if ((attruse->attrDecl != NULL) &&
  13254. (attruse->attrDecl->defValue != NULL)) {
  13255. *value = attruse->attrDecl->defValue;
  13256. if (val != NULL)
  13257. *val = attruse->attrDecl->defVal;
  13258. if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
  13259. *fixed = 1;
  13260. return(1);
  13261. }
  13262. return(0);
  13263. }
  13264. /**
  13265. * xmlSchemaCheckCVCWildcardNamespace:
  13266. * @wild: the wildcard
  13267. * @ns: the namespace
  13268. *
  13269. * Validation Rule: Wildcard allows Namespace Name
  13270. * (cvc-wildcard-namespace)
  13271. *
  13272. * Returns 0 if the given namespace matches the wildcard,
  13273. * 1 otherwise and -1 on API errors.
  13274. */
  13275. static int
  13276. xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
  13277. const xmlChar* ns)
  13278. {
  13279. if (wild == NULL)
  13280. return(-1);
  13281. if (wild->any)
  13282. return(0);
  13283. else if (wild->nsSet != NULL) {
  13284. xmlSchemaWildcardNsPtr cur;
  13285. cur = wild->nsSet;
  13286. while (cur != NULL) {
  13287. if (xmlStrEqual(cur->value, ns))
  13288. return(0);
  13289. cur = cur->next;
  13290. }
  13291. } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
  13292. (!xmlStrEqual(wild->negNsSet->value, ns)))
  13293. return(0);
  13294. return(1);
  13295. }
  13296. #define XML_SCHEMA_ACTION_DERIVE 0
  13297. #define XML_SCHEMA_ACTION_REDEFINE 1
  13298. #define WXS_ACTION_STR(a) \
  13299. ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
  13300. /*
  13301. * Schema Component Constraint:
  13302. * Derivation Valid (Restriction, Complex)
  13303. * derivation-ok-restriction (2) - (4)
  13304. *
  13305. * ATTENTION:
  13306. * In XML Schema 1.1 this will be:
  13307. * Validation Rule:
  13308. * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
  13309. *
  13310. */
  13311. static int
  13312. xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
  13313. int action,
  13314. xmlSchemaBasicItemPtr item,
  13315. xmlSchemaBasicItemPtr baseItem,
  13316. xmlSchemaItemListPtr uses,
  13317. xmlSchemaItemListPtr baseUses,
  13318. xmlSchemaWildcardPtr wild,
  13319. xmlSchemaWildcardPtr baseWild)
  13320. {
  13321. xmlSchemaAttributeUsePtr cur = NULL, bcur;
  13322. int i, j, found; /* err = 0; */
  13323. const xmlChar *bEffValue;
  13324. int effFixed;
  13325. if (uses != NULL) {
  13326. for (i = 0; i < uses->nbItems; i++) {
  13327. cur = uses->items[i];
  13328. found = 0;
  13329. if (baseUses == NULL)
  13330. goto not_found;
  13331. for (j = 0; j < baseUses->nbItems; j++) {
  13332. bcur = baseUses->items[j];
  13333. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13334. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13335. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13336. WXS_ATTRUSE_DECL_TNS(bcur)))
  13337. {
  13338. /*
  13339. * (2.1) "If there is an attribute use in the {attribute
  13340. * uses} of the {base type definition} (call this B) whose
  13341. * {attribute declaration} has the same {name} and {target
  13342. * namespace}, then all of the following must be true:"
  13343. */
  13344. found = 1;
  13345. if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  13346. (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
  13347. {
  13348. xmlChar *str = NULL;
  13349. /*
  13350. * (2.1.1) "one of the following must be true:"
  13351. * (2.1.1.1) "B's {required} is false."
  13352. * (2.1.1.2) "R's {required} is true."
  13353. */
  13354. xmlSchemaPAttrUseErr4(pctxt,
  13355. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
  13356. WXS_ITEM_NODE(item), item, cur,
  13357. "The 'optional' attribute use is inconsistent "
  13358. "with the corresponding 'required' attribute use of "
  13359. "the %s %s",
  13360. WXS_ACTION_STR(action),
  13361. xmlSchemaGetComponentDesignation(&str, baseItem),
  13362. NULL, NULL);
  13363. FREE_AND_NULL(str);
  13364. /* err = pctxt->err; */
  13365. } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  13366. WXS_ATTRUSE_TYPEDEF(cur),
  13367. WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
  13368. {
  13369. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  13370. /*
  13371. * SPEC (2.1.2) "R's {attribute declaration}'s
  13372. * {type definition} must be validly derived from
  13373. * B's {type definition} given the empty set as
  13374. * defined in Type Derivation OK (Simple) ($3.14.6)."
  13375. */
  13376. xmlSchemaPAttrUseErr4(pctxt,
  13377. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
  13378. WXS_ITEM_NODE(item), item, cur,
  13379. "The attribute declaration's %s "
  13380. "is not validly derived from "
  13381. "the corresponding %s of the "
  13382. "attribute declaration in the %s %s",
  13383. xmlSchemaGetComponentDesignation(&strA,
  13384. WXS_ATTRUSE_TYPEDEF(cur)),
  13385. xmlSchemaGetComponentDesignation(&strB,
  13386. WXS_ATTRUSE_TYPEDEF(bcur)),
  13387. WXS_ACTION_STR(action),
  13388. xmlSchemaGetComponentDesignation(&strC, baseItem));
  13389. /* xmlSchemaGetComponentDesignation(&str, baseItem), */
  13390. FREE_AND_NULL(strA);
  13391. FREE_AND_NULL(strB);
  13392. FREE_AND_NULL(strC);
  13393. /* err = pctxt->err; */
  13394. } else {
  13395. /*
  13396. * 2.1.3 [Definition:] Let the effective value
  13397. * constraint of an attribute use be its {value
  13398. * constraint}, if present, otherwise its {attribute
  13399. * declaration}'s {value constraint} .
  13400. */
  13401. xmlSchemaGetEffectiveValueConstraint(bcur,
  13402. &effFixed, &bEffValue, NULL);
  13403. /*
  13404. * 2.1.3 ... one of the following must be true
  13405. *
  13406. * 2.1.3.1 B's `effective value constraint` is
  13407. * `absent` or default.
  13408. */
  13409. if ((bEffValue != NULL) &&
  13410. (effFixed == 1)) {
  13411. const xmlChar *rEffValue = NULL;
  13412. xmlSchemaGetEffectiveValueConstraint(bcur,
  13413. &effFixed, &rEffValue, NULL);
  13414. /*
  13415. * 2.1.3.2 R's `effective value constraint` is
  13416. * fixed with the same string as B's.
  13417. * MAYBE TODO: Compare the computed values.
  13418. * Hmm, it says "same string" so
  13419. * string-equality might really be sufficient.
  13420. */
  13421. if ((effFixed == 0) ||
  13422. (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
  13423. {
  13424. xmlChar *str = NULL;
  13425. xmlSchemaPAttrUseErr4(pctxt,
  13426. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
  13427. WXS_ITEM_NODE(item), item, cur,
  13428. "The effective value constraint of the "
  13429. "attribute use is inconsistent with "
  13430. "its correspondent in the %s %s",
  13431. WXS_ACTION_STR(action),
  13432. xmlSchemaGetComponentDesignation(&str,
  13433. baseItem),
  13434. NULL, NULL);
  13435. FREE_AND_NULL(str);
  13436. /* err = pctxt->err; */
  13437. }
  13438. }
  13439. }
  13440. break;
  13441. }
  13442. }
  13443. not_found:
  13444. if (!found) {
  13445. /*
  13446. * (2.2) "otherwise the {base type definition} must have an
  13447. * {attribute wildcard} and the {target namespace} of the
  13448. * R's {attribute declaration} must be `valid` with respect
  13449. * to that wildcard, as defined in Wildcard allows Namespace
  13450. * Name ($3.10.4)."
  13451. */
  13452. if ((baseWild == NULL) ||
  13453. (xmlSchemaCheckCVCWildcardNamespace(baseWild,
  13454. (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
  13455. {
  13456. xmlChar *str = NULL;
  13457. xmlSchemaPAttrUseErr4(pctxt,
  13458. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
  13459. WXS_ITEM_NODE(item), item, cur,
  13460. "Neither a matching attribute use, "
  13461. "nor a matching wildcard exists in the %s %s",
  13462. WXS_ACTION_STR(action),
  13463. xmlSchemaGetComponentDesignation(&str, baseItem),
  13464. NULL, NULL);
  13465. FREE_AND_NULL(str);
  13466. /* err = pctxt->err; */
  13467. }
  13468. }
  13469. }
  13470. }
  13471. /*
  13472. * SPEC derivation-ok-restriction (3):
  13473. * (3) "For each attribute use in the {attribute uses} of the {base type
  13474. * definition} whose {required} is true, there must be an attribute
  13475. * use with an {attribute declaration} with the same {name} and
  13476. * {target namespace} as its {attribute declaration} in the {attribute
  13477. * uses} of the complex type definition itself whose {required} is true.
  13478. */
  13479. if (baseUses != NULL) {
  13480. for (j = 0; j < baseUses->nbItems; j++) {
  13481. bcur = baseUses->items[j];
  13482. if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
  13483. continue;
  13484. found = 0;
  13485. if (uses != NULL) {
  13486. for (i = 0; i < uses->nbItems; i++) {
  13487. cur = uses->items[i];
  13488. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13489. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13490. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13491. WXS_ATTRUSE_DECL_TNS(bcur))) {
  13492. found = 1;
  13493. break;
  13494. }
  13495. }
  13496. }
  13497. if (!found) {
  13498. xmlChar *strA = NULL, *strB = NULL;
  13499. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13500. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
  13501. NULL, item,
  13502. "A matching attribute use for the "
  13503. "'required' %s of the %s %s is missing",
  13504. xmlSchemaGetComponentDesignation(&strA, bcur),
  13505. WXS_ACTION_STR(action),
  13506. xmlSchemaGetComponentDesignation(&strB, baseItem),
  13507. NULL);
  13508. FREE_AND_NULL(strA);
  13509. FREE_AND_NULL(strB);
  13510. }
  13511. }
  13512. }
  13513. /*
  13514. * derivation-ok-restriction (4)
  13515. */
  13516. if (wild != NULL) {
  13517. /*
  13518. * (4) "If there is an {attribute wildcard}, all of the
  13519. * following must be true:"
  13520. */
  13521. if (baseWild == NULL) {
  13522. xmlChar *str = NULL;
  13523. /*
  13524. * (4.1) "The {base type definition} must also have one."
  13525. */
  13526. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13527. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
  13528. NULL, item,
  13529. "The %s has an attribute wildcard, "
  13530. "but the %s %s '%s' does not have one",
  13531. WXS_ITEM_TYPE_NAME(item),
  13532. WXS_ACTION_STR(action),
  13533. WXS_ITEM_TYPE_NAME(baseItem),
  13534. xmlSchemaGetComponentQName(&str, baseItem));
  13535. FREE_AND_NULL(str);
  13536. return(pctxt->err);
  13537. } else if ((baseWild->any == 0) &&
  13538. xmlSchemaCheckCOSNSSubset(wild, baseWild))
  13539. {
  13540. xmlChar *str = NULL;
  13541. /*
  13542. * (4.2) "The complex type definition's {attribute wildcard}'s
  13543. * {namespace constraint} must be a subset of the {base type
  13544. * definition}'s {attribute wildcard}'s {namespace constraint},
  13545. * as defined by Wildcard Subset ($3.10.6)."
  13546. */
  13547. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13548. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
  13549. NULL, item,
  13550. "The attribute wildcard is not a valid "
  13551. "subset of the wildcard in the %s %s '%s'",
  13552. WXS_ACTION_STR(action),
  13553. WXS_ITEM_TYPE_NAME(baseItem),
  13554. xmlSchemaGetComponentQName(&str, baseItem),
  13555. NULL);
  13556. FREE_AND_NULL(str);
  13557. return(pctxt->err);
  13558. }
  13559. /* 4.3 Unless the {base type definition} is the `ur-type
  13560. * definition`, the complex type definition's {attribute
  13561. * wildcard}'s {process contents} must be identical to or
  13562. * stronger than the {base type definition}'s {attribute
  13563. * wildcard}'s {process contents}, where strict is stronger
  13564. * than lax is stronger than skip.
  13565. */
  13566. if ((! WXS_IS_ANYTYPE(baseItem)) &&
  13567. (wild->processContents < baseWild->processContents)) {
  13568. xmlChar *str = NULL;
  13569. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13570. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
  13571. NULL, baseItem,
  13572. "The {process contents} of the attribute wildcard is "
  13573. "weaker than the one in the %s %s '%s'",
  13574. WXS_ACTION_STR(action),
  13575. WXS_ITEM_TYPE_NAME(baseItem),
  13576. xmlSchemaGetComponentQName(&str, baseItem),
  13577. NULL);
  13578. FREE_AND_NULL(str)
  13579. return(pctxt->err);
  13580. }
  13581. }
  13582. return(0);
  13583. }
  13584. static int
  13585. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  13586. xmlSchemaBasicItemPtr item,
  13587. xmlSchemaWildcardPtr *completeWild,
  13588. xmlSchemaItemListPtr list,
  13589. xmlSchemaItemListPtr prohibs);
  13590. /**
  13591. * xmlSchemaFixupTypeAttributeUses:
  13592. * @ctxt: the schema parser context
  13593. * @type: the complex type definition
  13594. *
  13595. *
  13596. * Builds the wildcard and the attribute uses on the given complex type.
  13597. * Returns -1 if an internal error occurs, 0 otherwise.
  13598. *
  13599. * ATTENTION TODO: Experimentally this uses pointer comparisons for
  13600. * strings, so recheck this if we start to hardcode some schemata, since
  13601. * they might not be in the same dict.
  13602. * NOTE: It is allowed to "extend" the xs:anyType type.
  13603. */
  13604. static int
  13605. xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
  13606. xmlSchemaTypePtr type)
  13607. {
  13608. xmlSchemaTypePtr baseType = NULL;
  13609. xmlSchemaAttributeUsePtr use;
  13610. xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
  13611. if (type->baseType == NULL) {
  13612. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13613. "no base type");
  13614. return (-1);
  13615. }
  13616. baseType = type->baseType;
  13617. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  13618. if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
  13619. return(-1);
  13620. uses = type->attrUses;
  13621. baseUses = baseType->attrUses;
  13622. /*
  13623. * Expand attribute group references. And build the 'complete'
  13624. * wildcard, i.e. intersect multiple wildcards.
  13625. * Move attribute prohibitions into a separate list.
  13626. */
  13627. if (uses != NULL) {
  13628. if (WXS_IS_RESTRICTION(type)) {
  13629. /*
  13630. * This one will transfer all attr. prohibitions
  13631. * into pctxt->attrProhibs.
  13632. */
  13633. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13634. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13635. pctxt->attrProhibs) == -1)
  13636. {
  13637. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13638. "failed to expand attributes");
  13639. }
  13640. if (pctxt->attrProhibs->nbItems != 0)
  13641. prohibs = pctxt->attrProhibs;
  13642. } else {
  13643. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13644. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13645. NULL) == -1)
  13646. {
  13647. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13648. "failed to expand attributes");
  13649. }
  13650. }
  13651. }
  13652. /*
  13653. * Inherit the attribute uses of the base type.
  13654. */
  13655. if (baseUses != NULL) {
  13656. int i, j;
  13657. xmlSchemaAttributeUseProhibPtr pro;
  13658. if (WXS_IS_RESTRICTION(type)) {
  13659. int usesCount;
  13660. xmlSchemaAttributeUsePtr tmp;
  13661. if (uses != NULL)
  13662. usesCount = uses->nbItems;
  13663. else
  13664. usesCount = 0;
  13665. /* Restriction. */
  13666. for (i = 0; i < baseUses->nbItems; i++) {
  13667. use = baseUses->items[i];
  13668. if (prohibs) {
  13669. /*
  13670. * Filter out prohibited uses.
  13671. */
  13672. for (j = 0; j < prohibs->nbItems; j++) {
  13673. pro = prohibs->items[j];
  13674. if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
  13675. (WXS_ATTRUSE_DECL_TNS(use) ==
  13676. pro->targetNamespace))
  13677. {
  13678. goto inherit_next;
  13679. }
  13680. }
  13681. }
  13682. if (usesCount) {
  13683. /*
  13684. * Filter out existing uses.
  13685. */
  13686. for (j = 0; j < usesCount; j++) {
  13687. tmp = uses->items[j];
  13688. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  13689. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  13690. (WXS_ATTRUSE_DECL_TNS(use) ==
  13691. WXS_ATTRUSE_DECL_TNS(tmp)))
  13692. {
  13693. goto inherit_next;
  13694. }
  13695. }
  13696. }
  13697. if (uses == NULL) {
  13698. type->attrUses = xmlSchemaItemListCreate();
  13699. if (type->attrUses == NULL)
  13700. goto exit_failure;
  13701. uses = type->attrUses;
  13702. }
  13703. xmlSchemaItemListAddSize(uses, 2, use);
  13704. inherit_next: {}
  13705. }
  13706. } else {
  13707. /* Extension. */
  13708. for (i = 0; i < baseUses->nbItems; i++) {
  13709. use = baseUses->items[i];
  13710. if (uses == NULL) {
  13711. type->attrUses = xmlSchemaItemListCreate();
  13712. if (type->attrUses == NULL)
  13713. goto exit_failure;
  13714. uses = type->attrUses;
  13715. }
  13716. xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
  13717. }
  13718. }
  13719. }
  13720. /*
  13721. * Shrink attr. uses.
  13722. */
  13723. if (uses) {
  13724. if (uses->nbItems == 0) {
  13725. xmlSchemaItemListFree(uses);
  13726. type->attrUses = NULL;
  13727. }
  13728. /*
  13729. * TODO: We could shrink the size of the array
  13730. * to fit the actual number of items.
  13731. */
  13732. }
  13733. /*
  13734. * Compute the complete wildcard.
  13735. */
  13736. if (WXS_IS_EXTENSION(type)) {
  13737. if (baseType->attributeWildcard != NULL) {
  13738. /*
  13739. * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
  13740. * the appropriate case among the following:"
  13741. */
  13742. if (type->attributeWildcard != NULL) {
  13743. /*
  13744. * Union the complete wildcard with the base wildcard.
  13745. * SPEC {attribute wildcard}
  13746. * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
  13747. * and {annotation} are those of the `complete wildcard`,
  13748. * and whose {namespace constraint} is the intensional union
  13749. * of the {namespace constraint} of the `complete wildcard`
  13750. * and of the `base wildcard`, as defined in Attribute
  13751. * Wildcard Union ($3.10.6)."
  13752. */
  13753. if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
  13754. baseType->attributeWildcard) == -1)
  13755. goto exit_failure;
  13756. } else {
  13757. /*
  13758. * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
  13759. * then the `base wildcard`."
  13760. */
  13761. type->attributeWildcard = baseType->attributeWildcard;
  13762. }
  13763. } else {
  13764. /*
  13765. * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
  13766. * `complete wildcard`"
  13767. * NOOP
  13768. */
  13769. }
  13770. } else {
  13771. /*
  13772. * SPEC {attribute wildcard}
  13773. * (3.1) "If the <restriction> alternative is chosen, then the
  13774. * `complete wildcard`;"
  13775. * NOOP
  13776. */
  13777. }
  13778. return (0);
  13779. exit_failure:
  13780. return(-1);
  13781. }
  13782. /**
  13783. * xmlSchemaTypeFinalContains:
  13784. * @schema: the schema
  13785. * @type: the type definition
  13786. * @final: the final
  13787. *
  13788. * Evaluates if a type definition contains the given "final".
  13789. * This does take "finalDefault" into account as well.
  13790. *
  13791. * Returns 1 if the type does contain the given "final",
  13792. * 0 otherwise.
  13793. */
  13794. static int
  13795. xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
  13796. {
  13797. if (type == NULL)
  13798. return (0);
  13799. if (type->flags & final)
  13800. return (1);
  13801. else
  13802. return (0);
  13803. }
  13804. /**
  13805. * xmlSchemaGetUnionSimpleTypeMemberTypes:
  13806. * @type: the Union Simple Type
  13807. *
  13808. * Returns a list of member types of @type if existing,
  13809. * returns NULL otherwise.
  13810. */
  13811. static xmlSchemaTypeLinkPtr
  13812. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
  13813. {
  13814. while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
  13815. if (type->memberTypes != NULL)
  13816. return (type->memberTypes);
  13817. else
  13818. type = type->baseType;
  13819. }
  13820. return (NULL);
  13821. }
  13822. #if 0
  13823. /**
  13824. * xmlSchemaGetParticleTotalRangeMin:
  13825. * @particle: the particle
  13826. *
  13827. * Schema Component Constraint: Effective Total Range
  13828. * (all and sequence) + (choice)
  13829. *
  13830. * Returns the minimum Effective Total Range.
  13831. */
  13832. static int
  13833. xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
  13834. {
  13835. if ((particle->children == NULL) ||
  13836. (particle->minOccurs == 0))
  13837. return (0);
  13838. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13839. int min = -1, cur;
  13840. xmlSchemaParticlePtr part =
  13841. (xmlSchemaParticlePtr) particle->children->children;
  13842. if (part == NULL)
  13843. return (0);
  13844. while (part != NULL) {
  13845. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13846. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13847. cur = part->minOccurs;
  13848. else
  13849. cur = xmlSchemaGetParticleTotalRangeMin(part);
  13850. if (cur == 0)
  13851. return (0);
  13852. if ((min > cur) || (min == -1))
  13853. min = cur;
  13854. part = (xmlSchemaParticlePtr) part->next;
  13855. }
  13856. return (particle->minOccurs * min);
  13857. } else {
  13858. /* <all> and <sequence> */
  13859. int sum = 0;
  13860. xmlSchemaParticlePtr part =
  13861. (xmlSchemaParticlePtr) particle->children->children;
  13862. if (part == NULL)
  13863. return (0);
  13864. do {
  13865. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13866. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13867. sum += part->minOccurs;
  13868. else
  13869. sum += xmlSchemaGetParticleTotalRangeMin(part);
  13870. part = (xmlSchemaParticlePtr) part->next;
  13871. } while (part != NULL);
  13872. return (particle->minOccurs * sum);
  13873. }
  13874. }
  13875. /**
  13876. * xmlSchemaGetParticleTotalRangeMax:
  13877. * @particle: the particle
  13878. *
  13879. * Schema Component Constraint: Effective Total Range
  13880. * (all and sequence) + (choice)
  13881. *
  13882. * Returns the maximum Effective Total Range.
  13883. */
  13884. static int
  13885. xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
  13886. {
  13887. if ((particle->children == NULL) ||
  13888. (particle->children->children == NULL))
  13889. return (0);
  13890. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13891. int max = -1, cur;
  13892. xmlSchemaParticlePtr part =
  13893. (xmlSchemaParticlePtr) particle->children->children;
  13894. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13895. if (part->children == NULL)
  13896. continue;
  13897. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13898. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13899. cur = part->maxOccurs;
  13900. else
  13901. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13902. if (cur == UNBOUNDED)
  13903. return (UNBOUNDED);
  13904. if ((max < cur) || (max == -1))
  13905. max = cur;
  13906. }
  13907. /* TODO: Handle overflows? */
  13908. return (particle->maxOccurs * max);
  13909. } else {
  13910. /* <all> and <sequence> */
  13911. int sum = 0, cur;
  13912. xmlSchemaParticlePtr part =
  13913. (xmlSchemaParticlePtr) particle->children->children;
  13914. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13915. if (part->children == NULL)
  13916. continue;
  13917. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13918. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13919. cur = part->maxOccurs;
  13920. else
  13921. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13922. if (cur == UNBOUNDED)
  13923. return (UNBOUNDED);
  13924. if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
  13925. return (UNBOUNDED);
  13926. sum += cur;
  13927. }
  13928. /* TODO: Handle overflows? */
  13929. return (particle->maxOccurs * sum);
  13930. }
  13931. }
  13932. #endif
  13933. /**
  13934. * xmlSchemaGetParticleEmptiable:
  13935. * @particle: the particle
  13936. *
  13937. * Returns 1 if emptiable, 0 otherwise.
  13938. */
  13939. static int
  13940. xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
  13941. {
  13942. xmlSchemaParticlePtr part;
  13943. int emptiable;
  13944. if ((particle->children == NULL) || (particle->minOccurs == 0))
  13945. return (1);
  13946. part = (xmlSchemaParticlePtr) particle->children->children;
  13947. if (part == NULL)
  13948. return (1);
  13949. while (part != NULL) {
  13950. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13951. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13952. emptiable = (part->minOccurs == 0);
  13953. else
  13954. emptiable = xmlSchemaGetParticleEmptiable(part);
  13955. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13956. if (emptiable)
  13957. return (1);
  13958. } else {
  13959. /* <all> and <sequence> */
  13960. if (!emptiable)
  13961. return (0);
  13962. }
  13963. part = (xmlSchemaParticlePtr) part->next;
  13964. }
  13965. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
  13966. return (0);
  13967. else
  13968. return (1);
  13969. }
  13970. /**
  13971. * xmlSchemaIsParticleEmptiable:
  13972. * @particle: the particle
  13973. *
  13974. * Schema Component Constraint: Particle Emptiable
  13975. * Checks whether the given particle is emptiable.
  13976. *
  13977. * Returns 1 if emptiable, 0 otherwise.
  13978. */
  13979. static int
  13980. xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
  13981. {
  13982. /*
  13983. * SPEC (1) "Its {min occurs} is 0."
  13984. */
  13985. if ((particle == NULL) || (particle->minOccurs == 0) ||
  13986. (particle->children == NULL))
  13987. return (1);
  13988. /*
  13989. * SPEC (2) "Its {term} is a group and the minimum part of the
  13990. * effective total range of that group, [...] is 0."
  13991. */
  13992. if (WXS_IS_MODEL_GROUP(particle->children))
  13993. return (xmlSchemaGetParticleEmptiable(particle));
  13994. return (0);
  13995. }
  13996. /**
  13997. * xmlSchemaCheckCOSSTDerivedOK:
  13998. * @actxt: a context
  13999. * @type: the derived simple type definition
  14000. * @baseType: the base type definition
  14001. * @subset: the subset of ('restriction', etc.)
  14002. *
  14003. * Schema Component Constraint:
  14004. * Type Derivation OK (Simple) (cos-st-derived-OK)
  14005. *
  14006. * Checks whether @type can be validly
  14007. * derived from @baseType.
  14008. *
  14009. * Returns 0 on success, an positive error code otherwise.
  14010. */
  14011. static int
  14012. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  14013. xmlSchemaTypePtr type,
  14014. xmlSchemaTypePtr baseType,
  14015. int subset)
  14016. {
  14017. /*
  14018. * 1 They are the same type definition.
  14019. * TODO: The identity check might have to be more complex than this.
  14020. */
  14021. if (type == baseType)
  14022. return (0);
  14023. /*
  14024. * 2.1 restriction is not in the subset, or in the {final}
  14025. * of its own {base type definition};
  14026. *
  14027. * NOTE that this will be used also via "xsi:type".
  14028. *
  14029. * TODO: Revise this, it looks strange. How can the "type"
  14030. * not be fixed or *in* fixing?
  14031. */
  14032. if (WXS_IS_TYPE_NOT_FIXED(type))
  14033. if (xmlSchemaTypeFixup(type, actxt) == -1)
  14034. return(-1);
  14035. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  14036. if (xmlSchemaTypeFixup(baseType, actxt) == -1)
  14037. return(-1);
  14038. if ((subset & SUBSET_RESTRICTION) ||
  14039. (xmlSchemaTypeFinalContains(type->baseType,
  14040. XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
  14041. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
  14042. }
  14043. /* 2.2 */
  14044. if (type->baseType == baseType) {
  14045. /*
  14046. * 2.2.1 D's `base type definition` is B.
  14047. */
  14048. return (0);
  14049. }
  14050. /*
  14051. * 2.2.2 D's `base type definition` is not the `ur-type definition`
  14052. * and is validly derived from B given the subset, as defined by this
  14053. * constraint.
  14054. */
  14055. if ((! WXS_IS_ANYTYPE(type->baseType)) &&
  14056. (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  14057. baseType, subset) == 0)) {
  14058. return (0);
  14059. }
  14060. /*
  14061. * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
  14062. * definition`.
  14063. */
  14064. if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
  14065. (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
  14066. return (0);
  14067. }
  14068. /*
  14069. * 2.2.4 B's {variety} is union and D is validly derived from a type
  14070. * definition in B's {member type definitions} given the subset, as
  14071. * defined by this constraint.
  14072. *
  14073. * NOTE: This seems not to involve built-in types, since there is no
  14074. * built-in Union Simple Type.
  14075. */
  14076. if (WXS_IS_UNION(baseType)) {
  14077. xmlSchemaTypeLinkPtr cur;
  14078. cur = baseType->memberTypes;
  14079. while (cur != NULL) {
  14080. if (WXS_IS_TYPE_NOT_FIXED(cur->type))
  14081. if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
  14082. return(-1);
  14083. if (xmlSchemaCheckCOSSTDerivedOK(actxt,
  14084. type, cur->type, subset) == 0)
  14085. {
  14086. /*
  14087. * It just has to be validly derived from at least one
  14088. * member-type.
  14089. */
  14090. return (0);
  14091. }
  14092. cur = cur->next;
  14093. }
  14094. }
  14095. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
  14096. }
  14097. /**
  14098. * xmlSchemaCheckTypeDefCircularInternal:
  14099. * @pctxt: the schema parser context
  14100. * @ctxtType: the type definition
  14101. * @ancestor: an ancestor of @ctxtType
  14102. *
  14103. * Checks st-props-correct (2) + ct-props-correct (3).
  14104. * Circular type definitions are not allowed.
  14105. *
  14106. * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
  14107. * circular, 0 otherwise.
  14108. */
  14109. static int
  14110. xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
  14111. xmlSchemaTypePtr ctxtType,
  14112. xmlSchemaTypePtr ancestor)
  14113. {
  14114. int ret;
  14115. if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
  14116. return (0);
  14117. if (ctxtType == ancestor) {
  14118. xmlSchemaPCustomErr(pctxt,
  14119. XML_SCHEMAP_ST_PROPS_CORRECT_2,
  14120. WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
  14121. "The definition is circular", NULL);
  14122. return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
  14123. }
  14124. if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
  14125. /*
  14126. * Avoid infinite recursion on circular types not yet checked.
  14127. */
  14128. return (0);
  14129. }
  14130. ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
  14131. ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
  14132. ancestor->baseType);
  14133. ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
  14134. return (ret);
  14135. }
  14136. /**
  14137. * xmlSchemaCheckTypeDefCircular:
  14138. * @item: the complex/simple type definition
  14139. * @ctxt: the parser context
  14140. * @name: the name
  14141. *
  14142. * Checks for circular type definitions.
  14143. */
  14144. static void
  14145. xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
  14146. xmlSchemaParserCtxtPtr ctxt)
  14147. {
  14148. if ((item == NULL) ||
  14149. (item->type == XML_SCHEMA_TYPE_BASIC) ||
  14150. (item->baseType == NULL))
  14151. return;
  14152. xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
  14153. item->baseType);
  14154. }
  14155. /*
  14156. * Simple Type Definition Representation OK (src-simple-type) 4
  14157. *
  14158. * "4 Circular union type definition is disallowed. That is, if the
  14159. * <union> alternative is chosen, there must not be any entries in the
  14160. * memberTypes [attribute] at any depth which resolve to the component
  14161. * corresponding to the <simpleType>."
  14162. *
  14163. * Note that this should work on the *representation* of a component,
  14164. * thus assumes any union types in the member types not being yet
  14165. * substituted. At this stage we need the variety of the types
  14166. * to be already computed.
  14167. */
  14168. static int
  14169. xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
  14170. xmlSchemaTypePtr ctxType,
  14171. xmlSchemaTypeLinkPtr members)
  14172. {
  14173. xmlSchemaTypeLinkPtr member;
  14174. xmlSchemaTypePtr memberType;
  14175. member = members;
  14176. while (member != NULL) {
  14177. memberType = member->type;
  14178. while ((memberType != NULL) &&
  14179. (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
  14180. if (memberType == ctxType) {
  14181. xmlSchemaPCustomErr(pctxt,
  14182. XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
  14183. WXS_BASIC_CAST ctxType, NULL,
  14184. "The union type definition is circular", NULL);
  14185. return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
  14186. }
  14187. if ((WXS_IS_UNION(memberType)) &&
  14188. ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
  14189. {
  14190. int res;
  14191. memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
  14192. res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
  14193. ctxType,
  14194. xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
  14195. memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
  14196. if (res != 0)
  14197. return(res);
  14198. }
  14199. memberType = memberType->baseType;
  14200. }
  14201. member = member->next;
  14202. }
  14203. return(0);
  14204. }
  14205. static int
  14206. xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
  14207. xmlSchemaTypePtr type)
  14208. {
  14209. if (! WXS_IS_UNION(type))
  14210. return(0);
  14211. return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
  14212. type->memberTypes));
  14213. }
  14214. /**
  14215. * xmlSchemaResolveTypeReferences:
  14216. * @item: the complex/simple type definition
  14217. * @ctxt: the parser context
  14218. * @name: the name
  14219. *
  14220. * Resolves type definition references
  14221. */
  14222. static void
  14223. xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
  14224. xmlSchemaParserCtxtPtr ctxt)
  14225. {
  14226. if (typeDef == NULL)
  14227. return;
  14228. /*
  14229. * Resolve the base type.
  14230. */
  14231. if (typeDef->baseType == NULL) {
  14232. typeDef->baseType = xmlSchemaGetType(ctxt->schema,
  14233. typeDef->base, typeDef->baseNs);
  14234. if (typeDef->baseType == NULL) {
  14235. xmlSchemaPResCompAttrErr(ctxt,
  14236. XML_SCHEMAP_SRC_RESOLVE,
  14237. WXS_BASIC_CAST typeDef, typeDef->node,
  14238. "base", typeDef->base, typeDef->baseNs,
  14239. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14240. return;
  14241. }
  14242. }
  14243. if (WXS_IS_SIMPLE(typeDef)) {
  14244. if (WXS_IS_UNION(typeDef)) {
  14245. /*
  14246. * Resolve the memberTypes.
  14247. */
  14248. xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
  14249. return;
  14250. } else if (WXS_IS_LIST(typeDef)) {
  14251. /*
  14252. * Resolve the itemType.
  14253. */
  14254. if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
  14255. typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
  14256. typeDef->base, typeDef->baseNs);
  14257. if ((typeDef->subtypes == NULL) ||
  14258. (! WXS_IS_SIMPLE(typeDef->subtypes)))
  14259. {
  14260. typeDef->subtypes = NULL;
  14261. xmlSchemaPResCompAttrErr(ctxt,
  14262. XML_SCHEMAP_SRC_RESOLVE,
  14263. WXS_BASIC_CAST typeDef, typeDef->node,
  14264. "itemType", typeDef->base, typeDef->baseNs,
  14265. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14266. }
  14267. }
  14268. return;
  14269. }
  14270. }
  14271. /*
  14272. * The ball of letters below means, that if we have a particle
  14273. * which has a QName-helper component as its {term}, we want
  14274. * to resolve it...
  14275. */
  14276. else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
  14277. ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
  14278. XML_SCHEMA_TYPE_PARTICLE) &&
  14279. (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
  14280. ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
  14281. XML_SCHEMA_EXTRA_QNAMEREF))
  14282. {
  14283. xmlSchemaQNameRefPtr ref =
  14284. WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
  14285. xmlSchemaModelGroupDefPtr groupDef;
  14286. /*
  14287. * URGENT TODO: Test this.
  14288. */
  14289. WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
  14290. /*
  14291. * Resolve the MG definition reference.
  14292. */
  14293. groupDef =
  14294. WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
  14295. ref->itemType, ref->name, ref->targetNamespace);
  14296. if (groupDef == NULL) {
  14297. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  14298. NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
  14299. "ref", ref->name, ref->targetNamespace, ref->itemType,
  14300. NULL);
  14301. /* Remove the particle. */
  14302. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14303. } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
  14304. /* Remove the particle. */
  14305. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14306. else {
  14307. /*
  14308. * Assign the MG definition's {model group} to the
  14309. * particle's {term}.
  14310. */
  14311. WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
  14312. if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
  14313. /*
  14314. * SPEC cos-all-limited (1.2)
  14315. * "1.2 the {term} property of a particle with
  14316. * {max occurs}=1 which is part of a pair which constitutes
  14317. * the {content type} of a complex type definition."
  14318. */
  14319. if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
  14320. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  14321. /* TODO: error code */
  14322. XML_SCHEMAP_COS_ALL_LIMITED,
  14323. WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
  14324. "The particle's {max occurs} must be 1, since the "
  14325. "reference resolves to an 'all' model group",
  14326. NULL, NULL);
  14327. }
  14328. }
  14329. }
  14330. }
  14331. }
  14332. /**
  14333. * xmlSchemaCheckSTPropsCorrect:
  14334. * @ctxt: the schema parser context
  14335. * @type: the simple type definition
  14336. *
  14337. * Checks st-props-correct.
  14338. *
  14339. * Returns 0 if the properties are correct,
  14340. * if not, a positive error code and -1 on internal
  14341. * errors.
  14342. */
  14343. static int
  14344. xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  14345. xmlSchemaTypePtr type)
  14346. {
  14347. xmlSchemaTypePtr baseType = type->baseType;
  14348. xmlChar *str = NULL;
  14349. /* STATE: error funcs converted. */
  14350. /*
  14351. * Schema Component Constraint: Simple Type Definition Properties Correct
  14352. *
  14353. * NOTE: This is somehow redundant, since we actually built a simple type
  14354. * to have all the needed information; this acts as an self test.
  14355. */
  14356. /* Base type: If the datatype has been `derived` by `restriction`
  14357. * then the Simple Type Definition component from which it is `derived`,
  14358. * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
  14359. */
  14360. if (baseType == NULL) {
  14361. /*
  14362. * TODO: Think about: "modulo the impact of Missing
  14363. * Sub-components ($5.3)."
  14364. */
  14365. xmlSchemaPCustomErr(ctxt,
  14366. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14367. WXS_BASIC_CAST type, NULL,
  14368. "No base type existent", NULL);
  14369. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14370. }
  14371. if (! WXS_IS_SIMPLE(baseType)) {
  14372. xmlSchemaPCustomErr(ctxt,
  14373. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14374. WXS_BASIC_CAST type, NULL,
  14375. "The base type '%s' is not a simple type",
  14376. xmlSchemaGetComponentQName(&str, baseType));
  14377. FREE_AND_NULL(str)
  14378. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14379. }
  14380. if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
  14381. (WXS_IS_RESTRICTION(type) == 0) &&
  14382. ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
  14383. (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
  14384. xmlSchemaPCustomErr(ctxt,
  14385. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14386. WXS_BASIC_CAST type, NULL,
  14387. "A type, derived by list or union, must have "
  14388. "the simple ur-type definition as base type, not '%s'",
  14389. xmlSchemaGetComponentQName(&str, baseType));
  14390. FREE_AND_NULL(str)
  14391. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14392. }
  14393. /*
  14394. * Variety: One of {atomic, list, union}.
  14395. */
  14396. if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
  14397. (! WXS_IS_LIST(type))) {
  14398. xmlSchemaPCustomErr(ctxt,
  14399. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14400. WXS_BASIC_CAST type, NULL,
  14401. "The variety is absent", NULL);
  14402. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14403. }
  14404. /* TODO: Finish this. Hmm, is this finished? */
  14405. /*
  14406. * 3 The {final} of the {base type definition} must not contain restriction.
  14407. */
  14408. if (xmlSchemaTypeFinalContains(baseType,
  14409. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14410. xmlSchemaPCustomErr(ctxt,
  14411. XML_SCHEMAP_ST_PROPS_CORRECT_3,
  14412. WXS_BASIC_CAST type, NULL,
  14413. "The 'final' of its base type '%s' must not contain "
  14414. "'restriction'",
  14415. xmlSchemaGetComponentQName(&str, baseType));
  14416. FREE_AND_NULL(str)
  14417. return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
  14418. }
  14419. /*
  14420. * 2 All simple type definitions must be derived ultimately from the `simple
  14421. * ur-type definition` (so circular definitions are disallowed). That is, it
  14422. * must be possible to reach a built-in primitive datatype or the `simple
  14423. * ur-type definition` by repeatedly following the {base type definition}.
  14424. *
  14425. * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
  14426. */
  14427. return (0);
  14428. }
  14429. /**
  14430. * xmlSchemaCheckCOSSTRestricts:
  14431. * @ctxt: the schema parser context
  14432. * @type: the simple type definition
  14433. *
  14434. * Schema Component Constraint:
  14435. * Derivation Valid (Restriction, Simple) (cos-st-restricts)
  14436. * Checks if the given @type (simpleType) is derived validly by restriction.
  14437. * STATUS:
  14438. *
  14439. * Returns -1 on internal errors, 0 if the type is validly derived,
  14440. * a positive error code otherwise.
  14441. */
  14442. static int
  14443. xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
  14444. xmlSchemaTypePtr type)
  14445. {
  14446. xmlChar *str = NULL;
  14447. if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
  14448. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14449. "given type is not a user-derived simpleType");
  14450. return (-1);
  14451. }
  14452. if (WXS_IS_ATOMIC(type)) {
  14453. xmlSchemaTypePtr primitive;
  14454. /*
  14455. * 1.1 The {base type definition} must be an atomic simple
  14456. * type definition or a built-in primitive datatype.
  14457. */
  14458. if (! WXS_IS_ATOMIC(type->baseType)) {
  14459. xmlSchemaPCustomErr(pctxt,
  14460. XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
  14461. WXS_BASIC_CAST type, NULL,
  14462. "The base type '%s' is not an atomic simple type",
  14463. xmlSchemaGetComponentQName(&str, type->baseType));
  14464. FREE_AND_NULL(str)
  14465. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
  14466. }
  14467. /* 1.2 The {final} of the {base type definition} must not contain
  14468. * restriction.
  14469. */
  14470. /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
  14471. if (xmlSchemaTypeFinalContains(type->baseType,
  14472. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14473. xmlSchemaPCustomErr(pctxt,
  14474. XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
  14475. WXS_BASIC_CAST type, NULL,
  14476. "The final of its base type '%s' must not contain 'restriction'",
  14477. xmlSchemaGetComponentQName(&str, type->baseType));
  14478. FREE_AND_NULL(str)
  14479. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
  14480. }
  14481. /*
  14482. * 1.3.1 DF must be an allowed constraining facet for the {primitive
  14483. * type definition}, as specified in the appropriate subsection of 3.2
  14484. * Primitive datatypes.
  14485. */
  14486. if (type->facets != NULL) {
  14487. xmlSchemaFacetPtr facet;
  14488. int ok = 1;
  14489. primitive = xmlSchemaGetPrimitiveType(type);
  14490. if (primitive == NULL) {
  14491. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14492. "failed to get primitive type");
  14493. return (-1);
  14494. }
  14495. facet = type->facets;
  14496. do {
  14497. if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
  14498. ok = 0;
  14499. xmlSchemaPIllegalFacetAtomicErr(pctxt,
  14500. XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
  14501. type, primitive, facet);
  14502. }
  14503. facet = facet->next;
  14504. } while (facet != NULL);
  14505. if (ok == 0)
  14506. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
  14507. }
  14508. /*
  14509. * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
  14510. * of the {base type definition} (call this BF),then the DF's {value}
  14511. * must be a valid restriction of BF's {value} as defined in
  14512. * [XML Schemas: Datatypes]."
  14513. *
  14514. * NOTE (1.3.2) Facet derivation constraints are currently handled in
  14515. * xmlSchemaDeriveAndValidateFacets()
  14516. */
  14517. } else if (WXS_IS_LIST(type)) {
  14518. xmlSchemaTypePtr itemType = NULL;
  14519. itemType = type->subtypes;
  14520. if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
  14521. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14522. "failed to evaluate the item type");
  14523. return (-1);
  14524. }
  14525. if (WXS_IS_TYPE_NOT_FIXED(itemType))
  14526. xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
  14527. /*
  14528. * 2.1 The {item type definition} must have a {variety} of atomic or
  14529. * union (in which case all the {member type definitions}
  14530. * must be atomic).
  14531. */
  14532. if ((! WXS_IS_ATOMIC(itemType)) &&
  14533. (! WXS_IS_UNION(itemType))) {
  14534. xmlSchemaPCustomErr(pctxt,
  14535. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14536. WXS_BASIC_CAST type, NULL,
  14537. "The item type '%s' does not have a variety of atomic or union",
  14538. xmlSchemaGetComponentQName(&str, itemType));
  14539. FREE_AND_NULL(str)
  14540. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14541. } else if (WXS_IS_UNION(itemType)) {
  14542. xmlSchemaTypeLinkPtr member;
  14543. member = itemType->memberTypes;
  14544. while (member != NULL) {
  14545. if (! WXS_IS_ATOMIC(member->type)) {
  14546. xmlSchemaPCustomErr(pctxt,
  14547. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14548. WXS_BASIC_CAST type, NULL,
  14549. "The item type is a union type, but the "
  14550. "member type '%s' of this item type is not atomic",
  14551. xmlSchemaGetComponentQName(&str, member->type));
  14552. FREE_AND_NULL(str)
  14553. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14554. }
  14555. member = member->next;
  14556. }
  14557. }
  14558. if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
  14559. xmlSchemaFacetPtr facet;
  14560. /*
  14561. * This is the case if we have: <simpleType><list ..
  14562. */
  14563. /*
  14564. * 2.3.1
  14565. * 2.3.1.1 The {final} of the {item type definition} must not
  14566. * contain list.
  14567. */
  14568. if (xmlSchemaTypeFinalContains(itemType,
  14569. XML_SCHEMAS_TYPE_FINAL_LIST)) {
  14570. xmlSchemaPCustomErr(pctxt,
  14571. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
  14572. WXS_BASIC_CAST type, NULL,
  14573. "The final of its item type '%s' must not contain 'list'",
  14574. xmlSchemaGetComponentQName(&str, itemType));
  14575. FREE_AND_NULL(str)
  14576. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
  14577. }
  14578. /*
  14579. * 2.3.1.2 The {facets} must only contain the whiteSpace
  14580. * facet component.
  14581. * OPTIMIZE TODO: the S4S already disallows any facet
  14582. * to be specified.
  14583. */
  14584. if (type->facets != NULL) {
  14585. facet = type->facets;
  14586. do {
  14587. if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
  14588. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14589. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
  14590. type, facet);
  14591. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
  14592. }
  14593. facet = facet->next;
  14594. } while (facet != NULL);
  14595. }
  14596. /*
  14597. * MAYBE TODO: (Hmm, not really) Datatypes states:
  14598. * A `list` datatype can be `derived` from an `atomic` datatype
  14599. * whose `lexical space` allows space (such as string or anyURI)or
  14600. * a `union` datatype any of whose {member type definitions}'s
  14601. * `lexical space` allows space.
  14602. */
  14603. } else {
  14604. /*
  14605. * This is the case if we have: <simpleType><restriction ...
  14606. * I.e. the variety of "list" is inherited.
  14607. */
  14608. /*
  14609. * 2.3.2
  14610. * 2.3.2.1 The {base type definition} must have a {variety} of list.
  14611. */
  14612. if (! WXS_IS_LIST(type->baseType)) {
  14613. xmlSchemaPCustomErr(pctxt,
  14614. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
  14615. WXS_BASIC_CAST type, NULL,
  14616. "The base type '%s' must be a list type",
  14617. xmlSchemaGetComponentQName(&str, type->baseType));
  14618. FREE_AND_NULL(str)
  14619. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
  14620. }
  14621. /*
  14622. * 2.3.2.2 The {final} of the {base type definition} must not
  14623. * contain restriction.
  14624. */
  14625. if (xmlSchemaTypeFinalContains(type->baseType,
  14626. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14627. xmlSchemaPCustomErr(pctxt,
  14628. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
  14629. WXS_BASIC_CAST type, NULL,
  14630. "The 'final' of the base type '%s' must not contain 'restriction'",
  14631. xmlSchemaGetComponentQName(&str, type->baseType));
  14632. FREE_AND_NULL(str)
  14633. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
  14634. }
  14635. /*
  14636. * 2.3.2.3 The {item type definition} must be validly derived
  14637. * from the {base type definition}'s {item type definition} given
  14638. * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
  14639. */
  14640. {
  14641. xmlSchemaTypePtr baseItemType;
  14642. baseItemType = type->baseType->subtypes;
  14643. if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
  14644. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14645. "failed to eval the item type of a base type");
  14646. return (-1);
  14647. }
  14648. if ((itemType != baseItemType) &&
  14649. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
  14650. baseItemType, 0) != 0)) {
  14651. xmlChar *strBIT = NULL, *strBT = NULL;
  14652. xmlSchemaPCustomErrExt(pctxt,
  14653. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
  14654. WXS_BASIC_CAST type, NULL,
  14655. "The item type '%s' is not validly derived from "
  14656. "the item type '%s' of the base type '%s'",
  14657. xmlSchemaGetComponentQName(&str, itemType),
  14658. xmlSchemaGetComponentQName(&strBIT, baseItemType),
  14659. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14660. FREE_AND_NULL(str)
  14661. FREE_AND_NULL(strBIT)
  14662. FREE_AND_NULL(strBT)
  14663. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
  14664. }
  14665. }
  14666. if (type->facets != NULL) {
  14667. xmlSchemaFacetPtr facet;
  14668. int ok = 1;
  14669. /*
  14670. * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
  14671. * and enumeration facet components are allowed among the {facets}.
  14672. */
  14673. facet = type->facets;
  14674. do {
  14675. switch (facet->type) {
  14676. case XML_SCHEMA_FACET_LENGTH:
  14677. case XML_SCHEMA_FACET_MINLENGTH:
  14678. case XML_SCHEMA_FACET_MAXLENGTH:
  14679. case XML_SCHEMA_FACET_WHITESPACE:
  14680. /*
  14681. * TODO: 2.5.1.2 List datatypes
  14682. * The value of `whiteSpace` is fixed to the value collapse.
  14683. */
  14684. case XML_SCHEMA_FACET_PATTERN:
  14685. case XML_SCHEMA_FACET_ENUMERATION:
  14686. break;
  14687. default: {
  14688. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14689. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
  14690. type, facet);
  14691. /*
  14692. * We could return, but it's nicer to report all
  14693. * invalid facets.
  14694. */
  14695. ok = 0;
  14696. }
  14697. }
  14698. facet = facet->next;
  14699. } while (facet != NULL);
  14700. if (ok == 0)
  14701. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
  14702. /*
  14703. * SPEC (2.3.2.5) (same as 1.3.2)
  14704. *
  14705. * NOTE (2.3.2.5) This is currently done in
  14706. * xmlSchemaDeriveAndValidateFacets()
  14707. */
  14708. }
  14709. }
  14710. } else if (WXS_IS_UNION(type)) {
  14711. /*
  14712. * 3.1 The {member type definitions} must all have {variety} of
  14713. * atomic or list.
  14714. */
  14715. xmlSchemaTypeLinkPtr member;
  14716. member = type->memberTypes;
  14717. while (member != NULL) {
  14718. if (WXS_IS_TYPE_NOT_FIXED(member->type))
  14719. xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
  14720. if ((! WXS_IS_ATOMIC(member->type)) &&
  14721. (! WXS_IS_LIST(member->type))) {
  14722. xmlSchemaPCustomErr(pctxt,
  14723. XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
  14724. WXS_BASIC_CAST type, NULL,
  14725. "The member type '%s' is neither an atomic, nor a list type",
  14726. xmlSchemaGetComponentQName(&str, member->type));
  14727. FREE_AND_NULL(str)
  14728. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
  14729. }
  14730. member = member->next;
  14731. }
  14732. /*
  14733. * 3.3.1 If the {base type definition} is the `simple ur-type
  14734. * definition`
  14735. */
  14736. if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
  14737. /*
  14738. * 3.3.1.1 All of the {member type definitions} must have a
  14739. * {final} which does not contain union.
  14740. */
  14741. member = type->memberTypes;
  14742. while (member != NULL) {
  14743. if (xmlSchemaTypeFinalContains(member->type,
  14744. XML_SCHEMAS_TYPE_FINAL_UNION)) {
  14745. xmlSchemaPCustomErr(pctxt,
  14746. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
  14747. WXS_BASIC_CAST type, NULL,
  14748. "The 'final' of member type '%s' contains 'union'",
  14749. xmlSchemaGetComponentQName(&str, member->type));
  14750. FREE_AND_NULL(str)
  14751. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
  14752. }
  14753. member = member->next;
  14754. }
  14755. /*
  14756. * 3.3.1.2 The {facets} must be empty.
  14757. */
  14758. if (type->facetSet != NULL) {
  14759. xmlSchemaPCustomErr(pctxt,
  14760. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
  14761. WXS_BASIC_CAST type, NULL,
  14762. "No facets allowed", NULL);
  14763. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
  14764. }
  14765. } else {
  14766. /*
  14767. * 3.3.2.1 The {base type definition} must have a {variety} of union.
  14768. * I.e. the variety of "list" is inherited.
  14769. */
  14770. if (! WXS_IS_UNION(type->baseType)) {
  14771. xmlSchemaPCustomErr(pctxt,
  14772. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
  14773. WXS_BASIC_CAST type, NULL,
  14774. "The base type '%s' is not a union type",
  14775. xmlSchemaGetComponentQName(&str, type->baseType));
  14776. FREE_AND_NULL(str)
  14777. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
  14778. }
  14779. /*
  14780. * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
  14781. */
  14782. if (xmlSchemaTypeFinalContains(type->baseType,
  14783. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14784. xmlSchemaPCustomErr(pctxt,
  14785. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
  14786. WXS_BASIC_CAST type, NULL,
  14787. "The 'final' of its base type '%s' must not contain 'restriction'",
  14788. xmlSchemaGetComponentQName(&str, type->baseType));
  14789. FREE_AND_NULL(str)
  14790. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
  14791. }
  14792. /*
  14793. * 3.3.2.3 The {member type definitions}, in order, must be validly
  14794. * derived from the corresponding type definitions in the {base
  14795. * type definition}'s {member type definitions} given the empty set,
  14796. * as defined in Type Derivation OK (Simple) ($3.14.6).
  14797. */
  14798. {
  14799. xmlSchemaTypeLinkPtr baseMember;
  14800. /*
  14801. * OPTIMIZE: if the type is restricting, it has no local defined
  14802. * member types and inherits the member types of the base type;
  14803. * thus a check for equality can be skipped.
  14804. */
  14805. /*
  14806. * Even worse: I cannot see a scenario where a restricting
  14807. * union simple type can have other member types as the member
  14808. * types of it's base type. This check seems not necessary with
  14809. * respect to the derivation process in libxml2.
  14810. * But necessary if constructing types with an API.
  14811. */
  14812. if (type->memberTypes != NULL) {
  14813. member = type->memberTypes;
  14814. baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
  14815. if ((member == NULL) && (baseMember != NULL)) {
  14816. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14817. "different number of member types in base");
  14818. }
  14819. while (member != NULL) {
  14820. if (baseMember == NULL) {
  14821. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14822. "different number of member types in base");
  14823. } else if ((member->type != baseMember->type) &&
  14824. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  14825. member->type, baseMember->type, 0) != 0)) {
  14826. xmlChar *strBMT = NULL, *strBT = NULL;
  14827. xmlSchemaPCustomErrExt(pctxt,
  14828. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
  14829. WXS_BASIC_CAST type, NULL,
  14830. "The member type %s is not validly "
  14831. "derived from its corresponding member "
  14832. "type %s of the base type %s",
  14833. xmlSchemaGetComponentQName(&str, member->type),
  14834. xmlSchemaGetComponentQName(&strBMT, baseMember->type),
  14835. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14836. FREE_AND_NULL(str)
  14837. FREE_AND_NULL(strBMT)
  14838. FREE_AND_NULL(strBT)
  14839. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
  14840. }
  14841. member = member->next;
  14842. if (baseMember != NULL)
  14843. baseMember = baseMember->next;
  14844. }
  14845. }
  14846. }
  14847. /*
  14848. * 3.3.2.4 Only pattern and enumeration facet components are
  14849. * allowed among the {facets}.
  14850. */
  14851. if (type->facets != NULL) {
  14852. xmlSchemaFacetPtr facet;
  14853. int ok = 1;
  14854. facet = type->facets;
  14855. do {
  14856. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  14857. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  14858. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14859. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
  14860. type, facet);
  14861. ok = 0;
  14862. }
  14863. facet = facet->next;
  14864. } while (facet != NULL);
  14865. if (ok == 0)
  14866. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
  14867. }
  14868. /*
  14869. * SPEC (3.3.2.5) (same as 1.3.2)
  14870. *
  14871. * NOTE (3.3.2.5) This is currently done in
  14872. * xmlSchemaDeriveAndValidateFacets()
  14873. */
  14874. }
  14875. }
  14876. return (0);
  14877. }
  14878. /**
  14879. * xmlSchemaCheckSRCSimpleType:
  14880. * @ctxt: the schema parser context
  14881. * @type: the simple type definition
  14882. *
  14883. * Checks crc-simple-type constraints.
  14884. *
  14885. * Returns 0 if the constraints are satisfied,
  14886. * if not a positive error code and -1 on internal
  14887. * errors.
  14888. */
  14889. #if 0
  14890. static int
  14891. xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
  14892. xmlSchemaTypePtr type)
  14893. {
  14894. /*
  14895. * src-simple-type.1 The corresponding simple type definition, if any,
  14896. * must satisfy the conditions set out in Constraints on Simple Type
  14897. * Definition Schema Components ($3.14.6).
  14898. */
  14899. if (WXS_IS_RESTRICTION(type)) {
  14900. /*
  14901. * src-simple-type.2 "If the <restriction> alternative is chosen,
  14902. * either it must have a base [attribute] or a <simpleType> among its
  14903. * [children], but not both."
  14904. * NOTE: This is checked in the parse function of <restriction>.
  14905. */
  14906. /*
  14907. *
  14908. */
  14909. } else if (WXS_IS_LIST(type)) {
  14910. /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
  14911. * an itemType [attribute] or a <simpleType> among its [children],
  14912. * but not both."
  14913. *
  14914. * NOTE: This is checked in the parse function of <list>.
  14915. */
  14916. } else if (WXS_IS_UNION(type)) {
  14917. /*
  14918. * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
  14919. */
  14920. }
  14921. return (0);
  14922. }
  14923. #endif
  14924. static int
  14925. xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
  14926. {
  14927. if (ctxt->vctxt == NULL) {
  14928. ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
  14929. if (ctxt->vctxt == NULL) {
  14930. xmlSchemaPErr(ctxt, NULL,
  14931. XML_SCHEMAP_INTERNAL,
  14932. "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
  14933. "failed to create a temp. validation context.\n",
  14934. NULL, NULL);
  14935. return (-1);
  14936. }
  14937. /* TODO: Pass user data. */
  14938. xmlSchemaSetValidErrors(ctxt->vctxt,
  14939. ctxt->error, ctxt->warning, ctxt->errCtxt);
  14940. xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
  14941. ctxt->serror, ctxt->errCtxt);
  14942. }
  14943. return (0);
  14944. }
  14945. static int
  14946. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  14947. xmlNodePtr node,
  14948. xmlSchemaTypePtr type,
  14949. const xmlChar *value,
  14950. xmlSchemaValPtr *retVal,
  14951. int fireErrors,
  14952. int normalize,
  14953. int isNormalized);
  14954. /**
  14955. * xmlSchemaParseCheckCOSValidDefault:
  14956. * @pctxt: the schema parser context
  14957. * @type: the simple type definition
  14958. * @value: the default value
  14959. * @node: an optional node (the holder of the value)
  14960. *
  14961. * Schema Component Constraint: Element Default Valid (Immediate)
  14962. * (cos-valid-default)
  14963. * This will be used by the parser only. For the validator there's
  14964. * an other version.
  14965. *
  14966. * Returns 0 if the constraints are satisfied,
  14967. * if not, a positive error code and -1 on internal
  14968. * errors.
  14969. */
  14970. static int
  14971. xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
  14972. xmlNodePtr node,
  14973. xmlSchemaTypePtr type,
  14974. const xmlChar *value,
  14975. xmlSchemaValPtr *val)
  14976. {
  14977. int ret = 0;
  14978. /*
  14979. * cos-valid-default:
  14980. * Schema Component Constraint: Element Default Valid (Immediate)
  14981. * For a string to be a valid default with respect to a type
  14982. * definition the appropriate case among the following must be true:
  14983. */
  14984. if WXS_IS_COMPLEX(type) {
  14985. /*
  14986. * Complex type.
  14987. *
  14988. * SPEC (2.1) "its {content type} must be a simple type definition
  14989. * or mixed."
  14990. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  14991. * type}'s particle must be `emptiable` as defined by
  14992. * Particle Emptiable ($3.9.6)."
  14993. */
  14994. if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
  14995. ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
  14996. /* NOTE that this covers (2.2.2) as well. */
  14997. xmlSchemaPCustomErr(pctxt,
  14998. XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
  14999. WXS_BASIC_CAST type, type->node,
  15000. "For a string to be a valid default, the type definition "
  15001. "must be a simple type or a complex type with mixed content "
  15002. "and a particle emptiable", NULL);
  15003. return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
  15004. }
  15005. }
  15006. /*
  15007. * 1 If the type definition is a simple type definition, then the string
  15008. * must be `valid` with respect to that definition as defined by String
  15009. * Valid ($3.14.4).
  15010. *
  15011. * AND
  15012. *
  15013. * 2.2.1 If the {content type} is a simple type definition, then the
  15014. * string must be `valid` with respect to that simple type definition
  15015. * as defined by String Valid ($3.14.4).
  15016. */
  15017. if (WXS_IS_SIMPLE(type))
  15018. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  15019. type, value, val, 1, 1, 0);
  15020. else if (WXS_HAS_SIMPLE_CONTENT(type))
  15021. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  15022. type->contentTypeDef, value, val, 1, 1, 0);
  15023. else
  15024. return (ret);
  15025. if (ret < 0) {
  15026. PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
  15027. "calling xmlSchemaVCheckCVCSimpleType()");
  15028. }
  15029. return (ret);
  15030. }
  15031. /**
  15032. * xmlSchemaCheckCTPropsCorrect:
  15033. * @ctxt: the schema parser context
  15034. * @type: the complex type definition
  15035. *
  15036. *.(4.6) Constraints on Complex Type Definition Schema Components
  15037. * Schema Component Constraint:
  15038. * Complex Type Definition Properties Correct (ct-props-correct)
  15039. * STATUS: (seems) complete
  15040. *
  15041. * Returns 0 if the constraints are satisfied, a positive
  15042. * error code if not and -1 if an internal error occurred.
  15043. */
  15044. static int
  15045. xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  15046. xmlSchemaTypePtr type)
  15047. {
  15048. /*
  15049. * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
  15050. *
  15051. * SPEC (1) "The values of the properties of a complex type definition must
  15052. * be as described in the property tableau in The Complex Type Definition
  15053. * Schema Component ($3.4.1), modulo the impact of Missing
  15054. * Sub-components ($5.3)."
  15055. */
  15056. if ((type->baseType != NULL) &&
  15057. (WXS_IS_SIMPLE(type->baseType)) &&
  15058. (WXS_IS_EXTENSION(type) == 0)) {
  15059. /*
  15060. * SPEC (2) "If the {base type definition} is a simple type definition,
  15061. * the {derivation method} must be extension."
  15062. */
  15063. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15064. XML_SCHEMAP_SRC_CT_1,
  15065. NULL, WXS_BASIC_CAST type,
  15066. "If the base type is a simple type, the derivation method must be "
  15067. "'extension'", NULL, NULL);
  15068. return (XML_SCHEMAP_SRC_CT_1);
  15069. }
  15070. /*
  15071. * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
  15072. * definition`. That is, it must be possible to reach the `ur-type
  15073. * definition` by repeatedly following the {base type definition}."
  15074. *
  15075. * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
  15076. */
  15077. /*
  15078. * NOTE that (4) and (5) need the following:
  15079. * - attribute uses need to be already inherited (apply attr. prohibitions)
  15080. * - attribute group references need to be expanded already
  15081. * - simple types need to be typefixed already
  15082. */
  15083. if (type->attrUses &&
  15084. (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
  15085. {
  15086. xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
  15087. xmlSchemaAttributeUsePtr use, tmp;
  15088. int i, j, hasId = 0;
  15089. for (i = uses->nbItems -1; i >= 0; i--) {
  15090. use = uses->items[i];
  15091. /*
  15092. * SPEC ct-props-correct
  15093. * (4) "Two distinct attribute declarations in the
  15094. * {attribute uses} must not have identical {name}s and
  15095. * {target namespace}s."
  15096. */
  15097. if (i > 0) {
  15098. for (j = i -1; j >= 0; j--) {
  15099. tmp = uses->items[j];
  15100. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  15101. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  15102. (WXS_ATTRUSE_DECL_TNS(use) ==
  15103. WXS_ATTRUSE_DECL_TNS(tmp)))
  15104. {
  15105. xmlChar *str = NULL;
  15106. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15107. XML_SCHEMAP_AG_PROPS_CORRECT,
  15108. NULL, WXS_BASIC_CAST type,
  15109. "Duplicate %s",
  15110. xmlSchemaGetComponentDesignation(&str, use),
  15111. NULL);
  15112. FREE_AND_NULL(str);
  15113. /*
  15114. * Remove the duplicate.
  15115. */
  15116. if (xmlSchemaItemListRemove(uses, i) == -1)
  15117. goto exit_failure;
  15118. goto next_use;
  15119. }
  15120. }
  15121. }
  15122. /*
  15123. * SPEC ct-props-correct
  15124. * (5) "Two distinct attribute declarations in the
  15125. * {attribute uses} must not have {type definition}s which
  15126. * are or are derived from ID."
  15127. */
  15128. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  15129. if (xmlSchemaIsDerivedFromBuiltInType(
  15130. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  15131. {
  15132. if (hasId) {
  15133. xmlChar *str = NULL;
  15134. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15135. XML_SCHEMAP_AG_PROPS_CORRECT,
  15136. NULL, WXS_BASIC_CAST type,
  15137. "There must not exist more than one attribute "
  15138. "declaration of type 'xs:ID' "
  15139. "(or derived from 'xs:ID'). The %s violates this "
  15140. "constraint",
  15141. xmlSchemaGetComponentDesignation(&str, use),
  15142. NULL);
  15143. FREE_AND_NULL(str);
  15144. if (xmlSchemaItemListRemove(uses, i) == -1)
  15145. goto exit_failure;
  15146. }
  15147. hasId = 1;
  15148. }
  15149. }
  15150. next_use: {}
  15151. }
  15152. }
  15153. return (0);
  15154. exit_failure:
  15155. return(-1);
  15156. }
  15157. static int
  15158. xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
  15159. xmlSchemaTypePtr typeB)
  15160. {
  15161. /*
  15162. * TODO: This should implement component-identity
  15163. * in the future.
  15164. */
  15165. if ((typeA == NULL) || (typeB == NULL))
  15166. return (0);
  15167. return (typeA == typeB);
  15168. }
  15169. /**
  15170. * xmlSchemaCheckCOSCTDerivedOK:
  15171. * @ctxt: the schema parser context
  15172. * @type: the to-be derived complex type definition
  15173. * @baseType: the base complex type definition
  15174. * @set: the given set
  15175. *
  15176. * Schema Component Constraint:
  15177. * Type Derivation OK (Complex) (cos-ct-derived-ok)
  15178. *
  15179. * STATUS: completed
  15180. *
  15181. * Returns 0 if the constraints are satisfied, or 1
  15182. * if not.
  15183. */
  15184. static int
  15185. xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15186. xmlSchemaTypePtr type,
  15187. xmlSchemaTypePtr baseType,
  15188. int set)
  15189. {
  15190. int equal = xmlSchemaAreEqualTypes(type, baseType);
  15191. /* TODO: Error codes. */
  15192. /*
  15193. * SPEC "For a complex type definition (call it D, for derived)
  15194. * to be validly derived from a type definition (call this
  15195. * B, for base) given a subset of {extension, restriction}
  15196. * all of the following must be true:"
  15197. */
  15198. if (! equal) {
  15199. /*
  15200. * SPEC (1) "If B and D are not the same type definition, then the
  15201. * {derivation method} of D must not be in the subset."
  15202. */
  15203. if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
  15204. ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
  15205. return (1);
  15206. } else {
  15207. /*
  15208. * SPEC (2.1) "B and D must be the same type definition."
  15209. */
  15210. return (0);
  15211. }
  15212. /*
  15213. * SPEC (2.2) "B must be D's {base type definition}."
  15214. */
  15215. if (type->baseType == baseType)
  15216. return (0);
  15217. /*
  15218. * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
  15219. * definition`."
  15220. */
  15221. if (WXS_IS_ANYTYPE(type->baseType))
  15222. return (1);
  15223. if (WXS_IS_COMPLEX(type->baseType)) {
  15224. /*
  15225. * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
  15226. * must be validly derived from B given the subset as defined by this
  15227. * constraint."
  15228. */
  15229. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
  15230. baseType, set));
  15231. } else {
  15232. /*
  15233. * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
  15234. * must be validly derived from B given the subset as defined in Type
  15235. * Derivation OK (Simple) ($3.14.6).
  15236. */
  15237. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  15238. baseType, set));
  15239. }
  15240. }
  15241. /**
  15242. * xmlSchemaCheckCOSDerivedOK:
  15243. * @type: the derived simple type definition
  15244. * @baseType: the base type definition
  15245. *
  15246. * Calls:
  15247. * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
  15248. *
  15249. * Checks whether @type can be validly derived from @baseType.
  15250. *
  15251. * Returns 0 on success, an positive error code otherwise.
  15252. */
  15253. static int
  15254. xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15255. xmlSchemaTypePtr type,
  15256. xmlSchemaTypePtr baseType,
  15257. int set)
  15258. {
  15259. if (WXS_IS_SIMPLE(type))
  15260. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
  15261. else
  15262. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
  15263. }
  15264. /**
  15265. * xmlSchemaCheckCOSCTExtends:
  15266. * @ctxt: the schema parser context
  15267. * @type: the complex type definition
  15268. *
  15269. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15270. * Schema Component Constraint:
  15271. * Derivation Valid (Extension) (cos-ct-extends)
  15272. *
  15273. * STATUS:
  15274. * missing:
  15275. * (1.5)
  15276. * (1.4.3.2.2.2) "Particle Valid (Extension)"
  15277. *
  15278. * Returns 0 if the constraints are satisfied, a positive
  15279. * error code if not and -1 if an internal error occurred.
  15280. */
  15281. static int
  15282. xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
  15283. xmlSchemaTypePtr type)
  15284. {
  15285. xmlSchemaTypePtr base = type->baseType;
  15286. /*
  15287. * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
  15288. * temporarily only.
  15289. */
  15290. /*
  15291. * SPEC (1) "If the {base type definition} is a complex type definition,
  15292. * then all of the following must be true:"
  15293. */
  15294. if (WXS_IS_COMPLEX(base)) {
  15295. /*
  15296. * SPEC (1.1) "The {final} of the {base type definition} must not
  15297. * contain extension."
  15298. */
  15299. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15300. xmlSchemaPCustomErr(ctxt,
  15301. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15302. WXS_BASIC_CAST type, NULL,
  15303. "The 'final' of the base type definition "
  15304. "contains 'extension'", NULL);
  15305. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15306. }
  15307. /*
  15308. * ATTENTION: The constrains (1.2) and (1.3) are not applied,
  15309. * since they are automatically satisfied through the
  15310. * inheriting mechanism.
  15311. * Note that even if redefining components, the inheriting mechanism
  15312. * is used.
  15313. */
  15314. #if 0
  15315. /*
  15316. * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
  15317. * uses}
  15318. * of the complex type definition itself, that is, for every attribute
  15319. * use in the {attribute uses} of the {base type definition}, there
  15320. * must be an attribute use in the {attribute uses} of the complex
  15321. * type definition itself whose {attribute declaration} has the same
  15322. * {name}, {target namespace} and {type definition} as its attribute
  15323. * declaration"
  15324. */
  15325. if (base->attrUses != NULL) {
  15326. int i, j, found;
  15327. xmlSchemaAttributeUsePtr use, buse;
  15328. for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
  15329. buse = (WXS_LIST_CAST base->attrUses)->items[i];
  15330. found = 0;
  15331. if (type->attrUses != NULL) {
  15332. use = (WXS_LIST_CAST type->attrUses)->items[j];
  15333. for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
  15334. {
  15335. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  15336. WXS_ATTRUSE_DECL_NAME(buse)) &&
  15337. (WXS_ATTRUSE_DECL_TNS(use) ==
  15338. WXS_ATTRUSE_DECL_TNS(buse)) &&
  15339. (WXS_ATTRUSE_TYPEDEF(use) ==
  15340. WXS_ATTRUSE_TYPEDEF(buse))
  15341. {
  15342. found = 1;
  15343. break;
  15344. }
  15345. }
  15346. }
  15347. if (! found) {
  15348. xmlChar *str = NULL;
  15349. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15350. XML_SCHEMAP_COS_CT_EXTENDS_1_2,
  15351. NULL, WXS_BASIC_CAST type,
  15352. /*
  15353. * TODO: The report does not indicate that also the
  15354. * type needs to be the same.
  15355. */
  15356. "This type is missing a matching correspondent "
  15357. "for its {base type}'s %s in its {attribute uses}",
  15358. xmlSchemaGetComponentDesignation(&str,
  15359. buse->children),
  15360. NULL);
  15361. FREE_AND_NULL(str)
  15362. }
  15363. }
  15364. }
  15365. /*
  15366. * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
  15367. * definition must also have one, and the base type definition's
  15368. * {attribute wildcard}'s {namespace constraint} must be a subset
  15369. * of the complex type definition's {attribute wildcard}'s {namespace
  15370. * constraint}, as defined by Wildcard Subset ($3.10.6)."
  15371. */
  15372. /*
  15373. * MAYBE TODO: Enable if ever needed. But this will be needed only
  15374. * if created the type via a schema construction API.
  15375. */
  15376. if (base->attributeWildcard != NULL) {
  15377. if (type->attributeWildcard == NULL) {
  15378. xmlChar *str = NULL;
  15379. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15380. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15381. NULL, type,
  15382. "The base %s has an attribute wildcard, "
  15383. "but this type is missing an attribute wildcard",
  15384. xmlSchemaGetComponentDesignation(&str, base));
  15385. FREE_AND_NULL(str)
  15386. } else if (xmlSchemaCheckCOSNSSubset(
  15387. base->attributeWildcard, type->attributeWildcard))
  15388. {
  15389. xmlChar *str = NULL;
  15390. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15391. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15392. NULL, type,
  15393. "The attribute wildcard is not a valid "
  15394. "superset of the one in the base %s",
  15395. xmlSchemaGetComponentDesignation(&str, base));
  15396. FREE_AND_NULL(str)
  15397. }
  15398. }
  15399. #endif
  15400. /*
  15401. * SPEC (1.4) "One of the following must be true:"
  15402. */
  15403. if ((type->contentTypeDef != NULL) &&
  15404. (type->contentTypeDef == base->contentTypeDef)) {
  15405. /*
  15406. * SPEC (1.4.1) "The {content type} of the {base type definition}
  15407. * and the {content type} of the complex type definition itself
  15408. * must be the same simple type definition"
  15409. * PASS
  15410. */
  15411. } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
  15412. (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
  15413. /*
  15414. * SPEC (1.4.2) "The {content type} of both the {base type
  15415. * definition} and the complex type definition itself must
  15416. * be empty."
  15417. * PASS
  15418. */
  15419. } else {
  15420. /*
  15421. * SPEC (1.4.3) "All of the following must be true:"
  15422. */
  15423. if (type->subtypes == NULL) {
  15424. /*
  15425. * SPEC 1.4.3.1 The {content type} of the complex type
  15426. * definition itself must specify a particle.
  15427. */
  15428. xmlSchemaPCustomErr(ctxt,
  15429. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15430. WXS_BASIC_CAST type, NULL,
  15431. "The content type must specify a particle", NULL);
  15432. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15433. }
  15434. /*
  15435. * SPEC (1.4.3.2) "One of the following must be true:"
  15436. */
  15437. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15438. /*
  15439. * SPEC (1.4.3.2.1) "The {content type} of the {base type
  15440. * definition} must be empty.
  15441. * PASS
  15442. */
  15443. } else {
  15444. /*
  15445. * SPEC (1.4.3.2.2) "All of the following must be true:"
  15446. */
  15447. if ((type->contentType != base->contentType) ||
  15448. ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
  15449. (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
  15450. /*
  15451. * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
  15452. * or both must be element-only."
  15453. */
  15454. xmlSchemaPCustomErr(ctxt,
  15455. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15456. WXS_BASIC_CAST type, NULL,
  15457. "The content type of both, the type and its base "
  15458. "type, must either 'mixed' or 'element-only'", NULL);
  15459. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15460. }
  15461. /*
  15462. * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
  15463. * complex type definition must be a `valid extension`
  15464. * of the {base type definition}'s particle, as defined
  15465. * in Particle Valid (Extension) ($3.9.6)."
  15466. *
  15467. * NOTE that we won't check "Particle Valid (Extension)",
  15468. * since it is ensured by the derivation process in
  15469. * xmlSchemaTypeFixup(). We need to implement this when heading
  15470. * for a construction API
  15471. * TODO: !! This is needed to be checked if redefining a type !!
  15472. */
  15473. }
  15474. /*
  15475. * URGENT TODO (1.5)
  15476. */
  15477. }
  15478. } else {
  15479. /*
  15480. * SPEC (2) "If the {base type definition} is a simple type definition,
  15481. * then all of the following must be true:"
  15482. */
  15483. if (type->contentTypeDef != base) {
  15484. /*
  15485. * SPEC (2.1) "The {content type} must be the same simple type
  15486. * definition."
  15487. */
  15488. xmlSchemaPCustomErr(ctxt,
  15489. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15490. WXS_BASIC_CAST type, NULL,
  15491. "The content type must be the simple base type", NULL);
  15492. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15493. }
  15494. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15495. /*
  15496. * SPEC (2.2) "The {final} of the {base type definition} must not
  15497. * contain extension"
  15498. * NOTE that this is the same as (1.1).
  15499. */
  15500. xmlSchemaPCustomErr(ctxt,
  15501. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15502. WXS_BASIC_CAST type, NULL,
  15503. "The 'final' of the base type definition "
  15504. "contains 'extension'", NULL);
  15505. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15506. }
  15507. }
  15508. return (0);
  15509. }
  15510. /**
  15511. * xmlSchemaCheckDerivationOKRestriction:
  15512. * @ctxt: the schema parser context
  15513. * @type: the complex type definition
  15514. *
  15515. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15516. * Schema Component Constraint:
  15517. * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
  15518. *
  15519. * STATUS:
  15520. * missing:
  15521. * (5.4.2) ???
  15522. *
  15523. * ATTENTION:
  15524. * In XML Schema 1.1 this will be:
  15525. * Validation Rule: Checking complex type subsumption
  15526. *
  15527. * Returns 0 if the constraints are satisfied, a positive
  15528. * error code if not and -1 if an internal error occurred.
  15529. */
  15530. static int
  15531. xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
  15532. xmlSchemaTypePtr type)
  15533. {
  15534. xmlSchemaTypePtr base;
  15535. /*
  15536. * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
  15537. * temporarily only.
  15538. */
  15539. base = type->baseType;
  15540. if (! WXS_IS_COMPLEX(base)) {
  15541. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15542. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15543. type->node, WXS_BASIC_CAST type,
  15544. "The base type must be a complex type", NULL, NULL);
  15545. return(ctxt->err);
  15546. }
  15547. if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
  15548. /*
  15549. * SPEC (1) "The {base type definition} must be a complex type
  15550. * definition whose {final} does not contain restriction."
  15551. */
  15552. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15553. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15554. type->node, WXS_BASIC_CAST type,
  15555. "The 'final' of the base type definition "
  15556. "contains 'restriction'", NULL, NULL);
  15557. return (ctxt->err);
  15558. }
  15559. /*
  15560. * SPEC (2), (3) and (4)
  15561. * Those are handled in a separate function, since the
  15562. * same constraints are needed for redefinition of
  15563. * attribute groups as well.
  15564. */
  15565. if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
  15566. XML_SCHEMA_ACTION_DERIVE,
  15567. WXS_BASIC_CAST type, WXS_BASIC_CAST base,
  15568. type->attrUses, base->attrUses,
  15569. type->attributeWildcard,
  15570. base->attributeWildcard) == -1)
  15571. {
  15572. return(-1);
  15573. }
  15574. /*
  15575. * SPEC (5) "One of the following must be true:"
  15576. */
  15577. if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
  15578. /*
  15579. * SPEC (5.1) "The {base type definition} must be the
  15580. * `ur-type definition`."
  15581. * PASS
  15582. */
  15583. } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15584. (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15585. /*
  15586. * SPEC (5.2.1) "The {content type} of the complex type definition
  15587. * must be a simple type definition"
  15588. *
  15589. * SPEC (5.2.2) "One of the following must be true:"
  15590. */
  15591. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15592. (base->contentType == XML_SCHEMA_CONTENT_BASIC))
  15593. {
  15594. int err;
  15595. /*
  15596. * SPEC (5.2.2.1) "The {content type} of the {base type
  15597. * definition} must be a simple type definition from which
  15598. * the {content type} is validly derived given the empty
  15599. * set as defined in Type Derivation OK (Simple) ($3.14.6)."
  15600. *
  15601. * ATTENTION TODO: This seems not needed if the type implicitly
  15602. * derived from the base type.
  15603. *
  15604. */
  15605. err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
  15606. type->contentTypeDef, base->contentTypeDef, 0);
  15607. if (err != 0) {
  15608. xmlChar *strA = NULL, *strB = NULL;
  15609. if (err == -1)
  15610. return(-1);
  15611. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15612. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15613. NULL, WXS_BASIC_CAST type,
  15614. "The {content type} %s is not validly derived from the "
  15615. "base type's {content type} %s",
  15616. xmlSchemaGetComponentDesignation(&strA,
  15617. type->contentTypeDef),
  15618. xmlSchemaGetComponentDesignation(&strB,
  15619. base->contentTypeDef));
  15620. FREE_AND_NULL(strA);
  15621. FREE_AND_NULL(strB);
  15622. return(ctxt->err);
  15623. }
  15624. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15625. (xmlSchemaIsParticleEmptiable(
  15626. (xmlSchemaParticlePtr) base->subtypes))) {
  15627. /*
  15628. * SPEC (5.2.2.2) "The {base type definition} must be mixed
  15629. * and have a particle which is `emptiable` as defined in
  15630. * Particle Emptiable ($3.9.6)."
  15631. * PASS
  15632. */
  15633. } else {
  15634. xmlSchemaPCustomErr(ctxt,
  15635. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15636. WXS_BASIC_CAST type, NULL,
  15637. "The content type of the base type must be either "
  15638. "a simple type or 'mixed' and an emptiable particle", NULL);
  15639. return (ctxt->err);
  15640. }
  15641. } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15642. /*
  15643. * SPEC (5.3.1) "The {content type} of the complex type itself must
  15644. * be empty"
  15645. */
  15646. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15647. /*
  15648. * SPEC (5.3.2.1) "The {content type} of the {base type
  15649. * definition} must also be empty."
  15650. * PASS
  15651. */
  15652. } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15653. (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
  15654. xmlSchemaIsParticleEmptiable(
  15655. (xmlSchemaParticlePtr) base->subtypes)) {
  15656. /*
  15657. * SPEC (5.3.2.2) "The {content type} of the {base type
  15658. * definition} must be elementOnly or mixed and have a particle
  15659. * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
  15660. * PASS
  15661. */
  15662. } else {
  15663. xmlSchemaPCustomErr(ctxt,
  15664. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15665. WXS_BASIC_CAST type, NULL,
  15666. "The content type of the base type must be either "
  15667. "empty or 'mixed' (or 'elements-only') and an emptiable "
  15668. "particle", NULL);
  15669. return (ctxt->err);
  15670. }
  15671. } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15672. WXS_HAS_MIXED_CONTENT(type)) {
  15673. /*
  15674. * SPEC (5.4.1.1) "The {content type} of the complex type definition
  15675. * itself must be element-only"
  15676. */
  15677. if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
  15678. /*
  15679. * SPEC (5.4.1.2) "The {content type} of the complex type
  15680. * definition itself and of the {base type definition} must be
  15681. * mixed"
  15682. */
  15683. xmlSchemaPCustomErr(ctxt,
  15684. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15685. WXS_BASIC_CAST type, NULL,
  15686. "If the content type is 'mixed', then the content type of the "
  15687. "base type must also be 'mixed'", NULL);
  15688. return (ctxt->err);
  15689. }
  15690. /*
  15691. * SPEC (5.4.2) "The particle of the complex type definition itself
  15692. * must be a `valid restriction` of the particle of the {content
  15693. * type} of the {base type definition} as defined in Particle Valid
  15694. * (Restriction) ($3.9.6).
  15695. *
  15696. * URGENT TODO: (5.4.2)
  15697. */
  15698. } else {
  15699. xmlSchemaPCustomErr(ctxt,
  15700. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15701. WXS_BASIC_CAST type, NULL,
  15702. "The type is not a valid restriction of its base type", NULL);
  15703. return (ctxt->err);
  15704. }
  15705. return (0);
  15706. }
  15707. /**
  15708. * xmlSchemaCheckCTComponent:
  15709. * @ctxt: the schema parser context
  15710. * @type: the complex type definition
  15711. *
  15712. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15713. *
  15714. * Returns 0 if the constraints are satisfied, a positive
  15715. * error code if not and -1 if an internal error occurred.
  15716. */
  15717. static int
  15718. xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
  15719. xmlSchemaTypePtr type)
  15720. {
  15721. int ret;
  15722. /*
  15723. * Complex Type Definition Properties Correct
  15724. */
  15725. ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
  15726. if (ret != 0)
  15727. return (ret);
  15728. if (WXS_IS_EXTENSION(type))
  15729. ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
  15730. else
  15731. ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
  15732. return (ret);
  15733. }
  15734. /**
  15735. * xmlSchemaCheckSRCCT:
  15736. * @ctxt: the schema parser context
  15737. * @type: the complex type definition
  15738. *
  15739. * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
  15740. * Schema Representation Constraint:
  15741. * Complex Type Definition Representation OK (src-ct)
  15742. *
  15743. * Returns 0 if the constraints are satisfied, a positive
  15744. * error code if not and -1 if an internal error occurred.
  15745. */
  15746. static int
  15747. xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
  15748. xmlSchemaTypePtr type)
  15749. {
  15750. xmlSchemaTypePtr base;
  15751. int ret = 0;
  15752. /*
  15753. * TODO: Adjust the error codes here, as I used
  15754. * XML_SCHEMAP_SRC_CT_1 only yet.
  15755. */
  15756. base = type->baseType;
  15757. if (! WXS_HAS_SIMPLE_CONTENT(type)) {
  15758. /*
  15759. * 1 If the <complexContent> alternative is chosen, the type definition
  15760. * `resolved` to by the `actual value` of the base [attribute]
  15761. * must be a complex type definition;
  15762. */
  15763. if (! WXS_IS_COMPLEX(base)) {
  15764. xmlChar *str = NULL;
  15765. xmlSchemaPCustomErr(ctxt,
  15766. XML_SCHEMAP_SRC_CT_1,
  15767. WXS_BASIC_CAST type, type->node,
  15768. "If using <complexContent>, the base type is expected to be "
  15769. "a complex type. The base type '%s' is a simple type",
  15770. xmlSchemaFormatQName(&str, base->targetNamespace,
  15771. base->name));
  15772. FREE_AND_NULL(str)
  15773. return (XML_SCHEMAP_SRC_CT_1);
  15774. }
  15775. } else {
  15776. /*
  15777. * SPEC
  15778. * 2 If the <simpleContent> alternative is chosen, all of the
  15779. * following must be true:
  15780. * 2.1 The type definition `resolved` to by the `actual value` of the
  15781. * base [attribute] must be one of the following:
  15782. */
  15783. if (WXS_IS_SIMPLE(base)) {
  15784. if (WXS_IS_EXTENSION(type) == 0) {
  15785. xmlChar *str = NULL;
  15786. /*
  15787. * 2.1.3 only if the <extension> alternative is also
  15788. * chosen, a simple type definition.
  15789. */
  15790. /* TODO: Change error code to ..._SRC_CT_2_1_3. */
  15791. xmlSchemaPCustomErr(ctxt,
  15792. XML_SCHEMAP_SRC_CT_1,
  15793. WXS_BASIC_CAST type, NULL,
  15794. "If using <simpleContent> and <restriction>, the base "
  15795. "type must be a complex type. The base type '%s' is "
  15796. "a simple type",
  15797. xmlSchemaFormatQName(&str, base->targetNamespace,
  15798. base->name));
  15799. FREE_AND_NULL(str)
  15800. return (XML_SCHEMAP_SRC_CT_1);
  15801. }
  15802. } else {
  15803. /* Base type is a complex type. */
  15804. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15805. (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15806. /*
  15807. * 2.1.1 a complex type definition whose {content type} is a
  15808. * simple type definition;
  15809. * PASS
  15810. */
  15811. if (base->contentTypeDef == NULL) {
  15812. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
  15813. WXS_BASIC_CAST type, NULL,
  15814. "Internal error: xmlSchemaCheckSRCCT, "
  15815. "'%s', base type has no content type",
  15816. type->name);
  15817. return (-1);
  15818. }
  15819. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15820. (WXS_IS_RESTRICTION(type))) {
  15821. /*
  15822. * 2.1.2 only if the <restriction> alternative is also
  15823. * chosen, a complex type definition whose {content type}
  15824. * is mixed and a particle emptiable.
  15825. */
  15826. if (! xmlSchemaIsParticleEmptiable(
  15827. (xmlSchemaParticlePtr) base->subtypes)) {
  15828. ret = XML_SCHEMAP_SRC_CT_1;
  15829. } else
  15830. /*
  15831. * Attention: at this point the <simpleType> child is in
  15832. * ->contentTypeDef (put there during parsing).
  15833. */
  15834. if (type->contentTypeDef == NULL) {
  15835. xmlChar *str = NULL;
  15836. /*
  15837. * 2.2 If clause 2.1.2 above is satisfied, then there
  15838. * must be a <simpleType> among the [children] of
  15839. * <restriction>.
  15840. */
  15841. /* TODO: Change error code to ..._SRC_CT_2_2. */
  15842. xmlSchemaPCustomErr(ctxt,
  15843. XML_SCHEMAP_SRC_CT_1,
  15844. WXS_BASIC_CAST type, NULL,
  15845. "A <simpleType> is expected among the children "
  15846. "of <restriction>, if <simpleContent> is used and "
  15847. "the base type '%s' is a complex type",
  15848. xmlSchemaFormatQName(&str, base->targetNamespace,
  15849. base->name));
  15850. FREE_AND_NULL(str)
  15851. return (XML_SCHEMAP_SRC_CT_1);
  15852. }
  15853. } else {
  15854. ret = XML_SCHEMAP_SRC_CT_1;
  15855. }
  15856. }
  15857. if (ret > 0) {
  15858. xmlChar *str = NULL;
  15859. if (WXS_IS_RESTRICTION(type)) {
  15860. xmlSchemaPCustomErr(ctxt,
  15861. XML_SCHEMAP_SRC_CT_1,
  15862. WXS_BASIC_CAST type, NULL,
  15863. "If <simpleContent> and <restriction> is used, the "
  15864. "base type must be a simple type or a complex type with "
  15865. "mixed content and particle emptiable. The base type "
  15866. "'%s' is none of those",
  15867. xmlSchemaFormatQName(&str, base->targetNamespace,
  15868. base->name));
  15869. } else {
  15870. xmlSchemaPCustomErr(ctxt,
  15871. XML_SCHEMAP_SRC_CT_1,
  15872. WXS_BASIC_CAST type, NULL,
  15873. "If <simpleContent> and <extension> is used, the "
  15874. "base type must be a simple type. The base type '%s' "
  15875. "is a complex type",
  15876. xmlSchemaFormatQName(&str, base->targetNamespace,
  15877. base->name));
  15878. }
  15879. FREE_AND_NULL(str)
  15880. }
  15881. }
  15882. /*
  15883. * SPEC (3) "The corresponding complex type definition component must
  15884. * satisfy the conditions set out in Constraints on Complex Type
  15885. * Definition Schema Components ($3.4.6);"
  15886. * NOTE (3) will be done in xmlSchemaTypeFixup().
  15887. */
  15888. /*
  15889. * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
  15890. * above for {attribute wildcard} is satisfied, the intensional
  15891. * intersection must be expressible, as defined in Attribute Wildcard
  15892. * Intersection ($3.10.6).
  15893. * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
  15894. */
  15895. return (ret);
  15896. }
  15897. #ifdef ENABLE_PARTICLE_RESTRICTION
  15898. /**
  15899. * xmlSchemaCheckParticleRangeOK:
  15900. * @ctxt: the schema parser context
  15901. * @type: the complex type definition
  15902. *
  15903. * (3.9.6) Constraints on Particle Schema Components
  15904. * Schema Component Constraint:
  15905. * Occurrence Range OK (range-ok)
  15906. *
  15907. * STATUS: complete
  15908. *
  15909. * Returns 0 if the constraints are satisfied, a positive
  15910. * error code if not and -1 if an internal error occurred.
  15911. */
  15912. static int
  15913. xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
  15914. int bmin, int bmax)
  15915. {
  15916. if (rmin < bmin)
  15917. return (1);
  15918. if ((bmax != UNBOUNDED) &&
  15919. (rmax > bmax))
  15920. return (1);
  15921. return (0);
  15922. }
  15923. /**
  15924. * xmlSchemaCheckRCaseNameAndTypeOK:
  15925. * @ctxt: the schema parser context
  15926. * @r: the restricting element declaration particle
  15927. * @b: the base element declaration particle
  15928. *
  15929. * (3.9.6) Constraints on Particle Schema Components
  15930. * Schema Component Constraint:
  15931. * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
  15932. * (rcase-NameAndTypeOK)
  15933. *
  15934. * STATUS:
  15935. * MISSING (3.2.3)
  15936. * CLARIFY: (3.2.2)
  15937. *
  15938. * Returns 0 if the constraints are satisfied, a positive
  15939. * error code if not and -1 if an internal error occurred.
  15940. */
  15941. static int
  15942. xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
  15943. xmlSchemaParticlePtr r,
  15944. xmlSchemaParticlePtr b)
  15945. {
  15946. xmlSchemaElementPtr elemR, elemB;
  15947. /* TODO: Error codes (rcase-NameAndTypeOK). */
  15948. elemR = (xmlSchemaElementPtr) r->children;
  15949. elemB = (xmlSchemaElementPtr) b->children;
  15950. /*
  15951. * SPEC (1) "The declarations' {name}s and {target namespace}s are
  15952. * the same."
  15953. */
  15954. if ((elemR != elemB) &&
  15955. ((! xmlStrEqual(elemR->name, elemB->name)) ||
  15956. (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
  15957. return (1);
  15958. /*
  15959. * SPEC (2) "R's occurrence range is a valid restriction of B's
  15960. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  15961. */
  15962. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  15963. b->minOccurs, b->maxOccurs) != 0)
  15964. return (1);
  15965. /*
  15966. * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
  15967. * {scope} are global."
  15968. */
  15969. if (elemR == elemB)
  15970. return (0);
  15971. /*
  15972. * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
  15973. */
  15974. if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
  15975. (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
  15976. return (1);
  15977. /*
  15978. * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
  15979. * or is not fixed, or R's declaration's {value constraint} is fixed
  15980. * with the same value."
  15981. */
  15982. if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
  15983. ((elemR->value == NULL) ||
  15984. ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
  15985. /* TODO: Equality of the initial value or normalized or canonical? */
  15986. (! xmlStrEqual(elemR->value, elemB->value))))
  15987. return (1);
  15988. /*
  15989. * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
  15990. * definitions} is a subset of B's declaration's {identity-constraint
  15991. * definitions}, if any."
  15992. */
  15993. if (elemB->idcs != NULL) {
  15994. /* TODO */
  15995. }
  15996. /*
  15997. * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
  15998. * superset of B's declaration's {disallowed substitutions}."
  15999. */
  16000. if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
  16001. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
  16002. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
  16003. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
  16004. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
  16005. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
  16006. return (1);
  16007. /*
  16008. * SPEC (3.2.5) "R's {type definition} is validly derived given
  16009. * {extension, list, union} from B's {type definition}"
  16010. *
  16011. * BADSPEC TODO: What's the point of adding "list" and "union" to the
  16012. * set, if the corresponding constraints handle "restriction" and
  16013. * "extension" only?
  16014. *
  16015. */
  16016. {
  16017. int set = 0;
  16018. set |= SUBSET_EXTENSION;
  16019. set |= SUBSET_LIST;
  16020. set |= SUBSET_UNION;
  16021. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
  16022. elemB->subtypes, set) != 0)
  16023. return (1);
  16024. }
  16025. return (0);
  16026. }
  16027. /**
  16028. * xmlSchemaCheckRCaseNSCompat:
  16029. * @ctxt: the schema parser context
  16030. * @r: the restricting element declaration particle
  16031. * @b: the base wildcard particle
  16032. *
  16033. * (3.9.6) Constraints on Particle Schema Components
  16034. * Schema Component Constraint:
  16035. * Particle Derivation OK (Elt:Any -- NSCompat)
  16036. * (rcase-NSCompat)
  16037. *
  16038. * STATUS: complete
  16039. *
  16040. * Returns 0 if the constraints are satisfied, a positive
  16041. * error code if not and -1 if an internal error occurred.
  16042. */
  16043. static int
  16044. xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
  16045. xmlSchemaParticlePtr r,
  16046. xmlSchemaParticlePtr b)
  16047. {
  16048. /* TODO:Error codes (rcase-NSCompat). */
  16049. /*
  16050. * SPEC "For an element declaration particle to be a `valid restriction`
  16051. * of a wildcard particle all of the following must be true:"
  16052. *
  16053. * SPEC (1) "The element declaration's {target namespace} is `valid`
  16054. * with respect to the wildcard's {namespace constraint} as defined by
  16055. * Wildcard allows Namespace Name ($3.10.4)."
  16056. */
  16057. if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
  16058. ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
  16059. return (1);
  16060. /*
  16061. * SPEC (2) "R's occurrence range is a valid restriction of B's
  16062. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16063. */
  16064. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16065. b->minOccurs, b->maxOccurs) != 0)
  16066. return (1);
  16067. return (0);
  16068. }
  16069. /**
  16070. * xmlSchemaCheckRCaseRecurseAsIfGroup:
  16071. * @ctxt: the schema parser context
  16072. * @r: the restricting element declaration particle
  16073. * @b: the base model group particle
  16074. *
  16075. * (3.9.6) Constraints on Particle Schema Components
  16076. * Schema Component Constraint:
  16077. * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
  16078. * (rcase-RecurseAsIfGroup)
  16079. *
  16080. * STATUS: TODO
  16081. *
  16082. * Returns 0 if the constraints are satisfied, a positive
  16083. * error code if not and -1 if an internal error occurred.
  16084. */
  16085. static int
  16086. xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
  16087. xmlSchemaParticlePtr r,
  16088. xmlSchemaParticlePtr b)
  16089. {
  16090. /* TODO: Error codes (rcase-RecurseAsIfGroup). */
  16091. TODO
  16092. return (0);
  16093. }
  16094. /**
  16095. * xmlSchemaCheckRCaseNSSubset:
  16096. * @ctxt: the schema parser context
  16097. * @r: the restricting wildcard particle
  16098. * @b: the base wildcard particle
  16099. *
  16100. * (3.9.6) Constraints on Particle Schema Components
  16101. * Schema Component Constraint:
  16102. * Particle Derivation OK (Any:Any -- NSSubset)
  16103. * (rcase-NSSubset)
  16104. *
  16105. * STATUS: complete
  16106. *
  16107. * Returns 0 if the constraints are satisfied, a positive
  16108. * error code if not and -1 if an internal error occurred.
  16109. */
  16110. static int
  16111. xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
  16112. xmlSchemaParticlePtr r,
  16113. xmlSchemaParticlePtr b,
  16114. int isAnyTypeBase)
  16115. {
  16116. /* TODO: Error codes (rcase-NSSubset). */
  16117. /*
  16118. * SPEC (1) "R's occurrence range is a valid restriction of B's
  16119. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16120. */
  16121. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16122. b->minOccurs, b->maxOccurs))
  16123. return (1);
  16124. /*
  16125. * SPEC (2) "R's {namespace constraint} must be an intensional subset
  16126. * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
  16127. */
  16128. if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
  16129. (xmlSchemaWildcardPtr) b->children))
  16130. return (1);
  16131. /*
  16132. * SPEC (3) "Unless B is the content model wildcard of the `ur-type
  16133. * definition`, R's {process contents} must be identical to or stronger
  16134. * than B's {process contents}, where strict is stronger than lax is
  16135. * stronger than skip."
  16136. */
  16137. if (! isAnyTypeBase) {
  16138. if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
  16139. ((xmlSchemaWildcardPtr) b->children)->processContents)
  16140. return (1);
  16141. }
  16142. return (0);
  16143. }
  16144. /**
  16145. * xmlSchemaCheckCOSParticleRestrict:
  16146. * @ctxt: the schema parser context
  16147. * @type: the complex type definition
  16148. *
  16149. * (3.9.6) Constraints on Particle Schema Components
  16150. * Schema Component Constraint:
  16151. * Particle Valid (Restriction) (cos-particle-restrict)
  16152. *
  16153. * STATUS: TODO
  16154. *
  16155. * Returns 0 if the constraints are satisfied, a positive
  16156. * error code if not and -1 if an internal error occurred.
  16157. */
  16158. static int
  16159. xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
  16160. xmlSchemaParticlePtr r,
  16161. xmlSchemaParticlePtr b)
  16162. {
  16163. int ret = 0;
  16164. /*part = WXS_TYPE_PARTICLE(type);
  16165. basePart = WXS_TYPE_PARTICLE(base);
  16166. */
  16167. TODO
  16168. /*
  16169. * SPEC (1) "They are the same particle."
  16170. */
  16171. if (r == b)
  16172. return (0);
  16173. return (0);
  16174. }
  16175. #if 0
  16176. /**
  16177. * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
  16178. * @ctxt: the schema parser context
  16179. * @r: the model group particle
  16180. * @b: the base wildcard particle
  16181. *
  16182. * (3.9.6) Constraints on Particle Schema Components
  16183. * Schema Component Constraint:
  16184. * Particle Derivation OK (All/Choice/Sequence:Any --
  16185. * NSRecurseCheckCardinality)
  16186. * (rcase-NSRecurseCheckCardinality)
  16187. *
  16188. * STATUS: TODO: subst-groups
  16189. *
  16190. * Returns 0 if the constraints are satisfied, a positive
  16191. * error code if not and -1 if an internal error occurred.
  16192. */
  16193. static int
  16194. xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
  16195. xmlSchemaParticlePtr r,
  16196. xmlSchemaParticlePtr b)
  16197. {
  16198. xmlSchemaParticlePtr part;
  16199. /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
  16200. if ((r->children == NULL) || (r->children->children == NULL))
  16201. return (-1);
  16202. /*
  16203. * SPEC "For a group particle to be a `valid restriction` of a
  16204. * wildcard particle..."
  16205. *
  16206. * SPEC (1) "Every member of the {particles} of the group is a `valid
  16207. * restriction` of the wildcard as defined by
  16208. * Particle Valid (Restriction) ($3.9.6)."
  16209. */
  16210. part = (xmlSchemaParticlePtr) r->children->children;
  16211. do {
  16212. if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
  16213. return (1);
  16214. part = (xmlSchemaParticlePtr) part->next;
  16215. } while (part != NULL);
  16216. /*
  16217. * SPEC (2) "The effective total range of the group [...] is a
  16218. * valid restriction of B's occurrence range as defined by
  16219. * Occurrence Range OK ($3.9.6)."
  16220. */
  16221. if (xmlSchemaCheckParticleRangeOK(
  16222. xmlSchemaGetParticleTotalRangeMin(r),
  16223. xmlSchemaGetParticleTotalRangeMax(r),
  16224. b->minOccurs, b->maxOccurs) != 0)
  16225. return (1);
  16226. return (0);
  16227. }
  16228. #endif
  16229. /**
  16230. * xmlSchemaCheckRCaseRecurse:
  16231. * @ctxt: the schema parser context
  16232. * @r: the <all> or <sequence> model group particle
  16233. * @b: the base <all> or <sequence> model group particle
  16234. *
  16235. * (3.9.6) Constraints on Particle Schema Components
  16236. * Schema Component Constraint:
  16237. * Particle Derivation OK (All:All,Sequence:Sequence --
  16238. Recurse)
  16239. * (rcase-Recurse)
  16240. *
  16241. * STATUS: ?
  16242. * TODO: subst-groups
  16243. *
  16244. * Returns 0 if the constraints are satisfied, a positive
  16245. * error code if not and -1 if an internal error occurred.
  16246. */
  16247. static int
  16248. xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
  16249. xmlSchemaParticlePtr r,
  16250. xmlSchemaParticlePtr b)
  16251. {
  16252. /* xmlSchemaParticlePtr part; */
  16253. /* TODO: Error codes (rcase-Recurse). */
  16254. if ((r->children == NULL) || (b->children == NULL) ||
  16255. (r->children->type != b->children->type))
  16256. return (-1);
  16257. /*
  16258. * SPEC "For an all or sequence group particle to be a `valid
  16259. * restriction` of another group particle with the same {compositor}..."
  16260. *
  16261. * SPEC (1) "R's occurrence range is a valid restriction of B's
  16262. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16263. */
  16264. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16265. b->minOccurs, b->maxOccurs))
  16266. return (1);
  16267. return (0);
  16268. }
  16269. #endif
  16270. #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
  16271. xmlSchemaPCustomErrExt(pctxt, \
  16272. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16273. WXS_BASIC_CAST fac1, fac1->node, \
  16274. "It is an error for both '%s' and '%s' to be specified on the "\
  16275. "same type definition", \
  16276. BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
  16277. BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
  16278. #define FACET_RESTR_ERR(fac1, msg) \
  16279. xmlSchemaPCustomErr(pctxt, \
  16280. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16281. WXS_BASIC_CAST fac1, fac1->node, \
  16282. msg, NULL);
  16283. #define FACET_RESTR_FIXED_ERR(fac) \
  16284. xmlSchemaPCustomErr(pctxt, \
  16285. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16286. WXS_BASIC_CAST fac, fac->node, \
  16287. "The base type's facet is 'fixed', thus the value must not " \
  16288. "differ", NULL);
  16289. static void
  16290. xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
  16291. xmlSchemaFacetPtr facet1,
  16292. xmlSchemaFacetPtr facet2,
  16293. int lessGreater,
  16294. int orEqual,
  16295. int ofBase)
  16296. {
  16297. xmlChar *msg = NULL;
  16298. msg = xmlStrdup(BAD_CAST "'");
  16299. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
  16300. msg = xmlStrcat(msg, BAD_CAST "' has to be");
  16301. if (lessGreater == 0)
  16302. msg = xmlStrcat(msg, BAD_CAST " equal to");
  16303. if (lessGreater == 1)
  16304. msg = xmlStrcat(msg, BAD_CAST " greater than");
  16305. else
  16306. msg = xmlStrcat(msg, BAD_CAST " less than");
  16307. if (orEqual)
  16308. msg = xmlStrcat(msg, BAD_CAST " or equal to");
  16309. msg = xmlStrcat(msg, BAD_CAST " '");
  16310. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
  16311. if (ofBase)
  16312. msg = xmlStrcat(msg, BAD_CAST "' of the base type");
  16313. else
  16314. msg = xmlStrcat(msg, BAD_CAST "'");
  16315. xmlSchemaPCustomErr(pctxt,
  16316. XML_SCHEMAP_INVALID_FACET_VALUE,
  16317. WXS_BASIC_CAST facet1, NULL,
  16318. (const char *) msg, NULL);
  16319. if (msg != NULL)
  16320. xmlFree(msg);
  16321. }
  16322. /*
  16323. * xmlSchemaDeriveAndValidateFacets:
  16324. *
  16325. * Schema Component Constraint: Simple Type Restriction (Facets)
  16326. * (st-restrict-facets)
  16327. */
  16328. static int
  16329. xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
  16330. xmlSchemaTypePtr type)
  16331. {
  16332. xmlSchemaTypePtr base = type->baseType;
  16333. xmlSchemaFacetLinkPtr link, cur, last = NULL;
  16334. xmlSchemaFacetPtr facet, bfacet,
  16335. flength = NULL, ftotdig = NULL, ffracdig = NULL,
  16336. fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
  16337. fmininc = NULL, fmaxinc = NULL,
  16338. fminexc = NULL, fmaxexc = NULL,
  16339. bflength = NULL, bftotdig = NULL, bffracdig = NULL,
  16340. bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
  16341. bfmininc = NULL, bfmaxinc = NULL,
  16342. bfminexc = NULL, bfmaxexc = NULL;
  16343. int res; /* err = 0, fixedErr; */
  16344. /*
  16345. * SPEC st-restrict-facets 1:
  16346. * "The {variety} of R is the same as that of B."
  16347. */
  16348. /*
  16349. * SPEC st-restrict-facets 2:
  16350. * "If {variety} is atomic, the {primitive type definition}
  16351. * of R is the same as that of B."
  16352. *
  16353. * NOTE: we leave 1 & 2 out for now, since this will be
  16354. * satisfied by the derivation process.
  16355. * CONSTRUCTION TODO: Maybe needed if using a construction API.
  16356. */
  16357. /*
  16358. * SPEC st-restrict-facets 3:
  16359. * "The {facets} of R are the union of S and the {facets}
  16360. * of B, eliminating duplicates. To eliminate duplicates,
  16361. * when a facet of the same kind occurs in both S and the
  16362. * {facets} of B, the one in the {facets} of B is not
  16363. * included, with the exception of enumeration and pattern
  16364. * facets, for which multiple occurrences with distinct values
  16365. * are allowed."
  16366. */
  16367. if ((type->facetSet == NULL) && (base->facetSet == NULL))
  16368. return (0);
  16369. last = type->facetSet;
  16370. if (last != NULL)
  16371. while (last->next != NULL)
  16372. last = last->next;
  16373. for (cur = type->facetSet; cur != NULL; cur = cur->next) {
  16374. facet = cur->facet;
  16375. switch (facet->type) {
  16376. case XML_SCHEMA_FACET_LENGTH:
  16377. flength = facet; break;
  16378. case XML_SCHEMA_FACET_MINLENGTH:
  16379. fminlen = facet; break;
  16380. case XML_SCHEMA_FACET_MININCLUSIVE:
  16381. fmininc = facet; break;
  16382. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16383. fminexc = facet; break;
  16384. case XML_SCHEMA_FACET_MAXLENGTH:
  16385. fmaxlen = facet; break;
  16386. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16387. fmaxinc = facet; break;
  16388. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16389. fmaxexc = facet; break;
  16390. case XML_SCHEMA_FACET_TOTALDIGITS:
  16391. ftotdig = facet; break;
  16392. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16393. ffracdig = facet; break;
  16394. default:
  16395. break;
  16396. }
  16397. }
  16398. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16399. facet = cur->facet;
  16400. switch (facet->type) {
  16401. case XML_SCHEMA_FACET_LENGTH:
  16402. bflength = facet; break;
  16403. case XML_SCHEMA_FACET_MINLENGTH:
  16404. bfminlen = facet; break;
  16405. case XML_SCHEMA_FACET_MININCLUSIVE:
  16406. bfmininc = facet; break;
  16407. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16408. bfminexc = facet; break;
  16409. case XML_SCHEMA_FACET_MAXLENGTH:
  16410. bfmaxlen = facet; break;
  16411. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16412. bfmaxinc = facet; break;
  16413. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16414. bfmaxexc = facet; break;
  16415. case XML_SCHEMA_FACET_TOTALDIGITS:
  16416. bftotdig = facet; break;
  16417. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16418. bffracdig = facet; break;
  16419. default:
  16420. break;
  16421. }
  16422. }
  16423. /*
  16424. * length and minLength or maxLength (2.2) + (3.2)
  16425. */
  16426. if (flength && (fminlen || fmaxlen)) {
  16427. FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
  16428. "either of 'minLength' or 'maxLength' to be specified on "
  16429. "the same type definition")
  16430. }
  16431. /*
  16432. * Mutual exclusions in the same derivation step.
  16433. */
  16434. if ((fmaxinc) && (fmaxexc)) {
  16435. /*
  16436. * SCC "maxInclusive and maxExclusive"
  16437. */
  16438. FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
  16439. }
  16440. if ((fmininc) && (fminexc)) {
  16441. /*
  16442. * SCC "minInclusive and minExclusive"
  16443. */
  16444. FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
  16445. }
  16446. if (flength && bflength) {
  16447. /*
  16448. * SCC "length valid restriction"
  16449. * The values have to be equal.
  16450. */
  16451. res = xmlSchemaCompareValues(flength->val, bflength->val);
  16452. if (res == -2)
  16453. goto internal_error;
  16454. if (res != 0)
  16455. xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
  16456. if ((res != 0) && (bflength->fixed)) {
  16457. FACET_RESTR_FIXED_ERR(flength)
  16458. }
  16459. }
  16460. if (fminlen && bfminlen) {
  16461. /*
  16462. * SCC "minLength valid restriction"
  16463. * minLength >= BASE minLength
  16464. */
  16465. res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
  16466. if (res == -2)
  16467. goto internal_error;
  16468. if (res == -1)
  16469. xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
  16470. if ((res != 0) && (bfminlen->fixed)) {
  16471. FACET_RESTR_FIXED_ERR(fminlen)
  16472. }
  16473. }
  16474. if (fmaxlen && bfmaxlen) {
  16475. /*
  16476. * SCC "maxLength valid restriction"
  16477. * maxLength <= BASE minLength
  16478. */
  16479. res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
  16480. if (res == -2)
  16481. goto internal_error;
  16482. if (res == 1)
  16483. xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
  16484. if ((res != 0) && (bfmaxlen->fixed)) {
  16485. FACET_RESTR_FIXED_ERR(fmaxlen)
  16486. }
  16487. }
  16488. /*
  16489. * SCC "length and minLength or maxLength"
  16490. */
  16491. if (! flength)
  16492. flength = bflength;
  16493. if (flength) {
  16494. if (! fminlen)
  16495. fminlen = bfminlen;
  16496. if (fminlen) {
  16497. /* (1.1) length >= minLength */
  16498. res = xmlSchemaCompareValues(flength->val, fminlen->val);
  16499. if (res == -2)
  16500. goto internal_error;
  16501. if (res == -1)
  16502. xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
  16503. }
  16504. if (! fmaxlen)
  16505. fmaxlen = bfmaxlen;
  16506. if (fmaxlen) {
  16507. /* (2.1) length <= maxLength */
  16508. res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
  16509. if (res == -2)
  16510. goto internal_error;
  16511. if (res == 1)
  16512. xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
  16513. }
  16514. }
  16515. if (fmaxinc) {
  16516. /*
  16517. * "maxInclusive"
  16518. */
  16519. if (fmininc) {
  16520. /* SCC "maxInclusive >= minInclusive" */
  16521. res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
  16522. if (res == -2)
  16523. goto internal_error;
  16524. if (res == -1) {
  16525. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
  16526. }
  16527. }
  16528. /*
  16529. * SCC "maxInclusive valid restriction"
  16530. */
  16531. if (bfmaxinc) {
  16532. /* maxInclusive <= BASE maxInclusive */
  16533. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
  16534. if (res == -2)
  16535. goto internal_error;
  16536. if (res == 1)
  16537. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
  16538. if ((res != 0) && (bfmaxinc->fixed)) {
  16539. FACET_RESTR_FIXED_ERR(fmaxinc)
  16540. }
  16541. }
  16542. if (bfmaxexc) {
  16543. /* maxInclusive < BASE maxExclusive */
  16544. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
  16545. if (res == -2)
  16546. goto internal_error;
  16547. if (res != -1) {
  16548. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
  16549. }
  16550. }
  16551. if (bfmininc) {
  16552. /* maxInclusive >= BASE minInclusive */
  16553. res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
  16554. if (res == -2)
  16555. goto internal_error;
  16556. if (res == -1) {
  16557. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
  16558. }
  16559. }
  16560. if (bfminexc) {
  16561. /* maxInclusive > BASE minExclusive */
  16562. res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
  16563. if (res == -2)
  16564. goto internal_error;
  16565. if (res != 1) {
  16566. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
  16567. }
  16568. }
  16569. }
  16570. if (fmaxexc) {
  16571. /*
  16572. * "maxExclusive >= minExclusive"
  16573. */
  16574. if (fminexc) {
  16575. res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
  16576. if (res == -2)
  16577. goto internal_error;
  16578. if (res == -1) {
  16579. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
  16580. }
  16581. }
  16582. /*
  16583. * "maxExclusive valid restriction"
  16584. */
  16585. if (bfmaxexc) {
  16586. /* maxExclusive <= BASE maxExclusive */
  16587. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
  16588. if (res == -2)
  16589. goto internal_error;
  16590. if (res == 1) {
  16591. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
  16592. }
  16593. if ((res != 0) && (bfmaxexc->fixed)) {
  16594. FACET_RESTR_FIXED_ERR(fmaxexc)
  16595. }
  16596. }
  16597. if (bfmaxinc) {
  16598. /* maxExclusive <= BASE maxInclusive */
  16599. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
  16600. if (res == -2)
  16601. goto internal_error;
  16602. if (res == 1) {
  16603. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
  16604. }
  16605. }
  16606. if (bfmininc) {
  16607. /* maxExclusive > BASE minInclusive */
  16608. res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
  16609. if (res == -2)
  16610. goto internal_error;
  16611. if (res != 1) {
  16612. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
  16613. }
  16614. }
  16615. if (bfminexc) {
  16616. /* maxExclusive > BASE minExclusive */
  16617. res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
  16618. if (res == -2)
  16619. goto internal_error;
  16620. if (res != 1) {
  16621. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
  16622. }
  16623. }
  16624. }
  16625. if (fminexc) {
  16626. /*
  16627. * "minExclusive < maxInclusive"
  16628. */
  16629. if (fmaxinc) {
  16630. res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
  16631. if (res == -2)
  16632. goto internal_error;
  16633. if (res != -1) {
  16634. xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
  16635. }
  16636. }
  16637. /*
  16638. * "minExclusive valid restriction"
  16639. */
  16640. if (bfminexc) {
  16641. /* minExclusive >= BASE minExclusive */
  16642. res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
  16643. if (res == -2)
  16644. goto internal_error;
  16645. if (res == -1) {
  16646. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
  16647. }
  16648. if ((res != 0) && (bfminexc->fixed)) {
  16649. FACET_RESTR_FIXED_ERR(fminexc)
  16650. }
  16651. }
  16652. if (bfmaxinc) {
  16653. /* minExclusive <= BASE maxInclusive */
  16654. res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
  16655. if (res == -2)
  16656. goto internal_error;
  16657. if (res == 1) {
  16658. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
  16659. }
  16660. }
  16661. if (bfmininc) {
  16662. /* minExclusive >= BASE minInclusive */
  16663. res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
  16664. if (res == -2)
  16665. goto internal_error;
  16666. if (res == -1) {
  16667. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
  16668. }
  16669. }
  16670. if (bfmaxexc) {
  16671. /* minExclusive < BASE maxExclusive */
  16672. res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
  16673. if (res == -2)
  16674. goto internal_error;
  16675. if (res != -1) {
  16676. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
  16677. }
  16678. }
  16679. }
  16680. if (fmininc) {
  16681. /*
  16682. * "minInclusive < maxExclusive"
  16683. */
  16684. if (fmaxexc) {
  16685. res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
  16686. if (res == -2)
  16687. goto internal_error;
  16688. if (res != -1) {
  16689. xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
  16690. }
  16691. }
  16692. /*
  16693. * "minExclusive valid restriction"
  16694. */
  16695. if (bfmininc) {
  16696. /* minInclusive >= BASE minInclusive */
  16697. res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
  16698. if (res == -2)
  16699. goto internal_error;
  16700. if (res == -1) {
  16701. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
  16702. }
  16703. if ((res != 0) && (bfmininc->fixed)) {
  16704. FACET_RESTR_FIXED_ERR(fmininc)
  16705. }
  16706. }
  16707. if (bfmaxinc) {
  16708. /* minInclusive <= BASE maxInclusive */
  16709. res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
  16710. if (res == -2)
  16711. goto internal_error;
  16712. if (res == 1) {
  16713. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
  16714. }
  16715. }
  16716. if (bfminexc) {
  16717. /* minInclusive > BASE minExclusive */
  16718. res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
  16719. if (res == -2)
  16720. goto internal_error;
  16721. if (res != 1)
  16722. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
  16723. }
  16724. if (bfmaxexc) {
  16725. /* minInclusive < BASE maxExclusive */
  16726. res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
  16727. if (res == -2)
  16728. goto internal_error;
  16729. if (res != -1)
  16730. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
  16731. }
  16732. }
  16733. if (ftotdig && bftotdig) {
  16734. /*
  16735. * SCC " totalDigits valid restriction"
  16736. * totalDigits <= BASE totalDigits
  16737. */
  16738. res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
  16739. if (res == -2)
  16740. goto internal_error;
  16741. if (res == 1)
  16742. xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
  16743. -1, 1, 1);
  16744. if ((res != 0) && (bftotdig->fixed)) {
  16745. FACET_RESTR_FIXED_ERR(ftotdig)
  16746. }
  16747. }
  16748. if (ffracdig && bffracdig) {
  16749. /*
  16750. * SCC "fractionDigits valid restriction"
  16751. * fractionDigits <= BASE fractionDigits
  16752. */
  16753. res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
  16754. if (res == -2)
  16755. goto internal_error;
  16756. if (res == 1)
  16757. xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
  16758. -1, 1, 1);
  16759. if ((res != 0) && (bffracdig->fixed)) {
  16760. FACET_RESTR_FIXED_ERR(ffracdig)
  16761. }
  16762. }
  16763. /*
  16764. * SCC "fractionDigits less than or equal to totalDigits"
  16765. */
  16766. if (! ftotdig)
  16767. ftotdig = bftotdig;
  16768. if (! ffracdig)
  16769. ffracdig = bffracdig;
  16770. if (ftotdig && ffracdig) {
  16771. res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
  16772. if (res == -2)
  16773. goto internal_error;
  16774. if (res == 1)
  16775. xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
  16776. -1, 1, 0);
  16777. }
  16778. /*
  16779. * *Enumerations* won' be added here, since only the first set
  16780. * of enumerations in the ancestor-or-self axis is used
  16781. * for validation, plus we need to use the base type of those
  16782. * enumerations for whitespace.
  16783. *
  16784. * *Patterns*: won't be add here, since they are ORed at
  16785. * type level and ANDed at ancestor level. This will
  16786. * happen during validation by walking the base axis
  16787. * of the type.
  16788. */
  16789. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16790. bfacet = cur->facet;
  16791. /*
  16792. * Special handling of enumerations and patterns.
  16793. * TODO: hmm, they should not appear in the set, so remove this.
  16794. */
  16795. if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
  16796. (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
  16797. continue;
  16798. /*
  16799. * Search for a duplicate facet in the current type.
  16800. */
  16801. link = type->facetSet;
  16802. /* err = 0; */
  16803. /* fixedErr = 0; */
  16804. while (link != NULL) {
  16805. facet = link->facet;
  16806. if (facet->type == bfacet->type) {
  16807. switch (facet->type) {
  16808. case XML_SCHEMA_FACET_WHITESPACE:
  16809. /*
  16810. * The whitespace must be stronger.
  16811. */
  16812. if (facet->whitespace < bfacet->whitespace) {
  16813. FACET_RESTR_ERR(facet,
  16814. "The 'whitespace' value has to be equal to "
  16815. "or stronger than the 'whitespace' value of "
  16816. "the base type")
  16817. }
  16818. if ((bfacet->fixed) &&
  16819. (facet->whitespace != bfacet->whitespace)) {
  16820. FACET_RESTR_FIXED_ERR(facet)
  16821. }
  16822. break;
  16823. default:
  16824. break;
  16825. }
  16826. /* Duplicate found. */
  16827. break;
  16828. }
  16829. link = link->next;
  16830. }
  16831. /*
  16832. * If no duplicate was found: add the base types's facet
  16833. * to the set.
  16834. */
  16835. if (link == NULL) {
  16836. link = (xmlSchemaFacetLinkPtr)
  16837. xmlMalloc(sizeof(xmlSchemaFacetLink));
  16838. if (link == NULL) {
  16839. xmlSchemaPErrMemory(pctxt,
  16840. "deriving facets, creating a facet link", NULL);
  16841. return (-1);
  16842. }
  16843. link->facet = cur->facet;
  16844. link->next = NULL;
  16845. if (last == NULL)
  16846. type->facetSet = link;
  16847. else
  16848. last->next = link;
  16849. last = link;
  16850. }
  16851. }
  16852. return (0);
  16853. internal_error:
  16854. PERROR_INT("xmlSchemaDeriveAndValidateFacets",
  16855. "an error occurred");
  16856. return (-1);
  16857. }
  16858. static int
  16859. xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
  16860. xmlSchemaTypePtr type)
  16861. {
  16862. xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
  16863. /*
  16864. * The actual value is then formed by replacing any union type
  16865. * definition in the `explicit members` with the members of their
  16866. * {member type definitions}, in order.
  16867. *
  16868. * TODO: There's a bug entry at
  16869. * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
  16870. * which indicates that we'll keep the union types the future.
  16871. */
  16872. link = type->memberTypes;
  16873. while (link != NULL) {
  16874. if (WXS_IS_TYPE_NOT_FIXED(link->type))
  16875. xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
  16876. if (WXS_IS_UNION(link->type)) {
  16877. subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
  16878. if (subLink != NULL) {
  16879. link->type = subLink->type;
  16880. if (subLink->next != NULL) {
  16881. lastLink = link->next;
  16882. subLink = subLink->next;
  16883. prevLink = link;
  16884. while (subLink != NULL) {
  16885. newLink = (xmlSchemaTypeLinkPtr)
  16886. xmlMalloc(sizeof(xmlSchemaTypeLink));
  16887. if (newLink == NULL) {
  16888. xmlSchemaPErrMemory(pctxt, "allocating a type link",
  16889. NULL);
  16890. return (-1);
  16891. }
  16892. newLink->type = subLink->type;
  16893. prevLink->next = newLink;
  16894. prevLink = newLink;
  16895. newLink->next = lastLink;
  16896. subLink = subLink->next;
  16897. }
  16898. }
  16899. }
  16900. }
  16901. link = link->next;
  16902. }
  16903. return (0);
  16904. }
  16905. static void
  16906. xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
  16907. {
  16908. int has = 0, needVal = 0, normVal = 0;
  16909. has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
  16910. if (has) {
  16911. needVal = (type->baseType->flags &
  16912. XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
  16913. normVal = (type->baseType->flags &
  16914. XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
  16915. }
  16916. if (type->facets != NULL) {
  16917. xmlSchemaFacetPtr fac;
  16918. for (fac = type->facets; fac != NULL; fac = fac->next) {
  16919. switch (fac->type) {
  16920. case XML_SCHEMA_FACET_WHITESPACE:
  16921. break;
  16922. case XML_SCHEMA_FACET_PATTERN:
  16923. normVal = 1;
  16924. has = 1;
  16925. break;
  16926. case XML_SCHEMA_FACET_ENUMERATION:
  16927. needVal = 1;
  16928. normVal = 1;
  16929. has = 1;
  16930. break;
  16931. default:
  16932. has = 1;
  16933. break;
  16934. }
  16935. }
  16936. }
  16937. if (normVal)
  16938. type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
  16939. if (needVal)
  16940. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16941. if (has)
  16942. type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
  16943. if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
  16944. xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
  16945. /*
  16946. * OPTIMIZE VAL TODO: Some facets need a computed value.
  16947. */
  16948. if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
  16949. (prim->builtInType != XML_SCHEMAS_STRING)) {
  16950. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16951. }
  16952. }
  16953. }
  16954. static int
  16955. xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
  16956. {
  16957. /*
  16958. * Evaluate the whitespace-facet value.
  16959. */
  16960. if (WXS_IS_LIST(type)) {
  16961. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16962. return (0);
  16963. } else if (WXS_IS_UNION(type))
  16964. return (0);
  16965. if (type->facetSet != NULL) {
  16966. xmlSchemaFacetLinkPtr lin;
  16967. for (lin = type->facetSet; lin != NULL; lin = lin->next) {
  16968. if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
  16969. switch (lin->facet->whitespace) {
  16970. case XML_SCHEMAS_FACET_PRESERVE:
  16971. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  16972. break;
  16973. case XML_SCHEMAS_FACET_REPLACE:
  16974. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  16975. break;
  16976. case XML_SCHEMAS_FACET_COLLAPSE:
  16977. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16978. break;
  16979. default:
  16980. return (-1);
  16981. }
  16982. return (0);
  16983. }
  16984. }
  16985. }
  16986. /*
  16987. * For all `atomic` datatypes other than string (and types `derived`
  16988. * by `restriction` from it) the value of whiteSpace is fixed to
  16989. * collapse
  16990. */
  16991. {
  16992. xmlSchemaTypePtr anc;
  16993. for (anc = type->baseType; anc != NULL &&
  16994. anc->builtInType != XML_SCHEMAS_ANYTYPE;
  16995. anc = anc->baseType) {
  16996. if (anc->type == XML_SCHEMA_TYPE_BASIC) {
  16997. if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
  16998. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  16999. } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
  17000. (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
  17001. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  17002. } else
  17003. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  17004. break;
  17005. }
  17006. }
  17007. }
  17008. return (0);
  17009. }
  17010. static int
  17011. xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
  17012. xmlSchemaTypePtr type)
  17013. {
  17014. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  17015. return(0);
  17016. if (! WXS_IS_TYPE_NOT_FIXED_1(type))
  17017. return(0);
  17018. type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
  17019. if (WXS_IS_LIST(type)) {
  17020. /*
  17021. * Corresponds to <simpleType><list>...
  17022. */
  17023. if (type->subtypes == NULL) {
  17024. /*
  17025. * This one is really needed, so get out.
  17026. */
  17027. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  17028. "list type has no item-type assigned");
  17029. return(-1);
  17030. }
  17031. } else if (WXS_IS_UNION(type)) {
  17032. /*
  17033. * Corresponds to <simpleType><union>...
  17034. */
  17035. if (type->memberTypes == NULL) {
  17036. /*
  17037. * This one is really needed, so get out.
  17038. */
  17039. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  17040. "union type has no member-types assigned");
  17041. return(-1);
  17042. }
  17043. } else {
  17044. /*
  17045. * Corresponds to <simpleType><restriction>...
  17046. */
  17047. if (type->baseType == NULL) {
  17048. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  17049. "type has no base-type assigned");
  17050. return(-1);
  17051. }
  17052. if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
  17053. if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
  17054. return(-1);
  17055. /*
  17056. * Variety
  17057. * If the <restriction> alternative is chosen, then the
  17058. * {variety} of the {base type definition}.
  17059. */
  17060. if (WXS_IS_ATOMIC(type->baseType))
  17061. type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
  17062. else if (WXS_IS_LIST(type->baseType)) {
  17063. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  17064. /*
  17065. * Inherit the itemType.
  17066. */
  17067. type->subtypes = type->baseType->subtypes;
  17068. } else if (WXS_IS_UNION(type->baseType)) {
  17069. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  17070. /*
  17071. * NOTE that we won't assign the memberTypes of the base,
  17072. * since this will make trouble when freeing them; we will
  17073. * use a lookup function to access them instead.
  17074. */
  17075. }
  17076. }
  17077. return(0);
  17078. }
  17079. #ifdef DEBUG_TYPE
  17080. static void
  17081. xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
  17082. xmlSchemaTypePtr type)
  17083. {
  17084. if (type->node != NULL) {
  17085. xmlGenericError(xmlGenericErrorContext,
  17086. "Type of %s : %s:%d :", name,
  17087. type->node->doc->URL,
  17088. xmlGetLineNo(type->node));
  17089. } else {
  17090. xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
  17091. }
  17092. if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
  17093. switch (type->contentType) {
  17094. case XML_SCHEMA_CONTENT_SIMPLE:
  17095. xmlGenericError(xmlGenericErrorContext, "simple\n");
  17096. break;
  17097. case XML_SCHEMA_CONTENT_ELEMENTS:
  17098. xmlGenericError(xmlGenericErrorContext, "elements\n");
  17099. break;
  17100. case XML_SCHEMA_CONTENT_UNKNOWN:
  17101. xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
  17102. break;
  17103. case XML_SCHEMA_CONTENT_EMPTY:
  17104. xmlGenericError(xmlGenericErrorContext, "empty\n");
  17105. break;
  17106. case XML_SCHEMA_CONTENT_MIXED:
  17107. if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
  17108. type->subtypes))
  17109. xmlGenericError(xmlGenericErrorContext,
  17110. "mixed as emptiable particle\n");
  17111. else
  17112. xmlGenericError(xmlGenericErrorContext, "mixed\n");
  17113. break;
  17114. /* Removed, since not used. */
  17115. /*
  17116. case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
  17117. xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
  17118. break;
  17119. */
  17120. case XML_SCHEMA_CONTENT_BASIC:
  17121. xmlGenericError(xmlGenericErrorContext, "basic\n");
  17122. break;
  17123. default:
  17124. xmlGenericError(xmlGenericErrorContext,
  17125. "not registered !!!\n");
  17126. break;
  17127. }
  17128. }
  17129. }
  17130. #endif
  17131. /*
  17132. * 3.14.6 Constraints on Simple Type Definition Schema Components
  17133. */
  17134. static int
  17135. xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
  17136. xmlSchemaTypePtr type)
  17137. {
  17138. int res, olderrs = pctxt->nberrors;
  17139. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  17140. return(-1);
  17141. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17142. return(0);
  17143. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  17144. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  17145. if (type->baseType == NULL) {
  17146. PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
  17147. "missing baseType");
  17148. goto exit_failure;
  17149. }
  17150. if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
  17151. xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
  17152. /*
  17153. * If a member type of a union is a union itself, we need to substitute
  17154. * that member type for its member types.
  17155. * NOTE that this might change in WXS 1.1; i.e. we will keep the union
  17156. * types in WXS 1.1.
  17157. */
  17158. if ((type->memberTypes != NULL) &&
  17159. (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
  17160. return(-1);
  17161. /*
  17162. * SPEC src-simple-type 1
  17163. * "The corresponding simple type definition, if any, must satisfy
  17164. * the conditions set out in Constraints on Simple Type Definition
  17165. * Schema Components ($3.14.6)."
  17166. */
  17167. /*
  17168. * Schema Component Constraint: Simple Type Definition Properties Correct
  17169. * (st-props-correct)
  17170. */
  17171. res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
  17172. HFAILURE HERROR
  17173. /*
  17174. * Schema Component Constraint: Derivation Valid (Restriction, Simple)
  17175. * (cos-st-restricts)
  17176. */
  17177. res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
  17178. HFAILURE HERROR
  17179. /*
  17180. * TODO: Removed the error report, since it got annoying to get an
  17181. * extra error report, if anything failed until now.
  17182. * Enable this if needed.
  17183. *
  17184. * xmlSchemaPErr(ctxt, type->node,
  17185. * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  17186. * "Simple type '%s' does not satisfy the constraints "
  17187. * "on simple type definitions.\n",
  17188. * type->name, NULL);
  17189. */
  17190. /*
  17191. * Schema Component Constraint: Simple Type Restriction (Facets)
  17192. * (st-restrict-facets)
  17193. */
  17194. res = xmlSchemaCheckFacetValues(type, pctxt);
  17195. HFAILURE HERROR
  17196. if ((type->facetSet != NULL) ||
  17197. (type->baseType->facetSet != NULL)) {
  17198. res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
  17199. HFAILURE HERROR
  17200. }
  17201. /*
  17202. * Whitespace value.
  17203. */
  17204. res = xmlSchemaTypeFixupWhitespace(type);
  17205. HFAILURE HERROR
  17206. xmlSchemaTypeFixupOptimFacets(type);
  17207. exit_error:
  17208. #ifdef DEBUG_TYPE
  17209. xmlSchemaDebugFixedType(pctxt, type);
  17210. #endif
  17211. if (olderrs != pctxt->nberrors)
  17212. return(pctxt->err);
  17213. return(0);
  17214. exit_failure:
  17215. #ifdef DEBUG_TYPE
  17216. xmlSchemaDebugFixedType(pctxt, type);
  17217. #endif
  17218. return(-1);
  17219. }
  17220. static int
  17221. xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
  17222. xmlSchemaTypePtr type)
  17223. {
  17224. int res = 0, olderrs = pctxt->nberrors;
  17225. xmlSchemaTypePtr baseType = type->baseType;
  17226. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17227. return(0);
  17228. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  17229. if (baseType == NULL) {
  17230. PERROR_INT("xmlSchemaFixupComplexType",
  17231. "missing baseType");
  17232. goto exit_failure;
  17233. }
  17234. /*
  17235. * Fixup the base type.
  17236. */
  17237. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  17238. xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
  17239. if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
  17240. /*
  17241. * Skip fixup if the base type is invalid.
  17242. * TODO: Generate a warning!
  17243. */
  17244. return(0);
  17245. }
  17246. /*
  17247. * This basically checks if the base type can be derived.
  17248. */
  17249. res = xmlSchemaCheckSRCCT(pctxt, type);
  17250. HFAILURE HERROR
  17251. /*
  17252. * Fixup the content type.
  17253. */
  17254. if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
  17255. /*
  17256. * Corresponds to <complexType><simpleContent>...
  17257. */
  17258. if ((WXS_IS_COMPLEX(baseType)) &&
  17259. (baseType->contentTypeDef != NULL) &&
  17260. (WXS_IS_RESTRICTION(type))) {
  17261. xmlSchemaTypePtr contentBase, content;
  17262. #ifdef ENABLE_NAMED_LOCALS
  17263. char buf[30];
  17264. const xmlChar *tmpname;
  17265. #endif
  17266. /*
  17267. * SPEC (1) If <restriction> + base type is <complexType>,
  17268. * "whose own {content type} is a simple type..."
  17269. */
  17270. if (type->contentTypeDef != NULL) {
  17271. /*
  17272. * SPEC (1.1) "the simple type definition corresponding to the
  17273. * <simpleType> among the [children] of <restriction> if there
  17274. * is one;"
  17275. * Note that this "<simpleType> among the [children]" was put
  17276. * into ->contentTypeDef during parsing.
  17277. */
  17278. contentBase = type->contentTypeDef;
  17279. type->contentTypeDef = NULL;
  17280. } else {
  17281. /*
  17282. * (1.2) "...otherwise (<restriction> has no <simpleType>
  17283. * among its [children]), the simple type definition which
  17284. * is the {content type} of the ... base type."
  17285. */
  17286. contentBase = baseType->contentTypeDef;
  17287. }
  17288. /*
  17289. * SPEC
  17290. * "... a simple type definition which restricts the simple
  17291. * type definition identified in clause 1.1 or clause 1.2
  17292. * with a set of facet components"
  17293. *
  17294. * Create the anonymous simple type, which will be the content
  17295. * type of the complex type.
  17296. */
  17297. #ifdef ENABLE_NAMED_LOCALS
  17298. snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
  17299. tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
  17300. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17301. XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
  17302. type->node, 0);
  17303. #else
  17304. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17305. XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
  17306. type->node, 0);
  17307. #endif
  17308. if (content == NULL)
  17309. goto exit_failure;
  17310. /*
  17311. * We will use the same node as for the <complexType>
  17312. * to have it somehow anchored in the schema doc.
  17313. */
  17314. content->type = XML_SCHEMA_TYPE_SIMPLE;
  17315. content->baseType = contentBase;
  17316. /*
  17317. * Move the facets, previously anchored on the
  17318. * complexType during parsing.
  17319. */
  17320. content->facets = type->facets;
  17321. type->facets = NULL;
  17322. content->facetSet = type->facetSet;
  17323. type->facetSet = NULL;
  17324. type->contentTypeDef = content;
  17325. if (WXS_IS_TYPE_NOT_FIXED(contentBase))
  17326. xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
  17327. /*
  17328. * Fixup the newly created type. We don't need to check
  17329. * for circularity here.
  17330. */
  17331. res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
  17332. HFAILURE HERROR
  17333. res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
  17334. HFAILURE HERROR
  17335. } else if ((WXS_IS_COMPLEX(baseType)) &&
  17336. (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  17337. (WXS_IS_RESTRICTION(type))) {
  17338. /*
  17339. * SPEC (2) If <restriction> + base is a mixed <complexType> with
  17340. * an emptiable particle, then a simple type definition which
  17341. * restricts the <restriction>'s <simpleType> child.
  17342. */
  17343. if ((type->contentTypeDef == NULL) ||
  17344. (type->contentTypeDef->baseType == NULL)) {
  17345. /*
  17346. * TODO: Check if this ever happens.
  17347. */
  17348. xmlSchemaPCustomErr(pctxt,
  17349. XML_SCHEMAP_INTERNAL,
  17350. WXS_BASIC_CAST type, NULL,
  17351. "Internal error: xmlSchemaTypeFixup, "
  17352. "complex type '%s': the <simpleContent><restriction> "
  17353. "is missing a <simpleType> child, but was not caught "
  17354. "by xmlSchemaCheckSRCCT()", type->name);
  17355. goto exit_failure;
  17356. }
  17357. } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
  17358. /*
  17359. * SPEC (3) If <extension> + base is <complexType> with
  17360. * <simpleType> content, "...then the {content type} of that
  17361. * complex type definition"
  17362. */
  17363. if (baseType->contentTypeDef == NULL) {
  17364. /*
  17365. * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
  17366. * should have caught this already.
  17367. */
  17368. xmlSchemaPCustomErr(pctxt,
  17369. XML_SCHEMAP_INTERNAL,
  17370. WXS_BASIC_CAST type, NULL,
  17371. "Internal error: xmlSchemaTypeFixup, "
  17372. "complex type '%s': the <extension>ed base type is "
  17373. "a complex type with no simple content type",
  17374. type->name);
  17375. goto exit_failure;
  17376. }
  17377. type->contentTypeDef = baseType->contentTypeDef;
  17378. } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
  17379. /*
  17380. * SPEC (4) <extension> + base is <simpleType>
  17381. * "... then that simple type definition"
  17382. */
  17383. type->contentTypeDef = baseType;
  17384. } else {
  17385. /*
  17386. * TODO: Check if this ever happens.
  17387. */
  17388. xmlSchemaPCustomErr(pctxt,
  17389. XML_SCHEMAP_INTERNAL,
  17390. WXS_BASIC_CAST type, NULL,
  17391. "Internal error: xmlSchemaTypeFixup, "
  17392. "complex type '%s' with <simpleContent>: unhandled "
  17393. "derivation case", type->name);
  17394. goto exit_failure;
  17395. }
  17396. } else {
  17397. int dummySequence = 0;
  17398. xmlSchemaParticlePtr particle =
  17399. (xmlSchemaParticlePtr) type->subtypes;
  17400. /*
  17401. * Corresponds to <complexType><complexContent>...
  17402. *
  17403. * NOTE that the effective mixed was already set during parsing of
  17404. * <complexType> and <complexContent>; its flag value is
  17405. * XML_SCHEMAS_TYPE_MIXED.
  17406. *
  17407. * Compute the "effective content":
  17408. * (2.1.1) + (2.1.2) + (2.1.3)
  17409. */
  17410. if ((particle == NULL) ||
  17411. ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
  17412. ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
  17413. (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  17414. ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
  17415. (particle->minOccurs == 0))) &&
  17416. ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
  17417. if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
  17418. /*
  17419. * SPEC (2.1.4) "If the `effective mixed` is true, then
  17420. * a particle whose properties are as follows:..."
  17421. *
  17422. * Empty sequence model group with
  17423. * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
  17424. * NOTE that we sill assign it the <complexType> node to
  17425. * somehow anchor it in the doc.
  17426. */
  17427. if ((particle == NULL) ||
  17428. (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
  17429. /*
  17430. * Create the particle.
  17431. */
  17432. particle = xmlSchemaAddParticle(pctxt,
  17433. type->node, 1, 1);
  17434. if (particle == NULL)
  17435. goto exit_failure;
  17436. /*
  17437. * Create the model group.
  17438. */ /* URGENT TODO: avoid adding to pending items. */
  17439. particle->children = (xmlSchemaTreeItemPtr)
  17440. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17441. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17442. if (particle->children == NULL)
  17443. goto exit_failure;
  17444. type->subtypes = (xmlSchemaTypePtr) particle;
  17445. }
  17446. dummySequence = 1;
  17447. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17448. } else {
  17449. /*
  17450. * SPEC (2.1.5) "otherwise empty"
  17451. */
  17452. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  17453. }
  17454. } else {
  17455. /*
  17456. * SPEC (2.2) "otherwise the particle corresponding to the
  17457. * <all>, <choice>, <group> or <sequence> among the
  17458. * [children]."
  17459. */
  17460. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17461. }
  17462. /*
  17463. * Compute the "content type".
  17464. */
  17465. if (WXS_IS_RESTRICTION(type)) {
  17466. /*
  17467. * SPEC (3.1) "If <restriction>..."
  17468. * (3.1.1) + (3.1.2) */
  17469. if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
  17470. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17471. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17472. }
  17473. } else {
  17474. /*
  17475. * SPEC (3.2) "If <extension>..."
  17476. */
  17477. if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17478. /*
  17479. * SPEC (3.2.1)
  17480. * "If the `effective content` is empty, then the
  17481. * {content type} of the [...] base ..."
  17482. */
  17483. type->contentType = baseType->contentType;
  17484. type->subtypes = baseType->subtypes;
  17485. /*
  17486. * Fixes bug #347316:
  17487. * This is the case when the base type has a simple
  17488. * type definition as content.
  17489. */
  17490. type->contentTypeDef = baseType->contentTypeDef;
  17491. /*
  17492. * NOTE that the effective mixed is ignored here.
  17493. */
  17494. } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17495. /*
  17496. * SPEC (3.2.2)
  17497. */
  17498. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17499. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17500. } else {
  17501. /*
  17502. * SPEC (3.2.3)
  17503. */
  17504. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17505. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17506. /*
  17507. * "A model group whose {compositor} is sequence and whose
  17508. * {particles} are..."
  17509. */
  17510. if ((WXS_TYPE_PARTICLE(type) != NULL) &&
  17511. (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
  17512. ((WXS_TYPE_PARTICLE_TERM(type))->type ==
  17513. XML_SCHEMA_TYPE_ALL))
  17514. {
  17515. /*
  17516. * SPEC cos-all-limited (1)
  17517. */
  17518. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17519. /* TODO: error code */
  17520. XML_SCHEMAP_COS_ALL_LIMITED,
  17521. WXS_ITEM_NODE(type), NULL,
  17522. "The type has an 'all' model group in its "
  17523. "{content type} and thus cannot be derived from "
  17524. "a non-empty type, since this would produce a "
  17525. "'sequence' model group containing the 'all' "
  17526. "model group; 'all' model groups are not "
  17527. "allowed to appear inside other model groups",
  17528. NULL, NULL);
  17529. } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
  17530. (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
  17531. ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
  17532. XML_SCHEMA_TYPE_ALL))
  17533. {
  17534. /*
  17535. * SPEC cos-all-limited (1)
  17536. */
  17537. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17538. /* TODO: error code */
  17539. XML_SCHEMAP_COS_ALL_LIMITED,
  17540. WXS_ITEM_NODE(type), NULL,
  17541. "A type cannot be derived by extension from a type "
  17542. "which has an 'all' model group in its "
  17543. "{content type}, since this would produce a "
  17544. "'sequence' model group containing the 'all' "
  17545. "model group; 'all' model groups are not "
  17546. "allowed to appear inside other model groups",
  17547. NULL, NULL);
  17548. } else if (! dummySequence) {
  17549. xmlSchemaTreeItemPtr effectiveContent =
  17550. (xmlSchemaTreeItemPtr) type->subtypes;
  17551. /*
  17552. * Create the particle.
  17553. */
  17554. particle = xmlSchemaAddParticle(pctxt,
  17555. type->node, 1, 1);
  17556. if (particle == NULL)
  17557. goto exit_failure;
  17558. /*
  17559. * Create the "sequence" model group.
  17560. */
  17561. particle->children = (xmlSchemaTreeItemPtr)
  17562. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17563. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17564. if (particle->children == NULL)
  17565. goto exit_failure;
  17566. WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
  17567. /*
  17568. * SPEC "the particle of the {content type} of
  17569. * the ... base ..."
  17570. * Create a duplicate of the base type's particle
  17571. * and assign its "term" to it.
  17572. */
  17573. particle->children->children =
  17574. (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
  17575. type->node,
  17576. ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
  17577. ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
  17578. if (particle->children->children == NULL)
  17579. goto exit_failure;
  17580. particle = (xmlSchemaParticlePtr)
  17581. particle->children->children;
  17582. particle->children =
  17583. ((xmlSchemaParticlePtr) baseType->subtypes)->children;
  17584. /*
  17585. * SPEC "followed by the `effective content`."
  17586. */
  17587. particle->next = effectiveContent;
  17588. /*
  17589. * This all will result in:
  17590. * new-particle
  17591. * --> new-sequence(
  17592. * new-particle
  17593. * --> base-model,
  17594. * this-particle
  17595. * --> this-model
  17596. * )
  17597. */
  17598. } else {
  17599. /*
  17600. * This is the case when there is already an empty
  17601. * <sequence> with minOccurs==maxOccurs==1.
  17602. * Just add the base types's content type.
  17603. * NOTE that, although we miss to add an intermediate
  17604. * <sequence>, this should produce no difference to
  17605. * neither the regex compilation of the content model,
  17606. * nor to the complex type constraints.
  17607. */
  17608. particle->children->children =
  17609. (xmlSchemaTreeItemPtr) baseType->subtypes;
  17610. }
  17611. }
  17612. }
  17613. }
  17614. /*
  17615. * Now fixup attribute uses:
  17616. * - expand attr. group references
  17617. * - intersect attribute wildcards
  17618. * - inherit attribute uses of the base type
  17619. * - inherit or union attr. wildcards if extending
  17620. * - apply attr. use prohibitions if restricting
  17621. */
  17622. res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
  17623. HFAILURE HERROR
  17624. /*
  17625. * Apply the complex type component constraints; this will not
  17626. * check attributes, since this is done in
  17627. * xmlSchemaFixupTypeAttributeUses().
  17628. */
  17629. res = xmlSchemaCheckCTComponent(pctxt, type);
  17630. HFAILURE HERROR
  17631. #ifdef DEBUG_TYPE
  17632. xmlSchemaDebugFixedType(pctxt, type);
  17633. #endif
  17634. if (olderrs != pctxt->nberrors)
  17635. return(pctxt->err);
  17636. else
  17637. return(0);
  17638. exit_error:
  17639. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17640. #ifdef DEBUG_TYPE
  17641. xmlSchemaDebugFixedType(pctxt, type);
  17642. #endif
  17643. return(pctxt->err);
  17644. exit_failure:
  17645. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17646. #ifdef DEBUG_TYPE
  17647. xmlSchemaDebugFixedType(pctxt, type);
  17648. #endif
  17649. return(-1);
  17650. }
  17651. /**
  17652. * xmlSchemaTypeFixup:
  17653. * @typeDecl: the schema type definition
  17654. * @ctxt: the schema parser context
  17655. *
  17656. * Fixes the content model of the type.
  17657. * URGENT TODO: We need an int result!
  17658. */
  17659. static int
  17660. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  17661. xmlSchemaAbstractCtxtPtr actxt)
  17662. {
  17663. if (type == NULL)
  17664. return(0);
  17665. if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
  17666. AERROR_INT("xmlSchemaTypeFixup",
  17667. "this function needs a parser context");
  17668. return(-1);
  17669. }
  17670. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17671. return(0);
  17672. if (type->type == XML_SCHEMA_TYPE_COMPLEX)
  17673. return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
  17674. else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
  17675. return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
  17676. return(0);
  17677. }
  17678. /**
  17679. * xmlSchemaCheckFacet:
  17680. * @facet: the facet
  17681. * @typeDecl: the schema type definition
  17682. * @pctxt: the schema parser context or NULL
  17683. * @name: the optional name of the type
  17684. *
  17685. * Checks and computes the values of facets.
  17686. *
  17687. * Returns 0 if valid, a positive error code if not valid and
  17688. * -1 in case of an internal or API error.
  17689. */
  17690. int
  17691. xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
  17692. xmlSchemaTypePtr typeDecl,
  17693. xmlSchemaParserCtxtPtr pctxt,
  17694. const xmlChar * name ATTRIBUTE_UNUSED)
  17695. {
  17696. int ret = 0, ctxtGiven;
  17697. if ((facet == NULL) || (typeDecl == NULL))
  17698. return(-1);
  17699. /*
  17700. * TODO: will the parser context be given if used from
  17701. * the relaxNG module?
  17702. */
  17703. if (pctxt == NULL)
  17704. ctxtGiven = 0;
  17705. else
  17706. ctxtGiven = 1;
  17707. switch (facet->type) {
  17708. case XML_SCHEMA_FACET_MININCLUSIVE:
  17709. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  17710. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  17711. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  17712. case XML_SCHEMA_FACET_ENUMERATION: {
  17713. /*
  17714. * Okay we need to validate the value
  17715. * at that point.
  17716. */
  17717. xmlSchemaTypePtr base;
  17718. /* 4.3.5.5 Constraints on enumeration Schema Components
  17719. * Schema Component Constraint: enumeration valid restriction
  17720. * It is an `error` if any member of {value} is not in the
  17721. * `value space` of {base type definition}.
  17722. *
  17723. * minInclusive, maxInclusive, minExclusive, maxExclusive:
  17724. * The value `must` be in the
  17725. * `value space` of the `base type`.
  17726. */
  17727. /*
  17728. * This function is intended to deliver a compiled value
  17729. * on the facet. In this implementation of XML Schemata the
  17730. * type holding a facet, won't be a built-in type.
  17731. * Thus to ensure that other API
  17732. * calls (relaxng) do work, if the given type is a built-in
  17733. * type, we will assume that the given built-in type *is
  17734. * already* the base type.
  17735. */
  17736. if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
  17737. base = typeDecl->baseType;
  17738. if (base == NULL) {
  17739. PERROR_INT("xmlSchemaCheckFacet",
  17740. "a type user derived type has no base type");
  17741. return (-1);
  17742. }
  17743. } else
  17744. base = typeDecl;
  17745. if (! ctxtGiven) {
  17746. /*
  17747. * A context is needed if called from RelaxNG.
  17748. */
  17749. pctxt = xmlSchemaNewParserCtxt("*");
  17750. if (pctxt == NULL)
  17751. return (-1);
  17752. }
  17753. /*
  17754. * NOTE: This call does not check the content nodes,
  17755. * since they are not available:
  17756. * facet->node is just the node holding the facet
  17757. * definition, *not* the attribute holding the *value*
  17758. * of the facet.
  17759. */
  17760. ret = xmlSchemaVCheckCVCSimpleType(
  17761. ACTXT_CAST pctxt, facet->node, base,
  17762. facet->value, &(facet->val), 1, 1, 0);
  17763. if (ret != 0) {
  17764. if (ret < 0) {
  17765. /* No error message for RelaxNG. */
  17766. if (ctxtGiven) {
  17767. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17768. XML_SCHEMAP_INTERNAL, facet->node, NULL,
  17769. "Internal error: xmlSchemaCheckFacet, "
  17770. "failed to validate the value '%s' of the "
  17771. "facet '%s' against the base type",
  17772. facet->value, xmlSchemaFacetTypeToString(facet->type));
  17773. }
  17774. goto internal_error;
  17775. }
  17776. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17777. /* No error message for RelaxNG. */
  17778. if (ctxtGiven) {
  17779. xmlChar *str = NULL;
  17780. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17781. ret, facet->node, WXS_BASIC_CAST facet,
  17782. "The value '%s' of the facet does not validate "
  17783. "against the base type '%s'",
  17784. facet->value,
  17785. xmlSchemaFormatQName(&str,
  17786. base->targetNamespace, base->name));
  17787. FREE_AND_NULL(str);
  17788. }
  17789. goto exit;
  17790. } else if (facet->val == NULL) {
  17791. if (ctxtGiven) {
  17792. PERROR_INT("xmlSchemaCheckFacet",
  17793. "value was not computed");
  17794. }
  17795. TODO
  17796. }
  17797. break;
  17798. }
  17799. case XML_SCHEMA_FACET_PATTERN:
  17800. facet->regexp = xmlRegexpCompile(facet->value);
  17801. if (facet->regexp == NULL) {
  17802. ret = XML_SCHEMAP_REGEXP_INVALID;
  17803. /* No error message for RelaxNG. */
  17804. if (ctxtGiven) {
  17805. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17806. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17807. "The value '%s' of the facet 'pattern' is not a "
  17808. "valid regular expression",
  17809. facet->value, NULL);
  17810. }
  17811. }
  17812. break;
  17813. case XML_SCHEMA_FACET_TOTALDIGITS:
  17814. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  17815. case XML_SCHEMA_FACET_LENGTH:
  17816. case XML_SCHEMA_FACET_MAXLENGTH:
  17817. case XML_SCHEMA_FACET_MINLENGTH:
  17818. if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
  17819. ret = xmlSchemaValidatePredefinedType(
  17820. xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
  17821. facet->value, &(facet->val));
  17822. } else {
  17823. ret = xmlSchemaValidatePredefinedType(
  17824. xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
  17825. facet->value, &(facet->val));
  17826. }
  17827. if (ret != 0) {
  17828. if (ret < 0) {
  17829. /* No error message for RelaxNG. */
  17830. if (ctxtGiven) {
  17831. PERROR_INT("xmlSchemaCheckFacet",
  17832. "validating facet value");
  17833. }
  17834. goto internal_error;
  17835. }
  17836. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17837. /* No error message for RelaxNG. */
  17838. if (ctxtGiven) {
  17839. /* error code */
  17840. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  17841. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17842. "The value '%s' of the facet '%s' is not a valid '%s'",
  17843. facet->value,
  17844. xmlSchemaFacetTypeToString(facet->type),
  17845. (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
  17846. BAD_CAST "nonNegativeInteger" :
  17847. BAD_CAST "positiveInteger",
  17848. NULL);
  17849. }
  17850. }
  17851. break;
  17852. case XML_SCHEMA_FACET_WHITESPACE:{
  17853. if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
  17854. facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
  17855. } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
  17856. facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
  17857. } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
  17858. facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
  17859. } else {
  17860. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17861. /* No error message for RelaxNG. */
  17862. if (ctxtGiven) {
  17863. /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
  17864. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17865. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17866. "The value '%s' of the facet 'whitespace' is not "
  17867. "valid", facet->value, NULL);
  17868. }
  17869. }
  17870. }
  17871. default:
  17872. break;
  17873. }
  17874. exit:
  17875. if ((! ctxtGiven) && (pctxt != NULL))
  17876. xmlSchemaFreeParserCtxt(pctxt);
  17877. return (ret);
  17878. internal_error:
  17879. if ((! ctxtGiven) && (pctxt != NULL))
  17880. xmlSchemaFreeParserCtxt(pctxt);
  17881. return (-1);
  17882. }
  17883. /**
  17884. * xmlSchemaCheckFacetValues:
  17885. * @typeDecl: the schema type definition
  17886. * @ctxt: the schema parser context
  17887. *
  17888. * Checks the default values types, especially for facets
  17889. */
  17890. static int
  17891. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  17892. xmlSchemaParserCtxtPtr pctxt)
  17893. {
  17894. int res, olderrs = pctxt->nberrors;
  17895. const xmlChar *name = typeDecl->name;
  17896. /*
  17897. * NOTE: It is intended to use the facets list, instead
  17898. * of facetSet.
  17899. */
  17900. if (typeDecl->facets != NULL) {
  17901. xmlSchemaFacetPtr facet = typeDecl->facets;
  17902. /*
  17903. * Temporarily assign the "schema" to the validation context
  17904. * of the parser context. This is needed for NOTATION validation.
  17905. */
  17906. if (pctxt->vctxt == NULL) {
  17907. if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
  17908. return(-1);
  17909. }
  17910. pctxt->vctxt->schema = pctxt->schema;
  17911. while (facet != NULL) {
  17912. res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
  17913. HFAILURE
  17914. facet = facet->next;
  17915. }
  17916. pctxt->vctxt->schema = NULL;
  17917. }
  17918. if (olderrs != pctxt->nberrors)
  17919. return(pctxt->err);
  17920. return(0);
  17921. exit_failure:
  17922. return(-1);
  17923. }
  17924. /**
  17925. * xmlSchemaGetCircModelGrDefRef:
  17926. * @ctxtMGroup: the searched model group
  17927. * @selfMGroup: the second searched model group
  17928. * @particle: the first particle
  17929. *
  17930. * This one is intended to be used by
  17931. * xmlSchemaCheckGroupDefCircular only.
  17932. *
  17933. * Returns the particle with the circular model group definition reference,
  17934. * otherwise NULL.
  17935. */
  17936. static xmlSchemaTreeItemPtr
  17937. xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
  17938. xmlSchemaTreeItemPtr particle)
  17939. {
  17940. xmlSchemaTreeItemPtr circ = NULL;
  17941. xmlSchemaTreeItemPtr term;
  17942. xmlSchemaModelGroupDefPtr gdef;
  17943. for (; particle != NULL; particle = particle->next) {
  17944. term = particle->children;
  17945. if (term == NULL)
  17946. continue;
  17947. switch (term->type) {
  17948. case XML_SCHEMA_TYPE_GROUP:
  17949. gdef = (xmlSchemaModelGroupDefPtr) term;
  17950. if (gdef == groupDef)
  17951. return (particle);
  17952. /*
  17953. * Mark this model group definition to avoid infinite
  17954. * recursion on circular references not yet examined.
  17955. */
  17956. if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
  17957. continue;
  17958. if (gdef->children != NULL) {
  17959. gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17960. circ = xmlSchemaGetCircModelGrDefRef(groupDef,
  17961. gdef->children->children);
  17962. gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17963. if (circ != NULL)
  17964. return (circ);
  17965. }
  17966. break;
  17967. case XML_SCHEMA_TYPE_SEQUENCE:
  17968. case XML_SCHEMA_TYPE_CHOICE:
  17969. case XML_SCHEMA_TYPE_ALL:
  17970. circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
  17971. if (circ != NULL)
  17972. return (circ);
  17973. break;
  17974. default:
  17975. break;
  17976. }
  17977. }
  17978. return (NULL);
  17979. }
  17980. /**
  17981. * xmlSchemaCheckGroupDefCircular:
  17982. * @item: the model group definition
  17983. * @ctxt: the parser context
  17984. * @name: the name
  17985. *
  17986. * Checks for circular references to model group definitions.
  17987. */
  17988. static void
  17989. xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
  17990. xmlSchemaParserCtxtPtr ctxt)
  17991. {
  17992. /*
  17993. * Schema Component Constraint: Model Group Correct
  17994. * 2 Circular groups are disallowed. That is, within the {particles}
  17995. * of a group there must not be at any depth a particle whose {term}
  17996. * is the group itself.
  17997. */
  17998. if ((item == NULL) ||
  17999. (item->type != XML_SCHEMA_TYPE_GROUP) ||
  18000. (item->children == NULL))
  18001. return;
  18002. {
  18003. xmlSchemaTreeItemPtr circ;
  18004. circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
  18005. if (circ != NULL) {
  18006. xmlChar *str = NULL;
  18007. /*
  18008. * TODO: The error report is not adequate: this constraint
  18009. * is defined for model groups but not definitions, but since
  18010. * there cannot be any circular model groups without a model group
  18011. * definition (if not using a construction API), we check those
  18012. * definitions only.
  18013. */
  18014. xmlSchemaPCustomErr(ctxt,
  18015. XML_SCHEMAP_MG_PROPS_CORRECT_2,
  18016. NULL, WXS_ITEM_NODE(circ),
  18017. "Circular reference to the model group definition '%s' "
  18018. "defined", xmlSchemaFormatQName(&str,
  18019. item->targetNamespace, item->name));
  18020. FREE_AND_NULL(str)
  18021. /*
  18022. * NOTE: We will cut the reference to avoid further
  18023. * confusion of the processor. This is a fatal error.
  18024. */
  18025. circ->children = NULL;
  18026. }
  18027. }
  18028. }
  18029. /**
  18030. * xmlSchemaModelGroupToModelGroupDefFixup:
  18031. * @ctxt: the parser context
  18032. * @mg: the model group
  18033. *
  18034. * Assigns the model group of model group definitions to the "term"
  18035. * of the referencing particle.
  18036. * In xmlSchemaResolveModelGroupParticleReferences the model group
  18037. * definitions were assigned to the "term", since needed for the
  18038. * circularity check.
  18039. *
  18040. * Schema Component Constraint:
  18041. * All Group Limited (cos-all-limited) (1.2)
  18042. */
  18043. static void
  18044. xmlSchemaModelGroupToModelGroupDefFixup(
  18045. xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
  18046. xmlSchemaModelGroupPtr mg)
  18047. {
  18048. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  18049. while (particle != NULL) {
  18050. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  18051. ((WXS_PARTICLE_TERM(particle))->type !=
  18052. XML_SCHEMA_TYPE_GROUP))
  18053. {
  18054. particle = WXS_PTC_CAST particle->next;
  18055. continue;
  18056. }
  18057. if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
  18058. /*
  18059. * TODO: Remove the particle.
  18060. */
  18061. WXS_PARTICLE_TERM(particle) = NULL;
  18062. particle = WXS_PTC_CAST particle->next;
  18063. continue;
  18064. }
  18065. /*
  18066. * Assign the model group to the {term} of the particle.
  18067. */
  18068. WXS_PARTICLE_TERM(particle) =
  18069. WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
  18070. particle = WXS_PTC_CAST particle->next;
  18071. }
  18072. }
  18073. /**
  18074. * xmlSchemaCheckAttrGroupCircularRecur:
  18075. * @ctxtGr: the searched attribute group
  18076. * @attr: the current attribute list to be processed
  18077. *
  18078. * This one is intended to be used by
  18079. * xmlSchemaCheckAttrGroupCircular only.
  18080. *
  18081. * Returns the circular attribute group reference, otherwise NULL.
  18082. */
  18083. static xmlSchemaQNameRefPtr
  18084. xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
  18085. xmlSchemaItemListPtr list)
  18086. {
  18087. xmlSchemaAttributeGroupPtr gr;
  18088. xmlSchemaQNameRefPtr ref, circ;
  18089. int i;
  18090. /*
  18091. * We will search for an attribute group reference which
  18092. * references the context attribute group.
  18093. */
  18094. for (i = 0; i < list->nbItems; i++) {
  18095. ref = list->items[i];
  18096. if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  18097. (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  18098. (ref->item != NULL))
  18099. {
  18100. gr = WXS_ATTR_GROUP_CAST ref->item;
  18101. if (gr == ctxtGr)
  18102. return(ref);
  18103. if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
  18104. continue;
  18105. /*
  18106. * Mark as visited to avoid infinite recursion on
  18107. * circular references not yet examined.
  18108. */
  18109. if ((gr->attrUses) &&
  18110. (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
  18111. {
  18112. gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
  18113. circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
  18114. (xmlSchemaItemListPtr) gr->attrUses);
  18115. gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
  18116. if (circ != NULL)
  18117. return (circ);
  18118. }
  18119. }
  18120. }
  18121. return (NULL);
  18122. }
  18123. /**
  18124. * xmlSchemaCheckAttrGroupCircular:
  18125. * attrGr: the attribute group definition
  18126. * @ctxt: the parser context
  18127. * @name: the name
  18128. *
  18129. * Checks for circular references of attribute groups.
  18130. */
  18131. static int
  18132. xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
  18133. xmlSchemaParserCtxtPtr ctxt)
  18134. {
  18135. /*
  18136. * Schema Representation Constraint:
  18137. * Attribute Group Definition Representation OK
  18138. * 3 Circular group reference is disallowed outside <redefine>.
  18139. * That is, unless this element information item's parent is
  18140. * <redefine>, then among the [children], if any, there must
  18141. * not be an <attributeGroup> with ref [attribute] which resolves
  18142. * to the component corresponding to this <attributeGroup>. Indirect
  18143. * circularity is also ruled out. That is, when QName resolution
  18144. * (Schema Document) ($3.15.3) is applied to a `QName` arising from
  18145. * any <attributeGroup>s with a ref [attribute] among the [children],
  18146. * it must not be the case that a `QName` is encountered at any depth
  18147. * which resolves to the component corresponding to this <attributeGroup>.
  18148. */
  18149. if (attrGr->attrUses == NULL)
  18150. return(0);
  18151. else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
  18152. return(0);
  18153. else {
  18154. xmlSchemaQNameRefPtr circ;
  18155. circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
  18156. (xmlSchemaItemListPtr) attrGr->attrUses);
  18157. if (circ != NULL) {
  18158. xmlChar *str = NULL;
  18159. /*
  18160. * TODO: Report the referenced attr group as QName.
  18161. */
  18162. xmlSchemaPCustomErr(ctxt,
  18163. XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
  18164. NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
  18165. "Circular reference to the attribute group '%s' "
  18166. "defined", xmlSchemaGetComponentQName(&str, attrGr));
  18167. FREE_AND_NULL(str);
  18168. /*
  18169. * NOTE: We will cut the reference to avoid further
  18170. * confusion of the processor.
  18171. * BADSPEC TODO: The spec should define how to process in this case.
  18172. */
  18173. circ->item = NULL;
  18174. return(ctxt->err);
  18175. }
  18176. }
  18177. return(0);
  18178. }
  18179. static int
  18180. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18181. xmlSchemaAttributeGroupPtr attrGr);
  18182. /**
  18183. * xmlSchemaExpandAttributeGroupRefs:
  18184. * @pctxt: the parser context
  18185. * @node: the node of the component holding the attribute uses
  18186. * @completeWild: the intersected wildcard to be returned
  18187. * @list: the attribute uses
  18188. *
  18189. * Substitutes contained attribute group references
  18190. * for their attribute uses. Wildcards are intersected.
  18191. * Attribute use prohibitions are removed from the list
  18192. * and returned via the @prohibs list.
  18193. * Pointlessness of attr. prohibs, if a matching attr. decl
  18194. * is existent a well, are checked.
  18195. */
  18196. static int
  18197. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  18198. xmlSchemaBasicItemPtr item,
  18199. xmlSchemaWildcardPtr *completeWild,
  18200. xmlSchemaItemListPtr list,
  18201. xmlSchemaItemListPtr prohibs)
  18202. {
  18203. xmlSchemaAttributeGroupPtr gr;
  18204. xmlSchemaAttributeUsePtr use;
  18205. xmlSchemaItemListPtr sublist;
  18206. int i, j;
  18207. int created = (*completeWild == NULL) ? 0 : 1;
  18208. if (prohibs)
  18209. prohibs->nbItems = 0;
  18210. for (i = 0; i < list->nbItems; i++) {
  18211. use = list->items[i];
  18212. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  18213. if (prohibs == NULL) {
  18214. PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
  18215. "unexpected attr prohibition found");
  18216. return(-1);
  18217. }
  18218. /*
  18219. * Remove from attribute uses.
  18220. */
  18221. if (xmlSchemaItemListRemove(list, i) == -1)
  18222. return(-1);
  18223. i--;
  18224. /*
  18225. * Note that duplicate prohibitions were already
  18226. * handled at parsing time.
  18227. */
  18228. /*
  18229. * Add to list of prohibitions.
  18230. */
  18231. xmlSchemaItemListAddSize(prohibs, 2, use);
  18232. continue;
  18233. }
  18234. if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  18235. ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
  18236. {
  18237. if ((WXS_QNAME_CAST use)->item == NULL)
  18238. return(-1);
  18239. gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
  18240. /*
  18241. * Expand the referenced attr. group.
  18242. * TODO: remove this, this is done in a previous step, so
  18243. * already done here.
  18244. */
  18245. if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
  18246. if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
  18247. return(-1);
  18248. }
  18249. /*
  18250. * Build the 'complete' wildcard; i.e. intersect multiple
  18251. * wildcards.
  18252. */
  18253. if (gr->attributeWildcard != NULL) {
  18254. if (*completeWild == NULL) {
  18255. *completeWild = gr->attributeWildcard;
  18256. } else {
  18257. if (! created) {
  18258. xmlSchemaWildcardPtr tmpWild;
  18259. /*
  18260. * Copy the first encountered wildcard as context,
  18261. * except for the annotation.
  18262. *
  18263. * Although the complete wildcard might not correspond
  18264. * to any node in the schema, we will anchor it on
  18265. * the node of the owner component.
  18266. */
  18267. tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
  18268. XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  18269. WXS_ITEM_NODE(item));
  18270. if (tmpWild == NULL)
  18271. return(-1);
  18272. if (xmlSchemaCloneWildcardNsConstraints(pctxt,
  18273. tmpWild, *completeWild) == -1)
  18274. return (-1);
  18275. tmpWild->processContents = (*completeWild)->processContents;
  18276. *completeWild = tmpWild;
  18277. created = 1;
  18278. }
  18279. if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
  18280. gr->attributeWildcard) == -1)
  18281. return(-1);
  18282. }
  18283. }
  18284. /*
  18285. * Just remove the reference if the referenced group does not
  18286. * contain any attribute uses.
  18287. */
  18288. sublist = ((xmlSchemaItemListPtr) gr->attrUses);
  18289. if ((sublist == NULL) || sublist->nbItems == 0) {
  18290. if (xmlSchemaItemListRemove(list, i) == -1)
  18291. return(-1);
  18292. i--;
  18293. continue;
  18294. }
  18295. /*
  18296. * Add the attribute uses.
  18297. */
  18298. list->items[i] = sublist->items[0];
  18299. if (sublist->nbItems != 1) {
  18300. for (j = 1; j < sublist->nbItems; j++) {
  18301. i++;
  18302. if (xmlSchemaItemListInsert(list,
  18303. sublist->items[j], i) == -1)
  18304. return(-1);
  18305. }
  18306. }
  18307. }
  18308. }
  18309. /*
  18310. * Handle pointless prohibitions of declared attributes.
  18311. */
  18312. if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
  18313. xmlSchemaAttributeUseProhibPtr prohib;
  18314. for (i = prohibs->nbItems -1; i >= 0; i--) {
  18315. prohib = prohibs->items[i];
  18316. for (j = 0; j < list->nbItems; j++) {
  18317. use = list->items[j];
  18318. if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
  18319. (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
  18320. {
  18321. xmlChar *str = NULL;
  18322. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  18323. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  18324. prohib->node, NULL,
  18325. "Skipping pointless attribute use prohibition "
  18326. "'%s', since a corresponding attribute use "
  18327. "exists already in the type definition",
  18328. xmlSchemaFormatQName(&str,
  18329. prohib->targetNamespace, prohib->name),
  18330. NULL, NULL);
  18331. FREE_AND_NULL(str);
  18332. /*
  18333. * Remove the prohibition.
  18334. */
  18335. if (xmlSchemaItemListRemove(prohibs, i) == -1)
  18336. return(-1);
  18337. break;
  18338. }
  18339. }
  18340. }
  18341. }
  18342. return(0);
  18343. }
  18344. /**
  18345. * xmlSchemaAttributeGroupExpandRefs:
  18346. * @pctxt: the parser context
  18347. * @attrGr: the attribute group definition
  18348. *
  18349. * Computation of:
  18350. * {attribute uses} property
  18351. * {attribute wildcard} property
  18352. *
  18353. * Substitutes contained attribute group references
  18354. * for their attribute uses. Wildcards are intersected.
  18355. */
  18356. static int
  18357. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18358. xmlSchemaAttributeGroupPtr attrGr)
  18359. {
  18360. if ((attrGr->attrUses == NULL) ||
  18361. (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
  18362. return(0);
  18363. attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
  18364. if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
  18365. &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
  18366. return(-1);
  18367. return(0);
  18368. }
  18369. /**
  18370. * xmlSchemaAttributeGroupExpandRefs:
  18371. * @pctxt: the parser context
  18372. * @attrGr: the attribute group definition
  18373. *
  18374. * Substitutes contained attribute group references
  18375. * for their attribute uses. Wildcards are intersected.
  18376. *
  18377. * Schema Component Constraint:
  18378. * Attribute Group Definition Properties Correct (ag-props-correct)
  18379. */
  18380. static int
  18381. xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18382. xmlSchemaAttributeGroupPtr attrGr)
  18383. {
  18384. /*
  18385. * SPEC ag-props-correct
  18386. * (1) "The values of the properties of an attribute group definition
  18387. * must be as described in the property tableau in The Attribute
  18388. * Group Definition Schema Component ($3.6.1), modulo the impact of
  18389. * Missing Sub-components ($5.3);"
  18390. */
  18391. if ((attrGr->attrUses != NULL) &&
  18392. (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
  18393. {
  18394. xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
  18395. xmlSchemaAttributeUsePtr use, tmp;
  18396. int i, j, hasId = 0;
  18397. for (i = uses->nbItems -1; i >= 0; i--) {
  18398. use = uses->items[i];
  18399. /*
  18400. * SPEC ag-props-correct
  18401. * (2) "Two distinct members of the {attribute uses} must not have
  18402. * {attribute declaration}s both of whose {name}s match and whose
  18403. * {target namespace}s are identical."
  18404. */
  18405. if (i > 0) {
  18406. for (j = i -1; j >= 0; j--) {
  18407. tmp = uses->items[j];
  18408. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  18409. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  18410. (WXS_ATTRUSE_DECL_TNS(use) ==
  18411. WXS_ATTRUSE_DECL_TNS(tmp)))
  18412. {
  18413. xmlChar *str = NULL;
  18414. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18415. XML_SCHEMAP_AG_PROPS_CORRECT,
  18416. attrGr->node, WXS_BASIC_CAST attrGr,
  18417. "Duplicate %s",
  18418. xmlSchemaGetComponentDesignation(&str, use),
  18419. NULL);
  18420. FREE_AND_NULL(str);
  18421. /*
  18422. * Remove the duplicate.
  18423. */
  18424. if (xmlSchemaItemListRemove(uses, i) == -1)
  18425. return(-1);
  18426. goto next_use;
  18427. }
  18428. }
  18429. }
  18430. /*
  18431. * SPEC ag-props-correct
  18432. * (3) "Two distinct members of the {attribute uses} must not have
  18433. * {attribute declaration}s both of whose {type definition}s are or
  18434. * are derived from ID."
  18435. * TODO: Does 'derived' include member-types of unions?
  18436. */
  18437. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  18438. if (xmlSchemaIsDerivedFromBuiltInType(
  18439. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  18440. {
  18441. if (hasId) {
  18442. xmlChar *str = NULL;
  18443. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18444. XML_SCHEMAP_AG_PROPS_CORRECT,
  18445. attrGr->node, WXS_BASIC_CAST attrGr,
  18446. "There must not exist more than one attribute "
  18447. "declaration of type 'xs:ID' "
  18448. "(or derived from 'xs:ID'). The %s violates this "
  18449. "constraint",
  18450. xmlSchemaGetComponentDesignation(&str, use),
  18451. NULL);
  18452. FREE_AND_NULL(str);
  18453. if (xmlSchemaItemListRemove(uses, i) == -1)
  18454. return(-1);
  18455. }
  18456. hasId = 1;
  18457. }
  18458. }
  18459. next_use: {}
  18460. }
  18461. }
  18462. return(0);
  18463. }
  18464. /**
  18465. * xmlSchemaResolveAttrGroupReferences:
  18466. * @attrgrpDecl: the schema attribute definition
  18467. * @ctxt: the schema parser context
  18468. * @name: the attribute name
  18469. *
  18470. * Resolves references to attribute group definitions.
  18471. */
  18472. static int
  18473. xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
  18474. xmlSchemaParserCtxtPtr ctxt)
  18475. {
  18476. xmlSchemaAttributeGroupPtr group;
  18477. if (ref->item != NULL)
  18478. return(0);
  18479. group = xmlSchemaGetAttributeGroup(ctxt->schema,
  18480. ref->name,
  18481. ref->targetNamespace);
  18482. if (group == NULL) {
  18483. xmlSchemaPResCompAttrErr(ctxt,
  18484. XML_SCHEMAP_SRC_RESOLVE,
  18485. NULL, ref->node,
  18486. "ref", ref->name, ref->targetNamespace,
  18487. ref->itemType, NULL);
  18488. return(ctxt->err);
  18489. }
  18490. ref->item = WXS_BASIC_CAST group;
  18491. return(0);
  18492. }
  18493. /**
  18494. * xmlSchemaCheckAttrPropsCorrect:
  18495. * @item: an schema attribute declaration/use
  18496. * @ctxt: a schema parser context
  18497. * @name: the name of the attribute
  18498. *
  18499. *
  18500. * Schema Component Constraint:
  18501. * Attribute Declaration Properties Correct (a-props-correct)
  18502. *
  18503. * Validates the value constraints of an attribute declaration/use.
  18504. * NOTE that this needs the simple type definitions to be already
  18505. * built and checked.
  18506. */
  18507. static int
  18508. xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18509. xmlSchemaAttributePtr attr)
  18510. {
  18511. /*
  18512. * SPEC a-props-correct (1)
  18513. * "The values of the properties of an attribute declaration must
  18514. * be as described in the property tableau in The Attribute
  18515. * Declaration Schema Component ($3.2.1), modulo the impact of
  18516. * Missing Sub-components ($5.3)."
  18517. */
  18518. if (WXS_ATTR_TYPEDEF(attr) == NULL)
  18519. return(0);
  18520. if (attr->defValue != NULL) {
  18521. int ret;
  18522. /*
  18523. * SPEC a-props-correct (3)
  18524. * "If the {type definition} is or is derived from ID then there
  18525. * must not be a {value constraint}."
  18526. */
  18527. if (xmlSchemaIsDerivedFromBuiltInType(
  18528. WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
  18529. {
  18530. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18531. XML_SCHEMAP_A_PROPS_CORRECT_3,
  18532. NULL, WXS_BASIC_CAST attr,
  18533. "Value constraints are not allowed if the type definition "
  18534. "is or is derived from xs:ID",
  18535. NULL, NULL);
  18536. return(pctxt->err);
  18537. }
  18538. /*
  18539. * SPEC a-props-correct (2)
  18540. * "if there is a {value constraint}, the canonical lexical
  18541. * representation of its value must be `valid` with respect
  18542. * to the {type definition} as defined in String Valid ($3.14.4)."
  18543. * TODO: Don't care about the *canonical* stuff here, this requirement
  18544. * will be removed in WXS 1.1 anyway.
  18545. */
  18546. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
  18547. attr->node, WXS_ATTR_TYPEDEF(attr),
  18548. attr->defValue, &(attr->defVal),
  18549. 1, 1, 0);
  18550. if (ret != 0) {
  18551. if (ret < 0) {
  18552. PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
  18553. "calling xmlSchemaVCheckCVCSimpleType()");
  18554. return(-1);
  18555. }
  18556. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18557. XML_SCHEMAP_A_PROPS_CORRECT_2,
  18558. NULL, WXS_BASIC_CAST attr,
  18559. "The value of the value constraint is not valid",
  18560. NULL, NULL);
  18561. return(pctxt->err);
  18562. }
  18563. }
  18564. return(0);
  18565. }
  18566. static xmlSchemaElementPtr
  18567. xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
  18568. xmlSchemaElementPtr ancestor)
  18569. {
  18570. xmlSchemaElementPtr ret;
  18571. if (WXS_SUBST_HEAD(ancestor) == NULL)
  18572. return (NULL);
  18573. if (WXS_SUBST_HEAD(ancestor) == elemDecl)
  18574. return (ancestor);
  18575. if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
  18576. return (NULL);
  18577. WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
  18578. ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
  18579. WXS_SUBST_HEAD(ancestor));
  18580. WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
  18581. return (ret);
  18582. }
  18583. /**
  18584. * xmlSchemaCheckElemPropsCorrect:
  18585. * @ctxt: a schema parser context
  18586. * @decl: the element declaration
  18587. * @name: the name of the attribute
  18588. *
  18589. * Schema Component Constraint:
  18590. * Element Declaration Properties Correct (e-props-correct)
  18591. *
  18592. * STATUS:
  18593. * missing: (6)
  18594. */
  18595. static int
  18596. xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18597. xmlSchemaElementPtr elemDecl)
  18598. {
  18599. int ret = 0;
  18600. xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
  18601. /*
  18602. * SPEC (1) "The values of the properties of an element declaration
  18603. * must be as described in the property tableau in The Element
  18604. * Declaration Schema Component ($3.3.1), modulo the impact of Missing
  18605. * Sub-components ($5.3)."
  18606. */
  18607. if (WXS_SUBST_HEAD(elemDecl) != NULL) {
  18608. xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
  18609. xmlSchemaCheckElementDeclComponent(head, pctxt);
  18610. /*
  18611. * SPEC (3) "If there is a non-`absent` {substitution group
  18612. * affiliation}, then {scope} must be global."
  18613. */
  18614. if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
  18615. xmlSchemaPCustomErr(pctxt,
  18616. XML_SCHEMAP_E_PROPS_CORRECT_3,
  18617. WXS_BASIC_CAST elemDecl, NULL,
  18618. "Only global element declarations can have a "
  18619. "substitution group affiliation", NULL);
  18620. ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
  18621. }
  18622. /*
  18623. * TODO: SPEC (6) "Circular substitution groups are disallowed.
  18624. * That is, it must not be possible to return to an element declaration
  18625. * by repeatedly following the {substitution group affiliation}
  18626. * property."
  18627. */
  18628. if (head == elemDecl)
  18629. circ = head;
  18630. else if (WXS_SUBST_HEAD(head) != NULL)
  18631. circ = xmlSchemaCheckSubstGroupCircular(head, head);
  18632. else
  18633. circ = NULL;
  18634. if (circ != NULL) {
  18635. xmlChar *strA = NULL, *strB = NULL;
  18636. xmlSchemaPCustomErrExt(pctxt,
  18637. XML_SCHEMAP_E_PROPS_CORRECT_6,
  18638. WXS_BASIC_CAST circ, NULL,
  18639. "The element declaration '%s' defines a circular "
  18640. "substitution group to element declaration '%s'",
  18641. xmlSchemaGetComponentQName(&strA, circ),
  18642. xmlSchemaGetComponentQName(&strB, head),
  18643. NULL);
  18644. FREE_AND_NULL(strA)
  18645. FREE_AND_NULL(strB)
  18646. ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
  18647. }
  18648. /*
  18649. * SPEC (4) "If there is a {substitution group affiliation},
  18650. * the {type definition}
  18651. * of the element declaration must be validly derived from the {type
  18652. * definition} of the {substitution group affiliation}, given the value
  18653. * of the {substitution group exclusions} of the {substitution group
  18654. * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
  18655. * (if the {type definition} is complex) or as defined in
  18656. * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
  18657. * simple)."
  18658. *
  18659. * NOTE: {substitution group exclusions} means the values of the
  18660. * attribute "final".
  18661. */
  18662. if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
  18663. int set = 0;
  18664. if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
  18665. set |= SUBSET_EXTENSION;
  18666. if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
  18667. set |= SUBSET_RESTRICTION;
  18668. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
  18669. WXS_ELEM_TYPEDEF(head), set) != 0) {
  18670. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  18671. ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
  18672. xmlSchemaPCustomErrExt(pctxt,
  18673. XML_SCHEMAP_E_PROPS_CORRECT_4,
  18674. WXS_BASIC_CAST elemDecl, NULL,
  18675. "The type definition '%s' was "
  18676. "either rejected by the substitution group "
  18677. "affiliation '%s', or not validly derived from its type "
  18678. "definition '%s'",
  18679. xmlSchemaGetComponentQName(&strA, typeDef),
  18680. xmlSchemaGetComponentQName(&strB, head),
  18681. xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
  18682. FREE_AND_NULL(strA)
  18683. FREE_AND_NULL(strB)
  18684. FREE_AND_NULL(strC)
  18685. }
  18686. }
  18687. }
  18688. /*
  18689. * SPEC (5) "If the {type definition} or {type definition}'s
  18690. * {content type}
  18691. * is or is derived from ID then there must not be a {value constraint}.
  18692. * Note: The use of ID as a type definition for elements goes beyond
  18693. * XML 1.0, and should be avoided if backwards compatibility is desired"
  18694. */
  18695. if ((elemDecl->value != NULL) &&
  18696. ((WXS_IS_SIMPLE(typeDef) &&
  18697. xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
  18698. (WXS_IS_COMPLEX(typeDef) &&
  18699. WXS_HAS_SIMPLE_CONTENT(typeDef) &&
  18700. xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
  18701. XML_SCHEMAS_ID)))) {
  18702. ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
  18703. xmlSchemaPCustomErr(pctxt,
  18704. XML_SCHEMAP_E_PROPS_CORRECT_5,
  18705. WXS_BASIC_CAST elemDecl, NULL,
  18706. "The type definition (or type definition's content type) is or "
  18707. "is derived from ID; value constraints are not allowed in "
  18708. "conjunction with such a type definition", NULL);
  18709. } else if (elemDecl->value != NULL) {
  18710. int vcret;
  18711. xmlNodePtr node = NULL;
  18712. /*
  18713. * SPEC (2) "If there is a {value constraint}, the canonical lexical
  18714. * representation of its value must be `valid` with respect to the
  18715. * {type definition} as defined in Element Default Valid (Immediate)
  18716. * ($3.3.6)."
  18717. */
  18718. if (typeDef == NULL) {
  18719. xmlSchemaPErr(pctxt, elemDecl->node,
  18720. XML_SCHEMAP_INTERNAL,
  18721. "Internal error: xmlSchemaCheckElemPropsCorrect, "
  18722. "type is missing... skipping validation of "
  18723. "the value constraint", NULL, NULL);
  18724. return (-1);
  18725. }
  18726. if (elemDecl->node != NULL) {
  18727. if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
  18728. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18729. BAD_CAST "fixed");
  18730. else
  18731. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18732. BAD_CAST "default");
  18733. }
  18734. vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
  18735. typeDef, elemDecl->value, &(elemDecl->defVal));
  18736. if (vcret != 0) {
  18737. if (vcret < 0) {
  18738. PERROR_INT("xmlSchemaElemCheckValConstr",
  18739. "failed to validate the value constraint of an "
  18740. "element declaration");
  18741. return (-1);
  18742. }
  18743. return (vcret);
  18744. }
  18745. }
  18746. return (ret);
  18747. }
  18748. /**
  18749. * xmlSchemaCheckElemSubstGroup:
  18750. * @ctxt: a schema parser context
  18751. * @decl: the element declaration
  18752. * @name: the name of the attribute
  18753. *
  18754. * Schema Component Constraint:
  18755. * Substitution Group (cos-equiv-class)
  18756. *
  18757. * In Libxml2 the subst. groups will be precomputed, in terms of that
  18758. * a list will be built for each subst. group head, holding all direct
  18759. * referents to this head.
  18760. * NOTE that this function needs:
  18761. * 1. circular subst. groups to be checked beforehand
  18762. * 2. the declaration's type to be derived from the head's type
  18763. *
  18764. * STATUS:
  18765. *
  18766. */
  18767. static void
  18768. xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
  18769. xmlSchemaElementPtr elemDecl)
  18770. {
  18771. if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
  18772. /* SPEC (1) "Its {abstract} is false." */
  18773. (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
  18774. return;
  18775. {
  18776. xmlSchemaElementPtr head;
  18777. xmlSchemaTypePtr headType, type;
  18778. int set, methSet;
  18779. /*
  18780. * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
  18781. * {disallowed substitutions} as the blocking constraint, as defined in
  18782. * Substitution Group OK (Transitive) ($3.3.6)."
  18783. */
  18784. for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
  18785. head = WXS_SUBST_HEAD(head)) {
  18786. set = 0;
  18787. methSet = 0;
  18788. /*
  18789. * The blocking constraints.
  18790. */
  18791. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
  18792. continue;
  18793. headType = head->subtypes;
  18794. type = elemDecl->subtypes;
  18795. if (headType == type)
  18796. goto add_member;
  18797. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
  18798. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18799. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
  18800. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18801. /*
  18802. * SPEC: Substitution Group OK (Transitive) (2.3)
  18803. * "The set of all {derivation method}s involved in the
  18804. * derivation of D's {type definition} from C's {type definition}
  18805. * does not intersect with the union of the blocking constraint,
  18806. * C's {prohibited substitutions} (if C is complex, otherwise the
  18807. * empty set) and the {prohibited substitutions} (respectively the
  18808. * empty set) of any intermediate {type definition}s in the
  18809. * derivation of D's {type definition} from C's {type definition}."
  18810. */
  18811. /*
  18812. * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
  18813. * subst.head axis, the methSet does not need to be computed for
  18814. * the full depth over and over.
  18815. */
  18816. /*
  18817. * The set of all {derivation method}s involved in the derivation
  18818. */
  18819. while ((type != NULL) && (type != headType)) {
  18820. if ((WXS_IS_EXTENSION(type)) &&
  18821. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18822. methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18823. if (WXS_IS_RESTRICTION(type) &&
  18824. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18825. methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18826. type = type->baseType;
  18827. }
  18828. /*
  18829. * The {prohibited substitutions} of all intermediate types +
  18830. * the head's type.
  18831. */
  18832. type = elemDecl->subtypes->baseType;
  18833. while (type != NULL) {
  18834. if (WXS_IS_COMPLEX(type)) {
  18835. if ((type->flags &
  18836. XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18837. ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
  18838. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18839. if ((type->flags &
  18840. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18841. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18842. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18843. } else
  18844. break;
  18845. if (type == headType)
  18846. break;
  18847. type = type->baseType;
  18848. }
  18849. if ((set != 0) &&
  18850. (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18851. (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
  18852. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18853. (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
  18854. continue;
  18855. }
  18856. add_member:
  18857. xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
  18858. if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
  18859. head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
  18860. }
  18861. }
  18862. }
  18863. #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
  18864. /**
  18865. * xmlSchemaCheckElementDeclComponent
  18866. * @pctxt: the schema parser context
  18867. * @ctxtComponent: the context component (an element declaration)
  18868. * @ctxtParticle: the first particle of the context component
  18869. * @searchParticle: the element declaration particle to be analysed
  18870. *
  18871. * Schema Component Constraint: Element Declarations Consistent
  18872. */
  18873. static int
  18874. xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
  18875. xmlSchemaBasicItemPtr ctxtComponent,
  18876. xmlSchemaParticlePtr ctxtParticle,
  18877. xmlSchemaParticlePtr searchParticle,
  18878. xmlSchemaParticlePtr curParticle,
  18879. int search)
  18880. {
  18881. return(0);
  18882. int ret = 0;
  18883. xmlSchemaParticlePtr cur = curParticle;
  18884. if (curParticle == NULL) {
  18885. return(0);
  18886. }
  18887. if (WXS_PARTICLE_TERM(curParticle) == NULL) {
  18888. /*
  18889. * Just return in this case. A missing "term" of the particle
  18890. * might arise due to an invalid "term" component.
  18891. */
  18892. return(0);
  18893. }
  18894. while (cur != NULL) {
  18895. switch (WXS_PARTICLE_TERM(cur)->type) {
  18896. case XML_SCHEMA_TYPE_ANY:
  18897. break;
  18898. case XML_SCHEMA_TYPE_ELEMENT:
  18899. if (search == 0) {
  18900. ret = xmlSchemaCheckElementDeclConsistent(pctxt,
  18901. ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
  18902. if (ret != 0)
  18903. return(ret);
  18904. } else {
  18905. xmlSchemaElementPtr elem =
  18906. WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
  18907. /*
  18908. * SPEC Element Declarations Consistent:
  18909. * "If the {particles} contains, either directly,
  18910. * indirectly (that is, within the {particles} of a
  18911. * contained model group, recursively) or `implicitly`
  18912. * two or more element declaration particles with
  18913. * the same {name} and {target namespace}, then
  18914. * all their type definitions must be the same
  18915. * top-level definition [...]"
  18916. */
  18917. if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
  18918. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
  18919. xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18920. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
  18921. {
  18922. xmlChar *strA = NULL, *strB = NULL;
  18923. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18924. /* TODO: error code */
  18925. XML_SCHEMAP_COS_NONAMBIG,
  18926. WXS_ITEM_NODE(cur), NULL,
  18927. "In the content model of %s, there are multiple "
  18928. "element declarations for '%s' with different "
  18929. "type definitions",
  18930. xmlSchemaGetComponentDesignation(&strA,
  18931. ctxtComponent),
  18932. xmlSchemaFormatQName(&strB,
  18933. WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18934. WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
  18935. FREE_AND_NULL(strA);
  18936. FREE_AND_NULL(strB);
  18937. return(XML_SCHEMAP_COS_NONAMBIG);
  18938. }
  18939. }
  18940. break;
  18941. case XML_SCHEMA_TYPE_SEQUENCE: {
  18942. break;
  18943. }
  18944. case XML_SCHEMA_TYPE_CHOICE:{
  18945. /*
  18946. xmlSchemaTreeItemPtr sub;
  18947. sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
  18948. while (sub != NULL) {
  18949. ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
  18950. ctxtParticle, ctxtElem);
  18951. if (ret != 0)
  18952. return(ret);
  18953. sub = sub->next;
  18954. }
  18955. */
  18956. break;
  18957. }
  18958. case XML_SCHEMA_TYPE_ALL:
  18959. break;
  18960. case XML_SCHEMA_TYPE_GROUP:
  18961. break;
  18962. default:
  18963. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  18964. "xmlSchemaCheckElementDeclConsistent",
  18965. "found unexpected term of type '%s' in content model",
  18966. WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
  18967. return(-1);
  18968. }
  18969. cur = (xmlSchemaParticlePtr) cur->next;
  18970. }
  18971. exit:
  18972. return(ret);
  18973. }
  18974. #endif
  18975. /**
  18976. * xmlSchemaCheckElementDeclComponent
  18977. * @item: an schema element declaration/particle
  18978. * @ctxt: a schema parser context
  18979. * @name: the name of the attribute
  18980. *
  18981. * Validates the value constraints of an element declaration.
  18982. * Adds substitution group members.
  18983. */
  18984. static void
  18985. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  18986. xmlSchemaParserCtxtPtr ctxt)
  18987. {
  18988. if (elemDecl == NULL)
  18989. return;
  18990. if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
  18991. return;
  18992. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
  18993. if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
  18994. /*
  18995. * Adds substitution group members.
  18996. */
  18997. xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
  18998. }
  18999. }
  19000. /**
  19001. * xmlSchemaResolveModelGroupParticleReferences:
  19002. * @particle: a particle component
  19003. * @ctxt: a parser context
  19004. *
  19005. * Resolves references of a model group's {particles} to
  19006. * model group definitions and to element declarations.
  19007. */
  19008. static void
  19009. xmlSchemaResolveModelGroupParticleReferences(
  19010. xmlSchemaParserCtxtPtr ctxt,
  19011. xmlSchemaModelGroupPtr mg)
  19012. {
  19013. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  19014. xmlSchemaQNameRefPtr ref;
  19015. xmlSchemaBasicItemPtr refItem;
  19016. /*
  19017. * URGENT TODO: Test this.
  19018. */
  19019. while (particle != NULL) {
  19020. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  19021. ((WXS_PARTICLE_TERM(particle))->type !=
  19022. XML_SCHEMA_EXTRA_QNAMEREF))
  19023. {
  19024. goto next_particle;
  19025. }
  19026. ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
  19027. /*
  19028. * Resolve the reference.
  19029. * NULL the {term} by default.
  19030. */
  19031. particle->children = NULL;
  19032. refItem = xmlSchemaGetNamedComponent(ctxt->schema,
  19033. ref->itemType, ref->name, ref->targetNamespace);
  19034. if (refItem == NULL) {
  19035. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  19036. NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
  19037. ref->targetNamespace, ref->itemType, NULL);
  19038. /* TODO: remove the particle. */
  19039. goto next_particle;
  19040. }
  19041. if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
  19042. if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
  19043. /* TODO: remove the particle. */
  19044. goto next_particle;
  19045. /*
  19046. * NOTE that we will assign the model group definition
  19047. * itself to the "term" of the particle. This will ease
  19048. * the check for circular model group definitions. After
  19049. * that the "term" will be assigned the model group of the
  19050. * model group definition.
  19051. */
  19052. if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
  19053. XML_SCHEMA_TYPE_ALL) {
  19054. /*
  19055. * SPEC cos-all-limited (1)
  19056. * SPEC cos-all-limited (1.2)
  19057. * "It appears only as the value of one or both of the
  19058. * following properties:"
  19059. * (1.1) "the {model group} property of a model group
  19060. * definition."
  19061. * (1.2) "the {term} property of a particle [... of] the "
  19062. * {content type} of a complex type definition."
  19063. */
  19064. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19065. /* TODO: error code */
  19066. XML_SCHEMAP_COS_ALL_LIMITED,
  19067. WXS_ITEM_NODE(particle), NULL,
  19068. "A model group definition is referenced, but "
  19069. "it contains an 'all' model group, which "
  19070. "cannot be contained by model groups",
  19071. NULL, NULL);
  19072. /* TODO: remove the particle. */
  19073. goto next_particle;
  19074. }
  19075. particle->children = (xmlSchemaTreeItemPtr) refItem;
  19076. } else {
  19077. /*
  19078. * TODO: Are referenced element declarations the only
  19079. * other components we expect here?
  19080. */
  19081. particle->children = (xmlSchemaTreeItemPtr) refItem;
  19082. }
  19083. next_particle:
  19084. particle = WXS_PTC_CAST particle->next;
  19085. }
  19086. }
  19087. static int
  19088. xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
  19089. xmlSchemaValPtr y)
  19090. {
  19091. xmlSchemaTypePtr tx, ty, ptx, pty;
  19092. int ret;
  19093. while (x != NULL) {
  19094. /* Same types. */
  19095. tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
  19096. ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
  19097. ptx = xmlSchemaGetPrimitiveType(tx);
  19098. pty = xmlSchemaGetPrimitiveType(ty);
  19099. /*
  19100. * (1) if a datatype T' is `derived` by `restriction` from an
  19101. * atomic datatype T then the `value space` of T' is a subset of
  19102. * the `value space` of T. */
  19103. /*
  19104. * (2) if datatypes T' and T'' are `derived` by `restriction`
  19105. * from a common atomic ancestor T then the `value space`s of T'
  19106. * and T'' may overlap.
  19107. */
  19108. if (ptx != pty)
  19109. return(0);
  19110. /*
  19111. * We assume computed values to be normalized, so do a fast
  19112. * string comparison for string based types.
  19113. */
  19114. if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
  19115. WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
  19116. if (! xmlStrEqual(
  19117. xmlSchemaValueGetAsString(x),
  19118. xmlSchemaValueGetAsString(y)))
  19119. return (0);
  19120. } else {
  19121. ret = xmlSchemaCompareValuesWhtsp(
  19122. x, XML_SCHEMA_WHITESPACE_PRESERVE,
  19123. y, XML_SCHEMA_WHITESPACE_PRESERVE);
  19124. if (ret == -2)
  19125. return(-1);
  19126. if (ret != 0)
  19127. return(0);
  19128. }
  19129. /*
  19130. * Lists.
  19131. */
  19132. x = xmlSchemaValueGetNext(x);
  19133. if (x != NULL) {
  19134. y = xmlSchemaValueGetNext(y);
  19135. if (y == NULL)
  19136. return (0);
  19137. } else if (xmlSchemaValueGetNext(y) != NULL)
  19138. return (0);
  19139. else
  19140. return (1);
  19141. }
  19142. return (0);
  19143. }
  19144. /**
  19145. * xmlSchemaResolveAttrUseReferences:
  19146. * @item: an attribute use
  19147. * @ctxt: a parser context
  19148. *
  19149. * Resolves the referenced attribute declaration.
  19150. */
  19151. static int
  19152. xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
  19153. xmlSchemaParserCtxtPtr ctxt)
  19154. {
  19155. if ((ctxt == NULL) || (ause == NULL))
  19156. return(-1);
  19157. if ((ause->attrDecl == NULL) ||
  19158. (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
  19159. return(0);
  19160. {
  19161. xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
  19162. /*
  19163. * TODO: Evaluate, what errors could occur if the declaration is not
  19164. * found.
  19165. */
  19166. ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
  19167. ref->name, ref->targetNamespace);
  19168. if (ause->attrDecl == NULL) {
  19169. xmlSchemaPResCompAttrErr(ctxt,
  19170. XML_SCHEMAP_SRC_RESOLVE,
  19171. WXS_BASIC_CAST ause, ause->node,
  19172. "ref", ref->name, ref->targetNamespace,
  19173. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  19174. return(ctxt->err);;
  19175. }
  19176. }
  19177. return(0);
  19178. }
  19179. /**
  19180. * xmlSchemaCheckAttrUsePropsCorrect:
  19181. * @ctxt: a parser context
  19182. * @use: an attribute use
  19183. *
  19184. * Schema Component Constraint:
  19185. * Attribute Use Correct (au-props-correct)
  19186. *
  19187. */
  19188. static int
  19189. xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  19190. xmlSchemaAttributeUsePtr use)
  19191. {
  19192. if ((ctxt == NULL) || (use == NULL))
  19193. return(-1);
  19194. if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
  19195. ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
  19196. return(0);
  19197. /*
  19198. * SPEC au-props-correct (1)
  19199. * "The values of the properties of an attribute use must be as
  19200. * described in the property tableau in The Attribute Use Schema
  19201. * Component ($3.5.1), modulo the impact of Missing
  19202. * Sub-components ($5.3)."
  19203. */
  19204. if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
  19205. ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
  19206. ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19207. {
  19208. xmlSchemaPCustomErr(ctxt,
  19209. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19210. WXS_BASIC_CAST use, NULL,
  19211. "The attribute declaration has a 'fixed' value constraint "
  19212. ", thus the attribute use must also have a 'fixed' value "
  19213. "constraint",
  19214. NULL);
  19215. return(ctxt->err);
  19216. }
  19217. /*
  19218. * Compute and check the value constraint's value.
  19219. */
  19220. if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
  19221. int ret;
  19222. /*
  19223. * TODO: The spec seems to be missing a check of the
  19224. * value constraint of the attribute use. We will do it here.
  19225. */
  19226. /*
  19227. * SPEC a-props-correct (3)
  19228. */
  19229. if (xmlSchemaIsDerivedFromBuiltInType(
  19230. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  19231. {
  19232. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19233. XML_SCHEMAP_AU_PROPS_CORRECT,
  19234. NULL, WXS_BASIC_CAST use,
  19235. "Value constraints are not allowed if the type definition "
  19236. "is or is derived from xs:ID",
  19237. NULL, NULL);
  19238. return(ctxt->err);
  19239. }
  19240. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
  19241. use->node, WXS_ATTRUSE_TYPEDEF(use),
  19242. use->defValue, &(use->defVal),
  19243. 1, 1, 0);
  19244. if (ret != 0) {
  19245. if (ret < 0) {
  19246. PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
  19247. "calling xmlSchemaVCheckCVCSimpleType()");
  19248. return(-1);
  19249. }
  19250. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19251. XML_SCHEMAP_AU_PROPS_CORRECT,
  19252. NULL, WXS_BASIC_CAST use,
  19253. "The value of the value constraint is not valid",
  19254. NULL, NULL);
  19255. return(ctxt->err);
  19256. }
  19257. }
  19258. /*
  19259. * SPEC au-props-correct (2)
  19260. * "If the {attribute declaration} has a fixed
  19261. * {value constraint}, then if the attribute use itself has a
  19262. * {value constraint}, it must also be fixed and its value must match
  19263. * that of the {attribute declaration}'s {value constraint}."
  19264. */
  19265. if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
  19266. (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19267. {
  19268. if (! xmlSchemaAreValuesEqual(use->defVal,
  19269. (WXS_ATTRUSE_DECL(use))->defVal))
  19270. {
  19271. xmlSchemaPCustomErr(ctxt,
  19272. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19273. WXS_BASIC_CAST use, NULL,
  19274. "The 'fixed' value constraint of the attribute use "
  19275. "must match the attribute declaration's value "
  19276. "constraint '%s'",
  19277. (WXS_ATTRUSE_DECL(use))->defValue);
  19278. }
  19279. return(ctxt->err);
  19280. }
  19281. return(0);
  19282. }
  19283. /**
  19284. * xmlSchemaResolveAttrTypeReferences:
  19285. * @item: an attribute declaration
  19286. * @ctxt: a parser context
  19287. *
  19288. * Resolves the referenced type definition component.
  19289. */
  19290. static int
  19291. xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
  19292. xmlSchemaParserCtxtPtr ctxt)
  19293. {
  19294. /*
  19295. * The simple type definition corresponding to the <simpleType> element
  19296. * information item in the [children], if present, otherwise the simple
  19297. * type definition `resolved` to by the `actual value` of the type
  19298. * [attribute], if present, otherwise the `simple ur-type definition`.
  19299. */
  19300. if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
  19301. return(0);
  19302. item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
  19303. if (item->subtypes != NULL)
  19304. return(0);
  19305. if (item->typeName != NULL) {
  19306. xmlSchemaTypePtr type;
  19307. type = xmlSchemaGetType(ctxt->schema, item->typeName,
  19308. item->typeNs);
  19309. if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
  19310. xmlSchemaPResCompAttrErr(ctxt,
  19311. XML_SCHEMAP_SRC_RESOLVE,
  19312. WXS_BASIC_CAST item, item->node,
  19313. "type", item->typeName, item->typeNs,
  19314. XML_SCHEMA_TYPE_SIMPLE, NULL);
  19315. return(ctxt->err);
  19316. } else
  19317. item->subtypes = type;
  19318. } else {
  19319. /*
  19320. * The type defaults to the xs:anySimpleType.
  19321. */
  19322. item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  19323. }
  19324. return(0);
  19325. }
  19326. /**
  19327. * xmlSchemaResolveIDCKeyReferences:
  19328. * @idc: the identity-constraint definition
  19329. * @ctxt: the schema parser context
  19330. * @name: the attribute name
  19331. *
  19332. * Resolve keyRef references to key/unique IDCs.
  19333. * Schema Component Constraint:
  19334. * Identity-constraint Definition Properties Correct (c-props-correct)
  19335. */
  19336. static int
  19337. xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
  19338. xmlSchemaParserCtxtPtr pctxt)
  19339. {
  19340. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
  19341. return(0);
  19342. if (idc->ref->name != NULL) {
  19343. idc->ref->item = (xmlSchemaBasicItemPtr)
  19344. xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
  19345. idc->ref->targetNamespace);
  19346. if (idc->ref->item == NULL) {
  19347. /*
  19348. * TODO: It is actually not an error to fail to resolve
  19349. * at this stage. BUT we need to be that strict!
  19350. */
  19351. xmlSchemaPResCompAttrErr(pctxt,
  19352. XML_SCHEMAP_SRC_RESOLVE,
  19353. WXS_BASIC_CAST idc, idc->node,
  19354. "refer", idc->ref->name,
  19355. idc->ref->targetNamespace,
  19356. XML_SCHEMA_TYPE_IDC_KEY, NULL);
  19357. return(pctxt->err);
  19358. } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  19359. /*
  19360. * SPEC c-props-correct (1)
  19361. */
  19362. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19363. XML_SCHEMAP_C_PROPS_CORRECT,
  19364. NULL, WXS_BASIC_CAST idc,
  19365. "The keyref references a keyref",
  19366. NULL, NULL);
  19367. idc->ref->item = NULL;
  19368. return(pctxt->err);
  19369. } else {
  19370. if (idc->nbFields !=
  19371. ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
  19372. xmlChar *str = NULL;
  19373. xmlSchemaIDCPtr refer;
  19374. refer = (xmlSchemaIDCPtr) idc->ref->item;
  19375. /*
  19376. * SPEC c-props-correct(2)
  19377. * "If the {identity-constraint category} is keyref,
  19378. * the cardinality of the {fields} must equal that of
  19379. * the {fields} of the {referenced key}.
  19380. */
  19381. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19382. XML_SCHEMAP_C_PROPS_CORRECT,
  19383. NULL, WXS_BASIC_CAST idc,
  19384. "The cardinality of the keyref differs from the "
  19385. "cardinality of the referenced key/unique '%s'",
  19386. xmlSchemaFormatQName(&str, refer->targetNamespace,
  19387. refer->name),
  19388. NULL);
  19389. FREE_AND_NULL(str)
  19390. return(pctxt->err);
  19391. }
  19392. }
  19393. }
  19394. return(0);
  19395. }
  19396. static int
  19397. xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
  19398. xmlSchemaParserCtxtPtr pctxt)
  19399. {
  19400. if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
  19401. prohib->targetNamespace) == NULL) {
  19402. xmlSchemaPResCompAttrErr(pctxt,
  19403. XML_SCHEMAP_SRC_RESOLVE,
  19404. NULL, prohib->node,
  19405. "ref", prohib->name, prohib->targetNamespace,
  19406. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  19407. return(XML_SCHEMAP_SRC_RESOLVE);
  19408. }
  19409. return(0);
  19410. }
  19411. #define WXS_REDEFINED_TYPE(c) \
  19412. (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
  19413. #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
  19414. (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19415. #define WXS_REDEFINED_ATTR_GROUP(c) \
  19416. (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19417. static int
  19418. xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
  19419. {
  19420. int err = 0;
  19421. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19422. xmlSchemaBasicItemPtr prev, item;
  19423. int wasRedefined;
  19424. if (redef == NULL)
  19425. return(0);
  19426. do {
  19427. item = redef->item;
  19428. /*
  19429. * First try to locate the redefined component in the
  19430. * schema graph starting with the redefined schema.
  19431. * NOTE: According to this schema bug entry:
  19432. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
  19433. * it's not clear if the referenced component needs to originate
  19434. * from the <redefine>d schema _document_ or the schema; the latter
  19435. * would include all imported and included sub-schemas of the
  19436. * <redefine>d schema. Currently the latter approach is used.
  19437. * SUPPLEMENT: It seems that the WG moves towards the latter
  19438. * approach, so we are doing it right.
  19439. *
  19440. */
  19441. prev = xmlSchemaFindRedefCompInGraph(
  19442. redef->targetBucket, item->type,
  19443. redef->refName, redef->refTargetNs);
  19444. if (prev == NULL) {
  19445. xmlChar *str = NULL;
  19446. xmlNodePtr node;
  19447. /*
  19448. * SPEC src-redefine:
  19449. * (6.2.1) "The `actual value` of its own name attribute plus
  19450. * target namespace must successfully `resolve` to a model
  19451. * group definition in I."
  19452. * (7.2.1) "The `actual value` of its own name attribute plus
  19453. * target namespace must successfully `resolve` to an attribute
  19454. * group definition in I."
  19455. *
  19456. * Note that, if we are redefining with the use of references
  19457. * to components, the spec assumes the src-resolve to be used;
  19458. * but this won't assure that we search only *inside* the
  19459. * redefined schema.
  19460. */
  19461. if (redef->reference)
  19462. node = WXS_ITEM_NODE(redef->reference);
  19463. else
  19464. node = WXS_ITEM_NODE(item);
  19465. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19466. /*
  19467. * TODO: error code.
  19468. * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
  19469. * reference kind.
  19470. */
  19471. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  19472. "The %s '%s' to be redefined could not be found in "
  19473. "the redefined schema",
  19474. WXS_ITEM_TYPE_NAME(item),
  19475. xmlSchemaFormatQName(&str, redef->refTargetNs,
  19476. redef->refName));
  19477. FREE_AND_NULL(str);
  19478. err = pctxt->err;
  19479. redef = redef->next;
  19480. continue;
  19481. }
  19482. /*
  19483. * TODO: Obtaining and setting the redefinition state is really
  19484. * clumsy.
  19485. */
  19486. wasRedefined = 0;
  19487. switch (item->type) {
  19488. case XML_SCHEMA_TYPE_COMPLEX:
  19489. case XML_SCHEMA_TYPE_SIMPLE:
  19490. if ((WXS_TYPE_CAST prev)->flags &
  19491. XML_SCHEMAS_TYPE_REDEFINED)
  19492. {
  19493. wasRedefined = 1;
  19494. break;
  19495. }
  19496. /* Mark it as redefined. */
  19497. (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
  19498. /*
  19499. * Assign the redefined type to the
  19500. * base type of the redefining type.
  19501. * TODO: How
  19502. */
  19503. ((xmlSchemaTypePtr) item)->baseType =
  19504. (xmlSchemaTypePtr) prev;
  19505. break;
  19506. case XML_SCHEMA_TYPE_GROUP:
  19507. if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
  19508. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19509. {
  19510. wasRedefined = 1;
  19511. break;
  19512. }
  19513. /* Mark it as redefined. */
  19514. (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
  19515. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
  19516. if (redef->reference != NULL) {
  19517. /*
  19518. * Overwrite the QName-reference with the
  19519. * referenced model group def.
  19520. */
  19521. (WXS_PTC_CAST redef->reference)->children =
  19522. WXS_TREE_CAST prev;
  19523. }
  19524. redef->target = prev;
  19525. break;
  19526. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19527. if ((WXS_ATTR_GROUP_CAST prev)->flags &
  19528. XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19529. {
  19530. wasRedefined = 1;
  19531. break;
  19532. }
  19533. (WXS_ATTR_GROUP_CAST prev)->flags |=
  19534. XML_SCHEMAS_ATTRGROUP_REDEFINED;
  19535. if (redef->reference != NULL) {
  19536. /*
  19537. * Assign the redefined attribute group to the
  19538. * QName-reference component.
  19539. * This is the easy case, since we will just
  19540. * expand the redefined group.
  19541. */
  19542. (WXS_QNAME_CAST redef->reference)->item = prev;
  19543. redef->target = NULL;
  19544. } else {
  19545. /*
  19546. * This is the complicated case: we need
  19547. * to apply src-redefine (7.2.2) at a later
  19548. * stage, i.e. when attribute group references
  19549. * have been expanded and simple types have
  19550. * been fixed.
  19551. */
  19552. redef->target = prev;
  19553. }
  19554. break;
  19555. default:
  19556. PERROR_INT("xmlSchemaResolveRedefReferences",
  19557. "Unexpected redefined component type");
  19558. return(-1);
  19559. }
  19560. if (wasRedefined) {
  19561. xmlChar *str = NULL;
  19562. xmlNodePtr node;
  19563. if (redef->reference)
  19564. node = WXS_ITEM_NODE(redef->reference);
  19565. else
  19566. node = WXS_ITEM_NODE(redef->item);
  19567. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19568. /* TODO: error code. */
  19569. XML_SCHEMAP_SRC_REDEFINE,
  19570. node, NULL,
  19571. "The referenced %s was already redefined. Multiple "
  19572. "redefinition of the same component is not supported",
  19573. xmlSchemaGetComponentDesignation(&str, prev),
  19574. NULL);
  19575. FREE_AND_NULL(str)
  19576. err = pctxt->err;
  19577. redef = redef->next;
  19578. continue;
  19579. }
  19580. redef = redef->next;
  19581. } while (redef != NULL);
  19582. return(err);
  19583. }
  19584. static int
  19585. xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
  19586. {
  19587. int err = 0;
  19588. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19589. xmlSchemaBasicItemPtr item;
  19590. if (redef == NULL)
  19591. return(0);
  19592. do {
  19593. if (redef->target == NULL) {
  19594. redef = redef->next;
  19595. continue;
  19596. }
  19597. item = redef->item;
  19598. switch (item->type) {
  19599. case XML_SCHEMA_TYPE_SIMPLE:
  19600. case XML_SCHEMA_TYPE_COMPLEX:
  19601. /*
  19602. * Since the spec wants the {name} of the redefined
  19603. * type to be 'absent', we'll NULL it.
  19604. */
  19605. (WXS_TYPE_CAST redef->target)->name = NULL;
  19606. /*
  19607. * TODO: Seems like there's nothing more to do. The normal
  19608. * inheritance mechanism is used. But not 100% sure.
  19609. */
  19610. break;
  19611. case XML_SCHEMA_TYPE_GROUP:
  19612. /*
  19613. * URGENT TODO:
  19614. * SPEC src-redefine:
  19615. * (6.2.2) "The {model group} of the model group definition
  19616. * which corresponds to it per XML Representation of Model
  19617. * Group Definition Schema Components ($3.7.2) must be a
  19618. * `valid restriction` of the {model group} of that model
  19619. * group definition in I, as defined in Particle Valid
  19620. * (Restriction) ($3.9.6)."
  19621. */
  19622. break;
  19623. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19624. /*
  19625. * SPEC src-redefine:
  19626. * (7.2.2) "The {attribute uses} and {attribute wildcard} of
  19627. * the attribute group definition which corresponds to it
  19628. * per XML Representation of Attribute Group Definition Schema
  19629. * Components ($3.6.2) must be `valid restrictions` of the
  19630. * {attribute uses} and {attribute wildcard} of that attribute
  19631. * group definition in I, as defined in clause 2, clause 3 and
  19632. * clause 4 of Derivation Valid (Restriction, Complex)
  19633. * ($3.4.6) (where references to the base type definition are
  19634. * understood as references to the attribute group definition
  19635. * in I)."
  19636. */
  19637. err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
  19638. XML_SCHEMA_ACTION_REDEFINE,
  19639. item, redef->target,
  19640. (WXS_ATTR_GROUP_CAST item)->attrUses,
  19641. (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
  19642. (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
  19643. (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
  19644. if (err == -1)
  19645. return(-1);
  19646. break;
  19647. default:
  19648. break;
  19649. }
  19650. redef = redef->next;
  19651. } while (redef != NULL);
  19652. return(0);
  19653. }
  19654. static int
  19655. xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
  19656. xmlSchemaBucketPtr bucket)
  19657. {
  19658. xmlSchemaBasicItemPtr item;
  19659. int err;
  19660. xmlHashTablePtr *table;
  19661. const xmlChar *name;
  19662. int i;
  19663. #define WXS_GET_GLOBAL_HASH(c, slot) { \
  19664. if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
  19665. table = &(WXS_IMPBUCKET((c))->schema->slot); \
  19666. else \
  19667. table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
  19668. /*
  19669. * Add global components to the schema's hash tables.
  19670. * This is the place where duplicate components will be
  19671. * detected.
  19672. * TODO: I think normally we should support imports of the
  19673. * same namespace from multiple locations. We don't do currently,
  19674. * but if we do then according to:
  19675. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
  19676. * we would need, if imported directly, to import redefined
  19677. * components as well to be able to catch clashing components.
  19678. * (I hope I'll still know what this means after some months :-()
  19679. */
  19680. if (bucket == NULL)
  19681. return(-1);
  19682. if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
  19683. return(0);
  19684. bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
  19685. for (i = 0; i < bucket->globals->nbItems; i++) {
  19686. item = bucket->globals->items[i];
  19687. table = NULL;
  19688. switch (item->type) {
  19689. case XML_SCHEMA_TYPE_COMPLEX:
  19690. case XML_SCHEMA_TYPE_SIMPLE:
  19691. if (WXS_REDEFINED_TYPE(item))
  19692. continue;
  19693. name = (WXS_TYPE_CAST item)->name;
  19694. WXS_GET_GLOBAL_HASH(bucket, typeDecl)
  19695. break;
  19696. case XML_SCHEMA_TYPE_ELEMENT:
  19697. name = (WXS_ELEM_CAST item)->name;
  19698. WXS_GET_GLOBAL_HASH(bucket, elemDecl)
  19699. break;
  19700. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19701. name = (WXS_ATTR_CAST item)->name;
  19702. WXS_GET_GLOBAL_HASH(bucket, attrDecl)
  19703. break;
  19704. case XML_SCHEMA_TYPE_GROUP:
  19705. if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
  19706. continue;
  19707. name = (WXS_MODEL_GROUPDEF_CAST item)->name;
  19708. WXS_GET_GLOBAL_HASH(bucket, groupDecl)
  19709. break;
  19710. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19711. if (WXS_REDEFINED_ATTR_GROUP(item))
  19712. continue;
  19713. name = (WXS_ATTR_GROUP_CAST item)->name;
  19714. WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
  19715. break;
  19716. case XML_SCHEMA_TYPE_IDC_KEY:
  19717. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19718. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19719. name = (WXS_IDC_CAST item)->name;
  19720. WXS_GET_GLOBAL_HASH(bucket, idcDef)
  19721. break;
  19722. case XML_SCHEMA_TYPE_NOTATION:
  19723. name = ((xmlSchemaNotationPtr) item)->name;
  19724. WXS_GET_GLOBAL_HASH(bucket, notaDecl)
  19725. break;
  19726. default:
  19727. PERROR_INT("xmlSchemaAddComponents",
  19728. "Unexpected global component type");
  19729. continue;
  19730. }
  19731. if (*table == NULL) {
  19732. *table = xmlHashCreateDict(10, pctxt->dict);
  19733. if (*table == NULL) {
  19734. PERROR_INT("xmlSchemaAddComponents",
  19735. "failed to create a component hash table");
  19736. return(-1);
  19737. }
  19738. }
  19739. err = xmlHashAddEntry(*table, name, item);
  19740. if (err != 0) {
  19741. xmlChar *str = NULL;
  19742. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19743. XML_SCHEMAP_REDEFINED_TYPE,
  19744. WXS_ITEM_NODE(item),
  19745. WXS_BASIC_CAST item,
  19746. "A global %s '%s' does already exist",
  19747. WXS_ITEM_TYPE_NAME(item),
  19748. xmlSchemaGetComponentQName(&str, item));
  19749. FREE_AND_NULL(str);
  19750. }
  19751. }
  19752. /*
  19753. * Process imported/included schemas.
  19754. */
  19755. if (bucket->relations != NULL) {
  19756. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  19757. do {
  19758. if ((rel->bucket != NULL) &&
  19759. ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
  19760. if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
  19761. return(-1);
  19762. }
  19763. rel = rel->next;
  19764. } while (rel != NULL);
  19765. }
  19766. return(0);
  19767. }
  19768. static int
  19769. xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
  19770. xmlSchemaBucketPtr rootBucket)
  19771. {
  19772. xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
  19773. xmlSchemaTreeItemPtr item, *items;
  19774. int nbItems, i, ret = 0;
  19775. xmlSchemaBucketPtr oldbucket = con->bucket;
  19776. xmlSchemaElementPtr elemDecl;
  19777. #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
  19778. if ((con->pending == NULL) ||
  19779. (con->pending->nbItems == 0))
  19780. return(0);
  19781. /*
  19782. * Since xmlSchemaFixupComplexType() will create new particles
  19783. * (local components), and those particle components need a bucket
  19784. * on the constructor, we'll assure here that the constructor has
  19785. * a bucket.
  19786. * TODO: Think about storing locals _only_ on the main bucket.
  19787. */
  19788. if (con->bucket == NULL)
  19789. con->bucket = rootBucket;
  19790. /* TODO:
  19791. * SPEC (src-redefine):
  19792. * (6.2) "If it has no such self-reference, then all of the
  19793. * following must be true:"
  19794. * (6.2.2) The {model group} of the model group definition which
  19795. * corresponds to it per XML Representation of Model Group
  19796. * Definition Schema Components ($3.7.2) must be a `valid
  19797. * restriction` of the {model group} of that model group definition
  19798. * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
  19799. */
  19800. xmlSchemaCheckSRCRedefineFirst(pctxt);
  19801. /*
  19802. * Add global components to the schemata's hash tables.
  19803. */
  19804. xmlSchemaAddComponents(pctxt, rootBucket);
  19805. pctxt->ctxtType = NULL;
  19806. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  19807. nbItems = con->pending->nbItems;
  19808. /*
  19809. * Now that we have parsed *all* the schema document(s) and converted
  19810. * them to schema components, we can resolve references, apply component
  19811. * constraints, create the FSA from the content model, etc.
  19812. */
  19813. /*
  19814. * Resolve references of..
  19815. *
  19816. * 1. element declarations:
  19817. * - the type definition
  19818. * - the substitution group affiliation
  19819. * 2. simple/complex types:
  19820. * - the base type definition
  19821. * - the memberTypes of union types
  19822. * - the itemType of list types
  19823. * 3. attributes declarations and attribute uses:
  19824. * - the type definition
  19825. * - if an attribute use, then the attribute declaration
  19826. * 4. attribute group references:
  19827. * - the attribute group definition
  19828. * 5. particles:
  19829. * - the term of the particle (e.g. a model group)
  19830. * 6. IDC key-references:
  19831. * - the referenced IDC 'key' or 'unique' definition
  19832. * 7. Attribute prohibitions which had a "ref" attribute.
  19833. */
  19834. for (i = 0; i < nbItems; i++) {
  19835. item = items[i];
  19836. switch (item->type) {
  19837. case XML_SCHEMA_TYPE_ELEMENT:
  19838. xmlSchemaResolveElementReferences(
  19839. (xmlSchemaElementPtr) item, pctxt);
  19840. FIXHFAILURE;
  19841. break;
  19842. case XML_SCHEMA_TYPE_COMPLEX:
  19843. case XML_SCHEMA_TYPE_SIMPLE:
  19844. xmlSchemaResolveTypeReferences(
  19845. (xmlSchemaTypePtr) item, pctxt);
  19846. FIXHFAILURE;
  19847. break;
  19848. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19849. xmlSchemaResolveAttrTypeReferences(
  19850. (xmlSchemaAttributePtr) item, pctxt);
  19851. FIXHFAILURE;
  19852. break;
  19853. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  19854. xmlSchemaResolveAttrUseReferences(
  19855. (xmlSchemaAttributeUsePtr) item, pctxt);
  19856. FIXHFAILURE;
  19857. break;
  19858. case XML_SCHEMA_EXTRA_QNAMEREF:
  19859. if ((WXS_QNAME_CAST item)->itemType ==
  19860. XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
  19861. {
  19862. xmlSchemaResolveAttrGroupReferences(
  19863. WXS_QNAME_CAST item, pctxt);
  19864. }
  19865. FIXHFAILURE;
  19866. break;
  19867. case XML_SCHEMA_TYPE_SEQUENCE:
  19868. case XML_SCHEMA_TYPE_CHOICE:
  19869. case XML_SCHEMA_TYPE_ALL:
  19870. xmlSchemaResolveModelGroupParticleReferences(pctxt,
  19871. WXS_MODEL_GROUP_CAST item);
  19872. FIXHFAILURE;
  19873. break;
  19874. case XML_SCHEMA_TYPE_IDC_KEY:
  19875. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19876. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19877. xmlSchemaResolveIDCKeyReferences(
  19878. (xmlSchemaIDCPtr) item, pctxt);
  19879. FIXHFAILURE;
  19880. break;
  19881. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  19882. /*
  19883. * Handle attribute prohibition which had a
  19884. * "ref" attribute.
  19885. */
  19886. xmlSchemaResolveAttrUseProhibReferences(
  19887. WXS_ATTR_PROHIB_CAST item, pctxt);
  19888. FIXHFAILURE;
  19889. break;
  19890. default:
  19891. break;
  19892. }
  19893. }
  19894. if (pctxt->nberrors != 0)
  19895. goto exit_error;
  19896. /*
  19897. * Now that all references are resolved we
  19898. * can check for circularity of...
  19899. * 1. the base axis of type definitions
  19900. * 2. nested model group definitions
  19901. * 3. nested attribute group definitions
  19902. * TODO: check for circular substitution groups.
  19903. */
  19904. for (i = 0; i < nbItems; i++) {
  19905. item = items[i];
  19906. /*
  19907. * Let's better stop on the first error here.
  19908. */
  19909. switch (item->type) {
  19910. case XML_SCHEMA_TYPE_COMPLEX:
  19911. case XML_SCHEMA_TYPE_SIMPLE:
  19912. xmlSchemaCheckTypeDefCircular(
  19913. (xmlSchemaTypePtr) item, pctxt);
  19914. FIXHFAILURE;
  19915. if (pctxt->nberrors != 0)
  19916. goto exit_error;
  19917. break;
  19918. case XML_SCHEMA_TYPE_GROUP:
  19919. xmlSchemaCheckGroupDefCircular(
  19920. (xmlSchemaModelGroupDefPtr) item, pctxt);
  19921. FIXHFAILURE;
  19922. if (pctxt->nberrors != 0)
  19923. goto exit_error;
  19924. break;
  19925. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19926. xmlSchemaCheckAttrGroupCircular(
  19927. (xmlSchemaAttributeGroupPtr) item, pctxt);
  19928. FIXHFAILURE;
  19929. if (pctxt->nberrors != 0)
  19930. goto exit_error;
  19931. break;
  19932. default:
  19933. break;
  19934. }
  19935. }
  19936. if (pctxt->nberrors != 0)
  19937. goto exit_error;
  19938. /*
  19939. * Model group definition references:
  19940. * Such a reference is reflected by a particle at the component
  19941. * level. Until now the 'term' of such particles pointed
  19942. * to the model group definition; this was done, in order to
  19943. * ease circularity checks. Now we need to set the 'term' of
  19944. * such particles to the model group of the model group definition.
  19945. */
  19946. for (i = 0; i < nbItems; i++) {
  19947. item = items[i];
  19948. switch (item->type) {
  19949. case XML_SCHEMA_TYPE_SEQUENCE:
  19950. case XML_SCHEMA_TYPE_CHOICE:
  19951. xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
  19952. WXS_MODEL_GROUP_CAST item);
  19953. break;
  19954. default:
  19955. break;
  19956. }
  19957. }
  19958. if (pctxt->nberrors != 0)
  19959. goto exit_error;
  19960. /*
  19961. * Expand attribute group references of attribute group definitions.
  19962. */
  19963. for (i = 0; i < nbItems; i++) {
  19964. item = items[i];
  19965. switch (item->type) {
  19966. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19967. if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
  19968. WXS_ATTR_GROUP_HAS_REFS(item))
  19969. {
  19970. xmlSchemaAttributeGroupExpandRefs(pctxt,
  19971. WXS_ATTR_GROUP_CAST item);
  19972. FIXHFAILURE;
  19973. }
  19974. break;
  19975. default:
  19976. break;
  19977. }
  19978. }
  19979. if (pctxt->nberrors != 0)
  19980. goto exit_error;
  19981. /*
  19982. * First compute the variety of simple types. This is needed as
  19983. * a separate step, since otherwise we won't be able to detect
  19984. * circular union types in all cases.
  19985. */
  19986. for (i = 0; i < nbItems; i++) {
  19987. item = items[i];
  19988. switch (item->type) {
  19989. case XML_SCHEMA_TYPE_SIMPLE:
  19990. if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
  19991. xmlSchemaFixupSimpleTypeStageOne(pctxt,
  19992. (xmlSchemaTypePtr) item);
  19993. FIXHFAILURE;
  19994. }
  19995. break;
  19996. default:
  19997. break;
  19998. }
  19999. }
  20000. if (pctxt->nberrors != 0)
  20001. goto exit_error;
  20002. /*
  20003. * Detect circular union types. Note that this needs the variety to
  20004. * be already computed.
  20005. */
  20006. for (i = 0; i < nbItems; i++) {
  20007. item = items[i];
  20008. switch (item->type) {
  20009. case XML_SCHEMA_TYPE_SIMPLE:
  20010. if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
  20011. xmlSchemaCheckUnionTypeDefCircular(pctxt,
  20012. (xmlSchemaTypePtr) item);
  20013. FIXHFAILURE;
  20014. }
  20015. break;
  20016. default:
  20017. break;
  20018. }
  20019. }
  20020. if (pctxt->nberrors != 0)
  20021. goto exit_error;
  20022. /*
  20023. * Do the complete type fixup for simple types.
  20024. */
  20025. for (i = 0; i < nbItems; i++) {
  20026. item = items[i];
  20027. switch (item->type) {
  20028. case XML_SCHEMA_TYPE_SIMPLE:
  20029. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  20030. xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
  20031. FIXHFAILURE;
  20032. }
  20033. break;
  20034. default:
  20035. break;
  20036. }
  20037. }
  20038. if (pctxt->nberrors != 0)
  20039. goto exit_error;
  20040. /*
  20041. * At this point we need build and check all simple types.
  20042. */
  20043. /*
  20044. * Apply constraints for attribute declarations.
  20045. */
  20046. for (i = 0; i < nbItems; i++) {
  20047. item = items[i];
  20048. switch (item->type) {
  20049. case XML_SCHEMA_TYPE_ATTRIBUTE:
  20050. xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
  20051. FIXHFAILURE;
  20052. break;
  20053. default:
  20054. break;
  20055. }
  20056. }
  20057. if (pctxt->nberrors != 0)
  20058. goto exit_error;
  20059. /*
  20060. * Apply constraints for attribute uses.
  20061. */
  20062. for (i = 0; i < nbItems; i++) {
  20063. item = items[i];
  20064. switch (item->type) {
  20065. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  20066. if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
  20067. xmlSchemaCheckAttrUsePropsCorrect(pctxt,
  20068. WXS_ATTR_USE_CAST item);
  20069. FIXHFAILURE;
  20070. }
  20071. break;
  20072. default:
  20073. break;
  20074. }
  20075. }
  20076. if (pctxt->nberrors != 0)
  20077. goto exit_error;
  20078. /*
  20079. * Apply constraints for attribute group definitions.
  20080. */
  20081. for (i = 0; i < nbItems; i++) {
  20082. item = items[i];
  20083. switch (item->type) {
  20084. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  20085. if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
  20086. ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
  20087. {
  20088. xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
  20089. FIXHFAILURE;
  20090. }
  20091. break;
  20092. default:
  20093. break;
  20094. }
  20095. }
  20096. if (pctxt->nberrors != 0)
  20097. goto exit_error;
  20098. /*
  20099. * Apply constraints for redefinitions.
  20100. */
  20101. if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
  20102. xmlSchemaCheckSRCRedefineSecond(pctxt);
  20103. if (pctxt->nberrors != 0)
  20104. goto exit_error;
  20105. /*
  20106. * Complex types are built and checked.
  20107. */
  20108. for (i = 0; i < nbItems; i++) {
  20109. item = con->pending->items[i];
  20110. switch (item->type) {
  20111. case XML_SCHEMA_TYPE_COMPLEX:
  20112. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  20113. xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
  20114. FIXHFAILURE;
  20115. }
  20116. break;
  20117. default:
  20118. break;
  20119. }
  20120. }
  20121. if (pctxt->nberrors != 0)
  20122. goto exit_error;
  20123. /*
  20124. * The list could have changed, since xmlSchemaFixupComplexType()
  20125. * will create particles and model groups in some cases.
  20126. */
  20127. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  20128. nbItems = con->pending->nbItems;
  20129. /*
  20130. * Apply some constraints for element declarations.
  20131. */
  20132. for (i = 0; i < nbItems; i++) {
  20133. item = items[i];
  20134. switch (item->type) {
  20135. case XML_SCHEMA_TYPE_ELEMENT:
  20136. elemDecl = (xmlSchemaElementPtr) item;
  20137. if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
  20138. {
  20139. xmlSchemaCheckElementDeclComponent(
  20140. (xmlSchemaElementPtr) elemDecl, pctxt);
  20141. FIXHFAILURE;
  20142. }
  20143. #ifdef WXS_ELEM_DECL_CONS_ENABLED
  20144. /*
  20145. * Schema Component Constraint: Element Declarations Consistent
  20146. * Apply this constraint to local types of element declarations.
  20147. */
  20148. if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
  20149. (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
  20150. (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
  20151. {
  20152. xmlSchemaCheckElementDeclConsistent(pctxt,
  20153. WXS_BASIC_CAST elemDecl,
  20154. WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
  20155. NULL, NULL, 0);
  20156. }
  20157. #endif
  20158. break;
  20159. default:
  20160. break;
  20161. }
  20162. }
  20163. if (pctxt->nberrors != 0)
  20164. goto exit_error;
  20165. /*
  20166. * Finally we can build the automaton from the content model of
  20167. * complex types.
  20168. */
  20169. for (i = 0; i < nbItems; i++) {
  20170. item = items[i];
  20171. switch (item->type) {
  20172. case XML_SCHEMA_TYPE_COMPLEX:
  20173. xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
  20174. /* FIXHFAILURE; */
  20175. break;
  20176. default:
  20177. break;
  20178. }
  20179. }
  20180. if (pctxt->nberrors != 0)
  20181. goto exit_error;
  20182. /*
  20183. * URGENT TODO: cos-element-consistent
  20184. */
  20185. goto exit;
  20186. exit_error:
  20187. ret = pctxt->err;
  20188. goto exit;
  20189. exit_failure:
  20190. ret = -1;
  20191. exit:
  20192. /*
  20193. * Reset the constructor. This is needed for XSI acquisition, since
  20194. * those items will be processed over and over again for every XSI
  20195. * if not cleared here.
  20196. */
  20197. con->bucket = oldbucket;
  20198. con->pending->nbItems = 0;
  20199. if (con->substGroups != NULL) {
  20200. xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
  20201. con->substGroups = NULL;
  20202. }
  20203. if (con->redefs != NULL) {
  20204. xmlSchemaRedefListFree(con->redefs);
  20205. con->redefs = NULL;
  20206. }
  20207. return(ret);
  20208. }
  20209. /**
  20210. * xmlSchemaParse:
  20211. * @ctxt: a schema validation context
  20212. *
  20213. * parse a schema definition resource and build an internal
  20214. * XML Schema structure which can be used to validate instances.
  20215. *
  20216. * Returns the internal XML Schema structure built from the resource or
  20217. * NULL in case of error
  20218. */
  20219. xmlSchemaPtr
  20220. xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
  20221. {
  20222. xmlSchemaPtr mainSchema = NULL;
  20223. xmlSchemaBucketPtr bucket = NULL;
  20224. int res;
  20225. /*
  20226. * This one is used if the schema to be parsed was specified via
  20227. * the API; i.e. not automatically by the validated instance document.
  20228. */
  20229. xmlSchemaInitTypes();
  20230. if (ctxt == NULL)
  20231. return (NULL);
  20232. /* TODO: Init the context. Is this all we need?*/
  20233. ctxt->nberrors = 0;
  20234. ctxt->err = 0;
  20235. ctxt->counter = 0;
  20236. /* Create the *main* schema. */
  20237. mainSchema = xmlSchemaNewSchema(ctxt);
  20238. if (mainSchema == NULL)
  20239. goto exit_failure;
  20240. /*
  20241. * Create the schema constructor.
  20242. */
  20243. if (ctxt->constructor == NULL) {
  20244. ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
  20245. if (ctxt->constructor == NULL)
  20246. return(NULL);
  20247. /* Take ownership of the constructor to be able to free it. */
  20248. ctxt->ownsConstructor = 1;
  20249. }
  20250. ctxt->constructor->mainSchema = mainSchema;
  20251. /*
  20252. * Locate and add the schema document.
  20253. */
  20254. res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
  20255. ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
  20256. NULL, NULL, &bucket);
  20257. if (res == -1)
  20258. goto exit_failure;
  20259. if (res != 0)
  20260. goto exit;
  20261. if (bucket == NULL) {
  20262. /* TODO: Error code, actually we failed to *locate* the schema. */
  20263. if (ctxt->URL)
  20264. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20265. NULL, NULL,
  20266. "Failed to locate the main schema resource at '%s'",
  20267. ctxt->URL, NULL);
  20268. else
  20269. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20270. NULL, NULL,
  20271. "Failed to locate the main schema resource",
  20272. NULL, NULL);
  20273. goto exit;
  20274. }
  20275. /* Then do the parsing for good. */
  20276. if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
  20277. goto exit_failure;
  20278. if (ctxt->nberrors != 0)
  20279. goto exit;
  20280. mainSchema->doc = bucket->doc;
  20281. mainSchema->preserve = ctxt->preserve;
  20282. ctxt->schema = mainSchema;
  20283. if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
  20284. goto exit_failure;
  20285. /*
  20286. * TODO: This is not nice, since we cannot distinguish from the
  20287. * result if there was an internal error or not.
  20288. */
  20289. exit:
  20290. if (ctxt->nberrors != 0) {
  20291. if (mainSchema) {
  20292. xmlSchemaFree(mainSchema);
  20293. mainSchema = NULL;
  20294. }
  20295. if (ctxt->constructor) {
  20296. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20297. ctxt->constructor = NULL;
  20298. ctxt->ownsConstructor = 0;
  20299. }
  20300. }
  20301. ctxt->schema = NULL;
  20302. return(mainSchema);
  20303. exit_failure:
  20304. /*
  20305. * Quite verbose, but should catch internal errors, which were
  20306. * not communicated.
  20307. */
  20308. if (mainSchema) {
  20309. xmlSchemaFree(mainSchema);
  20310. mainSchema = NULL;
  20311. }
  20312. if (ctxt->constructor) {
  20313. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20314. ctxt->constructor = NULL;
  20315. ctxt->ownsConstructor = 0;
  20316. }
  20317. PERROR_INT2("xmlSchemaParse",
  20318. "An internal error occurred");
  20319. ctxt->schema = NULL;
  20320. return(NULL);
  20321. }
  20322. /**
  20323. * xmlSchemaSetParserErrors:
  20324. * @ctxt: a schema validation context
  20325. * @err: the error callback
  20326. * @warn: the warning callback
  20327. * @ctx: contextual data for the callbacks
  20328. *
  20329. * Set the callback functions used to handle errors for a validation context
  20330. */
  20331. void
  20332. xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20333. xmlSchemaValidityErrorFunc err,
  20334. xmlSchemaValidityWarningFunc warn, void *ctx)
  20335. {
  20336. if (ctxt == NULL)
  20337. return;
  20338. ctxt->error = err;
  20339. ctxt->warning = warn;
  20340. ctxt->errCtxt = ctx;
  20341. if (ctxt->vctxt != NULL)
  20342. xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
  20343. }
  20344. /**
  20345. * xmlSchemaSetParserStructuredErrors:
  20346. * @ctxt: a schema parser context
  20347. * @serror: the structured error function
  20348. * @ctx: the functions context
  20349. *
  20350. * Set the structured error callback
  20351. */
  20352. void
  20353. xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
  20354. xmlStructuredErrorFunc serror,
  20355. void *ctx)
  20356. {
  20357. if (ctxt == NULL)
  20358. return;
  20359. ctxt->serror = serror;
  20360. ctxt->errCtxt = ctx;
  20361. if (ctxt->vctxt != NULL)
  20362. xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
  20363. }
  20364. /**
  20365. * xmlSchemaGetParserErrors:
  20366. * @ctxt: a XMl-Schema parser context
  20367. * @err: the error callback result
  20368. * @warn: the warning callback result
  20369. * @ctx: contextual data for the callbacks result
  20370. *
  20371. * Get the callback information used to handle errors for a parser context
  20372. *
  20373. * Returns -1 in case of failure, 0 otherwise
  20374. */
  20375. int
  20376. xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20377. xmlSchemaValidityErrorFunc * err,
  20378. xmlSchemaValidityWarningFunc * warn, void **ctx)
  20379. {
  20380. if (ctxt == NULL)
  20381. return(-1);
  20382. if (err != NULL)
  20383. *err = ctxt->error;
  20384. if (warn != NULL)
  20385. *warn = ctxt->warning;
  20386. if (ctx != NULL)
  20387. *ctx = ctxt->errCtxt;
  20388. return(0);
  20389. }
  20390. /**
  20391. * xmlSchemaFacetTypeToString:
  20392. * @type: the facet type
  20393. *
  20394. * Convert the xmlSchemaTypeType to a char string.
  20395. *
  20396. * Returns the char string representation of the facet type if the
  20397. * type is a facet and an "Internal Error" string otherwise.
  20398. */
  20399. static const xmlChar *
  20400. xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
  20401. {
  20402. switch (type) {
  20403. case XML_SCHEMA_FACET_PATTERN:
  20404. return (BAD_CAST "pattern");
  20405. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  20406. return (BAD_CAST "maxExclusive");
  20407. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  20408. return (BAD_CAST "maxInclusive");
  20409. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  20410. return (BAD_CAST "minExclusive");
  20411. case XML_SCHEMA_FACET_MININCLUSIVE:
  20412. return (BAD_CAST "minInclusive");
  20413. case XML_SCHEMA_FACET_WHITESPACE:
  20414. return (BAD_CAST "whiteSpace");
  20415. case XML_SCHEMA_FACET_ENUMERATION:
  20416. return (BAD_CAST "enumeration");
  20417. case XML_SCHEMA_FACET_LENGTH:
  20418. return (BAD_CAST "length");
  20419. case XML_SCHEMA_FACET_MAXLENGTH:
  20420. return (BAD_CAST "maxLength");
  20421. case XML_SCHEMA_FACET_MINLENGTH:
  20422. return (BAD_CAST "minLength");
  20423. case XML_SCHEMA_FACET_TOTALDIGITS:
  20424. return (BAD_CAST "totalDigits");
  20425. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  20426. return (BAD_CAST "fractionDigits");
  20427. default:
  20428. break;
  20429. }
  20430. return (BAD_CAST "Internal Error");
  20431. }
  20432. static xmlSchemaWhitespaceValueType
  20433. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
  20434. {
  20435. /*
  20436. * The normalization type can be changed only for types which are derived
  20437. * from xsd:string.
  20438. */
  20439. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  20440. /*
  20441. * Note that we assume a whitespace of preserve for anySimpleType.
  20442. */
  20443. if ((type->builtInType == XML_SCHEMAS_STRING) ||
  20444. (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  20445. return(XML_SCHEMA_WHITESPACE_PRESERVE);
  20446. else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
  20447. return(XML_SCHEMA_WHITESPACE_REPLACE);
  20448. else {
  20449. /*
  20450. * For all `atomic` datatypes other than string (and types `derived`
  20451. * by `restriction` from it) the value of whiteSpace is fixed to
  20452. * collapse
  20453. * Note that this includes built-in list datatypes.
  20454. */
  20455. return(XML_SCHEMA_WHITESPACE_COLLAPSE);
  20456. }
  20457. } else if (WXS_IS_LIST(type)) {
  20458. /*
  20459. * For list types the facet "whiteSpace" is fixed to "collapse".
  20460. */
  20461. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20462. } else if (WXS_IS_UNION(type)) {
  20463. return (XML_SCHEMA_WHITESPACE_UNKNOWN);
  20464. } else if (WXS_IS_ATOMIC(type)) {
  20465. if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
  20466. return (XML_SCHEMA_WHITESPACE_PRESERVE);
  20467. else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
  20468. return (XML_SCHEMA_WHITESPACE_REPLACE);
  20469. else
  20470. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20471. }
  20472. return (-1);
  20473. }
  20474. /************************************************************************
  20475. * *
  20476. * Simple type validation *
  20477. * *
  20478. ************************************************************************/
  20479. /************************************************************************
  20480. * *
  20481. * DOM Validation code *
  20482. * *
  20483. ************************************************************************/
  20484. /**
  20485. * xmlSchemaAssembleByLocation:
  20486. * @pctxt: a schema parser context
  20487. * @vctxt: a schema validation context
  20488. * @schema: the existing schema
  20489. * @node: the node that fired the assembling
  20490. * @nsName: the namespace name of the new schema
  20491. * @location: the location of the schema
  20492. *
  20493. * Expands an existing schema by an additional schema.
  20494. *
  20495. * Returns 0 if the new schema is correct, a positive error code
  20496. * number otherwise and -1 in case of an internal or API error.
  20497. */
  20498. static int
  20499. xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
  20500. xmlSchemaPtr schema,
  20501. xmlNodePtr node,
  20502. const xmlChar *nsName,
  20503. const xmlChar *location)
  20504. {
  20505. int ret = 0;
  20506. xmlSchemaParserCtxtPtr pctxt;
  20507. xmlSchemaBucketPtr bucket = NULL;
  20508. if ((vctxt == NULL) || (schema == NULL))
  20509. return (-1);
  20510. if (vctxt->pctxt == NULL) {
  20511. VERROR_INT("xmlSchemaAssembleByLocation",
  20512. "no parser context available");
  20513. return(-1);
  20514. }
  20515. pctxt = vctxt->pctxt;
  20516. if (pctxt->constructor == NULL) {
  20517. PERROR_INT("xmlSchemaAssembleByLocation",
  20518. "no constructor");
  20519. return(-1);
  20520. }
  20521. /*
  20522. * Acquire the schema document.
  20523. */
  20524. location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  20525. location, node);
  20526. /*
  20527. * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
  20528. * the process will automatically change this to
  20529. * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
  20530. */
  20531. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  20532. location, NULL, NULL, 0, node, NULL, nsName,
  20533. &bucket);
  20534. if (ret != 0)
  20535. return(ret);
  20536. if (bucket == NULL) {
  20537. /*
  20538. * Generate a warning that the document could not be located.
  20539. */
  20540. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20541. node, NULL,
  20542. "The document at location '%s' could not be acquired",
  20543. location, NULL, NULL);
  20544. return(ret);
  20545. }
  20546. /*
  20547. * The first located schema will be handled as if all other
  20548. * schemas imported by XSI were imported by this first schema.
  20549. */
  20550. if ((bucket != NULL) &&
  20551. (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
  20552. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  20553. /*
  20554. * TODO: Is this handled like an import? I.e. is it not an error
  20555. * if the schema cannot be located?
  20556. */
  20557. if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
  20558. return(0);
  20559. /*
  20560. * We will reuse the parser context for every schema imported
  20561. * directly via XSI. So reset the context.
  20562. */
  20563. pctxt->nberrors = 0;
  20564. pctxt->err = 0;
  20565. pctxt->doc = bucket->doc;
  20566. ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
  20567. if (ret == -1) {
  20568. pctxt->doc = NULL;
  20569. goto exit_failure;
  20570. }
  20571. /* Paranoid error channelling. */
  20572. if ((ret == 0) && (pctxt->nberrors != 0))
  20573. ret = pctxt->err;
  20574. if (pctxt->nberrors == 0) {
  20575. /*
  20576. * Only bother to fixup pending components, if there was
  20577. * no error yet.
  20578. * For every XSI acquired schema (and its sub-schemata) we will
  20579. * fixup the components.
  20580. */
  20581. xmlSchemaFixupComponents(pctxt, bucket);
  20582. ret = pctxt->err;
  20583. /*
  20584. * Not nice, but we need somehow to channel the schema parser
  20585. * error to the validation context.
  20586. */
  20587. if ((ret != 0) && (vctxt->err == 0))
  20588. vctxt->err = ret;
  20589. vctxt->nberrors += pctxt->nberrors;
  20590. } else {
  20591. /* Add to validation error sum. */
  20592. vctxt->nberrors += pctxt->nberrors;
  20593. }
  20594. pctxt->doc = NULL;
  20595. return(ret);
  20596. exit_failure:
  20597. pctxt->doc = NULL;
  20598. return (-1);
  20599. }
  20600. static xmlSchemaAttrInfoPtr
  20601. xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
  20602. int metaType)
  20603. {
  20604. if (vctxt->nbAttrInfos == 0)
  20605. return (NULL);
  20606. {
  20607. int i;
  20608. xmlSchemaAttrInfoPtr iattr;
  20609. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  20610. iattr = vctxt->attrInfos[i];
  20611. if (iattr->metaType == metaType)
  20612. return (iattr);
  20613. }
  20614. }
  20615. return (NULL);
  20616. }
  20617. /**
  20618. * xmlSchemaAssembleByXSI:
  20619. * @vctxt: a schema validation context
  20620. *
  20621. * Expands an existing schema by an additional schema using
  20622. * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
  20623. * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
  20624. * must be set to 1.
  20625. *
  20626. * Returns 0 if the new schema is correct, a positive error code
  20627. * number otherwise and -1 in case of an internal or API error.
  20628. */
  20629. static int
  20630. xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
  20631. {
  20632. const xmlChar *cur, *end;
  20633. const xmlChar *nsname = NULL, *location;
  20634. int count = 0;
  20635. int ret = 0;
  20636. xmlSchemaAttrInfoPtr iattr;
  20637. /*
  20638. * Parse the value; we will assume an even number of values
  20639. * to be given (this is how Xerces and XSV work).
  20640. *
  20641. * URGENT TODO: !! This needs to work for both
  20642. * @noNamespaceSchemaLocation AND @schemaLocation on the same
  20643. * element !!
  20644. */
  20645. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20646. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
  20647. if (iattr == NULL)
  20648. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20649. XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
  20650. if (iattr == NULL)
  20651. return (0);
  20652. cur = iattr->value;
  20653. do {
  20654. /*
  20655. * TODO: Move the string parsing mechanism away from here.
  20656. */
  20657. if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
  20658. /*
  20659. * Get the namespace name.
  20660. */
  20661. while (IS_BLANK_CH(*cur))
  20662. cur++;
  20663. end = cur;
  20664. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20665. end++;
  20666. if (end == cur)
  20667. break;
  20668. count++; /* TODO: Don't use the schema's dict. */
  20669. nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20670. cur = end;
  20671. }
  20672. /*
  20673. * Get the URI.
  20674. */
  20675. while (IS_BLANK_CH(*cur))
  20676. cur++;
  20677. end = cur;
  20678. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20679. end++;
  20680. if (end == cur) {
  20681. if (iattr->metaType ==
  20682. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
  20683. {
  20684. /*
  20685. * If using @schemaLocation then tuples are expected.
  20686. * I.e. the namespace name *and* the document's URI.
  20687. */
  20688. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20689. iattr->node, NULL,
  20690. "The value must consist of tuples: the target namespace "
  20691. "name and the document's URI", NULL, NULL, NULL);
  20692. }
  20693. break;
  20694. }
  20695. count++; /* TODO: Don't use the schema's dict. */
  20696. location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20697. cur = end;
  20698. ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
  20699. iattr->node, nsname, location);
  20700. if (ret == -1) {
  20701. VERROR_INT("xmlSchemaAssembleByXSI",
  20702. "assembling schemata");
  20703. return (-1);
  20704. }
  20705. } while (*cur != 0);
  20706. return (ret);
  20707. }
  20708. static const xmlChar *
  20709. xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
  20710. const xmlChar *prefix)
  20711. {
  20712. if (vctxt->sax != NULL) {
  20713. int i, j;
  20714. xmlSchemaNodeInfoPtr inode;
  20715. for (i = vctxt->depth; i >= 0; i--) {
  20716. if (vctxt->elemInfos[i]->nbNsBindings != 0) {
  20717. inode = vctxt->elemInfos[i];
  20718. for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
  20719. if (((prefix == NULL) &&
  20720. (inode->nsBindings[j] == NULL)) ||
  20721. ((prefix != NULL) && xmlStrEqual(prefix,
  20722. inode->nsBindings[j]))) {
  20723. /*
  20724. * Note that the namespace bindings are already
  20725. * in a string dict.
  20726. */
  20727. return (inode->nsBindings[j+1]);
  20728. }
  20729. }
  20730. }
  20731. }
  20732. return (NULL);
  20733. #ifdef LIBXML_READER_ENABLED
  20734. } else if (vctxt->reader != NULL) {
  20735. xmlChar *nsName;
  20736. nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
  20737. if (nsName != NULL) {
  20738. const xmlChar *ret;
  20739. ret = xmlDictLookup(vctxt->dict, nsName, -1);
  20740. xmlFree(nsName);
  20741. return (ret);
  20742. } else
  20743. return (NULL);
  20744. #endif
  20745. } else {
  20746. xmlNsPtr ns;
  20747. if ((vctxt->inode->node == NULL) ||
  20748. (vctxt->inode->node->doc == NULL)) {
  20749. VERROR_INT("xmlSchemaLookupNamespace",
  20750. "no node or node's doc available");
  20751. return (NULL);
  20752. }
  20753. ns = xmlSearchNs(vctxt->inode->node->doc,
  20754. vctxt->inode->node, prefix);
  20755. if (ns != NULL)
  20756. return (ns->href);
  20757. return (NULL);
  20758. }
  20759. }
  20760. /*
  20761. * This one works on the schema of the validation context.
  20762. */
  20763. static int
  20764. xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
  20765. xmlSchemaPtr schema,
  20766. xmlNodePtr node,
  20767. const xmlChar *value,
  20768. xmlSchemaValPtr *val,
  20769. int valNeeded)
  20770. {
  20771. int ret;
  20772. if (vctxt && (vctxt->schema == NULL)) {
  20773. VERROR_INT("xmlSchemaValidateNotation",
  20774. "a schema is needed on the validation context");
  20775. return (-1);
  20776. }
  20777. ret = xmlValidateQName(value, 1);
  20778. if (ret != 0)
  20779. return (ret);
  20780. {
  20781. xmlChar *localName = NULL;
  20782. xmlChar *prefix = NULL;
  20783. localName = xmlSplitQName2(value, &prefix);
  20784. if (prefix != NULL) {
  20785. const xmlChar *nsName = NULL;
  20786. if (vctxt != NULL)
  20787. nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
  20788. else if (node != NULL) {
  20789. xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
  20790. if (ns != NULL)
  20791. nsName = ns->href;
  20792. } else {
  20793. xmlFree(prefix);
  20794. xmlFree(localName);
  20795. return (1);
  20796. }
  20797. if (nsName == NULL) {
  20798. xmlFree(prefix);
  20799. xmlFree(localName);
  20800. return (1);
  20801. }
  20802. if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
  20803. if ((valNeeded) && (val != NULL)) {
  20804. (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
  20805. xmlStrdup(nsName));
  20806. if (*val == NULL)
  20807. ret = -1;
  20808. }
  20809. } else
  20810. ret = 1;
  20811. xmlFree(prefix);
  20812. xmlFree(localName);
  20813. } else {
  20814. if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
  20815. if (valNeeded && (val != NULL)) {
  20816. (*val) = xmlSchemaNewNOTATIONValue(
  20817. BAD_CAST xmlStrdup(value), NULL);
  20818. if (*val == NULL)
  20819. ret = -1;
  20820. }
  20821. } else
  20822. return (1);
  20823. }
  20824. }
  20825. return (ret);
  20826. }
  20827. static int
  20828. xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
  20829. const xmlChar* lname,
  20830. const xmlChar* nsname)
  20831. {
  20832. int i;
  20833. lname = xmlDictLookup(vctxt->dict, lname, -1);
  20834. if (lname == NULL)
  20835. return(-1);
  20836. if (nsname != NULL) {
  20837. nsname = xmlDictLookup(vctxt->dict, nsname, -1);
  20838. if (nsname == NULL)
  20839. return(-1);
  20840. }
  20841. for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
  20842. if ((vctxt->nodeQNames->items [i] == lname) &&
  20843. (vctxt->nodeQNames->items[i +1] == nsname))
  20844. /* Already there */
  20845. return(i);
  20846. }
  20847. /* Add new entry. */
  20848. i = vctxt->nodeQNames->nbItems;
  20849. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
  20850. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
  20851. return(i);
  20852. }
  20853. /************************************************************************
  20854. * *
  20855. * Validation of identity-constraints (IDC) *
  20856. * *
  20857. ************************************************************************/
  20858. /**
  20859. * xmlSchemaAugmentIDC:
  20860. * @idcDef: the IDC definition
  20861. *
  20862. * Creates an augmented IDC definition item.
  20863. *
  20864. * Returns the item, or NULL on internal errors.
  20865. */
  20866. static void
  20867. xmlSchemaAugmentIDC(void *payload, void *data,
  20868. const xmlChar *name ATTRIBUTE_UNUSED)
  20869. {
  20870. xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
  20871. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
  20872. xmlSchemaIDCAugPtr aidc;
  20873. aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
  20874. if (aidc == NULL) {
  20875. xmlSchemaVErrMemory(vctxt,
  20876. "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
  20877. NULL);
  20878. return;
  20879. }
  20880. aidc->keyrefDepth = -1;
  20881. aidc->def = idcDef;
  20882. aidc->next = NULL;
  20883. if (vctxt->aidcs == NULL)
  20884. vctxt->aidcs = aidc;
  20885. else {
  20886. aidc->next = vctxt->aidcs;
  20887. vctxt->aidcs = aidc;
  20888. }
  20889. /*
  20890. * Save if we have keyrefs at all.
  20891. */
  20892. if ((vctxt->hasKeyrefs == 0) &&
  20893. (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
  20894. vctxt->hasKeyrefs = 1;
  20895. }
  20896. /**
  20897. * xmlSchemaAugmentImportedIDC:
  20898. * @imported: the imported schema
  20899. *
  20900. * Creates an augmented IDC definition for the imported schema.
  20901. */
  20902. static void
  20903. xmlSchemaAugmentImportedIDC(void *payload, void *data,
  20904. const xmlChar *name ATTRIBUTE_UNUSED) {
  20905. xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
  20906. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
  20907. if (imported->schema->idcDef != NULL) {
  20908. xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
  20909. }
  20910. }
  20911. /**
  20912. * xmlSchemaIDCNewBinding:
  20913. * @idcDef: the IDC definition of this binding
  20914. *
  20915. * Creates a new IDC binding.
  20916. *
  20917. * Returns the new IDC binding, NULL on internal errors.
  20918. */
  20919. static xmlSchemaPSVIIDCBindingPtr
  20920. xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
  20921. {
  20922. xmlSchemaPSVIIDCBindingPtr ret;
  20923. ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
  20924. sizeof(xmlSchemaPSVIIDCBinding));
  20925. if (ret == NULL) {
  20926. xmlSchemaVErrMemory(NULL,
  20927. "allocating a PSVI IDC binding item", NULL);
  20928. return (NULL);
  20929. }
  20930. memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
  20931. ret->definition = idcDef;
  20932. return (ret);
  20933. }
  20934. /**
  20935. * xmlSchemaIDCStoreNodeTableItem:
  20936. * @vctxt: the WXS validation context
  20937. * @item: the IDC node table item
  20938. *
  20939. * The validation context is used to store IDC node table items.
  20940. * They are stored to avoid copying them if IDC node-tables are merged
  20941. * with corresponding parent IDC node-tables (bubbling).
  20942. *
  20943. * Returns 0 if succeeded, -1 on internal errors.
  20944. */
  20945. static int
  20946. xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
  20947. xmlSchemaPSVIIDCNodePtr item)
  20948. {
  20949. /*
  20950. * Add to global list.
  20951. */
  20952. if (vctxt->idcNodes == NULL) {
  20953. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20954. xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
  20955. if (vctxt->idcNodes == NULL) {
  20956. xmlSchemaVErrMemory(vctxt,
  20957. "allocating the IDC node table item list", NULL);
  20958. return (-1);
  20959. }
  20960. vctxt->sizeIdcNodes = 20;
  20961. } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
  20962. vctxt->sizeIdcNodes *= 2;
  20963. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20964. xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
  20965. sizeof(xmlSchemaPSVIIDCNodePtr));
  20966. if (vctxt->idcNodes == NULL) {
  20967. xmlSchemaVErrMemory(vctxt,
  20968. "re-allocating the IDC node table item list", NULL);
  20969. return (-1);
  20970. }
  20971. }
  20972. vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
  20973. return (0);
  20974. }
  20975. /**
  20976. * xmlSchemaIDCStoreKey:
  20977. * @vctxt: the WXS validation context
  20978. * @item: the IDC key
  20979. *
  20980. * The validation context is used to store an IDC key.
  20981. *
  20982. * Returns 0 if succeeded, -1 on internal errors.
  20983. */
  20984. static int
  20985. xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
  20986. xmlSchemaPSVIIDCKeyPtr key)
  20987. {
  20988. /*
  20989. * Add to global list.
  20990. */
  20991. if (vctxt->idcKeys == NULL) {
  20992. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  20993. xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
  20994. if (vctxt->idcKeys == NULL) {
  20995. xmlSchemaVErrMemory(vctxt,
  20996. "allocating the IDC key storage list", NULL);
  20997. return (-1);
  20998. }
  20999. vctxt->sizeIdcKeys = 40;
  21000. } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
  21001. vctxt->sizeIdcKeys *= 2;
  21002. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  21003. xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
  21004. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21005. if (vctxt->idcKeys == NULL) {
  21006. xmlSchemaVErrMemory(vctxt,
  21007. "re-allocating the IDC key storage list", NULL);
  21008. return (-1);
  21009. }
  21010. }
  21011. vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
  21012. return (0);
  21013. }
  21014. /**
  21015. * xmlSchemaIDCAppendNodeTableItem:
  21016. * @bind: the IDC binding
  21017. * @ntItem: the node-table item
  21018. *
  21019. * Appends the IDC node-table item to the binding.
  21020. *
  21021. * Returns 0 on success and -1 on internal errors.
  21022. */
  21023. static int
  21024. xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
  21025. xmlSchemaPSVIIDCNodePtr ntItem)
  21026. {
  21027. if (bind->nodeTable == NULL) {
  21028. bind->sizeNodes = 10;
  21029. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  21030. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  21031. if (bind->nodeTable == NULL) {
  21032. xmlSchemaVErrMemory(NULL,
  21033. "allocating an array of IDC node-table items", NULL);
  21034. return(-1);
  21035. }
  21036. } else if (bind->sizeNodes <= bind->nbNodes) {
  21037. bind->sizeNodes *= 2;
  21038. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  21039. xmlRealloc(bind->nodeTable, bind->sizeNodes *
  21040. sizeof(xmlSchemaPSVIIDCNodePtr));
  21041. if (bind->nodeTable == NULL) {
  21042. xmlSchemaVErrMemory(NULL,
  21043. "re-allocating an array of IDC node-table items", NULL);
  21044. return(-1);
  21045. }
  21046. }
  21047. bind->nodeTable[bind->nbNodes++] = ntItem;
  21048. return(0);
  21049. }
  21050. /**
  21051. * xmlSchemaIDCAcquireBinding:
  21052. * @vctxt: the WXS validation context
  21053. * @matcher: the IDC matcher
  21054. *
  21055. * Looks up an PSVI IDC binding, for the IDC definition and
  21056. * of the given matcher. If none found, a new one is created
  21057. * and added to the IDC table.
  21058. *
  21059. * Returns an IDC binding or NULL on internal errors.
  21060. */
  21061. static xmlSchemaPSVIIDCBindingPtr
  21062. xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
  21063. xmlSchemaIDCMatcherPtr matcher)
  21064. {
  21065. xmlSchemaNodeInfoPtr ielem;
  21066. ielem = vctxt->elemInfos[matcher->depth];
  21067. if (ielem->idcTable == NULL) {
  21068. ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
  21069. if (ielem->idcTable == NULL)
  21070. return (NULL);
  21071. return(ielem->idcTable);
  21072. } else {
  21073. xmlSchemaPSVIIDCBindingPtr bind = NULL;
  21074. bind = ielem->idcTable;
  21075. do {
  21076. if (bind->definition == matcher->aidc->def)
  21077. return(bind);
  21078. if (bind->next == NULL) {
  21079. bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
  21080. if (bind->next == NULL)
  21081. return (NULL);
  21082. return(bind->next);
  21083. }
  21084. bind = bind->next;
  21085. } while (bind != NULL);
  21086. }
  21087. return (NULL);
  21088. }
  21089. static xmlSchemaItemListPtr
  21090. xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
  21091. xmlSchemaIDCMatcherPtr matcher)
  21092. {
  21093. if (matcher->targets == NULL)
  21094. matcher->targets = xmlSchemaItemListCreate();
  21095. return(matcher->targets);
  21096. }
  21097. /**
  21098. * xmlSchemaIDCFreeKey:
  21099. * @key: the IDC key
  21100. *
  21101. * Frees an IDC key together with its compiled value.
  21102. */
  21103. static void
  21104. xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
  21105. {
  21106. if (key->val != NULL)
  21107. xmlSchemaFreeValue(key->val);
  21108. xmlFree(key);
  21109. }
  21110. /**
  21111. * xmlSchemaIDCFreeBinding:
  21112. *
  21113. * Frees an IDC binding. Note that the node table-items
  21114. * are not freed.
  21115. */
  21116. static void
  21117. xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
  21118. {
  21119. if (bind->nodeTable != NULL)
  21120. xmlFree(bind->nodeTable);
  21121. if (bind->dupls != NULL)
  21122. xmlSchemaItemListFree(bind->dupls);
  21123. xmlFree(bind);
  21124. }
  21125. /**
  21126. * xmlSchemaIDCFreeIDCTable:
  21127. * @bind: the first IDC binding in the list
  21128. *
  21129. * Frees an IDC table, i.e. all the IDC bindings in the list.
  21130. */
  21131. static void
  21132. xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
  21133. {
  21134. xmlSchemaPSVIIDCBindingPtr prev;
  21135. while (bind != NULL) {
  21136. prev = bind;
  21137. bind = bind->next;
  21138. xmlSchemaIDCFreeBinding(prev);
  21139. }
  21140. }
  21141. static void
  21142. xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
  21143. {
  21144. xmlIDCHashEntryPtr e = payload, n;
  21145. while (e) {
  21146. n = e->next;
  21147. xmlFree(e);
  21148. e = n;
  21149. }
  21150. }
  21151. /**
  21152. * xmlSchemaIDCFreeMatcherList:
  21153. * @matcher: the first IDC matcher in the list
  21154. *
  21155. * Frees a list of IDC matchers.
  21156. */
  21157. static void
  21158. xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
  21159. {
  21160. xmlSchemaIDCMatcherPtr next;
  21161. while (matcher != NULL) {
  21162. next = matcher->next;
  21163. if (matcher->keySeqs != NULL) {
  21164. int i;
  21165. for (i = 0; i < matcher->sizeKeySeqs; i++)
  21166. if (matcher->keySeqs[i] != NULL)
  21167. xmlFree(matcher->keySeqs[i]);
  21168. xmlFree(matcher->keySeqs);
  21169. }
  21170. if (matcher->targets != NULL) {
  21171. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21172. int i;
  21173. xmlSchemaPSVIIDCNodePtr idcNode;
  21174. /*
  21175. * Node-table items for keyrefs are not stored globally
  21176. * to the validation context, since they are not bubbled.
  21177. * We need to free them here.
  21178. */
  21179. for (i = 0; i < matcher->targets->nbItems; i++) {
  21180. idcNode =
  21181. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21182. xmlFree(idcNode->keys);
  21183. xmlFree(idcNode);
  21184. }
  21185. }
  21186. xmlSchemaItemListFree(matcher->targets);
  21187. }
  21188. if (matcher->htab != NULL)
  21189. xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
  21190. xmlFree(matcher);
  21191. matcher = next;
  21192. }
  21193. }
  21194. /**
  21195. * xmlSchemaIDCReleaseMatcherList:
  21196. * @vctxt: the WXS validation context
  21197. * @matcher: the first IDC matcher in the list
  21198. *
  21199. * Caches a list of IDC matchers for reuse.
  21200. */
  21201. static void
  21202. xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
  21203. xmlSchemaIDCMatcherPtr matcher)
  21204. {
  21205. xmlSchemaIDCMatcherPtr next;
  21206. while (matcher != NULL) {
  21207. next = matcher->next;
  21208. if (matcher->keySeqs != NULL) {
  21209. int i;
  21210. /*
  21211. * Don't free the array, but only the content.
  21212. */
  21213. for (i = 0; i < matcher->sizeKeySeqs; i++)
  21214. if (matcher->keySeqs[i] != NULL) {
  21215. xmlFree(matcher->keySeqs[i]);
  21216. matcher->keySeqs[i] = NULL;
  21217. }
  21218. }
  21219. if (matcher->targets) {
  21220. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21221. int i;
  21222. xmlSchemaPSVIIDCNodePtr idcNode;
  21223. /*
  21224. * Node-table items for keyrefs are not stored globally
  21225. * to the validation context, since they are not bubbled.
  21226. * We need to free them here.
  21227. */
  21228. for (i = 0; i < matcher->targets->nbItems; i++) {
  21229. idcNode =
  21230. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21231. xmlFree(idcNode->keys);
  21232. xmlFree(idcNode);
  21233. }
  21234. }
  21235. xmlSchemaItemListFree(matcher->targets);
  21236. matcher->targets = NULL;
  21237. }
  21238. if (matcher->htab != NULL) {
  21239. xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
  21240. matcher->htab = NULL;
  21241. }
  21242. matcher->next = NULL;
  21243. /*
  21244. * Cache the matcher.
  21245. */
  21246. if (vctxt->idcMatcherCache != NULL)
  21247. matcher->nextCached = vctxt->idcMatcherCache;
  21248. vctxt->idcMatcherCache = matcher;
  21249. matcher = next;
  21250. }
  21251. }
  21252. /**
  21253. * xmlSchemaIDCAddStateObject:
  21254. * @vctxt: the WXS validation context
  21255. * @matcher: the IDC matcher
  21256. * @sel: the XPath information
  21257. * @parent: the parent "selector" state object if any
  21258. * @type: "selector" or "field"
  21259. *
  21260. * Creates/reuses and activates state objects for the given
  21261. * XPath information; if the XPath expression consists of unions,
  21262. * multiple state objects are created for every unioned expression.
  21263. *
  21264. * Returns 0 on success and -1 on internal errors.
  21265. */
  21266. static int
  21267. xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
  21268. xmlSchemaIDCMatcherPtr matcher,
  21269. xmlSchemaIDCSelectPtr sel,
  21270. int type)
  21271. {
  21272. xmlSchemaIDCStateObjPtr sto;
  21273. /*
  21274. * Reuse the state objects from the pool.
  21275. */
  21276. if (vctxt->xpathStatePool != NULL) {
  21277. sto = vctxt->xpathStatePool;
  21278. vctxt->xpathStatePool = sto->next;
  21279. sto->next = NULL;
  21280. } else {
  21281. /*
  21282. * Create a new state object.
  21283. */
  21284. sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
  21285. if (sto == NULL) {
  21286. xmlSchemaVErrMemory(NULL,
  21287. "allocating an IDC state object", NULL);
  21288. return (-1);
  21289. }
  21290. memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
  21291. }
  21292. /*
  21293. * Add to global list.
  21294. */
  21295. if (vctxt->xpathStates != NULL)
  21296. sto->next = vctxt->xpathStates;
  21297. vctxt->xpathStates = sto;
  21298. /*
  21299. * Free the old xpath validation context.
  21300. */
  21301. if (sto->xpathCtxt != NULL)
  21302. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  21303. /*
  21304. * Create a new XPath (pattern) validation context.
  21305. */
  21306. sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
  21307. (xmlPatternPtr) sel->xpathComp);
  21308. if (sto->xpathCtxt == NULL) {
  21309. VERROR_INT("xmlSchemaIDCAddStateObject",
  21310. "failed to create an XPath validation context");
  21311. return (-1);
  21312. }
  21313. sto->type = type;
  21314. sto->depth = vctxt->depth;
  21315. sto->matcher = matcher;
  21316. sto->sel = sel;
  21317. sto->nbHistory = 0;
  21318. #ifdef DEBUG_IDC
  21319. xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n",
  21320. sto->sel->xpath);
  21321. #endif
  21322. return (0);
  21323. }
  21324. /**
  21325. * xmlSchemaXPathEvaluate:
  21326. * @vctxt: the WXS validation context
  21327. * @nodeType: the nodeType of the current node
  21328. *
  21329. * Evaluates all active XPath state objects.
  21330. *
  21331. * Returns the number of IC "field" state objects which resolved to
  21332. * this node, 0 if none resolved and -1 on internal errors.
  21333. */
  21334. static int
  21335. xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
  21336. xmlElementType nodeType)
  21337. {
  21338. xmlSchemaIDCStateObjPtr sto, head = NULL, first;
  21339. int res, resolved = 0, depth = vctxt->depth;
  21340. if (vctxt->xpathStates == NULL)
  21341. return (0);
  21342. if (nodeType == XML_ATTRIBUTE_NODE)
  21343. depth++;
  21344. #ifdef DEBUG_IDC
  21345. {
  21346. xmlChar *str = NULL;
  21347. xmlGenericError(xmlGenericErrorContext,
  21348. "IDC: EVAL on %s, depth %d, type %d\n",
  21349. xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21350. vctxt->inode->localName), depth, nodeType);
  21351. FREE_AND_NULL(str)
  21352. }
  21353. #endif
  21354. /*
  21355. * Process all active XPath state objects.
  21356. */
  21357. first = vctxt->xpathStates;
  21358. sto = first;
  21359. while (sto != head) {
  21360. #ifdef DEBUG_IDC
  21361. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
  21362. xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n",
  21363. sto->matcher->aidc->def->name, sto->sel->xpath);
  21364. else
  21365. xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
  21366. sto->matcher->aidc->def->name, sto->sel->xpath);
  21367. #endif
  21368. if (nodeType == XML_ELEMENT_NODE)
  21369. res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
  21370. vctxt->inode->localName, vctxt->inode->nsName);
  21371. else
  21372. res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
  21373. vctxt->inode->localName, vctxt->inode->nsName);
  21374. if (res == -1) {
  21375. VERROR_INT("xmlSchemaXPathEvaluate",
  21376. "calling xmlStreamPush()");
  21377. return (-1);
  21378. }
  21379. if (res == 0)
  21380. goto next_sto;
  21381. /*
  21382. * Full match.
  21383. */
  21384. #ifdef DEBUG_IDC
  21385. xmlGenericError(xmlGenericErrorContext, "IDC: "
  21386. "MATCH\n");
  21387. #endif
  21388. /*
  21389. * Register a match in the state object history.
  21390. */
  21391. if (sto->history == NULL) {
  21392. sto->history = (int *) xmlMalloc(5 * sizeof(int));
  21393. if (sto->history == NULL) {
  21394. xmlSchemaVErrMemory(NULL,
  21395. "allocating the state object history", NULL);
  21396. return(-1);
  21397. }
  21398. sto->sizeHistory = 5;
  21399. } else if (sto->sizeHistory <= sto->nbHistory) {
  21400. sto->sizeHistory *= 2;
  21401. sto->history = (int *) xmlRealloc(sto->history,
  21402. sto->sizeHistory * sizeof(int));
  21403. if (sto->history == NULL) {
  21404. xmlSchemaVErrMemory(NULL,
  21405. "re-allocating the state object history", NULL);
  21406. return(-1);
  21407. }
  21408. }
  21409. sto->history[sto->nbHistory++] = depth;
  21410. #ifdef DEBUG_IDC
  21411. xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n",
  21412. vctxt->depth);
  21413. #endif
  21414. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21415. xmlSchemaIDCSelectPtr sel;
  21416. /*
  21417. * Activate state objects for the IDC fields of
  21418. * the IDC selector.
  21419. */
  21420. #ifdef DEBUG_IDC
  21421. xmlGenericError(xmlGenericErrorContext, "IDC: "
  21422. "activating field states\n");
  21423. #endif
  21424. sel = sto->matcher->aidc->def->fields;
  21425. while (sel != NULL) {
  21426. if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
  21427. sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
  21428. return (-1);
  21429. sel = sel->next;
  21430. }
  21431. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21432. /*
  21433. * An IDC key node was found by the IDC field.
  21434. */
  21435. #ifdef DEBUG_IDC
  21436. xmlGenericError(xmlGenericErrorContext,
  21437. "IDC: key found\n");
  21438. #endif
  21439. /*
  21440. * Notify that the character value of this node is
  21441. * needed.
  21442. */
  21443. if (resolved == 0) {
  21444. if ((vctxt->inode->flags &
  21445. XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
  21446. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  21447. }
  21448. resolved++;
  21449. }
  21450. next_sto:
  21451. if (sto->next == NULL) {
  21452. /*
  21453. * Evaluate field state objects created on this node as well.
  21454. */
  21455. head = first;
  21456. sto = vctxt->xpathStates;
  21457. } else
  21458. sto = sto->next;
  21459. }
  21460. return (resolved);
  21461. }
  21462. static const xmlChar *
  21463. xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
  21464. xmlChar **buf,
  21465. xmlSchemaPSVIIDCKeyPtr *seq,
  21466. int count, int for_hash)
  21467. {
  21468. int i, res;
  21469. xmlChar *value = NULL;
  21470. *buf = xmlStrdup(BAD_CAST "[");
  21471. for (i = 0; i < count; i++) {
  21472. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21473. if (!for_hash)
  21474. res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
  21475. xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
  21476. &value);
  21477. else {
  21478. res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
  21479. }
  21480. if (res == 0)
  21481. *buf = xmlStrcat(*buf, BAD_CAST value);
  21482. else {
  21483. VERROR_INT("xmlSchemaFormatIDCKeySequence",
  21484. "failed to compute a canonical value");
  21485. *buf = xmlStrcat(*buf, BAD_CAST "???");
  21486. }
  21487. if (i < count -1)
  21488. *buf = xmlStrcat(*buf, BAD_CAST "', ");
  21489. else
  21490. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21491. if (value != NULL) {
  21492. xmlFree(value);
  21493. value = NULL;
  21494. }
  21495. }
  21496. *buf = xmlStrcat(*buf, BAD_CAST "]");
  21497. return (BAD_CAST *buf);
  21498. }
  21499. static const xmlChar *
  21500. xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
  21501. xmlChar **buf,
  21502. xmlSchemaPSVIIDCKeyPtr *seq,
  21503. int count)
  21504. {
  21505. return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
  21506. }
  21507. static const xmlChar *
  21508. xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
  21509. xmlChar **buf,
  21510. xmlSchemaPSVIIDCKeyPtr *seq,
  21511. int count)
  21512. {
  21513. return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
  21514. }
  21515. /**
  21516. * xmlSchemaXPathPop:
  21517. * @vctxt: the WXS validation context
  21518. *
  21519. * Pops all XPath states.
  21520. *
  21521. * Returns 0 on success and -1 on internal errors.
  21522. */
  21523. static int
  21524. xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
  21525. {
  21526. xmlSchemaIDCStateObjPtr sto;
  21527. int res;
  21528. if (vctxt->xpathStates == NULL)
  21529. return(0);
  21530. sto = vctxt->xpathStates;
  21531. do {
  21532. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21533. if (res == -1)
  21534. return (-1);
  21535. sto = sto->next;
  21536. } while (sto != NULL);
  21537. return(0);
  21538. }
  21539. /**
  21540. * xmlSchemaXPathProcessHistory:
  21541. * @vctxt: the WXS validation context
  21542. * @type: the simple/complex type of the current node if any at all
  21543. * @val: the precompiled value
  21544. *
  21545. * Processes and pops the history items of the IDC state objects.
  21546. * IDC key-sequences are validated/created on IDC bindings.
  21547. *
  21548. * Returns 0 on success and -1 on internal errors.
  21549. */
  21550. static int
  21551. xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
  21552. int depth)
  21553. {
  21554. xmlSchemaIDCStateObjPtr sto, nextsto;
  21555. int res, matchDepth;
  21556. xmlSchemaPSVIIDCKeyPtr key = NULL;
  21557. xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
  21558. if (vctxt->xpathStates == NULL)
  21559. return (0);
  21560. sto = vctxt->xpathStates;
  21561. #ifdef DEBUG_IDC
  21562. {
  21563. xmlChar *str = NULL;
  21564. xmlGenericError(xmlGenericErrorContext,
  21565. "IDC: BACK on %s, depth %d\n",
  21566. xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21567. vctxt->inode->localName), vctxt->depth);
  21568. FREE_AND_NULL(str)
  21569. }
  21570. #endif
  21571. /*
  21572. * Evaluate the state objects.
  21573. */
  21574. while (sto != NULL) {
  21575. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21576. if (res == -1) {
  21577. VERROR_INT("xmlSchemaXPathProcessHistory",
  21578. "calling xmlStreamPop()");
  21579. return (-1);
  21580. }
  21581. #ifdef DEBUG_IDC
  21582. xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
  21583. sto->sel->xpath);
  21584. #endif
  21585. if (sto->nbHistory == 0)
  21586. goto deregister_check;
  21587. matchDepth = sto->history[sto->nbHistory -1];
  21588. /*
  21589. * Only matches at the current depth are of interest.
  21590. */
  21591. if (matchDepth != depth) {
  21592. sto = sto->next;
  21593. continue;
  21594. }
  21595. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21596. /*
  21597. * NOTE: According to
  21598. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
  21599. * ... the simple-content of complex types is also allowed.
  21600. */
  21601. if (WXS_IS_COMPLEX(type)) {
  21602. if (WXS_HAS_SIMPLE_CONTENT(type)) {
  21603. /*
  21604. * Sanity check for complex types with simple content.
  21605. */
  21606. simpleType = type->contentTypeDef;
  21607. if (simpleType == NULL) {
  21608. VERROR_INT("xmlSchemaXPathProcessHistory",
  21609. "field resolves to a CT with simple content "
  21610. "but the CT is missing the ST definition");
  21611. return (-1);
  21612. }
  21613. } else
  21614. simpleType = NULL;
  21615. } else
  21616. simpleType = type;
  21617. if (simpleType == NULL) {
  21618. xmlChar *str = NULL;
  21619. /*
  21620. * Not qualified if the field resolves to a node of non
  21621. * simple type.
  21622. */
  21623. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21624. XML_SCHEMAV_CVC_IDC, NULL,
  21625. WXS_BASIC_CAST sto->matcher->aidc->def,
  21626. "The XPath '%s' of a field of %s does evaluate to a node of "
  21627. "non-simple type",
  21628. sto->sel->xpath,
  21629. xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
  21630. FREE_AND_NULL(str);
  21631. sto->nbHistory--;
  21632. goto deregister_check;
  21633. }
  21634. if ((key == NULL) && (vctxt->inode->val == NULL)) {
  21635. /*
  21636. * Failed to provide the normalized value; maybe
  21637. * the value was invalid.
  21638. */
  21639. VERROR(XML_SCHEMAV_CVC_IDC,
  21640. WXS_BASIC_CAST sto->matcher->aidc->def,
  21641. "Warning: No precomputed value available, the value "
  21642. "was either invalid or something strange happened");
  21643. sto->nbHistory--;
  21644. goto deregister_check;
  21645. } else {
  21646. xmlSchemaIDCMatcherPtr matcher = sto->matcher;
  21647. xmlSchemaPSVIIDCKeyPtr *keySeq;
  21648. int pos, idx;
  21649. /*
  21650. * The key will be anchored on the matcher's list of
  21651. * key-sequences. The position in this list is determined
  21652. * by the target node's depth relative to the matcher's
  21653. * depth of creation (i.e. the depth of the scope element).
  21654. *
  21655. * Element Depth Pos List-entries
  21656. * <scope> 0 NULL
  21657. * <bar> 1 NULL
  21658. * <target/> 2 2 target
  21659. * <bar>
  21660. * </scope>
  21661. *
  21662. * The size of the list is only dependent on the depth of
  21663. * the tree.
  21664. * An entry will be NULLed in selector_leave, i.e. when
  21665. * we hit the target's
  21666. */
  21667. pos = sto->depth - matcher->depth;
  21668. idx = sto->sel->index;
  21669. /*
  21670. * Create/grow the array of key-sequences.
  21671. */
  21672. if (matcher->keySeqs == NULL) {
  21673. if (pos > 9)
  21674. matcher->sizeKeySeqs = pos * 2;
  21675. else
  21676. matcher->sizeKeySeqs = 10;
  21677. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21678. xmlMalloc(matcher->sizeKeySeqs *
  21679. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21680. if (matcher->keySeqs == NULL) {
  21681. xmlSchemaVErrMemory(NULL,
  21682. "allocating an array of key-sequences",
  21683. NULL);
  21684. return(-1);
  21685. }
  21686. memset(matcher->keySeqs, 0,
  21687. matcher->sizeKeySeqs *
  21688. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21689. } else if (pos >= matcher->sizeKeySeqs) {
  21690. int i = matcher->sizeKeySeqs;
  21691. matcher->sizeKeySeqs *= 2;
  21692. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21693. xmlRealloc(matcher->keySeqs,
  21694. matcher->sizeKeySeqs *
  21695. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21696. if (matcher->keySeqs == NULL) {
  21697. xmlSchemaVErrMemory(NULL,
  21698. "reallocating an array of key-sequences",
  21699. NULL);
  21700. return (-1);
  21701. }
  21702. /*
  21703. * The array needs to be NULLed.
  21704. * TODO: Use memset?
  21705. */
  21706. for (; i < matcher->sizeKeySeqs; i++)
  21707. matcher->keySeqs[i] = NULL;
  21708. }
  21709. /*
  21710. * Get/create the key-sequence.
  21711. */
  21712. keySeq = matcher->keySeqs[pos];
  21713. if (keySeq == NULL) {
  21714. goto create_sequence;
  21715. } else if (keySeq[idx] != NULL) {
  21716. xmlChar *str = NULL;
  21717. /*
  21718. * cvc-identity-constraint:
  21719. * 3 For each node in the `target node set` all
  21720. * of the {fields}, with that node as the context
  21721. * node, evaluate to either an empty node-set or
  21722. * a node-set with exactly one member, which must
  21723. * have a simple type.
  21724. *
  21725. * The key was already set; report an error.
  21726. */
  21727. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21728. XML_SCHEMAV_CVC_IDC, NULL,
  21729. WXS_BASIC_CAST matcher->aidc->def,
  21730. "The XPath '%s' of a field of %s evaluates to a "
  21731. "node-set with more than one member",
  21732. sto->sel->xpath,
  21733. xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
  21734. FREE_AND_NULL(str);
  21735. sto->nbHistory--;
  21736. goto deregister_check;
  21737. } else
  21738. goto create_key;
  21739. create_sequence:
  21740. /*
  21741. * Create a key-sequence.
  21742. */
  21743. keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
  21744. matcher->aidc->def->nbFields *
  21745. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21746. if (keySeq == NULL) {
  21747. xmlSchemaVErrMemory(NULL,
  21748. "allocating an IDC key-sequence", NULL);
  21749. return(-1);
  21750. }
  21751. memset(keySeq, 0, matcher->aidc->def->nbFields *
  21752. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21753. matcher->keySeqs[pos] = keySeq;
  21754. create_key:
  21755. /*
  21756. * Create a key once per node only.
  21757. */
  21758. if (key == NULL) {
  21759. key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
  21760. sizeof(xmlSchemaPSVIIDCKey));
  21761. if (key == NULL) {
  21762. xmlSchemaVErrMemory(NULL,
  21763. "allocating a IDC key", NULL);
  21764. xmlFree(keySeq);
  21765. matcher->keySeqs[pos] = NULL;
  21766. return(-1);
  21767. }
  21768. /*
  21769. * Consume the compiled value.
  21770. */
  21771. key->type = simpleType;
  21772. key->val = vctxt->inode->val;
  21773. vctxt->inode->val = NULL;
  21774. /*
  21775. * Store the key in a global list.
  21776. */
  21777. if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
  21778. xmlSchemaIDCFreeKey(key);
  21779. return (-1);
  21780. }
  21781. }
  21782. keySeq[idx] = key;
  21783. }
  21784. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21785. xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
  21786. /* xmlSchemaPSVIIDCBindingPtr bind; */
  21787. xmlSchemaPSVIIDCNodePtr ntItem;
  21788. xmlSchemaIDCMatcherPtr matcher;
  21789. xmlSchemaIDCPtr idc;
  21790. xmlSchemaItemListPtr targets;
  21791. int pos, i, j, nbKeys;
  21792. /*
  21793. * Here we have the following scenario:
  21794. * An IDC 'selector' state object resolved to a target node,
  21795. * during the time this target node was in the
  21796. * ancestor-or-self axis, the 'field' state object(s) looked
  21797. * out for matching nodes to create a key-sequence for this
  21798. * target node. Now we are back to this target node and need
  21799. * to put the key-sequence, together with the target node
  21800. * itself, into the node-table of the corresponding IDC
  21801. * binding.
  21802. */
  21803. matcher = sto->matcher;
  21804. idc = matcher->aidc->def;
  21805. nbKeys = idc->nbFields;
  21806. pos = depth - matcher->depth;
  21807. /*
  21808. * Check if the matcher has any key-sequences at all, plus
  21809. * if it has a key-sequence for the current target node.
  21810. */
  21811. if ((matcher->keySeqs == NULL) ||
  21812. (matcher->sizeKeySeqs <= pos)) {
  21813. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21814. goto selector_key_error;
  21815. else
  21816. goto selector_leave;
  21817. }
  21818. keySeq = &(matcher->keySeqs[pos]);
  21819. if (*keySeq == NULL) {
  21820. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21821. goto selector_key_error;
  21822. else
  21823. goto selector_leave;
  21824. }
  21825. for (i = 0; i < nbKeys; i++) {
  21826. if ((*keySeq)[i] == NULL) {
  21827. /*
  21828. * Not qualified, if not all fields did resolve.
  21829. */
  21830. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
  21831. /*
  21832. * All fields of a "key" IDC must resolve.
  21833. */
  21834. goto selector_key_error;
  21835. }
  21836. goto selector_leave;
  21837. }
  21838. }
  21839. /*
  21840. * All fields did resolve.
  21841. */
  21842. /*
  21843. * 4.1 If the {identity-constraint category} is unique(/key),
  21844. * then no two members of the `qualified node set` have
  21845. * `key-sequences` whose members are pairwise equal, as
  21846. * defined by Equal in [XML Schemas: Datatypes].
  21847. *
  21848. * Get the IDC binding from the matcher and check for
  21849. * duplicate key-sequences.
  21850. */
  21851. #if 0
  21852. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  21853. #endif
  21854. targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
  21855. if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
  21856. (targets->nbItems != 0)) {
  21857. xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
  21858. xmlIDCHashEntryPtr e;
  21859. res = 0;
  21860. if (!matcher->htab)
  21861. e = NULL;
  21862. else {
  21863. xmlChar *value = NULL;
  21864. xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
  21865. e = xmlHashLookup(matcher->htab, value);
  21866. FREE_AND_NULL(value);
  21867. }
  21868. /*
  21869. * Compare the key-sequences, key by key.
  21870. */
  21871. for (;e; e = e->next) {
  21872. bkeySeq =
  21873. ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
  21874. for (j = 0; j < nbKeys; j++) {
  21875. ckey = (*keySeq)[j];
  21876. bkey = bkeySeq[j];
  21877. res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
  21878. if (res == -1) {
  21879. return (-1);
  21880. } else if (res == 0) {
  21881. /*
  21882. * One of the keys differs, so the key-sequence
  21883. * won't be equal; get out.
  21884. */
  21885. break;
  21886. }
  21887. }
  21888. if (res == 1) {
  21889. /*
  21890. * Duplicate key-sequence found.
  21891. */
  21892. break;
  21893. }
  21894. }
  21895. if (e) {
  21896. xmlChar *str = NULL, *strB = NULL;
  21897. /*
  21898. * TODO: Try to report the key-sequence.
  21899. */
  21900. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21901. XML_SCHEMAV_CVC_IDC, NULL,
  21902. WXS_BASIC_CAST idc,
  21903. "Duplicate key-sequence %s in %s",
  21904. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  21905. (*keySeq), nbKeys),
  21906. xmlSchemaGetIDCDesignation(&strB, idc));
  21907. FREE_AND_NULL(str);
  21908. FREE_AND_NULL(strB);
  21909. goto selector_leave;
  21910. }
  21911. }
  21912. /*
  21913. * Add a node-table item to the IDC binding.
  21914. */
  21915. ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
  21916. sizeof(xmlSchemaPSVIIDCNode));
  21917. if (ntItem == NULL) {
  21918. xmlSchemaVErrMemory(NULL,
  21919. "allocating an IDC node-table item", NULL);
  21920. xmlFree(*keySeq);
  21921. *keySeq = NULL;
  21922. return(-1);
  21923. }
  21924. memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
  21925. /*
  21926. * Store the node-table item in a global list.
  21927. */
  21928. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
  21929. if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
  21930. xmlFree(ntItem);
  21931. xmlFree(*keySeq);
  21932. *keySeq = NULL;
  21933. return (-1);
  21934. }
  21935. ntItem->nodeQNameID = -1;
  21936. } else {
  21937. /*
  21938. * Save a cached QName for this node on the IDC node, to be
  21939. * able to report it, even if the node is not saved.
  21940. */
  21941. ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
  21942. vctxt->inode->localName, vctxt->inode->nsName);
  21943. if (ntItem->nodeQNameID == -1) {
  21944. xmlFree(ntItem);
  21945. xmlFree(*keySeq);
  21946. *keySeq = NULL;
  21947. return (-1);
  21948. }
  21949. }
  21950. /*
  21951. * Init the node-table item: Save the node, position and
  21952. * consume the key-sequence.
  21953. */
  21954. ntItem->node = vctxt->node;
  21955. ntItem->nodeLine = vctxt->inode->nodeLine;
  21956. ntItem->keys = *keySeq;
  21957. *keySeq = NULL;
  21958. #if 0
  21959. if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
  21960. #endif
  21961. if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
  21962. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21963. /*
  21964. * Free the item, since keyref items won't be
  21965. * put on a global list.
  21966. */
  21967. xmlFree(ntItem->keys);
  21968. xmlFree(ntItem);
  21969. }
  21970. return (-1);
  21971. }
  21972. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
  21973. xmlChar *value = NULL;
  21974. xmlIDCHashEntryPtr r, e;
  21975. if (!matcher->htab)
  21976. matcher->htab = xmlHashCreate(4);
  21977. xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
  21978. e = xmlMalloc(sizeof *e);
  21979. e->index = targets->nbItems - 1;
  21980. r = xmlHashLookup(matcher->htab, value);
  21981. if (r) {
  21982. e->next = r->next;
  21983. r->next = e;
  21984. } else {
  21985. e->next = NULL;
  21986. xmlHashAddEntry(matcher->htab, value, e);
  21987. }
  21988. FREE_AND_NULL(value);
  21989. }
  21990. goto selector_leave;
  21991. selector_key_error:
  21992. {
  21993. xmlChar *str = NULL;
  21994. /*
  21995. * 4.2.1 (KEY) The `target node set` and the
  21996. * `qualified node set` are equal, that is, every
  21997. * member of the `target node set` is also a member
  21998. * of the `qualified node set` and vice versa.
  21999. */
  22000. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  22001. XML_SCHEMAV_CVC_IDC, NULL,
  22002. WXS_BASIC_CAST idc,
  22003. "Not all fields of %s evaluate to a node",
  22004. xmlSchemaGetIDCDesignation(&str, idc), NULL);
  22005. FREE_AND_NULL(str);
  22006. }
  22007. selector_leave:
  22008. /*
  22009. * Free the key-sequence if not added to the IDC table.
  22010. */
  22011. if ((keySeq != NULL) && (*keySeq != NULL)) {
  22012. xmlFree(*keySeq);
  22013. *keySeq = NULL;
  22014. }
  22015. } /* if selector */
  22016. sto->nbHistory--;
  22017. deregister_check:
  22018. /*
  22019. * Deregister state objects if they reach the depth of creation.
  22020. */
  22021. if ((sto->nbHistory == 0) && (sto->depth == depth)) {
  22022. #ifdef DEBUG_IDC
  22023. xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n",
  22024. sto->sel->xpath);
  22025. #endif
  22026. if (vctxt->xpathStates != sto) {
  22027. VERROR_INT("xmlSchemaXPathProcessHistory",
  22028. "The state object to be removed is not the first "
  22029. "in the list");
  22030. }
  22031. nextsto = sto->next;
  22032. /*
  22033. * Unlink from the list of active XPath state objects.
  22034. */
  22035. vctxt->xpathStates = sto->next;
  22036. sto->next = vctxt->xpathStatePool;
  22037. /*
  22038. * Link it to the pool of reusable state objects.
  22039. */
  22040. vctxt->xpathStatePool = sto;
  22041. sto = nextsto;
  22042. } else
  22043. sto = sto->next;
  22044. } /* while (sto != NULL) */
  22045. return (0);
  22046. }
  22047. /**
  22048. * xmlSchemaIDCRegisterMatchers:
  22049. * @vctxt: the WXS validation context
  22050. * @elemDecl: the element declaration
  22051. *
  22052. * Creates helper objects to evaluate IDC selectors/fields
  22053. * successively.
  22054. *
  22055. * Returns 0 if OK and -1 on internal errors.
  22056. */
  22057. static int
  22058. xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
  22059. xmlSchemaElementPtr elemDecl)
  22060. {
  22061. xmlSchemaIDCMatcherPtr matcher, last = NULL;
  22062. xmlSchemaIDCPtr idc, refIdc;
  22063. xmlSchemaIDCAugPtr aidc;
  22064. idc = (xmlSchemaIDCPtr) elemDecl->idcs;
  22065. if (idc == NULL)
  22066. return (0);
  22067. #ifdef DEBUG_IDC
  22068. {
  22069. xmlChar *str = NULL;
  22070. xmlGenericError(xmlGenericErrorContext,
  22071. "IDC: REGISTER on %s, depth %d\n",
  22072. (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  22073. vctxt->inode->localName), vctxt->depth);
  22074. FREE_AND_NULL(str)
  22075. }
  22076. #endif
  22077. if (vctxt->inode->idcMatchers != NULL) {
  22078. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  22079. "The chain of IDC matchers is expected to be empty");
  22080. return (-1);
  22081. }
  22082. do {
  22083. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  22084. /*
  22085. * Since IDCs bubbles are expensive we need to know the
  22086. * depth at which the bubbles should stop; this will be
  22087. * the depth of the top-most keyref IDC. If no keyref
  22088. * references a key/unique IDC, the keyrefDepth will
  22089. * be -1, indicating that no bubbles are needed.
  22090. */
  22091. refIdc = (xmlSchemaIDCPtr) idc->ref->item;
  22092. if (refIdc != NULL) {
  22093. /*
  22094. * Remember that we have keyrefs on this node.
  22095. */
  22096. vctxt->inode->hasKeyrefs = 1;
  22097. /*
  22098. * Lookup the referenced augmented IDC info.
  22099. */
  22100. aidc = vctxt->aidcs;
  22101. while (aidc != NULL) {
  22102. if (aidc->def == refIdc)
  22103. break;
  22104. aidc = aidc->next;
  22105. }
  22106. if (aidc == NULL) {
  22107. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  22108. "Could not find an augmented IDC item for an IDC "
  22109. "definition");
  22110. return (-1);
  22111. }
  22112. if ((aidc->keyrefDepth == -1) ||
  22113. (vctxt->depth < aidc->keyrefDepth))
  22114. aidc->keyrefDepth = vctxt->depth;
  22115. }
  22116. }
  22117. /*
  22118. * Lookup the augmented IDC item for the IDC definition.
  22119. */
  22120. aidc = vctxt->aidcs;
  22121. while (aidc != NULL) {
  22122. if (aidc->def == idc)
  22123. break;
  22124. aidc = aidc->next;
  22125. }
  22126. if (aidc == NULL) {
  22127. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  22128. "Could not find an augmented IDC item for an IDC definition");
  22129. return (-1);
  22130. }
  22131. /*
  22132. * Create an IDC matcher for every IDC definition.
  22133. */
  22134. if (vctxt->idcMatcherCache != NULL) {
  22135. /*
  22136. * Reuse a cached matcher.
  22137. */
  22138. matcher = vctxt->idcMatcherCache;
  22139. vctxt->idcMatcherCache = matcher->nextCached;
  22140. matcher->nextCached = NULL;
  22141. } else {
  22142. matcher = (xmlSchemaIDCMatcherPtr)
  22143. xmlMalloc(sizeof(xmlSchemaIDCMatcher));
  22144. if (matcher == NULL) {
  22145. xmlSchemaVErrMemory(vctxt,
  22146. "allocating an IDC matcher", NULL);
  22147. return (-1);
  22148. }
  22149. memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
  22150. }
  22151. if (last == NULL)
  22152. vctxt->inode->idcMatchers = matcher;
  22153. else
  22154. last->next = matcher;
  22155. last = matcher;
  22156. matcher->type = IDC_MATCHER;
  22157. matcher->depth = vctxt->depth;
  22158. matcher->aidc = aidc;
  22159. matcher->idcType = aidc->def->type;
  22160. #ifdef DEBUG_IDC
  22161. xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n");
  22162. #endif
  22163. /*
  22164. * Init the automaton state object.
  22165. */
  22166. if (xmlSchemaIDCAddStateObject(vctxt, matcher,
  22167. idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
  22168. return (-1);
  22169. idc = idc->next;
  22170. } while (idc != NULL);
  22171. return (0);
  22172. }
  22173. static int
  22174. xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
  22175. xmlSchemaNodeInfoPtr ielem)
  22176. {
  22177. xmlSchemaPSVIIDCBindingPtr bind;
  22178. int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
  22179. xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
  22180. xmlSchemaPSVIIDCNodePtr *targets, *dupls;
  22181. xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
  22182. /* vctxt->createIDCNodeTables */
  22183. while (matcher != NULL) {
  22184. /*
  22185. * Skip keyref IDCs and empty IDC target-lists.
  22186. */
  22187. if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
  22188. WXS_ILIST_IS_EMPTY(matcher->targets))
  22189. {
  22190. matcher = matcher->next;
  22191. continue;
  22192. }
  22193. /*
  22194. * If we _want_ the IDC node-table to be created in any case
  22195. * then do so. Otherwise create them only if keyrefs need them.
  22196. */
  22197. if ((! vctxt->createIDCNodeTables) &&
  22198. ((matcher->aidc->keyrefDepth == -1) ||
  22199. (matcher->aidc->keyrefDepth > vctxt->depth)))
  22200. {
  22201. matcher = matcher->next;
  22202. continue;
  22203. }
  22204. /*
  22205. * Get/create the IDC binding on this element for the IDC definition.
  22206. */
  22207. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  22208. if (bind == NULL)
  22209. goto internal_error;
  22210. if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
  22211. dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
  22212. nbDupls = bind->dupls->nbItems;
  22213. } else {
  22214. dupls = NULL;
  22215. nbDupls = 0;
  22216. }
  22217. if (bind->nodeTable != NULL) {
  22218. nbNodeTable = bind->nbNodes;
  22219. } else {
  22220. nbNodeTable = 0;
  22221. }
  22222. if ((nbNodeTable == 0) && (nbDupls == 0)) {
  22223. /*
  22224. * Transfer all IDC target-nodes to the IDC node-table.
  22225. */
  22226. bind->nodeTable =
  22227. (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  22228. bind->sizeNodes = matcher->targets->sizeItems;
  22229. bind->nbNodes = matcher->targets->nbItems;
  22230. matcher->targets->items = NULL;
  22231. matcher->targets->sizeItems = 0;
  22232. matcher->targets->nbItems = 0;
  22233. if (matcher->htab) {
  22234. xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
  22235. matcher->htab = NULL;
  22236. }
  22237. } else {
  22238. /*
  22239. * Compare the key-sequences and add to the IDC node-table.
  22240. */
  22241. nbTargets = matcher->targets->nbItems;
  22242. targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  22243. nbFields = matcher->aidc->def->nbFields;
  22244. i = 0;
  22245. do {
  22246. keys = targets[i]->keys;
  22247. if (nbDupls) {
  22248. /*
  22249. * Search in already found duplicates first.
  22250. */
  22251. j = 0;
  22252. do {
  22253. if (nbFields == 1) {
  22254. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22255. dupls[j]->keys[0]->val);
  22256. if (res == -1)
  22257. goto internal_error;
  22258. if (res == 1) {
  22259. /*
  22260. * Equal key-sequence.
  22261. */
  22262. goto next_target;
  22263. }
  22264. } else {
  22265. res = 0;
  22266. ntkeys = dupls[j]->keys;
  22267. for (k = 0; k < nbFields; k++) {
  22268. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22269. ntkeys[k]->val);
  22270. if (res == -1)
  22271. goto internal_error;
  22272. if (res == 0) {
  22273. /*
  22274. * One of the keys differs.
  22275. */
  22276. break;
  22277. }
  22278. }
  22279. if (res == 1) {
  22280. /*
  22281. * Equal key-sequence found.
  22282. */
  22283. goto next_target;
  22284. }
  22285. }
  22286. j++;
  22287. } while (j < nbDupls);
  22288. }
  22289. if (nbNodeTable) {
  22290. j = 0;
  22291. do {
  22292. if (nbFields == 1) {
  22293. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22294. bind->nodeTable[j]->keys[0]->val);
  22295. if (res == -1)
  22296. goto internal_error;
  22297. if (res == 0) {
  22298. /*
  22299. * The key-sequence differs.
  22300. */
  22301. goto next_node_table_entry;
  22302. }
  22303. } else {
  22304. res = 0;
  22305. ntkeys = bind->nodeTable[j]->keys;
  22306. for (k = 0; k < nbFields; k++) {
  22307. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22308. ntkeys[k]->val);
  22309. if (res == -1)
  22310. goto internal_error;
  22311. if (res == 0) {
  22312. /*
  22313. * One of the keys differs.
  22314. */
  22315. goto next_node_table_entry;
  22316. }
  22317. }
  22318. }
  22319. /*
  22320. * Add the duplicate to the list of duplicates.
  22321. */
  22322. if (bind->dupls == NULL) {
  22323. bind->dupls = xmlSchemaItemListCreate();
  22324. if (bind->dupls == NULL)
  22325. goto internal_error;
  22326. }
  22327. if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
  22328. goto internal_error;
  22329. /*
  22330. * Remove the duplicate entry from the IDC node-table.
  22331. */
  22332. bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
  22333. bind->nbNodes--;
  22334. goto next_target;
  22335. next_node_table_entry:
  22336. j++;
  22337. } while (j < nbNodeTable);
  22338. }
  22339. /*
  22340. * If everything is fine, then add the IDC target-node to
  22341. * the IDC node-table.
  22342. */
  22343. if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
  22344. goto internal_error;
  22345. next_target:
  22346. i++;
  22347. } while (i < nbTargets);
  22348. }
  22349. matcher = matcher->next;
  22350. }
  22351. return(0);
  22352. internal_error:
  22353. return(-1);
  22354. }
  22355. /**
  22356. * xmlSchemaBubbleIDCNodeTables:
  22357. * @depth: the current tree depth
  22358. *
  22359. * Merges IDC bindings of an element at @depth into the corresponding IDC
  22360. * bindings of its parent element. If a duplicate note-table entry is found,
  22361. * both, the parent node-table entry and child entry are discarded from the
  22362. * node-table of the parent.
  22363. *
  22364. * Returns 0 if OK and -1 on internal errors.
  22365. */
  22366. static int
  22367. xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
  22368. {
  22369. xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
  22370. xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
  22371. xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
  22372. xmlSchemaIDCAugPtr aidc;
  22373. int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
  22374. bind = vctxt->inode->idcTable;
  22375. if (bind == NULL) {
  22376. /* Fine, no table, no bubbles. */
  22377. return (0);
  22378. }
  22379. parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
  22380. /*
  22381. * Walk all bindings; create new or add to existing bindings.
  22382. * Remove duplicate key-sequences.
  22383. */
  22384. while (bind != NULL) {
  22385. if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
  22386. goto next_binding;
  22387. /*
  22388. * Check if the key/unique IDC table needs to be bubbled.
  22389. */
  22390. if (! vctxt->createIDCNodeTables) {
  22391. aidc = vctxt->aidcs;
  22392. do {
  22393. if (aidc->def == bind->definition) {
  22394. if ((aidc->keyrefDepth == -1) ||
  22395. (aidc->keyrefDepth >= vctxt->depth)) {
  22396. goto next_binding;
  22397. }
  22398. break;
  22399. }
  22400. aidc = aidc->next;
  22401. } while (aidc != NULL);
  22402. }
  22403. if (parTable != NULL)
  22404. parBind = *parTable;
  22405. /*
  22406. * Search a matching parent binding for the
  22407. * IDC definition.
  22408. */
  22409. while (parBind != NULL) {
  22410. if (parBind->definition == bind->definition)
  22411. break;
  22412. parBind = parBind->next;
  22413. }
  22414. if (parBind != NULL) {
  22415. /*
  22416. * Compare every node-table entry of the child node,
  22417. * i.e. the key-sequence within, ...
  22418. */
  22419. oldNum = parBind->nbNodes; /* Skip newly added items. */
  22420. if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
  22421. oldDupls = parBind->dupls->nbItems;
  22422. dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
  22423. } else {
  22424. dupls = NULL;
  22425. oldDupls = 0;
  22426. }
  22427. parNodes = parBind->nodeTable;
  22428. nbFields = bind->definition->nbFields;
  22429. for (i = 0; i < bind->nbNodes; i++) {
  22430. node = bind->nodeTable[i];
  22431. if (node == NULL)
  22432. continue;
  22433. /*
  22434. * ...with every key-sequence of the parent node, already
  22435. * evaluated to be a duplicate key-sequence.
  22436. */
  22437. if (oldDupls) {
  22438. j = 0;
  22439. while (j < oldDupls) {
  22440. if (nbFields == 1) {
  22441. ret = xmlSchemaAreValuesEqual(
  22442. node->keys[0]->val,
  22443. dupls[j]->keys[0]->val);
  22444. if (ret == -1)
  22445. goto internal_error;
  22446. if (ret == 0) {
  22447. j++;
  22448. continue;
  22449. }
  22450. } else {
  22451. parNode = dupls[j];
  22452. for (k = 0; k < nbFields; k++) {
  22453. ret = xmlSchemaAreValuesEqual(
  22454. node->keys[k]->val,
  22455. parNode->keys[k]->val);
  22456. if (ret == -1)
  22457. goto internal_error;
  22458. if (ret == 0)
  22459. break;
  22460. }
  22461. }
  22462. if (ret == 1)
  22463. /* Duplicate found. */
  22464. break;
  22465. j++;
  22466. }
  22467. if (j != oldDupls) {
  22468. /* Duplicate found. Skip this entry. */
  22469. continue;
  22470. }
  22471. }
  22472. /*
  22473. * ... and with every key-sequence of the parent node.
  22474. */
  22475. if (oldNum) {
  22476. j = 0;
  22477. while (j < oldNum) {
  22478. parNode = parNodes[j];
  22479. if (nbFields == 1) {
  22480. ret = xmlSchemaAreValuesEqual(
  22481. node->keys[0]->val,
  22482. parNode->keys[0]->val);
  22483. if (ret == -1)
  22484. goto internal_error;
  22485. if (ret == 0) {
  22486. j++;
  22487. continue;
  22488. }
  22489. } else {
  22490. for (k = 0; k < nbFields; k++) {
  22491. ret = xmlSchemaAreValuesEqual(
  22492. node->keys[k]->val,
  22493. parNode->keys[k]->val);
  22494. if (ret == -1)
  22495. goto internal_error;
  22496. if (ret == 0)
  22497. break;
  22498. }
  22499. }
  22500. if (ret == 1)
  22501. /* Duplicate found. */
  22502. break;
  22503. j++;
  22504. }
  22505. if (j != oldNum) {
  22506. /*
  22507. * Handle duplicates. Move the duplicate in
  22508. * the parent's node-table to the list of
  22509. * duplicates.
  22510. */
  22511. oldNum--;
  22512. parBind->nbNodes--;
  22513. /*
  22514. * Move last old item to pos of duplicate.
  22515. */
  22516. parNodes[j] = parNodes[oldNum];
  22517. if (parBind->nbNodes != oldNum) {
  22518. /*
  22519. * If new items exist, move last new item to
  22520. * last of old items.
  22521. */
  22522. parNodes[oldNum] =
  22523. parNodes[parBind->nbNodes];
  22524. }
  22525. if (parBind->dupls == NULL) {
  22526. parBind->dupls = xmlSchemaItemListCreate();
  22527. if (parBind->dupls == NULL)
  22528. goto internal_error;
  22529. }
  22530. xmlSchemaItemListAdd(parBind->dupls, parNode);
  22531. } else {
  22532. /*
  22533. * Add the node-table entry (node and key-sequence) of
  22534. * the child node to the node table of the parent node.
  22535. */
  22536. if (parBind->nodeTable == NULL) {
  22537. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22538. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  22539. if (parBind->nodeTable == NULL) {
  22540. xmlSchemaVErrMemory(NULL,
  22541. "allocating IDC list of node-table items", NULL);
  22542. goto internal_error;
  22543. }
  22544. parBind->sizeNodes = 1;
  22545. } else if (parBind->nbNodes >= parBind->sizeNodes) {
  22546. parBind->sizeNodes *= 2;
  22547. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22548. xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
  22549. sizeof(xmlSchemaPSVIIDCNodePtr));
  22550. if (parBind->nodeTable == NULL) {
  22551. xmlSchemaVErrMemory(NULL,
  22552. "re-allocating IDC list of node-table items", NULL);
  22553. goto internal_error;
  22554. }
  22555. }
  22556. parNodes = parBind->nodeTable;
  22557. /*
  22558. * Append the new node-table entry to the 'new node-table
  22559. * entries' section.
  22560. */
  22561. parNodes[parBind->nbNodes++] = node;
  22562. }
  22563. }
  22564. }
  22565. } else {
  22566. /*
  22567. * No binding for the IDC was found: create a new one and
  22568. * copy all node-tables.
  22569. */
  22570. parBind = xmlSchemaIDCNewBinding(bind->definition);
  22571. if (parBind == NULL)
  22572. goto internal_error;
  22573. /*
  22574. * TODO: Hmm, how to optimize the initial number of
  22575. * allocated entries?
  22576. */
  22577. if (bind->nbNodes != 0) {
  22578. /*
  22579. * Add all IDC node-table entries.
  22580. */
  22581. if (! vctxt->psviExposeIDCNodeTables) {
  22582. /*
  22583. * Just move the entries.
  22584. * NOTE: this is quite save here, since
  22585. * all the keyref lookups have already been
  22586. * performed.
  22587. */
  22588. parBind->nodeTable = bind->nodeTable;
  22589. bind->nodeTable = NULL;
  22590. parBind->sizeNodes = bind->sizeNodes;
  22591. bind->sizeNodes = 0;
  22592. parBind->nbNodes = bind->nbNodes;
  22593. bind->nbNodes = 0;
  22594. } else {
  22595. /*
  22596. * Copy the entries.
  22597. */
  22598. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22599. xmlMalloc(bind->nbNodes *
  22600. sizeof(xmlSchemaPSVIIDCNodePtr));
  22601. if (parBind->nodeTable == NULL) {
  22602. xmlSchemaVErrMemory(NULL,
  22603. "allocating an array of IDC node-table "
  22604. "items", NULL);
  22605. xmlSchemaIDCFreeBinding(parBind);
  22606. goto internal_error;
  22607. }
  22608. parBind->sizeNodes = bind->nbNodes;
  22609. parBind->nbNodes = bind->nbNodes;
  22610. memcpy(parBind->nodeTable, bind->nodeTable,
  22611. bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
  22612. }
  22613. }
  22614. if (bind->dupls) {
  22615. /*
  22616. * Move the duplicates.
  22617. */
  22618. if (parBind->dupls != NULL)
  22619. xmlSchemaItemListFree(parBind->dupls);
  22620. parBind->dupls = bind->dupls;
  22621. bind->dupls = NULL;
  22622. }
  22623. if (parTable != NULL) {
  22624. if (*parTable == NULL)
  22625. *parTable = parBind;
  22626. else {
  22627. parBind->next = *parTable;
  22628. *parTable = parBind;
  22629. }
  22630. }
  22631. }
  22632. next_binding:
  22633. bind = bind->next;
  22634. }
  22635. return (0);
  22636. internal_error:
  22637. return(-1);
  22638. }
  22639. /**
  22640. * xmlSchemaCheckCVCIDCKeyRef:
  22641. * @vctxt: the WXS validation context
  22642. * @elemDecl: the element declaration
  22643. *
  22644. * Check the cvc-idc-keyref constraints.
  22645. */
  22646. static int
  22647. xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
  22648. {
  22649. xmlSchemaIDCMatcherPtr matcher;
  22650. xmlSchemaPSVIIDCBindingPtr bind;
  22651. matcher = vctxt->inode->idcMatchers;
  22652. /*
  22653. * Find a keyref.
  22654. */
  22655. while (matcher != NULL) {
  22656. if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
  22657. matcher->targets &&
  22658. matcher->targets->nbItems)
  22659. {
  22660. int i, j, k, res, nbFields, hasDupls;
  22661. xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
  22662. xmlSchemaPSVIIDCNodePtr refNode = NULL;
  22663. xmlHashTablePtr table = NULL;
  22664. nbFields = matcher->aidc->def->nbFields;
  22665. /*
  22666. * Find the IDC node-table for the referenced IDC key/unique.
  22667. */
  22668. bind = vctxt->inode->idcTable;
  22669. while (bind != NULL) {
  22670. if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
  22671. bind->definition)
  22672. break;
  22673. bind = bind->next;
  22674. }
  22675. hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
  22676. /*
  22677. * Search for a matching key-sequences.
  22678. */
  22679. if (bind) {
  22680. table = xmlHashCreate(bind->nbNodes * 2);
  22681. for (j = 0; j < bind->nbNodes; j++) {
  22682. xmlChar *value;
  22683. xmlIDCHashEntryPtr r, e;
  22684. keys = bind->nodeTable[j]->keys;
  22685. xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
  22686. e = xmlMalloc(sizeof *e);
  22687. e->index = j;
  22688. r = xmlHashLookup(table, value);
  22689. if (r) {
  22690. e->next = r->next;
  22691. r->next = e;
  22692. } else {
  22693. e->next = NULL;
  22694. xmlHashAddEntry(table, value, e);
  22695. }
  22696. FREE_AND_NULL(value);
  22697. }
  22698. }
  22699. for (i = 0; i < matcher->targets->nbItems; i++) {
  22700. res = 0;
  22701. refNode = matcher->targets->items[i];
  22702. if (bind != NULL) {
  22703. xmlChar *value;
  22704. xmlIDCHashEntryPtr e;
  22705. refKeys = refNode->keys;
  22706. xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
  22707. e = xmlHashLookup(table, value);
  22708. FREE_AND_NULL(value);
  22709. res = 0;
  22710. for (;e; e = e->next) {
  22711. keys = bind->nodeTable[e->index]->keys;
  22712. for (k = 0; k < nbFields; k++) {
  22713. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22714. refKeys[k]->val);
  22715. if (res == 0)
  22716. break;
  22717. else if (res == -1) {
  22718. return (-1);
  22719. }
  22720. }
  22721. if (res == 1) {
  22722. /*
  22723. * Match found.
  22724. */
  22725. break;
  22726. }
  22727. }
  22728. if ((res == 0) && hasDupls) {
  22729. /*
  22730. * Search in duplicates
  22731. */
  22732. for (j = 0; j < bind->dupls->nbItems; j++) {
  22733. keys = ((xmlSchemaPSVIIDCNodePtr)
  22734. bind->dupls->items[j])->keys;
  22735. for (k = 0; k < nbFields; k++) {
  22736. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22737. refKeys[k]->val);
  22738. if (res == 0)
  22739. break;
  22740. else if (res == -1) {
  22741. return (-1);
  22742. }
  22743. }
  22744. if (res == 1) {
  22745. /*
  22746. * Match in duplicates found.
  22747. */
  22748. xmlChar *str = NULL, *strB = NULL;
  22749. xmlSchemaKeyrefErr(vctxt,
  22750. XML_SCHEMAV_CVC_IDC, refNode,
  22751. (xmlSchemaTypePtr) matcher->aidc->def,
  22752. "More than one match found for "
  22753. "key-sequence %s of keyref '%s'",
  22754. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22755. refNode->keys, nbFields),
  22756. xmlSchemaGetComponentQName(&strB,
  22757. matcher->aidc->def));
  22758. FREE_AND_NULL(str);
  22759. FREE_AND_NULL(strB);
  22760. break;
  22761. }
  22762. }
  22763. }
  22764. }
  22765. if (res == 0) {
  22766. xmlChar *str = NULL, *strB = NULL;
  22767. xmlSchemaKeyrefErr(vctxt,
  22768. XML_SCHEMAV_CVC_IDC, refNode,
  22769. (xmlSchemaTypePtr) matcher->aidc->def,
  22770. "No match found for key-sequence %s of keyref '%s'",
  22771. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22772. refNode->keys, nbFields),
  22773. xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
  22774. FREE_AND_NULL(str);
  22775. FREE_AND_NULL(strB);
  22776. }
  22777. }
  22778. if (table) {
  22779. xmlHashFree(table, xmlFreeIDCHashEntry);
  22780. }
  22781. }
  22782. matcher = matcher->next;
  22783. }
  22784. /* TODO: Return an error if any error encountered. */
  22785. return (0);
  22786. }
  22787. /************************************************************************
  22788. * *
  22789. * XML Reader validation code *
  22790. * *
  22791. ************************************************************************/
  22792. static xmlSchemaAttrInfoPtr
  22793. xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
  22794. {
  22795. xmlSchemaAttrInfoPtr iattr;
  22796. /*
  22797. * Grow/create list of attribute infos.
  22798. */
  22799. if (vctxt->attrInfos == NULL) {
  22800. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22801. xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
  22802. vctxt->sizeAttrInfos = 1;
  22803. if (vctxt->attrInfos == NULL) {
  22804. xmlSchemaVErrMemory(vctxt,
  22805. "allocating attribute info list", NULL);
  22806. return (NULL);
  22807. }
  22808. } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
  22809. vctxt->sizeAttrInfos++;
  22810. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22811. xmlRealloc(vctxt->attrInfos,
  22812. vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
  22813. if (vctxt->attrInfos == NULL) {
  22814. xmlSchemaVErrMemory(vctxt,
  22815. "re-allocating attribute info list", NULL);
  22816. return (NULL);
  22817. }
  22818. } else {
  22819. iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
  22820. if (iattr->localName != NULL) {
  22821. VERROR_INT("xmlSchemaGetFreshAttrInfo",
  22822. "attr info not cleared");
  22823. return (NULL);
  22824. }
  22825. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22826. return (iattr);
  22827. }
  22828. /*
  22829. * Create an attribute info.
  22830. */
  22831. iattr = (xmlSchemaAttrInfoPtr)
  22832. xmlMalloc(sizeof(xmlSchemaAttrInfo));
  22833. if (iattr == NULL) {
  22834. xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
  22835. return (NULL);
  22836. }
  22837. memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
  22838. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22839. vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
  22840. return (iattr);
  22841. }
  22842. static int
  22843. xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
  22844. xmlNodePtr attrNode,
  22845. int nodeLine,
  22846. const xmlChar *localName,
  22847. const xmlChar *nsName,
  22848. int ownedNames,
  22849. xmlChar *value,
  22850. int ownedValue)
  22851. {
  22852. xmlSchemaAttrInfoPtr attr;
  22853. attr = xmlSchemaGetFreshAttrInfo(vctxt);
  22854. if (attr == NULL) {
  22855. VERROR_INT("xmlSchemaPushAttribute",
  22856. "calling xmlSchemaGetFreshAttrInfo()");
  22857. return (-1);
  22858. }
  22859. attr->node = attrNode;
  22860. attr->nodeLine = nodeLine;
  22861. attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
  22862. attr->localName = localName;
  22863. attr->nsName = nsName;
  22864. if (ownedNames)
  22865. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  22866. /*
  22867. * Evaluate if it's an XSI attribute.
  22868. */
  22869. if (nsName != NULL) {
  22870. if (xmlStrEqual(localName, BAD_CAST "nil")) {
  22871. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22872. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
  22873. }
  22874. } else if (xmlStrEqual(localName, BAD_CAST "type")) {
  22875. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22876. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
  22877. }
  22878. } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
  22879. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22880. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
  22881. }
  22882. } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
  22883. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22884. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
  22885. }
  22886. } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
  22887. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
  22888. }
  22889. }
  22890. attr->value = value;
  22891. if (ownedValue)
  22892. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  22893. if (attr->metaType != 0)
  22894. attr->state = XML_SCHEMAS_ATTR_META;
  22895. return (0);
  22896. }
  22897. /**
  22898. * xmlSchemaClearElemInfo:
  22899. * @vctxt: the WXS validation context
  22900. * @ielem: the element information item
  22901. */
  22902. static void
  22903. xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
  22904. xmlSchemaNodeInfoPtr ielem)
  22905. {
  22906. ielem->hasKeyrefs = 0;
  22907. ielem->appliedXPath = 0;
  22908. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  22909. FREE_AND_NULL(ielem->localName);
  22910. FREE_AND_NULL(ielem->nsName);
  22911. } else {
  22912. ielem->localName = NULL;
  22913. ielem->nsName = NULL;
  22914. }
  22915. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  22916. FREE_AND_NULL(ielem->value);
  22917. } else {
  22918. ielem->value = NULL;
  22919. }
  22920. if (ielem->val != NULL) {
  22921. /*
  22922. * PSVI TODO: Be careful not to free it when the value is
  22923. * exposed via PSVI.
  22924. */
  22925. xmlSchemaFreeValue(ielem->val);
  22926. ielem->val = NULL;
  22927. }
  22928. if (ielem->idcMatchers != NULL) {
  22929. /*
  22930. * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
  22931. * Does it work?
  22932. */
  22933. xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
  22934. #if 0
  22935. xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
  22936. #endif
  22937. ielem->idcMatchers = NULL;
  22938. }
  22939. if (ielem->idcTable != NULL) {
  22940. /*
  22941. * OPTIMIZE TODO: Use a pool of IDC tables??.
  22942. */
  22943. xmlSchemaIDCFreeIDCTable(ielem->idcTable);
  22944. ielem->idcTable = NULL;
  22945. }
  22946. if (ielem->regexCtxt != NULL) {
  22947. xmlRegFreeExecCtxt(ielem->regexCtxt);
  22948. ielem->regexCtxt = NULL;
  22949. }
  22950. if (ielem->nsBindings != NULL) {
  22951. xmlFree((xmlChar **)ielem->nsBindings);
  22952. ielem->nsBindings = NULL;
  22953. ielem->nbNsBindings = 0;
  22954. ielem->sizeNsBindings = 0;
  22955. }
  22956. }
  22957. /**
  22958. * xmlSchemaGetFreshElemInfo:
  22959. * @vctxt: the schema validation context
  22960. *
  22961. * Creates/reuses and initializes the element info item for
  22962. * the current tree depth.
  22963. *
  22964. * Returns the element info item or NULL on API or internal errors.
  22965. */
  22966. static xmlSchemaNodeInfoPtr
  22967. xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
  22968. {
  22969. xmlSchemaNodeInfoPtr info = NULL;
  22970. if (vctxt->depth > vctxt->sizeElemInfos) {
  22971. VERROR_INT("xmlSchemaGetFreshElemInfo",
  22972. "inconsistent depth encountered");
  22973. return (NULL);
  22974. }
  22975. if (vctxt->elemInfos == NULL) {
  22976. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22977. xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
  22978. if (vctxt->elemInfos == NULL) {
  22979. xmlSchemaVErrMemory(vctxt,
  22980. "allocating the element info array", NULL);
  22981. return (NULL);
  22982. }
  22983. memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
  22984. vctxt->sizeElemInfos = 10;
  22985. } else if (vctxt->sizeElemInfos <= vctxt->depth) {
  22986. int i = vctxt->sizeElemInfos;
  22987. vctxt->sizeElemInfos *= 2;
  22988. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22989. xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
  22990. sizeof(xmlSchemaNodeInfoPtr));
  22991. if (vctxt->elemInfos == NULL) {
  22992. xmlSchemaVErrMemory(vctxt,
  22993. "re-allocating the element info array", NULL);
  22994. return (NULL);
  22995. }
  22996. /*
  22997. * We need the new memory to be NULLed.
  22998. * TODO: Use memset instead?
  22999. */
  23000. for (; i < vctxt->sizeElemInfos; i++)
  23001. vctxt->elemInfos[i] = NULL;
  23002. } else
  23003. info = vctxt->elemInfos[vctxt->depth];
  23004. if (info == NULL) {
  23005. info = (xmlSchemaNodeInfoPtr)
  23006. xmlMalloc(sizeof(xmlSchemaNodeInfo));
  23007. if (info == NULL) {
  23008. xmlSchemaVErrMemory(vctxt,
  23009. "allocating an element info", NULL);
  23010. return (NULL);
  23011. }
  23012. vctxt->elemInfos[vctxt->depth] = info;
  23013. } else {
  23014. if (info->localName != NULL) {
  23015. VERROR_INT("xmlSchemaGetFreshElemInfo",
  23016. "elem info has not been cleared");
  23017. return (NULL);
  23018. }
  23019. }
  23020. memset(info, 0, sizeof(xmlSchemaNodeInfo));
  23021. info->nodeType = XML_ELEMENT_NODE;
  23022. info->depth = vctxt->depth;
  23023. return (info);
  23024. }
  23025. #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
  23026. #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
  23027. #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
  23028. static int
  23029. xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
  23030. xmlNodePtr node,
  23031. xmlSchemaTypePtr type,
  23032. xmlSchemaValType valType,
  23033. const xmlChar * value,
  23034. xmlSchemaValPtr val,
  23035. unsigned long length,
  23036. int fireErrors)
  23037. {
  23038. int ret, error = 0, found;
  23039. xmlSchemaTypePtr tmpType;
  23040. xmlSchemaFacetLinkPtr facetLink;
  23041. xmlSchemaFacetPtr facet;
  23042. unsigned long len = 0;
  23043. xmlSchemaWhitespaceValueType ws;
  23044. /*
  23045. * In Libxml2, derived built-in types have currently no explicit facets.
  23046. */
  23047. if (type->type == XML_SCHEMA_TYPE_BASIC)
  23048. return (0);
  23049. /*
  23050. * NOTE: Do not jump away, if the facetSet of the given type is
  23051. * empty: until now, "pattern" and "enumeration" facets of the
  23052. * *base types* need to be checked as well.
  23053. */
  23054. if (type->facetSet == NULL)
  23055. goto pattern_and_enum;
  23056. if (! WXS_IS_ATOMIC(type)) {
  23057. if (WXS_IS_LIST(type))
  23058. goto WXS_IS_LIST;
  23059. else
  23060. goto pattern_and_enum;
  23061. }
  23062. /*
  23063. * Whitespace handling is only of importance for string-based
  23064. * types.
  23065. */
  23066. tmpType = xmlSchemaGetPrimitiveType(type);
  23067. if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
  23068. WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
  23069. ws = xmlSchemaGetWhiteSpaceFacetValue(type);
  23070. } else
  23071. ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
  23072. /*
  23073. * If the value was not computed (for string or
  23074. * anySimpleType based types), then use the provided
  23075. * type.
  23076. */
  23077. if (val != NULL)
  23078. valType = xmlSchemaGetValType(val);
  23079. ret = 0;
  23080. for (facetLink = type->facetSet; facetLink != NULL;
  23081. facetLink = facetLink->next) {
  23082. /*
  23083. * Skip the pattern "whiteSpace": it is used to
  23084. * format the character content beforehand.
  23085. */
  23086. switch (facetLink->facet->type) {
  23087. case XML_SCHEMA_FACET_WHITESPACE:
  23088. case XML_SCHEMA_FACET_PATTERN:
  23089. case XML_SCHEMA_FACET_ENUMERATION:
  23090. continue;
  23091. case XML_SCHEMA_FACET_LENGTH:
  23092. case XML_SCHEMA_FACET_MINLENGTH:
  23093. case XML_SCHEMA_FACET_MAXLENGTH:
  23094. ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
  23095. valType, value, val, &len, ws);
  23096. break;
  23097. default:
  23098. ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
  23099. valType, value, val, ws);
  23100. break;
  23101. }
  23102. if (ret < 0) {
  23103. AERROR_INT("xmlSchemaValidateFacets",
  23104. "validating against a atomic type facet");
  23105. return (-1);
  23106. } else if (ret > 0) {
  23107. if (fireErrors)
  23108. xmlSchemaFacetErr(actxt, ret, node,
  23109. value, len, type, facetLink->facet, NULL, NULL, NULL);
  23110. else
  23111. return (ret);
  23112. if (error == 0)
  23113. error = ret;
  23114. }
  23115. ret = 0;
  23116. }
  23117. WXS_IS_LIST:
  23118. if (! WXS_IS_LIST(type))
  23119. goto pattern_and_enum;
  23120. /*
  23121. * "length", "minLength" and "maxLength" of list types.
  23122. */
  23123. ret = 0;
  23124. for (facetLink = type->facetSet; facetLink != NULL;
  23125. facetLink = facetLink->next) {
  23126. switch (facetLink->facet->type) {
  23127. case XML_SCHEMA_FACET_LENGTH:
  23128. case XML_SCHEMA_FACET_MINLENGTH:
  23129. case XML_SCHEMA_FACET_MAXLENGTH:
  23130. ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
  23131. value, length, NULL);
  23132. break;
  23133. default:
  23134. continue;
  23135. }
  23136. if (ret < 0) {
  23137. AERROR_INT("xmlSchemaValidateFacets",
  23138. "validating against a list type facet");
  23139. return (-1);
  23140. } else if (ret > 0) {
  23141. if (fireErrors)
  23142. xmlSchemaFacetErr(actxt, ret, node,
  23143. value, length, type, facetLink->facet, NULL, NULL, NULL);
  23144. else
  23145. return (ret);
  23146. if (error == 0)
  23147. error = ret;
  23148. }
  23149. ret = 0;
  23150. }
  23151. pattern_and_enum:
  23152. found = 0;
  23153. /*
  23154. * Process enumerations. Facet values are in the value space
  23155. * of the defining type's base type. This seems to be a bug in the
  23156. * XML Schema 1.0 spec. Use the whitespace type of the base type.
  23157. * Only the first set of enumerations in the ancestor-or-self axis
  23158. * is used for validation.
  23159. */
  23160. ret = 0;
  23161. tmpType = type;
  23162. do {
  23163. for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
  23164. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  23165. continue;
  23166. found = 1;
  23167. ret = xmlSchemaAreValuesEqual(facet->val, val);
  23168. if (ret == 1)
  23169. break;
  23170. else if (ret < 0) {
  23171. AERROR_INT("xmlSchemaValidateFacets",
  23172. "validating against an enumeration facet");
  23173. return (-1);
  23174. }
  23175. }
  23176. if (ret != 0)
  23177. break;
  23178. /*
  23179. * Break on the first set of enumerations. Any additional
  23180. * enumerations which might be existent on the ancestors
  23181. * of the current type are restricted by this set; thus
  23182. * *must* *not* be taken into account.
  23183. */
  23184. if (found)
  23185. break;
  23186. tmpType = tmpType->baseType;
  23187. } while ((tmpType != NULL) &&
  23188. (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  23189. if (found && (ret == 0)) {
  23190. ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
  23191. if (fireErrors) {
  23192. xmlSchemaFacetErr(actxt, ret, node,
  23193. value, 0, type, NULL, NULL, NULL, NULL);
  23194. } else
  23195. return (ret);
  23196. if (error == 0)
  23197. error = ret;
  23198. }
  23199. /*
  23200. * Process patters. Pattern facets are ORed at type level
  23201. * and ANDed if derived. Walk the base type axis.
  23202. */
  23203. tmpType = type;
  23204. facet = NULL;
  23205. do {
  23206. found = 0;
  23207. for (facetLink = tmpType->facetSet; facetLink != NULL;
  23208. facetLink = facetLink->next) {
  23209. if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
  23210. continue;
  23211. found = 1;
  23212. /*
  23213. * NOTE that for patterns, @value needs to be the
  23214. * normalized value.
  23215. */
  23216. ret = xmlRegexpExec(facetLink->facet->regexp, value);
  23217. if (ret == 1)
  23218. break;
  23219. else if (ret < 0) {
  23220. AERROR_INT("xmlSchemaValidateFacets",
  23221. "validating against a pattern facet");
  23222. return (-1);
  23223. } else {
  23224. /*
  23225. * Save the last non-validating facet.
  23226. */
  23227. facet = facetLink->facet;
  23228. }
  23229. }
  23230. if (found && (ret != 1)) {
  23231. ret = XML_SCHEMAV_CVC_PATTERN_VALID;
  23232. if (fireErrors) {
  23233. xmlSchemaFacetErr(actxt, ret, node,
  23234. value, 0, type, facet, NULL, NULL, NULL);
  23235. } else
  23236. return (ret);
  23237. if (error == 0)
  23238. error = ret;
  23239. break;
  23240. }
  23241. tmpType = tmpType->baseType;
  23242. } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  23243. return (error);
  23244. }
  23245. static xmlChar *
  23246. xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
  23247. const xmlChar *value)
  23248. {
  23249. switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
  23250. case XML_SCHEMA_WHITESPACE_COLLAPSE:
  23251. return (xmlSchemaCollapseString(value));
  23252. case XML_SCHEMA_WHITESPACE_REPLACE:
  23253. return (xmlSchemaWhiteSpaceReplace(value));
  23254. default:
  23255. return (NULL);
  23256. }
  23257. }
  23258. static int
  23259. xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
  23260. const xmlChar *value,
  23261. xmlSchemaValPtr *val,
  23262. int valNeeded)
  23263. {
  23264. int ret;
  23265. const xmlChar *nsName;
  23266. xmlChar *local, *prefix = NULL;
  23267. ret = xmlValidateQName(value, 1);
  23268. if (ret != 0) {
  23269. if (ret == -1) {
  23270. VERROR_INT("xmlSchemaValidateQName",
  23271. "calling xmlValidateQName()");
  23272. return (-1);
  23273. }
  23274. return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
  23275. }
  23276. /*
  23277. * NOTE: xmlSplitQName2 will always return a duplicated
  23278. * strings.
  23279. */
  23280. local = xmlSplitQName2(value, &prefix);
  23281. if (local == NULL)
  23282. local = xmlStrdup(value);
  23283. /*
  23284. * OPTIMIZE TODO: Use flags for:
  23285. * - is there any namespace binding?
  23286. * - is there a default namespace?
  23287. */
  23288. nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23289. if (prefix != NULL) {
  23290. xmlFree(prefix);
  23291. /*
  23292. * A namespace must be found if the prefix is
  23293. * NOT NULL.
  23294. */
  23295. if (nsName == NULL) {
  23296. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23297. xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
  23298. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23299. "The QName value '%s' has no "
  23300. "corresponding namespace declaration in "
  23301. "scope", value, NULL);
  23302. if (local != NULL)
  23303. xmlFree(local);
  23304. return (ret);
  23305. }
  23306. }
  23307. if (valNeeded && val) {
  23308. if (nsName != NULL)
  23309. *val = xmlSchemaNewQNameValue(
  23310. BAD_CAST xmlStrdup(nsName), BAD_CAST local);
  23311. else
  23312. *val = xmlSchemaNewQNameValue(NULL,
  23313. BAD_CAST local);
  23314. } else
  23315. xmlFree(local);
  23316. return (0);
  23317. }
  23318. /*
  23319. * cvc-simple-type
  23320. */
  23321. static int
  23322. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  23323. xmlNodePtr node,
  23324. xmlSchemaTypePtr type,
  23325. const xmlChar *value,
  23326. xmlSchemaValPtr *retVal,
  23327. int fireErrors,
  23328. int normalize,
  23329. int isNormalized)
  23330. {
  23331. int ret = 0, valNeeded = (retVal) ? 1 : 0;
  23332. xmlSchemaValPtr val = NULL;
  23333. /* xmlSchemaWhitespaceValueType ws; */
  23334. xmlChar *normValue = NULL;
  23335. #define NORMALIZE(atype) \
  23336. if ((! isNormalized) && \
  23337. (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
  23338. normValue = xmlSchemaNormalizeValue(atype, value); \
  23339. if (normValue != NULL) \
  23340. value = normValue; \
  23341. isNormalized = 1; \
  23342. }
  23343. if ((retVal != NULL) && (*retVal != NULL)) {
  23344. xmlSchemaFreeValue(*retVal);
  23345. *retVal = NULL;
  23346. }
  23347. /*
  23348. * 3.14.4 Simple Type Definition Validation Rules
  23349. * Validation Rule: String Valid
  23350. */
  23351. /*
  23352. * 1 It is schema-valid with respect to that definition as defined
  23353. * by Datatype Valid in [XML Schemas: Datatypes].
  23354. */
  23355. /*
  23356. * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
  23357. * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
  23358. * the string must be a `declared entity name`.
  23359. */
  23360. /*
  23361. * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
  23362. * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
  23363. * then every whitespace-delimited substring of the string must be a `declared
  23364. * entity name`.
  23365. */
  23366. /*
  23367. * 2.3 otherwise no further condition applies.
  23368. */
  23369. if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
  23370. valNeeded = 1;
  23371. if (value == NULL)
  23372. value = BAD_CAST "";
  23373. if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
  23374. xmlSchemaTypePtr biType; /* The built-in type. */
  23375. /*
  23376. * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
  23377. * a literal in the `lexical space` of {base type definition}"
  23378. */
  23379. /*
  23380. * Whitespace-normalize.
  23381. */
  23382. NORMALIZE(type);
  23383. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  23384. /*
  23385. * Get the built-in type.
  23386. */
  23387. biType = type->baseType;
  23388. while ((biType != NULL) &&
  23389. (biType->type != XML_SCHEMA_TYPE_BASIC))
  23390. biType = biType->baseType;
  23391. if (biType == NULL) {
  23392. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23393. "could not get the built-in type");
  23394. goto internal_error;
  23395. }
  23396. } else
  23397. biType = type;
  23398. /*
  23399. * NOTATIONs need to be processed here, since they need
  23400. * to lookup in the hashtable of NOTATION declarations of the schema.
  23401. */
  23402. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  23403. switch (biType->builtInType) {
  23404. case XML_SCHEMAS_NOTATION:
  23405. ret = xmlSchemaValidateNotation(
  23406. (xmlSchemaValidCtxtPtr) actxt,
  23407. ((xmlSchemaValidCtxtPtr) actxt)->schema,
  23408. NULL, value, &val, valNeeded);
  23409. break;
  23410. case XML_SCHEMAS_QNAME:
  23411. ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
  23412. value, &val, valNeeded);
  23413. break;
  23414. default:
  23415. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23416. if (valNeeded)
  23417. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23418. value, &val, node);
  23419. else
  23420. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23421. value, NULL, node);
  23422. break;
  23423. }
  23424. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  23425. switch (biType->builtInType) {
  23426. case XML_SCHEMAS_NOTATION:
  23427. ret = xmlSchemaValidateNotation(NULL,
  23428. ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
  23429. value, &val, valNeeded);
  23430. break;
  23431. default:
  23432. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23433. if (valNeeded)
  23434. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23435. value, &val, node);
  23436. else
  23437. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23438. value, NULL, node);
  23439. break;
  23440. }
  23441. } else {
  23442. /*
  23443. * Validation via a public API is not implemented yet.
  23444. */
  23445. TODO
  23446. goto internal_error;
  23447. }
  23448. if (ret != 0) {
  23449. if (ret < 0) {
  23450. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23451. "validating against a built-in type");
  23452. goto internal_error;
  23453. }
  23454. if (WXS_IS_LIST(type))
  23455. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23456. else
  23457. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23458. }
  23459. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23460. /*
  23461. * Check facets.
  23462. */
  23463. ret = xmlSchemaValidateFacets(actxt, node, type,
  23464. (xmlSchemaValType) biType->builtInType, value, val,
  23465. 0, fireErrors);
  23466. if (ret != 0) {
  23467. if (ret < 0) {
  23468. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23469. "validating facets of atomic simple type");
  23470. goto internal_error;
  23471. }
  23472. if (WXS_IS_LIST(type))
  23473. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23474. else
  23475. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23476. }
  23477. }
  23478. else if (fireErrors && (ret > 0))
  23479. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23480. } else if (WXS_IS_LIST(type)) {
  23481. xmlSchemaTypePtr itemType;
  23482. const xmlChar *cur, *end;
  23483. xmlChar *tmpValue = NULL;
  23484. unsigned long len = 0;
  23485. xmlSchemaValPtr prevVal = NULL, curVal = NULL;
  23486. /* 1.2.2 if {variety} is `list` then the string must be a sequence
  23487. * of white space separated tokens, each of which `match`es a literal
  23488. * in the `lexical space` of {item type definition}
  23489. */
  23490. /*
  23491. * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
  23492. * the list type has an enum or pattern facet.
  23493. */
  23494. NORMALIZE(type);
  23495. /*
  23496. * VAL TODO: Optimize validation of empty values.
  23497. * VAL TODO: We do not have computed values for lists.
  23498. */
  23499. itemType = WXS_LIST_ITEMTYPE(type);
  23500. cur = value;
  23501. do {
  23502. while (IS_BLANK_CH(*cur))
  23503. cur++;
  23504. end = cur;
  23505. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  23506. end++;
  23507. if (end == cur)
  23508. break;
  23509. tmpValue = xmlStrndup(cur, end - cur);
  23510. len++;
  23511. if (valNeeded)
  23512. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23513. tmpValue, &curVal, fireErrors, 0, 1);
  23514. else
  23515. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23516. tmpValue, NULL, fireErrors, 0, 1);
  23517. FREE_AND_NULL(tmpValue);
  23518. if (curVal != NULL) {
  23519. /*
  23520. * Add to list of computed values.
  23521. */
  23522. if (val == NULL)
  23523. val = curVal;
  23524. else
  23525. xmlSchemaValueAppend(prevVal, curVal);
  23526. prevVal = curVal;
  23527. curVal = NULL;
  23528. }
  23529. if (ret != 0) {
  23530. if (ret < 0) {
  23531. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23532. "validating an item of list simple type");
  23533. goto internal_error;
  23534. }
  23535. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23536. break;
  23537. }
  23538. cur = end;
  23539. } while (*cur != 0);
  23540. FREE_AND_NULL(tmpValue);
  23541. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23542. /*
  23543. * Apply facets (pattern, enumeration).
  23544. */
  23545. ret = xmlSchemaValidateFacets(actxt, node, type,
  23546. XML_SCHEMAS_UNKNOWN, value, val,
  23547. len, fireErrors);
  23548. if (ret != 0) {
  23549. if (ret < 0) {
  23550. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23551. "validating facets of list simple type");
  23552. goto internal_error;
  23553. }
  23554. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23555. }
  23556. }
  23557. if (fireErrors && (ret > 0)) {
  23558. /*
  23559. * Report the normalized value.
  23560. */
  23561. normalize = 1;
  23562. NORMALIZE(type);
  23563. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23564. }
  23565. } else if (WXS_IS_UNION(type)) {
  23566. xmlSchemaTypeLinkPtr memberLink;
  23567. /*
  23568. * TODO: For all datatypes `derived` by `union` whiteSpace does
  23569. * not apply directly; however, the normalization behavior of `union`
  23570. * types is controlled by the value of whiteSpace on that one of the
  23571. * `memberTypes` against which the `union` is successfully validated.
  23572. *
  23573. * This means that the value is normalized by the first validating
  23574. * member type, then the facets of the union type are applied. This
  23575. * needs changing of the value!
  23576. */
  23577. /*
  23578. * 1.2.3 if {variety} is `union` then the string must `match` a
  23579. * literal in the `lexical space` of at least one member of
  23580. * {member type definitions}
  23581. */
  23582. memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
  23583. if (memberLink == NULL) {
  23584. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23585. "union simple type has no member types");
  23586. goto internal_error;
  23587. }
  23588. /*
  23589. * Always normalize union type values, since we currently
  23590. * cannot store the whitespace information with the value
  23591. * itself; otherwise a later value-comparison would be
  23592. * not possible.
  23593. */
  23594. while (memberLink != NULL) {
  23595. if (valNeeded)
  23596. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23597. memberLink->type, value, &val, 0, 1, 0);
  23598. else
  23599. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23600. memberLink->type, value, NULL, 0, 1, 0);
  23601. if (ret <= 0)
  23602. break;
  23603. memberLink = memberLink->next;
  23604. }
  23605. if (ret != 0) {
  23606. if (ret < 0) {
  23607. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23608. "validating members of union simple type");
  23609. goto internal_error;
  23610. }
  23611. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23612. }
  23613. /*
  23614. * Apply facets (pattern, enumeration).
  23615. */
  23616. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23617. /*
  23618. * The normalization behavior of `union` types is controlled by
  23619. * the value of whiteSpace on that one of the `memberTypes`
  23620. * against which the `union` is successfully validated.
  23621. */
  23622. NORMALIZE(memberLink->type);
  23623. ret = xmlSchemaValidateFacets(actxt, node, type,
  23624. XML_SCHEMAS_UNKNOWN, value, val,
  23625. 0, fireErrors);
  23626. if (ret != 0) {
  23627. if (ret < 0) {
  23628. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23629. "validating facets of union simple type");
  23630. goto internal_error;
  23631. }
  23632. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23633. }
  23634. }
  23635. if (fireErrors && (ret > 0))
  23636. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23637. }
  23638. if (normValue != NULL)
  23639. xmlFree(normValue);
  23640. if (ret == 0) {
  23641. if (retVal != NULL)
  23642. *retVal = val;
  23643. else if (val != NULL)
  23644. xmlSchemaFreeValue(val);
  23645. } else if (val != NULL)
  23646. xmlSchemaFreeValue(val);
  23647. return (ret);
  23648. internal_error:
  23649. if (normValue != NULL)
  23650. xmlFree(normValue);
  23651. if (val != NULL)
  23652. xmlSchemaFreeValue(val);
  23653. return (-1);
  23654. }
  23655. static int
  23656. xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
  23657. const xmlChar *value,
  23658. const xmlChar **nsName,
  23659. const xmlChar **localName)
  23660. {
  23661. int ret = 0;
  23662. if ((nsName == NULL) || (localName == NULL))
  23663. return (-1);
  23664. *nsName = NULL;
  23665. *localName = NULL;
  23666. ret = xmlValidateQName(value, 1);
  23667. if (ret == -1)
  23668. return (-1);
  23669. if (ret > 0) {
  23670. xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
  23671. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23672. value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
  23673. return (1);
  23674. }
  23675. {
  23676. xmlChar *local = NULL;
  23677. xmlChar *prefix;
  23678. /*
  23679. * NOTE: xmlSplitQName2 will return a duplicated
  23680. * string.
  23681. */
  23682. local = xmlSplitQName2(value, &prefix);
  23683. if (local == NULL)
  23684. *localName = xmlDictLookup(vctxt->dict, value, -1);
  23685. else {
  23686. *localName = xmlDictLookup(vctxt->dict, local, -1);
  23687. xmlFree(local);
  23688. }
  23689. *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23690. if (prefix != NULL) {
  23691. xmlFree(prefix);
  23692. /*
  23693. * A namespace must be found if the prefix is NOT NULL.
  23694. */
  23695. if (*nsName == NULL) {
  23696. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23697. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23698. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23699. "The QName value '%s' has no "
  23700. "corresponding namespace declaration in scope",
  23701. value, NULL);
  23702. return (2);
  23703. }
  23704. }
  23705. }
  23706. return (0);
  23707. }
  23708. static int
  23709. xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
  23710. xmlSchemaAttrInfoPtr iattr,
  23711. xmlSchemaTypePtr *localType,
  23712. xmlSchemaElementPtr elemDecl)
  23713. {
  23714. int ret = 0;
  23715. /*
  23716. * cvc-elt (3.3.4) : (4)
  23717. * AND
  23718. * Schema-Validity Assessment (Element) (cvc-assess-elt)
  23719. * (1.2.1.2.1) - (1.2.1.2.4)
  23720. * Handle 'xsi:type'.
  23721. */
  23722. if (localType == NULL)
  23723. return (-1);
  23724. *localType = NULL;
  23725. if (iattr == NULL)
  23726. return (0);
  23727. else {
  23728. const xmlChar *nsName = NULL, *local = NULL;
  23729. /*
  23730. * TODO: We should report a *warning* that the type was overridden
  23731. * by the instance.
  23732. */
  23733. ACTIVATE_ATTRIBUTE(iattr);
  23734. /*
  23735. * (cvc-elt) (3.3.4) : (4.1)
  23736. * (cvc-assess-elt) (1.2.1.2.2)
  23737. */
  23738. ret = xmlSchemaVExpandQName(vctxt, iattr->value,
  23739. &nsName, &local);
  23740. if (ret != 0) {
  23741. if (ret < 0) {
  23742. VERROR_INT("xmlSchemaValidateElementByDeclaration",
  23743. "calling xmlSchemaQNameExpand() to validate the "
  23744. "attribute 'xsi:type'");
  23745. goto internal_error;
  23746. }
  23747. goto exit;
  23748. }
  23749. /*
  23750. * (cvc-elt) (3.3.4) : (4.2)
  23751. * (cvc-assess-elt) (1.2.1.2.3)
  23752. */
  23753. *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
  23754. if (*localType == NULL) {
  23755. xmlChar *str = NULL;
  23756. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23757. XML_SCHEMAV_CVC_ELT_4_2, NULL,
  23758. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23759. "The QName value '%s' of the xsi:type attribute does not "
  23760. "resolve to a type definition",
  23761. xmlSchemaFormatQName(&str, nsName, local), NULL);
  23762. FREE_AND_NULL(str);
  23763. ret = vctxt->err;
  23764. goto exit;
  23765. }
  23766. if (elemDecl != NULL) {
  23767. int set = 0;
  23768. /*
  23769. * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
  23770. * "The `local type definition` must be validly
  23771. * derived from the {type definition} given the union of
  23772. * the {disallowed substitutions} and the {type definition}'s
  23773. * {prohibited substitutions}, as defined in
  23774. * Type Derivation OK (Complex) ($3.4.6)
  23775. * (if it is a complex type definition),
  23776. * or given {disallowed substitutions} as defined in Type
  23777. * Derivation OK (Simple) ($3.14.6) (if it is a simple type
  23778. * definition)."
  23779. *
  23780. * {disallowed substitutions}: the "block" on the element decl.
  23781. * {prohibited substitutions}: the "block" on the type def.
  23782. */
  23783. /*
  23784. * OPTIMIZE TODO: We could map types already evaluated
  23785. * to be validly derived from other types to avoid checking
  23786. * this over and over for the same types.
  23787. */
  23788. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
  23789. (elemDecl->subtypes->flags &
  23790. XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
  23791. set |= SUBSET_EXTENSION;
  23792. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
  23793. (elemDecl->subtypes->flags &
  23794. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
  23795. set |= SUBSET_RESTRICTION;
  23796. /*
  23797. * REMOVED and CHANGED since this produced a parser context
  23798. * which adds to the string dict of the schema. So this would
  23799. * change the schema and we don't want this. We don't need
  23800. * the parser context anymore.
  23801. *
  23802. * if ((vctxt->pctxt == NULL) &&
  23803. * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  23804. * return (-1);
  23805. */
  23806. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
  23807. elemDecl->subtypes, set) != 0) {
  23808. xmlChar *str = NULL;
  23809. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23810. XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
  23811. "The type definition '%s', specified by xsi:type, is "
  23812. "blocked or not validly derived from the type definition "
  23813. "of the element declaration",
  23814. xmlSchemaFormatQName(&str,
  23815. (*localType)->targetNamespace,
  23816. (*localType)->name),
  23817. NULL);
  23818. FREE_AND_NULL(str);
  23819. ret = vctxt->err;
  23820. *localType = NULL;
  23821. }
  23822. }
  23823. }
  23824. exit:
  23825. ACTIVATE_ELEM;
  23826. return (ret);
  23827. internal_error:
  23828. ACTIVATE_ELEM;
  23829. return (-1);
  23830. }
  23831. static int
  23832. xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
  23833. {
  23834. xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
  23835. xmlSchemaTypePtr actualType;
  23836. /*
  23837. * cvc-elt (3.3.4) : 1
  23838. */
  23839. if (elemDecl == NULL) {
  23840. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
  23841. "No matching declaration available");
  23842. return (vctxt->err);
  23843. }
  23844. actualType = WXS_ELEM_TYPEDEF(elemDecl);
  23845. /*
  23846. * cvc-elt (3.3.4) : 2
  23847. */
  23848. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
  23849. VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
  23850. "The element declaration is abstract");
  23851. return (vctxt->err);
  23852. }
  23853. if (actualType == NULL) {
  23854. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23855. "The type definition is absent");
  23856. return (XML_SCHEMAV_CVC_TYPE_1);
  23857. }
  23858. if (vctxt->nbAttrInfos != 0) {
  23859. int ret;
  23860. xmlSchemaAttrInfoPtr iattr;
  23861. /*
  23862. * cvc-elt (3.3.4) : 3
  23863. * Handle 'xsi:nil'.
  23864. */
  23865. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23866. XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
  23867. if (iattr) {
  23868. ACTIVATE_ATTRIBUTE(iattr);
  23869. /*
  23870. * Validate the value.
  23871. */
  23872. ret = xmlSchemaVCheckCVCSimpleType(
  23873. ACTXT_CAST vctxt, NULL,
  23874. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  23875. iattr->value, &(iattr->val), 1, 0, 0);
  23876. ACTIVATE_ELEM;
  23877. if (ret < 0) {
  23878. VERROR_INT("xmlSchemaValidateElemDecl",
  23879. "calling xmlSchemaVCheckCVCSimpleType() to "
  23880. "validate the attribute 'xsi:nil'");
  23881. return (-1);
  23882. }
  23883. if (ret == 0) {
  23884. if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
  23885. /*
  23886. * cvc-elt (3.3.4) : 3.1
  23887. */
  23888. VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
  23889. "The element is not 'nillable'");
  23890. /* Does not return an error on purpose. */
  23891. } else {
  23892. if (xmlSchemaValueGetAsBoolean(iattr->val)) {
  23893. /*
  23894. * cvc-elt (3.3.4) : 3.2.2
  23895. */
  23896. if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
  23897. (elemDecl->value != NULL)) {
  23898. VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
  23899. "The element cannot be 'nilled' because "
  23900. "there is a fixed value constraint defined "
  23901. "for it");
  23902. /* Does not return an error on purpose. */
  23903. } else
  23904. vctxt->inode->flags |=
  23905. XML_SCHEMA_ELEM_INFO_NILLED;
  23906. }
  23907. }
  23908. }
  23909. }
  23910. /*
  23911. * cvc-elt (3.3.4) : 4
  23912. * Handle 'xsi:type'.
  23913. */
  23914. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23915. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  23916. if (iattr) {
  23917. xmlSchemaTypePtr localType = NULL;
  23918. ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
  23919. elemDecl);
  23920. if (ret != 0) {
  23921. if (ret == -1) {
  23922. VERROR_INT("xmlSchemaValidateElemDecl",
  23923. "calling xmlSchemaProcessXSIType() to "
  23924. "process the attribute 'xsi:type'");
  23925. return (-1);
  23926. }
  23927. /* Does not return an error on purpose. */
  23928. }
  23929. if (localType != NULL) {
  23930. vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
  23931. actualType = localType;
  23932. }
  23933. }
  23934. }
  23935. /*
  23936. * IDC: Register identity-constraint XPath matchers.
  23937. */
  23938. if ((elemDecl->idcs != NULL) &&
  23939. (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
  23940. return (-1);
  23941. /*
  23942. * No actual type definition.
  23943. */
  23944. if (actualType == NULL) {
  23945. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23946. "The type definition is absent");
  23947. return (XML_SCHEMAV_CVC_TYPE_1);
  23948. }
  23949. /*
  23950. * Remember the actual type definition.
  23951. */
  23952. vctxt->inode->typeDef = actualType;
  23953. return (0);
  23954. }
  23955. static int
  23956. xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
  23957. {
  23958. xmlSchemaAttrInfoPtr iattr;
  23959. int ret = 0, i;
  23960. /*
  23961. * SPEC cvc-type (3.1.1)
  23962. * "The attributes of must be empty, excepting those whose namespace
  23963. * name is identical to http://www.w3.org/2001/XMLSchema-instance and
  23964. * whose local name is one of type, nil, schemaLocation or
  23965. * noNamespaceSchemaLocation."
  23966. */
  23967. if (vctxt->nbAttrInfos == 0)
  23968. return (0);
  23969. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23970. iattr = vctxt->attrInfos[i];
  23971. if (! iattr->metaType) {
  23972. ACTIVATE_ATTRIBUTE(iattr)
  23973. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  23974. XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
  23975. ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
  23976. }
  23977. }
  23978. ACTIVATE_ELEM
  23979. return (ret);
  23980. }
  23981. /*
  23982. * Cleanup currently used attribute infos.
  23983. */
  23984. static void
  23985. xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
  23986. {
  23987. int i;
  23988. xmlSchemaAttrInfoPtr attr;
  23989. if (vctxt->nbAttrInfos == 0)
  23990. return;
  23991. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23992. attr = vctxt->attrInfos[i];
  23993. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  23994. if (attr->localName != NULL)
  23995. xmlFree((xmlChar *) attr->localName);
  23996. if (attr->nsName != NULL)
  23997. xmlFree((xmlChar *) attr->nsName);
  23998. }
  23999. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  24000. if (attr->value != NULL)
  24001. xmlFree((xmlChar *) attr->value);
  24002. }
  24003. if (attr->val != NULL) {
  24004. xmlSchemaFreeValue(attr->val);
  24005. attr->val = NULL;
  24006. }
  24007. memset(attr, 0, sizeof(xmlSchemaAttrInfo));
  24008. }
  24009. vctxt->nbAttrInfos = 0;
  24010. }
  24011. /*
  24012. * 3.4.4 Complex Type Definition Validation Rules
  24013. * Element Locally Valid (Complex Type) (cvc-complex-type)
  24014. * 3.2.4 Attribute Declaration Validation Rules
  24015. * Validation Rule: Attribute Locally Valid (cvc-attribute)
  24016. * Attribute Locally Valid (Use) (cvc-au)
  24017. *
  24018. * Only "assessed" attribute information items will be visible to
  24019. * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
  24020. */
  24021. static int
  24022. xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
  24023. {
  24024. xmlSchemaTypePtr type = vctxt->inode->typeDef;
  24025. xmlSchemaItemListPtr attrUseList;
  24026. xmlSchemaAttributeUsePtr attrUse = NULL;
  24027. xmlSchemaAttributePtr attrDecl = NULL;
  24028. xmlSchemaAttrInfoPtr iattr, tmpiattr;
  24029. int i, j, found, nbAttrs, nbUses;
  24030. int xpathRes = 0, res, wildIDs = 0, fixed;
  24031. xmlNodePtr defAttrOwnerElem = NULL;
  24032. /*
  24033. * SPEC (cvc-attribute)
  24034. * (1) "The declaration must not be `absent` (see Missing
  24035. * Sub-components ($5.3) for how this can fail to be
  24036. * the case)."
  24037. * (2) "Its {type definition} must not be absent."
  24038. *
  24039. * NOTE (1) + (2): This is not handled here, since we currently do not
  24040. * allow validation against schemas which have missing sub-components.
  24041. *
  24042. * SPEC (cvc-complex-type)
  24043. * (3) "For each attribute information item in the element information
  24044. * item's [attributes] excepting those whose [namespace name] is
  24045. * identical to http://www.w3.org/2001/XMLSchema-instance and whose
  24046. * [local name] is one of type, nil, schemaLocation or
  24047. * noNamespaceSchemaLocation, the appropriate case among the following
  24048. * must be true:
  24049. *
  24050. */
  24051. attrUseList = (xmlSchemaItemListPtr) type->attrUses;
  24052. /*
  24053. * @nbAttrs is the number of attributes present in the instance.
  24054. */
  24055. nbAttrs = vctxt->nbAttrInfos;
  24056. if (attrUseList != NULL)
  24057. nbUses = attrUseList->nbItems;
  24058. else
  24059. nbUses = 0;
  24060. for (i = 0; i < nbUses; i++) {
  24061. found = 0;
  24062. attrUse = attrUseList->items[i];
  24063. attrDecl = WXS_ATTRUSE_DECL(attrUse);
  24064. for (j = 0; j < nbAttrs; j++) {
  24065. iattr = vctxt->attrInfos[j];
  24066. /*
  24067. * SPEC (cvc-complex-type) (3)
  24068. * Skip meta attributes.
  24069. */
  24070. if (iattr->metaType)
  24071. continue;
  24072. if (iattr->localName[0] != attrDecl->name[0])
  24073. continue;
  24074. if (!xmlStrEqual(iattr->localName, attrDecl->name))
  24075. continue;
  24076. if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
  24077. continue;
  24078. found = 1;
  24079. /*
  24080. * SPEC (cvc-complex-type)
  24081. * (3.1) "If there is among the {attribute uses} an attribute
  24082. * use with an {attribute declaration} whose {name} matches
  24083. * the attribute information item's [local name] and whose
  24084. * {target namespace} is identical to the attribute information
  24085. * item's [namespace name] (where an `absent` {target namespace}
  24086. * is taken to be identical to a [namespace name] with no value),
  24087. * then the attribute information must be `valid` with respect
  24088. * to that attribute use as per Attribute Locally Valid (Use)
  24089. * ($3.5.4). In this case the {attribute declaration} of that
  24090. * attribute use is the `context-determined declaration` for the
  24091. * attribute information item with respect to Schema-Validity
  24092. * Assessment (Attribute) ($3.2.4) and
  24093. * Assessment Outcome (Attribute) ($3.2.5).
  24094. */
  24095. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  24096. iattr->use = attrUse;
  24097. /*
  24098. * Context-determined declaration.
  24099. */
  24100. iattr->decl = attrDecl;
  24101. iattr->typeDef = attrDecl->subtypes;
  24102. break;
  24103. }
  24104. if (found)
  24105. continue;
  24106. if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
  24107. /*
  24108. * Handle non-existent, required attributes.
  24109. *
  24110. * SPEC (cvc-complex-type)
  24111. * (4) "The {attribute declaration} of each attribute use in
  24112. * the {attribute uses} whose {required} is true matches one
  24113. * of the attribute information items in the element information
  24114. * item's [attributes] as per clause 3.1 above."
  24115. */
  24116. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  24117. if (tmpiattr == NULL) {
  24118. VERROR_INT(
  24119. "xmlSchemaVAttributesComplex",
  24120. "calling xmlSchemaGetFreshAttrInfo()");
  24121. return (-1);
  24122. }
  24123. tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
  24124. tmpiattr->use = attrUse;
  24125. tmpiattr->decl = attrDecl;
  24126. } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  24127. ((attrUse->defValue != NULL) ||
  24128. (attrDecl->defValue != NULL))) {
  24129. /*
  24130. * Handle non-existent, optional, default/fixed attributes.
  24131. */
  24132. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  24133. if (tmpiattr == NULL) {
  24134. VERROR_INT(
  24135. "xmlSchemaVAttributesComplex",
  24136. "calling xmlSchemaGetFreshAttrInfo()");
  24137. return (-1);
  24138. }
  24139. tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
  24140. tmpiattr->use = attrUse;
  24141. tmpiattr->decl = attrDecl;
  24142. tmpiattr->typeDef = attrDecl->subtypes;
  24143. tmpiattr->localName = attrDecl->name;
  24144. tmpiattr->nsName = attrDecl->targetNamespace;
  24145. }
  24146. }
  24147. if (vctxt->nbAttrInfos == 0)
  24148. return (0);
  24149. /*
  24150. * Validate against the wildcard.
  24151. */
  24152. if (type->attributeWildcard != NULL) {
  24153. /*
  24154. * SPEC (cvc-complex-type)
  24155. * (3.2.1) "There must be an {attribute wildcard}."
  24156. */
  24157. for (i = 0; i < nbAttrs; i++) {
  24158. iattr = vctxt->attrInfos[i];
  24159. /*
  24160. * SPEC (cvc-complex-type) (3)
  24161. * Skip meta attributes.
  24162. */
  24163. if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
  24164. continue;
  24165. /*
  24166. * SPEC (cvc-complex-type)
  24167. * (3.2.2) "The attribute information item must be `valid` with
  24168. * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
  24169. *
  24170. * SPEC Item Valid (Wildcard) (cvc-wildcard)
  24171. * "... its [namespace name] must be `valid` with respect to
  24172. * the wildcard constraint, as defined in Wildcard allows
  24173. * Namespace Name ($3.10.4)."
  24174. */
  24175. if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
  24176. iattr->nsName) == 0) {
  24177. /*
  24178. * Handle processContents.
  24179. *
  24180. * SPEC (cvc-wildcard):
  24181. * processContents | context-determined declaration:
  24182. * "strict" "mustFind"
  24183. * "lax" "none"
  24184. * "skip" "skip"
  24185. */
  24186. if (type->attributeWildcard->processContents ==
  24187. XML_SCHEMAS_ANY_SKIP) {
  24188. /*
  24189. * context-determined declaration = "skip"
  24190. *
  24191. * SPEC PSVI Assessment Outcome (Attribute)
  24192. * [validity] = "notKnown"
  24193. * [validation attempted] = "none"
  24194. */
  24195. iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
  24196. continue;
  24197. }
  24198. /*
  24199. * Find an attribute declaration.
  24200. */
  24201. iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
  24202. iattr->localName, iattr->nsName);
  24203. if (iattr->decl != NULL) {
  24204. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  24205. /*
  24206. * SPEC (cvc-complex-type)
  24207. * (5) "Let [Definition:] the wild IDs be the set of
  24208. * all attribute information item to which clause 3.2
  24209. * applied and whose `validation` resulted in a
  24210. * `context-determined declaration` of mustFind or no
  24211. * `context-determined declaration` at all, and whose
  24212. * [local name] and [namespace name] resolve (as
  24213. * defined by QName resolution (Instance) ($3.15.4)) to
  24214. * an attribute declaration whose {type definition} is
  24215. * or is derived from ID. Then all of the following
  24216. * must be true:"
  24217. */
  24218. iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
  24219. if (xmlSchemaIsDerivedFromBuiltInType(
  24220. iattr->typeDef, XML_SCHEMAS_ID)) {
  24221. /*
  24222. * SPEC (5.1) "There must be no more than one
  24223. * item in `wild IDs`."
  24224. */
  24225. if (wildIDs != 0) {
  24226. /* VAL TODO */
  24227. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
  24228. TODO
  24229. continue;
  24230. }
  24231. wildIDs++;
  24232. /*
  24233. * SPEC (cvc-complex-type)
  24234. * (5.2) "If `wild IDs` is non-empty, there must not
  24235. * be any attribute uses among the {attribute uses}
  24236. * whose {attribute declaration}'s {type definition}
  24237. * is or is derived from ID."
  24238. */
  24239. if (attrUseList != NULL) {
  24240. for (j = 0; j < attrUseList->nbItems; j++) {
  24241. if (xmlSchemaIsDerivedFromBuiltInType(
  24242. WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
  24243. XML_SCHEMAS_ID)) {
  24244. /* URGENT VAL TODO: implement */
  24245. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
  24246. TODO
  24247. break;
  24248. }
  24249. }
  24250. }
  24251. }
  24252. } else if (type->attributeWildcard->processContents ==
  24253. XML_SCHEMAS_ANY_LAX) {
  24254. iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
  24255. /*
  24256. * SPEC PSVI Assessment Outcome (Attribute)
  24257. * [validity] = "notKnown"
  24258. * [validation attempted] = "none"
  24259. */
  24260. } else {
  24261. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
  24262. }
  24263. }
  24264. }
  24265. }
  24266. if (vctxt->nbAttrInfos == 0)
  24267. return (0);
  24268. /*
  24269. * Get the owner element; needed for creation of default attributes.
  24270. * This fixes bug #341337, reported by David Grohmann.
  24271. */
  24272. if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
  24273. xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
  24274. if (ielem && ielem->node && ielem->node->doc)
  24275. defAttrOwnerElem = ielem->node;
  24276. }
  24277. /*
  24278. * Validate values, create default attributes, evaluate IDCs.
  24279. */
  24280. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24281. iattr = vctxt->attrInfos[i];
  24282. /*
  24283. * VAL TODO: Note that we won't try to resolve IDCs to
  24284. * "lax" and "skip" validated attributes. Check what to
  24285. * do in this case.
  24286. */
  24287. if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
  24288. (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
  24289. continue;
  24290. /*
  24291. * VAL TODO: What to do if the type definition is missing?
  24292. */
  24293. if (iattr->typeDef == NULL) {
  24294. iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
  24295. continue;
  24296. }
  24297. ACTIVATE_ATTRIBUTE(iattr);
  24298. fixed = 0;
  24299. xpathRes = 0;
  24300. if (vctxt->xpathStates != NULL) {
  24301. /*
  24302. * Evaluate IDCs.
  24303. */
  24304. xpathRes = xmlSchemaXPathEvaluate(vctxt,
  24305. XML_ATTRIBUTE_NODE);
  24306. if (xpathRes == -1) {
  24307. VERROR_INT("xmlSchemaVAttributesComplex",
  24308. "calling xmlSchemaXPathEvaluate()");
  24309. goto internal_error;
  24310. }
  24311. }
  24312. if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
  24313. /*
  24314. * Default/fixed attributes.
  24315. * We need the value only if we need to resolve IDCs or
  24316. * will create default attributes.
  24317. */
  24318. if ((xpathRes) || (defAttrOwnerElem)) {
  24319. if (iattr->use->defValue != NULL) {
  24320. iattr->value = (xmlChar *) iattr->use->defValue;
  24321. iattr->val = iattr->use->defVal;
  24322. } else {
  24323. iattr->value = (xmlChar *) iattr->decl->defValue;
  24324. iattr->val = iattr->decl->defVal;
  24325. }
  24326. /*
  24327. * IDCs will consume the precomputed default value,
  24328. * so we need to clone it.
  24329. */
  24330. if (iattr->val == NULL) {
  24331. VERROR_INT("xmlSchemaVAttributesComplex",
  24332. "default/fixed value on an attribute use was "
  24333. "not precomputed");
  24334. goto internal_error;
  24335. }
  24336. iattr->val = xmlSchemaCopyValue(iattr->val);
  24337. if (iattr->val == NULL) {
  24338. VERROR_INT("xmlSchemaVAttributesComplex",
  24339. "calling xmlSchemaCopyValue()");
  24340. goto internal_error;
  24341. }
  24342. }
  24343. /*
  24344. * PSVI: Add the default attribute to the current element.
  24345. * VAL TODO: Should we use the *normalized* value? This currently
  24346. * uses the *initial* value.
  24347. */
  24348. if (defAttrOwnerElem) {
  24349. xmlChar *normValue;
  24350. const xmlChar *value;
  24351. value = iattr->value;
  24352. /*
  24353. * Normalize the value.
  24354. */
  24355. normValue = xmlSchemaNormalizeValue(iattr->typeDef,
  24356. iattr->value);
  24357. if (normValue != NULL)
  24358. value = BAD_CAST normValue;
  24359. if (iattr->nsName == NULL) {
  24360. if (xmlNewProp(defAttrOwnerElem,
  24361. iattr->localName, value) == NULL) {
  24362. VERROR_INT("xmlSchemaVAttributesComplex",
  24363. "calling xmlNewProp()");
  24364. if (normValue != NULL)
  24365. xmlFree(normValue);
  24366. goto internal_error;
  24367. }
  24368. } else {
  24369. xmlNsPtr ns;
  24370. ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
  24371. defAttrOwnerElem, iattr->nsName);
  24372. if (ns == NULL) {
  24373. xmlChar prefix[12];
  24374. int counter = 0;
  24375. /*
  24376. * Create a namespace declaration on the validation
  24377. * root node if no namespace declaration is in scope.
  24378. */
  24379. do {
  24380. snprintf((char *) prefix, 12, "p%d", counter++);
  24381. ns = xmlSearchNs(defAttrOwnerElem->doc,
  24382. defAttrOwnerElem, BAD_CAST prefix);
  24383. if (counter > 1000) {
  24384. VERROR_INT(
  24385. "xmlSchemaVAttributesComplex",
  24386. "could not compute a ns prefix for a "
  24387. "default/fixed attribute");
  24388. if (normValue != NULL)
  24389. xmlFree(normValue);
  24390. goto internal_error;
  24391. }
  24392. } while (ns != NULL);
  24393. ns = xmlNewNs(vctxt->validationRoot,
  24394. iattr->nsName, BAD_CAST prefix);
  24395. }
  24396. /*
  24397. * TODO:
  24398. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
  24399. * If we have QNames: do we need to ensure there's a
  24400. * prefix defined for the QName?
  24401. */
  24402. xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
  24403. }
  24404. if (normValue != NULL)
  24405. xmlFree(normValue);
  24406. }
  24407. /*
  24408. * Go directly to IDC evaluation.
  24409. */
  24410. goto eval_idcs;
  24411. }
  24412. /*
  24413. * Validate the value.
  24414. */
  24415. if (vctxt->value != NULL) {
  24416. /*
  24417. * Free last computed value; just for safety reasons.
  24418. */
  24419. xmlSchemaFreeValue(vctxt->value);
  24420. vctxt->value = NULL;
  24421. }
  24422. /*
  24423. * Note that the attribute *use* can be unavailable, if
  24424. * the attribute was a wild attribute.
  24425. */
  24426. if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
  24427. ((iattr->use != NULL) &&
  24428. (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
  24429. fixed = 1;
  24430. else
  24431. fixed = 0;
  24432. /*
  24433. * SPEC (cvc-attribute)
  24434. * (3) "The item's `normalized value` must be locally `valid`
  24435. * with respect to that {type definition} as per
  24436. * String Valid ($3.14.4)."
  24437. *
  24438. * VAL TODO: Do we already have the
  24439. * "normalized attribute value" here?
  24440. */
  24441. if (xpathRes || fixed) {
  24442. iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  24443. /*
  24444. * Request a computed value.
  24445. */
  24446. res = xmlSchemaVCheckCVCSimpleType(
  24447. ACTXT_CAST vctxt,
  24448. iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
  24449. 1, 1, 0);
  24450. } else {
  24451. res = xmlSchemaVCheckCVCSimpleType(
  24452. ACTXT_CAST vctxt,
  24453. iattr->node, iattr->typeDef, iattr->value, NULL,
  24454. 1, 0, 0);
  24455. }
  24456. if (res != 0) {
  24457. if (res == -1) {
  24458. VERROR_INT("xmlSchemaVAttributesComplex",
  24459. "calling xmlSchemaStreamValidateSimpleTypeValue()");
  24460. goto internal_error;
  24461. }
  24462. iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
  24463. /*
  24464. * SPEC PSVI Assessment Outcome (Attribute)
  24465. * [validity] = "invalid"
  24466. */
  24467. goto eval_idcs;
  24468. }
  24469. if (fixed) {
  24470. /*
  24471. * SPEC Attribute Locally Valid (Use) (cvc-au)
  24472. * "For an attribute information item to be `valid`
  24473. * with respect to an attribute use its *normalized*
  24474. * value must match the *canonical* lexical
  24475. * representation of the attribute use's {value
  24476. * constraint}value, if it is present and fixed."
  24477. *
  24478. * VAL TODO: The requirement for the *canonical* value
  24479. * will be removed in XML Schema 1.1.
  24480. */
  24481. /*
  24482. * SPEC Attribute Locally Valid (cvc-attribute)
  24483. * (4) "The item's *actual* value must match the *value* of
  24484. * the {value constraint}, if it is present and fixed."
  24485. */
  24486. if (iattr->val == NULL) {
  24487. /* VAL TODO: A value was not precomputed. */
  24488. TODO
  24489. goto eval_idcs;
  24490. }
  24491. if ((iattr->use != NULL) &&
  24492. (iattr->use->defValue != NULL)) {
  24493. if (iattr->use->defVal == NULL) {
  24494. /* VAL TODO: A default value was not precomputed. */
  24495. TODO
  24496. goto eval_idcs;
  24497. }
  24498. iattr->vcValue = iattr->use->defValue;
  24499. /*
  24500. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24501. (xmlSchemaWhitespaceValueType) ws,
  24502. attr->use->defVal,
  24503. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24504. */
  24505. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
  24506. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24507. } else {
  24508. if (iattr->decl->defVal == NULL) {
  24509. /* VAL TODO: A default value was not precomputed. */
  24510. TODO
  24511. goto eval_idcs;
  24512. }
  24513. iattr->vcValue = iattr->decl->defValue;
  24514. /*
  24515. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24516. (xmlSchemaWhitespaceValueType) ws,
  24517. attrDecl->defVal,
  24518. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24519. */
  24520. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
  24521. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24522. }
  24523. /*
  24524. * [validity] = "valid"
  24525. */
  24526. }
  24527. eval_idcs:
  24528. /*
  24529. * Evaluate IDCs.
  24530. */
  24531. if (xpathRes) {
  24532. if (xmlSchemaXPathProcessHistory(vctxt,
  24533. vctxt->depth +1) == -1) {
  24534. VERROR_INT("xmlSchemaVAttributesComplex",
  24535. "calling xmlSchemaXPathEvaluate()");
  24536. goto internal_error;
  24537. }
  24538. } else if (vctxt->xpathStates != NULL)
  24539. xmlSchemaXPathPop(vctxt);
  24540. }
  24541. /*
  24542. * Report errors.
  24543. */
  24544. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24545. iattr = vctxt->attrInfos[i];
  24546. if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
  24547. (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
  24548. (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
  24549. (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
  24550. continue;
  24551. ACTIVATE_ATTRIBUTE(iattr);
  24552. switch (iattr->state) {
  24553. case XML_SCHEMAS_ATTR_ERR_MISSING: {
  24554. xmlChar *str = NULL;
  24555. ACTIVATE_ELEM;
  24556. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24557. XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
  24558. "The attribute '%s' is required but missing",
  24559. xmlSchemaFormatQName(&str,
  24560. iattr->decl->targetNamespace,
  24561. iattr->decl->name),
  24562. NULL);
  24563. FREE_AND_NULL(str)
  24564. break;
  24565. }
  24566. case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
  24567. VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
  24568. "The type definition is absent");
  24569. break;
  24570. case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
  24571. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24572. XML_SCHEMAV_CVC_AU, NULL, NULL,
  24573. "The value '%s' does not match the fixed "
  24574. "value constraint '%s'",
  24575. iattr->value, iattr->vcValue);
  24576. break;
  24577. case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
  24578. VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
  24579. "No matching global attribute declaration available, but "
  24580. "demanded by the strict wildcard");
  24581. break;
  24582. case XML_SCHEMAS_ATTR_UNKNOWN:
  24583. if (iattr->metaType)
  24584. break;
  24585. /*
  24586. * MAYBE VAL TODO: One might report different error messages
  24587. * for the following errors.
  24588. */
  24589. if (type->attributeWildcard == NULL) {
  24590. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24591. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
  24592. } else {
  24593. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24594. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
  24595. }
  24596. break;
  24597. default:
  24598. break;
  24599. }
  24600. }
  24601. ACTIVATE_ELEM;
  24602. return (0);
  24603. internal_error:
  24604. ACTIVATE_ELEM;
  24605. return (-1);
  24606. }
  24607. static int
  24608. xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
  24609. int *skip)
  24610. {
  24611. xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
  24612. /*
  24613. * The namespace of the element was already identified to be
  24614. * matching the wildcard.
  24615. */
  24616. if ((skip == NULL) || (wild == NULL) ||
  24617. (wild->type != XML_SCHEMA_TYPE_ANY)) {
  24618. VERROR_INT("xmlSchemaValidateElemWildcard",
  24619. "bad arguments");
  24620. return (-1);
  24621. }
  24622. *skip = 0;
  24623. if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
  24624. /*
  24625. * URGENT VAL TODO: Either we need to position the stream to the
  24626. * next sibling, or walk the whole subtree.
  24627. */
  24628. *skip = 1;
  24629. return (0);
  24630. }
  24631. {
  24632. xmlSchemaElementPtr decl = NULL;
  24633. decl = xmlSchemaGetElem(vctxt->schema,
  24634. vctxt->inode->localName, vctxt->inode->nsName);
  24635. if (decl != NULL) {
  24636. vctxt->inode->decl = decl;
  24637. return (0);
  24638. }
  24639. }
  24640. if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
  24641. /* VAL TODO: Change to proper error code. */
  24642. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
  24643. "No matching global element declaration available, but "
  24644. "demanded by the strict wildcard");
  24645. return (vctxt->err);
  24646. }
  24647. if (vctxt->nbAttrInfos != 0) {
  24648. xmlSchemaAttrInfoPtr iattr;
  24649. /*
  24650. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24651. * (1.2.1.2.1) - (1.2.1.2.3 )
  24652. *
  24653. * Use the xsi:type attribute for the type definition.
  24654. */
  24655. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  24656. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  24657. if (iattr != NULL) {
  24658. if (xmlSchemaProcessXSIType(vctxt, iattr,
  24659. &(vctxt->inode->typeDef), NULL) == -1) {
  24660. VERROR_INT("xmlSchemaValidateElemWildcard",
  24661. "calling xmlSchemaProcessXSIType() to "
  24662. "process the attribute 'xsi:nil'");
  24663. return (-1);
  24664. }
  24665. /*
  24666. * Don't return an error on purpose.
  24667. */
  24668. return (0);
  24669. }
  24670. }
  24671. /*
  24672. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24673. *
  24674. * Fallback to "anyType".
  24675. */
  24676. vctxt->inode->typeDef =
  24677. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  24678. return (0);
  24679. }
  24680. /*
  24681. * xmlSchemaCheckCOSValidDefault:
  24682. *
  24683. * This will be called if: not nilled, no content and a default/fixed
  24684. * value is provided.
  24685. */
  24686. static int
  24687. xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
  24688. const xmlChar *value,
  24689. xmlSchemaValPtr *val)
  24690. {
  24691. int ret = 0;
  24692. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24693. /*
  24694. * cos-valid-default:
  24695. * Schema Component Constraint: Element Default Valid (Immediate)
  24696. * For a string to be a valid default with respect to a type
  24697. * definition the appropriate case among the following must be true:
  24698. */
  24699. if WXS_IS_COMPLEX(inode->typeDef) {
  24700. /*
  24701. * Complex type.
  24702. *
  24703. * SPEC (2.1) "its {content type} must be a simple type definition
  24704. * or mixed."
  24705. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  24706. * type}'s particle must be `emptiable` as defined by
  24707. * Particle Emptiable ($3.9.6)."
  24708. */
  24709. if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
  24710. ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
  24711. (! WXS_EMPTIABLE(inode->typeDef)))) {
  24712. ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
  24713. /* NOTE that this covers (2.2.2) as well. */
  24714. VERROR(ret, NULL,
  24715. "For a string to be a valid default, the type definition "
  24716. "must be a simple type or a complex type with simple content "
  24717. "or mixed content and a particle emptiable");
  24718. return(ret);
  24719. }
  24720. }
  24721. /*
  24722. * 1 If the type definition is a simple type definition, then the string
  24723. * must be `valid` with respect to that definition as defined by String
  24724. * Valid ($3.14.4).
  24725. *
  24726. * AND
  24727. *
  24728. * 2.2.1 If the {content type} is a simple type definition, then the
  24729. * string must be `valid` with respect to that simple type definition
  24730. * as defined by String Valid ($3.14.4).
  24731. */
  24732. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24733. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24734. NULL, inode->typeDef, value, val, 1, 1, 0);
  24735. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24736. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24737. NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
  24738. }
  24739. if (ret < 0) {
  24740. VERROR_INT("xmlSchemaCheckCOSValidDefault",
  24741. "calling xmlSchemaVCheckCVCSimpleType()");
  24742. }
  24743. return (ret);
  24744. }
  24745. static void
  24746. xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
  24747. const xmlChar * name ATTRIBUTE_UNUSED,
  24748. void *transdata, void *inputdata)
  24749. {
  24750. xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
  24751. xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
  24752. inode->decl = item;
  24753. #ifdef DEBUG_CONTENT
  24754. {
  24755. xmlChar *str = NULL;
  24756. if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
  24757. xmlGenericError(xmlGenericErrorContext,
  24758. "AUTOMATON callback for '%s' [declaration]\n",
  24759. xmlSchemaFormatQName(&str,
  24760. inode->localName, inode->nsName));
  24761. } else {
  24762. xmlGenericError(xmlGenericErrorContext,
  24763. "AUTOMATON callback for '%s' [wildcard]\n",
  24764. xmlSchemaFormatQName(&str,
  24765. inode->localName, inode->nsName));
  24766. }
  24767. FREE_AND_NULL(str)
  24768. }
  24769. #endif
  24770. }
  24771. static int
  24772. xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
  24773. {
  24774. vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
  24775. if (vctxt->inode == NULL) {
  24776. VERROR_INT("xmlSchemaValidatorPushElem",
  24777. "calling xmlSchemaGetFreshElemInfo()");
  24778. return (-1);
  24779. }
  24780. vctxt->nbAttrInfos = 0;
  24781. return (0);
  24782. }
  24783. static int
  24784. xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
  24785. xmlSchemaNodeInfoPtr inode,
  24786. xmlSchemaTypePtr type,
  24787. const xmlChar *value)
  24788. {
  24789. if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
  24790. return (xmlSchemaVCheckCVCSimpleType(
  24791. ACTXT_CAST vctxt, NULL,
  24792. type, value, &(inode->val), 1, 1, 0));
  24793. else
  24794. return (xmlSchemaVCheckCVCSimpleType(
  24795. ACTXT_CAST vctxt, NULL,
  24796. type, value, NULL, 1, 0, 0));
  24797. }
  24798. /*
  24799. * Process END of element.
  24800. */
  24801. static int
  24802. xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
  24803. {
  24804. int ret = 0;
  24805. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24806. if (vctxt->nbAttrInfos != 0)
  24807. xmlSchemaClearAttrInfos(vctxt);
  24808. if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
  24809. /*
  24810. * This element was not expected;
  24811. * we will not validate child elements of broken parents.
  24812. * Skip validation of all content of the parent.
  24813. */
  24814. vctxt->skipDepth = vctxt->depth -1;
  24815. goto end_elem;
  24816. }
  24817. if ((inode->typeDef == NULL) ||
  24818. (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
  24819. /*
  24820. * 1. the type definition might be missing if the element was
  24821. * error prone
  24822. * 2. it might be abstract.
  24823. */
  24824. goto end_elem;
  24825. }
  24826. /*
  24827. * Check the content model.
  24828. */
  24829. if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
  24830. (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
  24831. /*
  24832. * Workaround for "anyType".
  24833. */
  24834. if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
  24835. goto character_content;
  24836. if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
  24837. xmlChar *values[10];
  24838. int terminal, nbval = 10, nbneg;
  24839. if (inode->regexCtxt == NULL) {
  24840. /*
  24841. * Create the regex context.
  24842. */
  24843. inode->regexCtxt =
  24844. xmlRegNewExecCtxt(inode->typeDef->contModel,
  24845. xmlSchemaVContentModelCallback, vctxt);
  24846. if (inode->regexCtxt == NULL) {
  24847. VERROR_INT("xmlSchemaValidatorPopElem",
  24848. "failed to create a regex context");
  24849. goto internal_error;
  24850. }
  24851. #ifdef DEBUG_AUTOMATA
  24852. xmlGenericError(xmlGenericErrorContext,
  24853. "AUTOMATON create on '%s'\n", inode->localName);
  24854. #endif
  24855. }
  24856. /*
  24857. * Do not check further content if the node has been nilled
  24858. */
  24859. if (INODE_NILLED(inode)) {
  24860. ret = 0;
  24861. #ifdef DEBUG_AUTOMATA
  24862. xmlGenericError(xmlGenericErrorContext,
  24863. "AUTOMATON succeeded on nilled '%s'\n",
  24864. inode->localName);
  24865. #endif
  24866. goto skip_nilled;
  24867. }
  24868. /*
  24869. * Get hold of the still expected content, since a further
  24870. * call to xmlRegExecPushString() will lose this information.
  24871. */
  24872. xmlRegExecNextValues(inode->regexCtxt,
  24873. &nbval, &nbneg, &values[0], &terminal);
  24874. ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
  24875. if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
  24876. /*
  24877. * Still missing something.
  24878. */
  24879. ret = 1;
  24880. inode->flags |=
  24881. XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  24882. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  24883. XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
  24884. "Missing child element(s)",
  24885. nbval, nbneg, values);
  24886. #ifdef DEBUG_AUTOMATA
  24887. xmlGenericError(xmlGenericErrorContext,
  24888. "AUTOMATON missing ERROR on '%s'\n",
  24889. inode->localName);
  24890. #endif
  24891. } else {
  24892. /*
  24893. * Content model is satisfied.
  24894. */
  24895. ret = 0;
  24896. #ifdef DEBUG_AUTOMATA
  24897. xmlGenericError(xmlGenericErrorContext,
  24898. "AUTOMATON succeeded on '%s'\n",
  24899. inode->localName);
  24900. #endif
  24901. }
  24902. }
  24903. }
  24904. skip_nilled:
  24905. if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
  24906. goto end_elem;
  24907. character_content:
  24908. if (vctxt->value != NULL) {
  24909. xmlSchemaFreeValue(vctxt->value);
  24910. vctxt->value = NULL;
  24911. }
  24912. /*
  24913. * Check character content.
  24914. */
  24915. if (inode->decl == NULL) {
  24916. /*
  24917. * Speedup if no declaration exists.
  24918. */
  24919. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24920. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24921. inode, inode->typeDef, inode->value);
  24922. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24923. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24924. inode, inode->typeDef->contentTypeDef,
  24925. inode->value);
  24926. }
  24927. if (ret < 0) {
  24928. VERROR_INT("xmlSchemaValidatorPopElem",
  24929. "calling xmlSchemaVCheckCVCSimpleType()");
  24930. goto internal_error;
  24931. }
  24932. goto end_elem;
  24933. }
  24934. /*
  24935. * cvc-elt (3.3.4) : 5
  24936. * The appropriate case among the following must be true:
  24937. */
  24938. /*
  24939. * cvc-elt (3.3.4) : 5.1
  24940. * If the declaration has a {value constraint},
  24941. * the item has neither element nor character [children] and
  24942. * clause 3.2 has not applied, then all of the following must be true:
  24943. */
  24944. if ((inode->decl->value != NULL) &&
  24945. (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
  24946. (! INODE_NILLED(inode))) {
  24947. /*
  24948. * cvc-elt (3.3.4) : 5.1.1
  24949. * If the `actual type definition` is a `local type definition`
  24950. * then the canonical lexical representation of the {value constraint}
  24951. * value must be a valid default for the `actual type definition` as
  24952. * defined in Element Default Valid (Immediate) ($3.3.6).
  24953. */
  24954. /*
  24955. * NOTE: 'local' above means types acquired by xsi:type.
  24956. * NOTE: Although the *canonical* value is stated, it is not
  24957. * relevant if canonical or not. Additionally XML Schema 1.1
  24958. * will removed this requirement as well.
  24959. */
  24960. if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
  24961. ret = xmlSchemaCheckCOSValidDefault(vctxt,
  24962. inode->decl->value, &(inode->val));
  24963. if (ret != 0) {
  24964. if (ret < 0) {
  24965. VERROR_INT("xmlSchemaValidatorPopElem",
  24966. "calling xmlSchemaCheckCOSValidDefault()");
  24967. goto internal_error;
  24968. }
  24969. goto end_elem;
  24970. }
  24971. /*
  24972. * Stop here, to avoid redundant validation of the value
  24973. * (see following).
  24974. */
  24975. goto default_psvi;
  24976. }
  24977. /*
  24978. * cvc-elt (3.3.4) : 5.1.2
  24979. * The element information item with the canonical lexical
  24980. * representation of the {value constraint} value used as its
  24981. * `normalized value` must be `valid` with respect to the
  24982. * `actual type definition` as defined by Element Locally Valid (Type)
  24983. * ($3.3.4).
  24984. */
  24985. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24986. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24987. inode, inode->typeDef, inode->decl->value);
  24988. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24989. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24990. inode, inode->typeDef->contentTypeDef,
  24991. inode->decl->value);
  24992. }
  24993. if (ret != 0) {
  24994. if (ret < 0) {
  24995. VERROR_INT("xmlSchemaValidatorPopElem",
  24996. "calling xmlSchemaVCheckCVCSimpleType()");
  24997. goto internal_error;
  24998. }
  24999. goto end_elem;
  25000. }
  25001. default_psvi:
  25002. /*
  25003. * PSVI: Create a text node on the instance element.
  25004. */
  25005. if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
  25006. (inode->node != NULL)) {
  25007. xmlNodePtr textChild;
  25008. xmlChar *normValue;
  25009. /*
  25010. * VAL TODO: Normalize the value.
  25011. */
  25012. normValue = xmlSchemaNormalizeValue(inode->typeDef,
  25013. inode->decl->value);
  25014. if (normValue != NULL) {
  25015. textChild = xmlNewText(BAD_CAST normValue);
  25016. xmlFree(normValue);
  25017. } else
  25018. textChild = xmlNewText(inode->decl->value);
  25019. if (textChild == NULL) {
  25020. VERROR_INT("xmlSchemaValidatorPopElem",
  25021. "calling xmlNewText()");
  25022. goto internal_error;
  25023. } else
  25024. xmlAddChild(inode->node, textChild);
  25025. }
  25026. } else if (! INODE_NILLED(inode)) {
  25027. /*
  25028. * 5.2.1 The element information item must be `valid` with respect
  25029. * to the `actual type definition` as defined by Element Locally
  25030. * Valid (Type) ($3.3.4).
  25031. */
  25032. if (WXS_IS_SIMPLE(inode->typeDef)) {
  25033. /*
  25034. * SPEC (cvc-type) (3.1)
  25035. * "If the type definition is a simple type definition, ..."
  25036. * (3.1.3) "If clause 3.2 of Element Locally Valid
  25037. * (Element) ($3.3.4) did not apply, then the `normalized value`
  25038. * must be `valid` with respect to the type definition as defined
  25039. * by String Valid ($3.14.4).
  25040. */
  25041. ret = xmlSchemaVCheckINodeDataType(vctxt,
  25042. inode, inode->typeDef, inode->value);
  25043. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  25044. /*
  25045. * SPEC (cvc-type) (3.2) "If the type definition is a complex type
  25046. * definition, then the element information item must be
  25047. * `valid` with respect to the type definition as per
  25048. * Element Locally Valid (Complex Type) ($3.4.4);"
  25049. *
  25050. * SPEC (cvc-complex-type) (2.2)
  25051. * "If the {content type} is a simple type definition, ...
  25052. * the `normalized value` of the element information item is
  25053. * `valid` with respect to that simple type definition as
  25054. * defined by String Valid ($3.14.4)."
  25055. */
  25056. ret = xmlSchemaVCheckINodeDataType(vctxt,
  25057. inode, inode->typeDef->contentTypeDef, inode->value);
  25058. }
  25059. if (ret != 0) {
  25060. if (ret < 0) {
  25061. VERROR_INT("xmlSchemaValidatorPopElem",
  25062. "calling xmlSchemaVCheckCVCSimpleType()");
  25063. goto internal_error;
  25064. }
  25065. goto end_elem;
  25066. }
  25067. /*
  25068. * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
  25069. * not applied, all of the following must be true:
  25070. */
  25071. if ((inode->decl->value != NULL) &&
  25072. (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
  25073. /*
  25074. * TODO: We will need a computed value, when comparison is
  25075. * done on computed values.
  25076. */
  25077. /*
  25078. * 5.2.2.1 The element information item must have no element
  25079. * information item [children].
  25080. */
  25081. if (inode->flags &
  25082. XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
  25083. ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
  25084. VERROR(ret, NULL,
  25085. "The content must not contain element nodes since "
  25086. "there is a fixed value constraint");
  25087. goto end_elem;
  25088. } else {
  25089. /*
  25090. * 5.2.2.2 The appropriate case among the following must
  25091. * be true:
  25092. */
  25093. if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
  25094. /*
  25095. * 5.2.2.2.1 If the {content type} of the `actual type
  25096. * definition` is mixed, then the *initial value* of the
  25097. * item must match the canonical lexical representation
  25098. * of the {value constraint} value.
  25099. *
  25100. * ... the *initial value* of an element information
  25101. * item is the string composed of, in order, the
  25102. * [character code] of each character information item in
  25103. * the [children] of that element information item.
  25104. */
  25105. if (! xmlStrEqual(inode->value, inode->decl->value)){
  25106. /*
  25107. * VAL TODO: Report invalid & expected values as well.
  25108. * VAL TODO: Implement the canonical stuff.
  25109. */
  25110. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
  25111. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  25112. ret, NULL, NULL,
  25113. "The initial value '%s' does not match the fixed "
  25114. "value constraint '%s'",
  25115. inode->value, inode->decl->value);
  25116. goto end_elem;
  25117. }
  25118. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  25119. /*
  25120. * 5.2.2.2.2 If the {content type} of the `actual type
  25121. * definition` is a simple type definition, then the
  25122. * *actual value* of the item must match the canonical
  25123. * lexical representation of the {value constraint} value.
  25124. */
  25125. /*
  25126. * VAL TODO: *actual value* is the normalized value, impl.
  25127. * this.
  25128. * VAL TODO: Report invalid & expected values as well.
  25129. * VAL TODO: Implement a comparison with the computed values.
  25130. */
  25131. if (! xmlStrEqual(inode->value,
  25132. inode->decl->value)) {
  25133. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
  25134. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  25135. ret, NULL, NULL,
  25136. "The actual value '%s' does not match the fixed "
  25137. "value constraint '%s'",
  25138. inode->value,
  25139. inode->decl->value);
  25140. goto end_elem;
  25141. }
  25142. }
  25143. }
  25144. }
  25145. }
  25146. end_elem:
  25147. if (vctxt->depth < 0) {
  25148. /* TODO: raise error? */
  25149. return (0);
  25150. }
  25151. if (vctxt->depth == vctxt->skipDepth)
  25152. vctxt->skipDepth = -1;
  25153. /*
  25154. * Evaluate the history of XPath state objects.
  25155. */
  25156. if (inode->appliedXPath &&
  25157. (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
  25158. goto internal_error;
  25159. /*
  25160. * MAYBE TODO:
  25161. * SPEC (6) "The element information item must be `valid` with
  25162. * respect to each of the {identity-constraint definitions} as per
  25163. * Identity-constraint Satisfied ($3.11.4)."
  25164. */
  25165. /*
  25166. * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
  25167. * need to be built in any case.
  25168. * We will currently build IDC node-tables and bubble them only if
  25169. * keyrefs do exist.
  25170. */
  25171. /*
  25172. * Add the current IDC target-nodes to the IDC node-tables.
  25173. */
  25174. if ((inode->idcMatchers != NULL) &&
  25175. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  25176. {
  25177. if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
  25178. goto internal_error;
  25179. }
  25180. /*
  25181. * Validate IDC keyrefs.
  25182. */
  25183. if (vctxt->inode->hasKeyrefs)
  25184. if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
  25185. goto internal_error;
  25186. /*
  25187. * Merge/free the IDC table.
  25188. */
  25189. if (inode->idcTable != NULL) {
  25190. #ifdef DEBUG_IDC_NODE_TABLE
  25191. xmlSchemaDebugDumpIDCTable(stdout,
  25192. inode->nsName,
  25193. inode->localName,
  25194. inode->idcTable);
  25195. #endif
  25196. if ((vctxt->depth > 0) &&
  25197. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  25198. {
  25199. /*
  25200. * Merge the IDC node table with the table of the parent node.
  25201. */
  25202. if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
  25203. goto internal_error;
  25204. }
  25205. }
  25206. /*
  25207. * Clear the current ielem.
  25208. * VAL TODO: Don't free the PSVI IDC tables if they are
  25209. * requested for the PSVI.
  25210. */
  25211. xmlSchemaClearElemInfo(vctxt, inode);
  25212. /*
  25213. * Skip further processing if we are on the validation root.
  25214. */
  25215. if (vctxt->depth == 0) {
  25216. vctxt->depth--;
  25217. vctxt->inode = NULL;
  25218. return (0);
  25219. }
  25220. /*
  25221. * Reset the keyrefDepth if needed.
  25222. */
  25223. if (vctxt->aidcs != NULL) {
  25224. xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
  25225. do {
  25226. if (aidc->keyrefDepth == vctxt->depth) {
  25227. /*
  25228. * A 'keyrefDepth' of a key/unique IDC matches the current
  25229. * depth, this means that we are leaving the scope of the
  25230. * top-most keyref IDC which refers to this IDC.
  25231. */
  25232. aidc->keyrefDepth = -1;
  25233. }
  25234. aidc = aidc->next;
  25235. } while (aidc != NULL);
  25236. }
  25237. vctxt->depth--;
  25238. vctxt->inode = vctxt->elemInfos[vctxt->depth];
  25239. /*
  25240. * VAL TODO: 7 If the element information item is the `validation root`, it must be
  25241. * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
  25242. */
  25243. return (ret);
  25244. internal_error:
  25245. vctxt->err = -1;
  25246. return (-1);
  25247. }
  25248. /*
  25249. * 3.4.4 Complex Type Definition Validation Rules
  25250. * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
  25251. */
  25252. static int
  25253. xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
  25254. {
  25255. xmlSchemaNodeInfoPtr pielem;
  25256. xmlSchemaTypePtr ptype;
  25257. int ret = 0;
  25258. if (vctxt->depth <= 0) {
  25259. VERROR_INT("xmlSchemaValidateChildElem",
  25260. "not intended for the validation root");
  25261. return (-1);
  25262. }
  25263. pielem = vctxt->elemInfos[vctxt->depth -1];
  25264. if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25265. pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25266. /*
  25267. * Handle 'nilled' elements.
  25268. */
  25269. if (INODE_NILLED(pielem)) {
  25270. /*
  25271. * SPEC (cvc-elt) (3.3.4) : (3.2.1)
  25272. */
  25273. ACTIVATE_PARENT_ELEM;
  25274. ret = XML_SCHEMAV_CVC_ELT_3_2_1;
  25275. VERROR(ret, NULL,
  25276. "Neither character nor element content is allowed, "
  25277. "because the element was 'nilled'");
  25278. ACTIVATE_ELEM;
  25279. goto unexpected_elem;
  25280. }
  25281. ptype = pielem->typeDef;
  25282. if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
  25283. /*
  25284. * Workaround for "anyType": we have currently no content model
  25285. * assigned for "anyType", so handle it explicitly.
  25286. * "anyType" has an unbounded, lax "any" wildcard.
  25287. */
  25288. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25289. vctxt->inode->localName,
  25290. vctxt->inode->nsName);
  25291. if (vctxt->inode->decl == NULL) {
  25292. xmlSchemaAttrInfoPtr iattr;
  25293. /*
  25294. * Process "xsi:type".
  25295. * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
  25296. */
  25297. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  25298. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  25299. if (iattr != NULL) {
  25300. ret = xmlSchemaProcessXSIType(vctxt, iattr,
  25301. &(vctxt->inode->typeDef), NULL);
  25302. if (ret != 0) {
  25303. if (ret == -1) {
  25304. VERROR_INT("xmlSchemaValidateChildElem",
  25305. "calling xmlSchemaProcessXSIType() to "
  25306. "process the attribute 'xsi:nil'");
  25307. return (-1);
  25308. }
  25309. return (ret);
  25310. }
  25311. } else {
  25312. /*
  25313. * Fallback to "anyType".
  25314. *
  25315. * SPEC (cvc-assess-elt)
  25316. * "If the item cannot be `strictly assessed`, [...]
  25317. * an element information item's schema validity may be laxly
  25318. * assessed if its `context-determined declaration` is not
  25319. * skip by `validating` with respect to the `ur-type
  25320. * definition` as per Element Locally Valid (Type) ($3.3.4)."
  25321. */
  25322. vctxt->inode->typeDef =
  25323. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  25324. }
  25325. }
  25326. return (0);
  25327. }
  25328. switch (ptype->contentType) {
  25329. case XML_SCHEMA_CONTENT_EMPTY:
  25330. /*
  25331. * SPEC (2.1) "If the {content type} is empty, then the
  25332. * element information item has no character or element
  25333. * information item [children]."
  25334. */
  25335. ACTIVATE_PARENT_ELEM
  25336. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
  25337. VERROR(ret, NULL,
  25338. "Element content is not allowed, "
  25339. "because the content type is empty");
  25340. ACTIVATE_ELEM
  25341. goto unexpected_elem;
  25342. break;
  25343. case XML_SCHEMA_CONTENT_MIXED:
  25344. case XML_SCHEMA_CONTENT_ELEMENTS: {
  25345. xmlRegExecCtxtPtr regexCtxt;
  25346. xmlChar *values[10];
  25347. int terminal, nbval = 10, nbneg;
  25348. /* VAL TODO: Optimized "anyType" validation.*/
  25349. if (ptype->contModel == NULL) {
  25350. VERROR_INT("xmlSchemaValidateChildElem",
  25351. "type has elem content but no content model");
  25352. return (-1);
  25353. }
  25354. /*
  25355. * Safety belt for evaluation if the cont. model was already
  25356. * examined to be invalid.
  25357. */
  25358. if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
  25359. VERROR_INT("xmlSchemaValidateChildElem",
  25360. "validating elem, but elem content is already invalid");
  25361. return (-1);
  25362. }
  25363. regexCtxt = pielem->regexCtxt;
  25364. if (regexCtxt == NULL) {
  25365. /*
  25366. * Create the regex context.
  25367. */
  25368. regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
  25369. xmlSchemaVContentModelCallback, vctxt);
  25370. if (regexCtxt == NULL) {
  25371. VERROR_INT("xmlSchemaValidateChildElem",
  25372. "failed to create a regex context");
  25373. return (-1);
  25374. }
  25375. pielem->regexCtxt = regexCtxt;
  25376. #ifdef DEBUG_AUTOMATA
  25377. xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
  25378. pielem->localName);
  25379. #endif
  25380. }
  25381. /*
  25382. * SPEC (2.4) "If the {content type} is element-only or mixed,
  25383. * then the sequence of the element information item's
  25384. * element information item [children], if any, taken in
  25385. * order, is `valid` with respect to the {content type}'s
  25386. * particle, as defined in Element Sequence Locally Valid
  25387. * (Particle) ($3.9.4)."
  25388. */
  25389. ret = xmlRegExecPushString2(regexCtxt,
  25390. vctxt->inode->localName,
  25391. vctxt->inode->nsName,
  25392. vctxt->inode);
  25393. #ifdef DEBUG_AUTOMATA
  25394. if (ret < 0)
  25395. xmlGenericError(xmlGenericErrorContext,
  25396. "AUTOMATON push ERROR for '%s' on '%s'\n",
  25397. vctxt->inode->localName, pielem->localName);
  25398. else
  25399. xmlGenericError(xmlGenericErrorContext,
  25400. "AUTOMATON push OK for '%s' on '%s'\n",
  25401. vctxt->inode->localName, pielem->localName);
  25402. #endif
  25403. if (vctxt->err == XML_SCHEMAV_INTERNAL) {
  25404. VERROR_INT("xmlSchemaValidateChildElem",
  25405. "calling xmlRegExecPushString2()");
  25406. return (-1);
  25407. }
  25408. if (ret < 0) {
  25409. xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
  25410. &values[0], &terminal);
  25411. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  25412. XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
  25413. "This element is not expected",
  25414. nbval, nbneg, values);
  25415. ret = vctxt->err;
  25416. goto unexpected_elem;
  25417. } else
  25418. ret = 0;
  25419. }
  25420. break;
  25421. case XML_SCHEMA_CONTENT_SIMPLE:
  25422. case XML_SCHEMA_CONTENT_BASIC:
  25423. ACTIVATE_PARENT_ELEM
  25424. if (WXS_IS_COMPLEX(ptype)) {
  25425. /*
  25426. * SPEC (cvc-complex-type) (2.2)
  25427. * "If the {content type} is a simple type definition, then
  25428. * the element information item has no element information
  25429. * item [children], ..."
  25430. */
  25431. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
  25432. VERROR(ret, NULL, "Element content is not allowed, "
  25433. "because the content type is a simple type definition");
  25434. } else {
  25435. /*
  25436. * SPEC (cvc-type) (3.1.2) "The element information item must
  25437. * have no element information item [children]."
  25438. */
  25439. ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
  25440. VERROR(ret, NULL, "Element content is not allowed, "
  25441. "because the type definition is simple");
  25442. }
  25443. ACTIVATE_ELEM
  25444. ret = vctxt->err;
  25445. goto unexpected_elem;
  25446. break;
  25447. default:
  25448. break;
  25449. }
  25450. return (ret);
  25451. unexpected_elem:
  25452. /*
  25453. * Pop this element and set the skipDepth to skip
  25454. * all further content of the parent element.
  25455. */
  25456. vctxt->skipDepth = vctxt->depth;
  25457. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
  25458. pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  25459. return (ret);
  25460. }
  25461. #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
  25462. #define XML_SCHEMA_PUSH_TEXT_CREATED 2
  25463. #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
  25464. static int
  25465. xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
  25466. int nodeType, const xmlChar *value, int len,
  25467. int mode, int *consumed)
  25468. {
  25469. /*
  25470. * Unfortunately we have to duplicate the text sometimes.
  25471. * OPTIMIZE: Maybe we could skip it, if:
  25472. * 1. content type is simple
  25473. * 2. whitespace is "collapse"
  25474. * 3. it consists of whitespace only
  25475. *
  25476. * Process character content.
  25477. */
  25478. if (consumed != NULL)
  25479. *consumed = 0;
  25480. if (INODE_NILLED(vctxt->inode)) {
  25481. /*
  25482. * SPEC cvc-elt (3.3.4 - 3.2.1)
  25483. * "The element information item must have no character or
  25484. * element information item [children]."
  25485. */
  25486. VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
  25487. "Neither character nor element content is allowed "
  25488. "because the element is 'nilled'");
  25489. return (vctxt->err);
  25490. }
  25491. /*
  25492. * SPEC (2.1) "If the {content type} is empty, then the
  25493. * element information item has no character or element
  25494. * information item [children]."
  25495. */
  25496. if (vctxt->inode->typeDef->contentType ==
  25497. XML_SCHEMA_CONTENT_EMPTY) {
  25498. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
  25499. "Character content is not allowed, "
  25500. "because the content type is empty");
  25501. return (vctxt->err);
  25502. }
  25503. if (vctxt->inode->typeDef->contentType ==
  25504. XML_SCHEMA_CONTENT_ELEMENTS) {
  25505. if ((nodeType != XML_TEXT_NODE) ||
  25506. (! xmlSchemaIsBlank((xmlChar *) value, len))) {
  25507. /*
  25508. * SPEC cvc-complex-type (2.3)
  25509. * "If the {content type} is element-only, then the
  25510. * element information item has no character information
  25511. * item [children] other than those whose [character
  25512. * code] is defined as a white space in [XML 1.0 (Second
  25513. * Edition)]."
  25514. */
  25515. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
  25516. "Character content other than whitespace is not allowed "
  25517. "because the content type is 'element-only'");
  25518. return (vctxt->err);
  25519. }
  25520. return (0);
  25521. }
  25522. if ((value == NULL) || (value[0] == 0))
  25523. return (0);
  25524. /*
  25525. * Save the value.
  25526. * NOTE that even if the content type is *mixed*, we need the
  25527. * *initial value* for default/fixed value constraints.
  25528. */
  25529. if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  25530. ((vctxt->inode->decl == NULL) ||
  25531. (vctxt->inode->decl->value == NULL)))
  25532. return (0);
  25533. if (vctxt->inode->value == NULL) {
  25534. /*
  25535. * Set the value.
  25536. */
  25537. switch (mode) {
  25538. case XML_SCHEMA_PUSH_TEXT_PERSIST:
  25539. /*
  25540. * When working on a tree.
  25541. */
  25542. vctxt->inode->value = value;
  25543. break;
  25544. case XML_SCHEMA_PUSH_TEXT_CREATED:
  25545. /*
  25546. * When working with the reader.
  25547. * The value will be freed by the element info.
  25548. */
  25549. vctxt->inode->value = value;
  25550. if (consumed != NULL)
  25551. *consumed = 1;
  25552. vctxt->inode->flags |=
  25553. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25554. break;
  25555. case XML_SCHEMA_PUSH_TEXT_VOLATILE:
  25556. /*
  25557. * When working with SAX.
  25558. * The value will be freed by the element info.
  25559. */
  25560. if (len != -1)
  25561. vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
  25562. else
  25563. vctxt->inode->value = BAD_CAST xmlStrdup(value);
  25564. vctxt->inode->flags |=
  25565. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25566. break;
  25567. default:
  25568. break;
  25569. }
  25570. } else {
  25571. if (len < 0)
  25572. len = xmlStrlen(value);
  25573. /*
  25574. * Concat the value.
  25575. */
  25576. if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  25577. vctxt->inode->value = BAD_CAST xmlStrncat(
  25578. (xmlChar *) vctxt->inode->value, value, len);
  25579. } else {
  25580. vctxt->inode->value =
  25581. BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
  25582. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25583. }
  25584. }
  25585. return (0);
  25586. }
  25587. static int
  25588. xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
  25589. {
  25590. int ret = 0;
  25591. if ((vctxt->skipDepth != -1) &&
  25592. (vctxt->depth >= vctxt->skipDepth)) {
  25593. VERROR_INT("xmlSchemaValidateElem",
  25594. "in skip-state");
  25595. goto internal_error;
  25596. }
  25597. if (vctxt->xsiAssemble) {
  25598. /*
  25599. * We will stop validation if there was an error during
  25600. * dynamic schema construction.
  25601. * Note that we simply set @skipDepth to 0, this could
  25602. * mean that a streaming document via SAX would be
  25603. * still read to the end but it won't be validated any more.
  25604. * TODO: If we are sure how to stop the validation at once
  25605. * for all input scenarios, then this should be changed to
  25606. * instantly stop the validation.
  25607. */
  25608. ret = xmlSchemaAssembleByXSI(vctxt);
  25609. if (ret != 0) {
  25610. if (ret == -1)
  25611. goto internal_error;
  25612. vctxt->skipDepth = 0;
  25613. return(ret);
  25614. }
  25615. /*
  25616. * Augment the IDC definitions for the main schema and all imported ones
  25617. * NOTE: main schema is the first in the imported list
  25618. */
  25619. xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
  25620. vctxt);
  25621. }
  25622. if (vctxt->depth > 0) {
  25623. /*
  25624. * Validate this element against the content model
  25625. * of the parent.
  25626. */
  25627. ret = xmlSchemaValidateChildElem(vctxt);
  25628. if (ret != 0) {
  25629. if (ret < 0) {
  25630. VERROR_INT("xmlSchemaValidateElem",
  25631. "calling xmlSchemaStreamValidateChildElement()");
  25632. goto internal_error;
  25633. }
  25634. goto exit;
  25635. }
  25636. if (vctxt->depth == vctxt->skipDepth)
  25637. goto exit;
  25638. if ((vctxt->inode->decl == NULL) &&
  25639. (vctxt->inode->typeDef == NULL)) {
  25640. VERROR_INT("xmlSchemaValidateElem",
  25641. "the child element was valid but neither the "
  25642. "declaration nor the type was set");
  25643. goto internal_error;
  25644. }
  25645. } else {
  25646. /*
  25647. * Get the declaration of the validation root.
  25648. */
  25649. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25650. vctxt->inode->localName,
  25651. vctxt->inode->nsName);
  25652. if (vctxt->inode->decl == NULL) {
  25653. ret = XML_SCHEMAV_CVC_ELT_1;
  25654. VERROR(ret, NULL,
  25655. "No matching global declaration available "
  25656. "for the validation root");
  25657. goto exit;
  25658. }
  25659. }
  25660. if (vctxt->inode->decl == NULL)
  25661. goto type_validation;
  25662. if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
  25663. int skip;
  25664. /*
  25665. * Wildcards.
  25666. */
  25667. ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
  25668. if (ret != 0) {
  25669. if (ret < 0) {
  25670. VERROR_INT("xmlSchemaValidateElem",
  25671. "calling xmlSchemaValidateElemWildcard()");
  25672. goto internal_error;
  25673. }
  25674. goto exit;
  25675. }
  25676. if (skip) {
  25677. vctxt->skipDepth = vctxt->depth;
  25678. goto exit;
  25679. }
  25680. /*
  25681. * The declaration might be set by the wildcard validation,
  25682. * when the processContents is "lax" or "strict".
  25683. */
  25684. if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
  25685. /*
  25686. * Clear the "decl" field to not confuse further processing.
  25687. */
  25688. vctxt->inode->decl = NULL;
  25689. goto type_validation;
  25690. }
  25691. }
  25692. /*
  25693. * Validate against the declaration.
  25694. */
  25695. ret = xmlSchemaValidateElemDecl(vctxt);
  25696. if (ret != 0) {
  25697. if (ret < 0) {
  25698. VERROR_INT("xmlSchemaValidateElem",
  25699. "calling xmlSchemaValidateElemDecl()");
  25700. goto internal_error;
  25701. }
  25702. goto exit;
  25703. }
  25704. /*
  25705. * Validate against the type definition.
  25706. */
  25707. type_validation:
  25708. if (vctxt->inode->typeDef == NULL) {
  25709. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25710. ret = XML_SCHEMAV_CVC_TYPE_1;
  25711. VERROR(ret, NULL,
  25712. "The type definition is absent");
  25713. goto exit;
  25714. }
  25715. if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
  25716. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25717. ret = XML_SCHEMAV_CVC_TYPE_2;
  25718. VERROR(ret, NULL,
  25719. "The type definition is abstract");
  25720. goto exit;
  25721. }
  25722. /*
  25723. * Evaluate IDCs. Do it here, since new IDC matchers are registered
  25724. * during validation against the declaration. This must be done
  25725. * _before_ attribute validation.
  25726. */
  25727. if (vctxt->xpathStates != NULL) {
  25728. ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
  25729. vctxt->inode->appliedXPath = 1;
  25730. if (ret == -1) {
  25731. VERROR_INT("xmlSchemaValidateElem",
  25732. "calling xmlSchemaXPathEvaluate()");
  25733. goto internal_error;
  25734. }
  25735. }
  25736. /*
  25737. * Validate attributes.
  25738. */
  25739. if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
  25740. if ((vctxt->nbAttrInfos != 0) ||
  25741. (vctxt->inode->typeDef->attrUses != NULL)) {
  25742. ret = xmlSchemaVAttributesComplex(vctxt);
  25743. }
  25744. } else if (vctxt->nbAttrInfos != 0) {
  25745. ret = xmlSchemaVAttributesSimple(vctxt);
  25746. }
  25747. /*
  25748. * Clear registered attributes.
  25749. */
  25750. if (vctxt->nbAttrInfos != 0)
  25751. xmlSchemaClearAttrInfos(vctxt);
  25752. if (ret == -1) {
  25753. VERROR_INT("xmlSchemaValidateElem",
  25754. "calling attributes validation");
  25755. goto internal_error;
  25756. }
  25757. /*
  25758. * Don't return an error if attributes are invalid on purpose.
  25759. */
  25760. ret = 0;
  25761. exit:
  25762. if (ret != 0)
  25763. vctxt->skipDepth = vctxt->depth;
  25764. return (ret);
  25765. internal_error:
  25766. return (-1);
  25767. }
  25768. #ifdef XML_SCHEMA_READER_ENABLED
  25769. static int
  25770. xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
  25771. {
  25772. const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
  25773. int depth, nodeType, ret = 0, consumed;
  25774. xmlSchemaNodeInfoPtr ielem;
  25775. vctxt->depth = -1;
  25776. ret = xmlTextReaderRead(vctxt->reader);
  25777. /*
  25778. * Move to the document element.
  25779. */
  25780. while (ret == 1) {
  25781. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25782. if (nodeType == XML_ELEMENT_NODE)
  25783. goto root_found;
  25784. ret = xmlTextReaderRead(vctxt->reader);
  25785. }
  25786. goto exit;
  25787. root_found:
  25788. do {
  25789. depth = xmlTextReaderDepth(vctxt->reader);
  25790. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25791. if (nodeType == XML_ELEMENT_NODE) {
  25792. vctxt->depth++;
  25793. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  25794. VERROR_INT("xmlSchemaVReaderWalk",
  25795. "calling xmlSchemaValidatorPushElem()");
  25796. goto internal_error;
  25797. }
  25798. ielem = vctxt->inode;
  25799. ielem->localName = xmlTextReaderLocalName(vctxt->reader);
  25800. ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
  25801. ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  25802. /*
  25803. * Is the element empty?
  25804. */
  25805. ret = xmlTextReaderIsEmptyElement(vctxt->reader);
  25806. if (ret == -1) {
  25807. VERROR_INT("xmlSchemaVReaderWalk",
  25808. "calling xmlTextReaderIsEmptyElement()");
  25809. goto internal_error;
  25810. }
  25811. if (ret) {
  25812. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  25813. }
  25814. /*
  25815. * Register attributes.
  25816. */
  25817. vctxt->nbAttrInfos = 0;
  25818. ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
  25819. if (ret == -1) {
  25820. VERROR_INT("xmlSchemaVReaderWalk",
  25821. "calling xmlTextReaderMoveToFirstAttribute()");
  25822. goto internal_error;
  25823. }
  25824. if (ret == 1) {
  25825. do {
  25826. /*
  25827. * VAL TODO: How do we know that the reader works on a
  25828. * node tree, to be able to pass a node here?
  25829. */
  25830. if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
  25831. (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
  25832. xmlTextReaderNamespaceUri(vctxt->reader), 1,
  25833. xmlTextReaderValue(vctxt->reader), 1) == -1) {
  25834. VERROR_INT("xmlSchemaVReaderWalk",
  25835. "calling xmlSchemaValidatorPushAttribute()");
  25836. goto internal_error;
  25837. }
  25838. ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
  25839. if (ret == -1) {
  25840. VERROR_INT("xmlSchemaVReaderWalk",
  25841. "calling xmlTextReaderMoveToFirstAttribute()");
  25842. goto internal_error;
  25843. }
  25844. } while (ret == 1);
  25845. /*
  25846. * Back to element position.
  25847. */
  25848. ret = xmlTextReaderMoveToElement(vctxt->reader);
  25849. if (ret == -1) {
  25850. VERROR_INT("xmlSchemaVReaderWalk",
  25851. "calling xmlTextReaderMoveToElement()");
  25852. goto internal_error;
  25853. }
  25854. }
  25855. /*
  25856. * Validate the element.
  25857. */
  25858. ret= xmlSchemaValidateElem(vctxt);
  25859. if (ret != 0) {
  25860. if (ret == -1) {
  25861. VERROR_INT("xmlSchemaVReaderWalk",
  25862. "calling xmlSchemaValidateElem()");
  25863. goto internal_error;
  25864. }
  25865. goto exit;
  25866. }
  25867. if (vctxt->depth == vctxt->skipDepth) {
  25868. int curDepth;
  25869. /*
  25870. * Skip all content.
  25871. */
  25872. if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
  25873. ret = xmlTextReaderRead(vctxt->reader);
  25874. curDepth = xmlTextReaderDepth(vctxt->reader);
  25875. while ((ret == 1) && (curDepth != depth)) {
  25876. ret = xmlTextReaderRead(vctxt->reader);
  25877. curDepth = xmlTextReaderDepth(vctxt->reader);
  25878. }
  25879. if (ret < 0) {
  25880. /*
  25881. * VAL TODO: A reader error occurred; what to do here?
  25882. */
  25883. ret = 1;
  25884. goto exit;
  25885. }
  25886. }
  25887. goto leave_elem;
  25888. }
  25889. /*
  25890. * READER VAL TODO: Is an END_ELEM really never called
  25891. * if the elem is empty?
  25892. */
  25893. if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25894. goto leave_elem;
  25895. } else if (nodeType == END_ELEM) {
  25896. /*
  25897. * Process END of element.
  25898. */
  25899. leave_elem:
  25900. ret = xmlSchemaValidatorPopElem(vctxt);
  25901. if (ret != 0) {
  25902. if (ret < 0) {
  25903. VERROR_INT("xmlSchemaVReaderWalk",
  25904. "calling xmlSchemaValidatorPopElem()");
  25905. goto internal_error;
  25906. }
  25907. goto exit;
  25908. }
  25909. if (vctxt->depth >= 0)
  25910. ielem = vctxt->inode;
  25911. else
  25912. ielem = NULL;
  25913. } else if ((nodeType == XML_TEXT_NODE) ||
  25914. (nodeType == XML_CDATA_SECTION_NODE) ||
  25915. (nodeType == WHTSP) ||
  25916. (nodeType == SIGN_WHTSP)) {
  25917. /*
  25918. * Process character content.
  25919. */
  25920. xmlChar *value;
  25921. if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
  25922. nodeType = XML_TEXT_NODE;
  25923. value = xmlTextReaderValue(vctxt->reader);
  25924. ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
  25925. -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
  25926. if (! consumed)
  25927. xmlFree(value);
  25928. if (ret == -1) {
  25929. VERROR_INT("xmlSchemaVReaderWalk",
  25930. "calling xmlSchemaVPushText()");
  25931. goto internal_error;
  25932. }
  25933. } else if ((nodeType == XML_ENTITY_NODE) ||
  25934. (nodeType == XML_ENTITY_REF_NODE)) {
  25935. /*
  25936. * VAL TODO: What to do with entities?
  25937. */
  25938. TODO
  25939. }
  25940. /*
  25941. * Read next node.
  25942. */
  25943. ret = xmlTextReaderRead(vctxt->reader);
  25944. } while (ret == 1);
  25945. exit:
  25946. return (ret);
  25947. internal_error:
  25948. return (-1);
  25949. }
  25950. #endif
  25951. /************************************************************************
  25952. * *
  25953. * SAX validation handlers *
  25954. * *
  25955. ************************************************************************/
  25956. /*
  25957. * Process text content.
  25958. */
  25959. static void
  25960. xmlSchemaSAXHandleText(void *ctx,
  25961. const xmlChar * ch,
  25962. int len)
  25963. {
  25964. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25965. if (vctxt->depth < 0)
  25966. return;
  25967. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25968. return;
  25969. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25970. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25971. if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
  25972. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  25973. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  25974. "calling xmlSchemaVPushText()");
  25975. vctxt->err = -1;
  25976. xmlStopParser(vctxt->parserCtxt);
  25977. }
  25978. }
  25979. /*
  25980. * Process CDATA content.
  25981. */
  25982. static void
  25983. xmlSchemaSAXHandleCDataSection(void *ctx,
  25984. const xmlChar * ch,
  25985. int len)
  25986. {
  25987. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25988. if (vctxt->depth < 0)
  25989. return;
  25990. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25991. return;
  25992. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25993. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25994. if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
  25995. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  25996. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  25997. "calling xmlSchemaVPushText()");
  25998. vctxt->err = -1;
  25999. xmlStopParser(vctxt->parserCtxt);
  26000. }
  26001. }
  26002. static void
  26003. xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
  26004. const xmlChar * name ATTRIBUTE_UNUSED)
  26005. {
  26006. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  26007. if (vctxt->depth < 0)
  26008. return;
  26009. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  26010. return;
  26011. /* SAX VAL TODO: What to do here? */
  26012. TODO
  26013. }
  26014. static void
  26015. xmlSchemaSAXHandleStartElementNs(void *ctx,
  26016. const xmlChar * localname,
  26017. const xmlChar * prefix ATTRIBUTE_UNUSED,
  26018. const xmlChar * URI,
  26019. int nb_namespaces,
  26020. const xmlChar ** namespaces,
  26021. int nb_attributes,
  26022. int nb_defaulted ATTRIBUTE_UNUSED,
  26023. const xmlChar ** attributes)
  26024. {
  26025. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  26026. int ret;
  26027. xmlSchemaNodeInfoPtr ielem;
  26028. int i, j;
  26029. /*
  26030. * SAX VAL TODO: What to do with nb_defaulted?
  26031. */
  26032. /*
  26033. * Skip elements if inside a "skip" wildcard or invalid.
  26034. */
  26035. vctxt->depth++;
  26036. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  26037. return;
  26038. /*
  26039. * Push the element.
  26040. */
  26041. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  26042. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  26043. "calling xmlSchemaValidatorPushElem()");
  26044. goto internal_error;
  26045. }
  26046. ielem = vctxt->inode;
  26047. /*
  26048. * TODO: Is this OK?
  26049. */
  26050. ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
  26051. ielem->localName = localname;
  26052. ielem->nsName = URI;
  26053. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  26054. /*
  26055. * Register namespaces on the elem info.
  26056. */
  26057. if (nb_namespaces != 0) {
  26058. /*
  26059. * Although the parser builds its own namespace list,
  26060. * we have no access to it, so we'll use an own one.
  26061. */
  26062. for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
  26063. /*
  26064. * Store prefix and namespace name.
  26065. */
  26066. if (ielem->nsBindings == NULL) {
  26067. ielem->nsBindings =
  26068. (const xmlChar **) xmlMalloc(10 *
  26069. sizeof(const xmlChar *));
  26070. if (ielem->nsBindings == NULL) {
  26071. xmlSchemaVErrMemory(vctxt,
  26072. "allocating namespace bindings for SAX validation",
  26073. NULL);
  26074. goto internal_error;
  26075. }
  26076. ielem->nbNsBindings = 0;
  26077. ielem->sizeNsBindings = 5;
  26078. } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
  26079. ielem->sizeNsBindings *= 2;
  26080. ielem->nsBindings =
  26081. (const xmlChar **) xmlRealloc(
  26082. (void *) ielem->nsBindings,
  26083. ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
  26084. if (ielem->nsBindings == NULL) {
  26085. xmlSchemaVErrMemory(vctxt,
  26086. "re-allocating namespace bindings for SAX validation",
  26087. NULL);
  26088. goto internal_error;
  26089. }
  26090. }
  26091. ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
  26092. if (namespaces[j+1][0] == 0) {
  26093. /*
  26094. * Handle xmlns="".
  26095. */
  26096. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
  26097. } else
  26098. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
  26099. namespaces[j+1];
  26100. ielem->nbNsBindings++;
  26101. }
  26102. }
  26103. /*
  26104. * Register attributes.
  26105. * SAX VAL TODO: We are not adding namespace declaration
  26106. * attributes yet.
  26107. */
  26108. if (nb_attributes != 0) {
  26109. int valueLen, k, l;
  26110. xmlChar *value;
  26111. for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
  26112. /*
  26113. * Duplicate the value, changing any &#38; to a literal ampersand.
  26114. *
  26115. * libxml2 differs from normal SAX here in that it escapes all ampersands
  26116. * as &#38; instead of delivering the raw converted string. Changing the
  26117. * behavior at this point would break applications that use this API, so
  26118. * we are forced to work around it.
  26119. */
  26120. valueLen = attributes[j+4] - attributes[j+3];
  26121. value = xmlMallocAtomic(valueLen + 1);
  26122. if (value == NULL) {
  26123. xmlSchemaVErrMemory(vctxt,
  26124. "allocating string for decoded attribute",
  26125. NULL);
  26126. goto internal_error;
  26127. }
  26128. for (k = 0, l = 0; k < valueLen; l++) {
  26129. if (k < valueLen - 4 &&
  26130. attributes[j+3][k+0] == '&' &&
  26131. attributes[j+3][k+1] == '#' &&
  26132. attributes[j+3][k+2] == '3' &&
  26133. attributes[j+3][k+3] == '8' &&
  26134. attributes[j+3][k+4] == ';') {
  26135. value[l] = '&';
  26136. k += 5;
  26137. } else {
  26138. value[l] = attributes[j+3][k];
  26139. k++;
  26140. }
  26141. }
  26142. value[l] = '\0';
  26143. /*
  26144. * TODO: Set the node line.
  26145. */
  26146. ret = xmlSchemaValidatorPushAttribute(vctxt,
  26147. NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
  26148. value, 1);
  26149. if (ret == -1) {
  26150. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  26151. "calling xmlSchemaValidatorPushAttribute()");
  26152. goto internal_error;
  26153. }
  26154. }
  26155. }
  26156. /*
  26157. * Validate the element.
  26158. */
  26159. ret = xmlSchemaValidateElem(vctxt);
  26160. if (ret != 0) {
  26161. if (ret == -1) {
  26162. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  26163. "calling xmlSchemaValidateElem()");
  26164. goto internal_error;
  26165. }
  26166. goto exit;
  26167. }
  26168. exit:
  26169. return;
  26170. internal_error:
  26171. vctxt->err = -1;
  26172. xmlStopParser(vctxt->parserCtxt);
  26173. return;
  26174. }
  26175. static void
  26176. xmlSchemaSAXHandleEndElementNs(void *ctx,
  26177. const xmlChar * localname ATTRIBUTE_UNUSED,
  26178. const xmlChar * prefix ATTRIBUTE_UNUSED,
  26179. const xmlChar * URI ATTRIBUTE_UNUSED)
  26180. {
  26181. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  26182. int res;
  26183. /*
  26184. * Skip elements if inside a "skip" wildcard or if invalid.
  26185. */
  26186. if (vctxt->skipDepth != -1) {
  26187. if (vctxt->depth > vctxt->skipDepth) {
  26188. vctxt->depth--;
  26189. return;
  26190. } else
  26191. vctxt->skipDepth = -1;
  26192. }
  26193. /*
  26194. * SAX VAL TODO: Just a temporary check.
  26195. */
  26196. if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
  26197. (!xmlStrEqual(vctxt->inode->nsName, URI))) {
  26198. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  26199. "elem pop mismatch");
  26200. }
  26201. res = xmlSchemaValidatorPopElem(vctxt);
  26202. if (res != 0) {
  26203. if (res < 0) {
  26204. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  26205. "calling xmlSchemaValidatorPopElem()");
  26206. goto internal_error;
  26207. }
  26208. goto exit;
  26209. }
  26210. exit:
  26211. return;
  26212. internal_error:
  26213. vctxt->err = -1;
  26214. xmlStopParser(vctxt->parserCtxt);
  26215. return;
  26216. }
  26217. /************************************************************************
  26218. * *
  26219. * Validation interfaces *
  26220. * *
  26221. ************************************************************************/
  26222. /**
  26223. * xmlSchemaNewValidCtxt:
  26224. * @schema: a precompiled XML Schemas
  26225. *
  26226. * Create an XML Schemas validation context based on the given schema.
  26227. *
  26228. * Returns the validation context or NULL in case of error
  26229. */
  26230. xmlSchemaValidCtxtPtr
  26231. xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
  26232. {
  26233. xmlSchemaValidCtxtPtr ret;
  26234. ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
  26235. if (ret == NULL) {
  26236. xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
  26237. return (NULL);
  26238. }
  26239. memset(ret, 0, sizeof(xmlSchemaValidCtxt));
  26240. ret->type = XML_SCHEMA_CTXT_VALIDATOR;
  26241. ret->dict = xmlDictCreate();
  26242. ret->nodeQNames = xmlSchemaItemListCreate();
  26243. ret->schema = schema;
  26244. return (ret);
  26245. }
  26246. /**
  26247. * xmlSchemaValidateSetFilename:
  26248. * @vctxt: the schema validation context
  26249. * @filename: the file name
  26250. *
  26251. * Workaround to provide file error reporting information when this is
  26252. * not provided by current APIs
  26253. */
  26254. void
  26255. xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
  26256. if (vctxt == NULL)
  26257. return;
  26258. if (vctxt->filename != NULL)
  26259. xmlFree(vctxt->filename);
  26260. if (filename != NULL)
  26261. vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
  26262. else
  26263. vctxt->filename = NULL;
  26264. }
  26265. /**
  26266. * xmlSchemaClearValidCtxt:
  26267. * @vctxt: the schema validation context
  26268. *
  26269. * Free the resources associated to the schema validation context;
  26270. * leaves some fields alive intended for reuse of the context.
  26271. */
  26272. static void
  26273. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
  26274. {
  26275. if (vctxt == NULL)
  26276. return;
  26277. /*
  26278. * TODO: Should we clear the flags?
  26279. * Might be problematic if one reuses the context
  26280. * and assumes that the options remain the same.
  26281. */
  26282. vctxt->flags = 0;
  26283. vctxt->validationRoot = NULL;
  26284. vctxt->doc = NULL;
  26285. #ifdef LIBXML_READER_ENABLED
  26286. vctxt->reader = NULL;
  26287. #endif
  26288. vctxt->hasKeyrefs = 0;
  26289. if (vctxt->value != NULL) {
  26290. xmlSchemaFreeValue(vctxt->value);
  26291. vctxt->value = NULL;
  26292. }
  26293. /*
  26294. * Augmented IDC information.
  26295. */
  26296. if (vctxt->aidcs != NULL) {
  26297. xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
  26298. do {
  26299. next = cur->next;
  26300. xmlFree(cur);
  26301. cur = next;
  26302. } while (cur != NULL);
  26303. vctxt->aidcs = NULL;
  26304. }
  26305. if (vctxt->idcMatcherCache != NULL) {
  26306. xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
  26307. while (matcher) {
  26308. tmp = matcher;
  26309. matcher = matcher->nextCached;
  26310. xmlSchemaIDCFreeMatcherList(tmp);
  26311. }
  26312. vctxt->idcMatcherCache = NULL;
  26313. }
  26314. if (vctxt->idcNodes != NULL) {
  26315. int i;
  26316. xmlSchemaPSVIIDCNodePtr item;
  26317. for (i = 0; i < vctxt->nbIdcNodes; i++) {
  26318. item = vctxt->idcNodes[i];
  26319. xmlFree(item->keys);
  26320. xmlFree(item);
  26321. }
  26322. xmlFree(vctxt->idcNodes);
  26323. vctxt->idcNodes = NULL;
  26324. vctxt->nbIdcNodes = 0;
  26325. vctxt->sizeIdcNodes = 0;
  26326. }
  26327. if (vctxt->idcKeys != NULL) {
  26328. int i;
  26329. for (i = 0; i < vctxt->nbIdcKeys; i++)
  26330. xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
  26331. xmlFree(vctxt->idcKeys);
  26332. vctxt->idcKeys = NULL;
  26333. vctxt->nbIdcKeys = 0;
  26334. vctxt->sizeIdcKeys = 0;
  26335. }
  26336. /*
  26337. * Note that we won't delete the XPath state pool here.
  26338. */
  26339. if (vctxt->xpathStates != NULL) {
  26340. xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
  26341. vctxt->xpathStates = NULL;
  26342. }
  26343. /*
  26344. * Attribute info.
  26345. */
  26346. if (vctxt->nbAttrInfos != 0) {
  26347. xmlSchemaClearAttrInfos(vctxt);
  26348. }
  26349. /*
  26350. * Element info.
  26351. */
  26352. if (vctxt->elemInfos != NULL) {
  26353. int i;
  26354. xmlSchemaNodeInfoPtr ei;
  26355. for (i = 0; i < vctxt->sizeElemInfos; i++) {
  26356. ei = vctxt->elemInfos[i];
  26357. if (ei == NULL)
  26358. break;
  26359. xmlSchemaClearElemInfo(vctxt, ei);
  26360. }
  26361. }
  26362. xmlSchemaItemListClear(vctxt->nodeQNames);
  26363. /* Recreate the dict. */
  26364. xmlDictFree(vctxt->dict);
  26365. /*
  26366. * TODO: Is is save to recreate it? Do we have a scenario
  26367. * where the user provides the dict?
  26368. */
  26369. vctxt->dict = xmlDictCreate();
  26370. if (vctxt->filename != NULL) {
  26371. xmlFree(vctxt->filename);
  26372. vctxt->filename = NULL;
  26373. }
  26374. }
  26375. /**
  26376. * xmlSchemaFreeValidCtxt:
  26377. * @ctxt: the schema validation context
  26378. *
  26379. * Free the resources associated to the schema validation context
  26380. */
  26381. void
  26382. xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
  26383. {
  26384. if (ctxt == NULL)
  26385. return;
  26386. if (ctxt->value != NULL)
  26387. xmlSchemaFreeValue(ctxt->value);
  26388. if (ctxt->pctxt != NULL)
  26389. xmlSchemaFreeParserCtxt(ctxt->pctxt);
  26390. if (ctxt->idcNodes != NULL) {
  26391. int i;
  26392. xmlSchemaPSVIIDCNodePtr item;
  26393. for (i = 0; i < ctxt->nbIdcNodes; i++) {
  26394. item = ctxt->idcNodes[i];
  26395. xmlFree(item->keys);
  26396. xmlFree(item);
  26397. }
  26398. xmlFree(ctxt->idcNodes);
  26399. }
  26400. if (ctxt->idcKeys != NULL) {
  26401. int i;
  26402. for (i = 0; i < ctxt->nbIdcKeys; i++)
  26403. xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
  26404. xmlFree(ctxt->idcKeys);
  26405. }
  26406. if (ctxt->xpathStates != NULL) {
  26407. xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
  26408. ctxt->xpathStates = NULL;
  26409. }
  26410. if (ctxt->xpathStatePool != NULL) {
  26411. xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
  26412. ctxt->xpathStatePool = NULL;
  26413. }
  26414. /*
  26415. * Augmented IDC information.
  26416. */
  26417. if (ctxt->aidcs != NULL) {
  26418. xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
  26419. do {
  26420. next = cur->next;
  26421. xmlFree(cur);
  26422. cur = next;
  26423. } while (cur != NULL);
  26424. }
  26425. if (ctxt->attrInfos != NULL) {
  26426. int i;
  26427. xmlSchemaAttrInfoPtr attr;
  26428. /* Just a paranoid call to the cleanup. */
  26429. if (ctxt->nbAttrInfos != 0)
  26430. xmlSchemaClearAttrInfos(ctxt);
  26431. for (i = 0; i < ctxt->sizeAttrInfos; i++) {
  26432. attr = ctxt->attrInfos[i];
  26433. xmlFree(attr);
  26434. }
  26435. xmlFree(ctxt->attrInfos);
  26436. }
  26437. if (ctxt->elemInfos != NULL) {
  26438. int i;
  26439. xmlSchemaNodeInfoPtr ei;
  26440. for (i = 0; i < ctxt->sizeElemInfos; i++) {
  26441. ei = ctxt->elemInfos[i];
  26442. if (ei == NULL)
  26443. break;
  26444. xmlSchemaClearElemInfo(ctxt, ei);
  26445. xmlFree(ei);
  26446. }
  26447. xmlFree(ctxt->elemInfos);
  26448. }
  26449. if (ctxt->nodeQNames != NULL)
  26450. xmlSchemaItemListFree(ctxt->nodeQNames);
  26451. if (ctxt->dict != NULL)
  26452. xmlDictFree(ctxt->dict);
  26453. if (ctxt->filename != NULL)
  26454. xmlFree(ctxt->filename);
  26455. xmlFree(ctxt);
  26456. }
  26457. /**
  26458. * xmlSchemaIsValid:
  26459. * @ctxt: the schema validation context
  26460. *
  26461. * Check if any error was detected during validation.
  26462. *
  26463. * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
  26464. * of internal error.
  26465. */
  26466. int
  26467. xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
  26468. {
  26469. if (ctxt == NULL)
  26470. return(-1);
  26471. return(ctxt->err == 0);
  26472. }
  26473. /**
  26474. * xmlSchemaSetValidErrors:
  26475. * @ctxt: a schema validation context
  26476. * @err: the error function
  26477. * @warn: the warning function
  26478. * @ctx: the functions context
  26479. *
  26480. * Set the error and warning callback information
  26481. */
  26482. void
  26483. xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26484. xmlSchemaValidityErrorFunc err,
  26485. xmlSchemaValidityWarningFunc warn, void *ctx)
  26486. {
  26487. if (ctxt == NULL)
  26488. return;
  26489. ctxt->error = err;
  26490. ctxt->warning = warn;
  26491. ctxt->errCtxt = ctx;
  26492. if (ctxt->pctxt != NULL)
  26493. xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
  26494. }
  26495. /**
  26496. * xmlSchemaSetValidStructuredErrors:
  26497. * @ctxt: a schema validation context
  26498. * @serror: the structured error function
  26499. * @ctx: the functions context
  26500. *
  26501. * Set the structured error callback
  26502. */
  26503. void
  26504. xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
  26505. xmlStructuredErrorFunc serror, void *ctx)
  26506. {
  26507. if (ctxt == NULL)
  26508. return;
  26509. ctxt->serror = serror;
  26510. ctxt->error = NULL;
  26511. ctxt->warning = NULL;
  26512. ctxt->errCtxt = ctx;
  26513. if (ctxt->pctxt != NULL)
  26514. xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
  26515. }
  26516. /**
  26517. * xmlSchemaGetValidErrors:
  26518. * @ctxt: a XML-Schema validation context
  26519. * @err: the error function result
  26520. * @warn: the warning function result
  26521. * @ctx: the functions context result
  26522. *
  26523. * Get the error and warning callback information
  26524. *
  26525. * Returns -1 in case of error and 0 otherwise
  26526. */
  26527. int
  26528. xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26529. xmlSchemaValidityErrorFunc * err,
  26530. xmlSchemaValidityWarningFunc * warn, void **ctx)
  26531. {
  26532. if (ctxt == NULL)
  26533. return (-1);
  26534. if (err != NULL)
  26535. *err = ctxt->error;
  26536. if (warn != NULL)
  26537. *warn = ctxt->warning;
  26538. if (ctx != NULL)
  26539. *ctx = ctxt->errCtxt;
  26540. return (0);
  26541. }
  26542. /**
  26543. * xmlSchemaSetValidOptions:
  26544. * @ctxt: a schema validation context
  26545. * @options: a combination of xmlSchemaValidOption
  26546. *
  26547. * Sets the options to be used during the validation.
  26548. *
  26549. * Returns 0 in case of success, -1 in case of an
  26550. * API error.
  26551. */
  26552. int
  26553. xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
  26554. int options)
  26555. {
  26556. int i;
  26557. if (ctxt == NULL)
  26558. return (-1);
  26559. /*
  26560. * WARNING: Change the start value if adding to the
  26561. * xmlSchemaValidOption.
  26562. * TODO: Is there an other, more easy to maintain,
  26563. * way?
  26564. */
  26565. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  26566. if (options & 1<<i)
  26567. return (-1);
  26568. }
  26569. ctxt->options = options;
  26570. return (0);
  26571. }
  26572. /**
  26573. * xmlSchemaValidCtxtGetOptions:
  26574. * @ctxt: a schema validation context
  26575. *
  26576. * Get the validation context options.
  26577. *
  26578. * Returns the option combination or -1 on error.
  26579. */
  26580. int
  26581. xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
  26582. {
  26583. if (ctxt == NULL)
  26584. return (-1);
  26585. else
  26586. return (ctxt->options);
  26587. }
  26588. static int
  26589. xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
  26590. {
  26591. xmlAttrPtr attr;
  26592. int ret = 0;
  26593. xmlSchemaNodeInfoPtr ielem = NULL;
  26594. xmlNodePtr node, valRoot;
  26595. const xmlChar *nsName;
  26596. /* DOC VAL TODO: Move this to the start function. */
  26597. if (vctxt->validationRoot != NULL)
  26598. valRoot = vctxt->validationRoot;
  26599. else
  26600. valRoot = xmlDocGetRootElement(vctxt->doc);
  26601. if (valRoot == NULL) {
  26602. /* VAL TODO: Error code? */
  26603. VERROR(1, NULL, "The document has no document element");
  26604. return (1);
  26605. }
  26606. for (node = valRoot->next; node != NULL; node = node->next) {
  26607. if (node->type == XML_ELEMENT_NODE)
  26608. VERROR(1, NULL, "The document has more than one top element");
  26609. }
  26610. vctxt->depth = -1;
  26611. vctxt->validationRoot = valRoot;
  26612. node = valRoot;
  26613. while (node != NULL) {
  26614. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  26615. goto next_sibling;
  26616. if (node->type == XML_ELEMENT_NODE) {
  26617. /*
  26618. * Init the node-info.
  26619. */
  26620. vctxt->depth++;
  26621. if (xmlSchemaValidatorPushElem(vctxt) == -1)
  26622. goto internal_error;
  26623. ielem = vctxt->inode;
  26624. ielem->node = node;
  26625. ielem->nodeLine = node->line;
  26626. ielem->localName = node->name;
  26627. if (node->ns != NULL)
  26628. ielem->nsName = node->ns->href;
  26629. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  26630. /*
  26631. * Register attributes.
  26632. * DOC VAL TODO: We do not register namespace declaration
  26633. * attributes yet.
  26634. */
  26635. vctxt->nbAttrInfos = 0;
  26636. if (node->properties != NULL) {
  26637. attr = node->properties;
  26638. do {
  26639. if (attr->ns != NULL)
  26640. nsName = attr->ns->href;
  26641. else
  26642. nsName = NULL;
  26643. ret = xmlSchemaValidatorPushAttribute(vctxt,
  26644. (xmlNodePtr) attr,
  26645. /*
  26646. * Note that we give it the line number of the
  26647. * parent element.
  26648. */
  26649. ielem->nodeLine,
  26650. attr->name, nsName, 0,
  26651. xmlNodeListGetString(attr->doc, attr->children, 1), 1);
  26652. if (ret == -1) {
  26653. VERROR_INT("xmlSchemaDocWalk",
  26654. "calling xmlSchemaValidatorPushAttribute()");
  26655. goto internal_error;
  26656. }
  26657. attr = attr->next;
  26658. } while (attr);
  26659. }
  26660. /*
  26661. * Validate the element.
  26662. */
  26663. ret = xmlSchemaValidateElem(vctxt);
  26664. if (ret != 0) {
  26665. if (ret == -1) {
  26666. VERROR_INT("xmlSchemaDocWalk",
  26667. "calling xmlSchemaValidateElem()");
  26668. goto internal_error;
  26669. }
  26670. /*
  26671. * Don't stop validation; just skip the content
  26672. * of this element.
  26673. */
  26674. goto leave_node;
  26675. }
  26676. if ((vctxt->skipDepth != -1) &&
  26677. (vctxt->depth >= vctxt->skipDepth))
  26678. goto leave_node;
  26679. } else if ((node->type == XML_TEXT_NODE) ||
  26680. (node->type == XML_CDATA_SECTION_NODE)) {
  26681. /*
  26682. * Process character content.
  26683. */
  26684. if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
  26685. ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  26686. ret = xmlSchemaVPushText(vctxt, node->type, node->content,
  26687. -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
  26688. if (ret < 0) {
  26689. VERROR_INT("xmlSchemaVDocWalk",
  26690. "calling xmlSchemaVPushText()");
  26691. goto internal_error;
  26692. }
  26693. /*
  26694. * DOC VAL TODO: Should we skip further validation of the
  26695. * element content here?
  26696. */
  26697. } else if ((node->type == XML_ENTITY_NODE) ||
  26698. (node->type == XML_ENTITY_REF_NODE)) {
  26699. /*
  26700. * DOC VAL TODO: What to do with entities?
  26701. */
  26702. VERROR_INT("xmlSchemaVDocWalk",
  26703. "there is at least one entity reference in the node-tree "
  26704. "currently being validated. Processing of entities with "
  26705. "this XML Schema processor is not supported (yet). Please "
  26706. "substitute entities before validation.");
  26707. goto internal_error;
  26708. } else {
  26709. goto leave_node;
  26710. /*
  26711. * DOC VAL TODO: XInclude nodes, etc.
  26712. */
  26713. }
  26714. /*
  26715. * Walk the doc.
  26716. */
  26717. if (node->children != NULL) {
  26718. node = node->children;
  26719. continue;
  26720. }
  26721. leave_node:
  26722. if (node->type == XML_ELEMENT_NODE) {
  26723. /*
  26724. * Leaving the scope of an element.
  26725. */
  26726. if (node != vctxt->inode->node) {
  26727. VERROR_INT("xmlSchemaVDocWalk",
  26728. "element position mismatch");
  26729. goto internal_error;
  26730. }
  26731. ret = xmlSchemaValidatorPopElem(vctxt);
  26732. if (ret != 0) {
  26733. if (ret < 0) {
  26734. VERROR_INT("xmlSchemaVDocWalk",
  26735. "calling xmlSchemaValidatorPopElem()");
  26736. goto internal_error;
  26737. }
  26738. }
  26739. if (node == valRoot)
  26740. goto exit;
  26741. }
  26742. next_sibling:
  26743. if (node->next != NULL)
  26744. node = node->next;
  26745. else {
  26746. node = node->parent;
  26747. goto leave_node;
  26748. }
  26749. }
  26750. exit:
  26751. return (ret);
  26752. internal_error:
  26753. return (-1);
  26754. }
  26755. static int
  26756. xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
  26757. /*
  26758. * Some initialization.
  26759. */
  26760. vctxt->err = 0;
  26761. vctxt->nberrors = 0;
  26762. vctxt->depth = -1;
  26763. vctxt->skipDepth = -1;
  26764. vctxt->hasKeyrefs = 0;
  26765. #ifdef ENABLE_IDC_NODE_TABLES_TEST
  26766. vctxt->createIDCNodeTables = 1;
  26767. #else
  26768. vctxt->createIDCNodeTables = 0;
  26769. #endif
  26770. /*
  26771. * Create a schema + parser if necessary.
  26772. */
  26773. if (vctxt->schema == NULL) {
  26774. xmlSchemaParserCtxtPtr pctxt;
  26775. vctxt->xsiAssemble = 1;
  26776. /*
  26777. * If not schema was given then we will create a schema
  26778. * dynamically using XSI schema locations.
  26779. *
  26780. * Create the schema parser context.
  26781. */
  26782. if ((vctxt->pctxt == NULL) &&
  26783. (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  26784. return (-1);
  26785. pctxt = vctxt->pctxt;
  26786. pctxt->xsiAssemble = 1;
  26787. /*
  26788. * Create the schema.
  26789. */
  26790. vctxt->schema = xmlSchemaNewSchema(pctxt);
  26791. if (vctxt->schema == NULL)
  26792. return (-1);
  26793. /*
  26794. * Create the schema construction context.
  26795. */
  26796. pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
  26797. if (pctxt->constructor == NULL)
  26798. return(-1);
  26799. pctxt->constructor->mainSchema = vctxt->schema;
  26800. /*
  26801. * Take ownership of the constructor to be able to free it.
  26802. */
  26803. pctxt->ownsConstructor = 1;
  26804. }
  26805. /*
  26806. * Augment the IDC definitions for the main schema and all imported ones
  26807. * NOTE: main schema if the first in the imported list
  26808. */
  26809. xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
  26810. vctxt);
  26811. return(0);
  26812. }
  26813. static void
  26814. xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
  26815. if (vctxt->xsiAssemble) {
  26816. if (vctxt->schema != NULL) {
  26817. xmlSchemaFree(vctxt->schema);
  26818. vctxt->schema = NULL;
  26819. }
  26820. }
  26821. xmlSchemaClearValidCtxt(vctxt);
  26822. }
  26823. static int
  26824. xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
  26825. {
  26826. int ret = 0;
  26827. if (xmlSchemaPreRun(vctxt) < 0)
  26828. return(-1);
  26829. if (vctxt->doc != NULL) {
  26830. /*
  26831. * Tree validation.
  26832. */
  26833. ret = xmlSchemaVDocWalk(vctxt);
  26834. #ifdef LIBXML_READER_ENABLED
  26835. } else if (vctxt->reader != NULL) {
  26836. /*
  26837. * XML Reader validation.
  26838. */
  26839. #ifdef XML_SCHEMA_READER_ENABLED
  26840. ret = xmlSchemaVReaderWalk(vctxt);
  26841. #endif
  26842. #endif
  26843. } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
  26844. /*
  26845. * SAX validation.
  26846. */
  26847. ret = xmlParseDocument(vctxt->parserCtxt);
  26848. } else {
  26849. VERROR_INT("xmlSchemaVStart",
  26850. "no instance to validate");
  26851. ret = -1;
  26852. }
  26853. xmlSchemaPostRun(vctxt);
  26854. if (ret == 0)
  26855. ret = vctxt->err;
  26856. return (ret);
  26857. }
  26858. /**
  26859. * xmlSchemaValidateOneElement:
  26860. * @ctxt: a schema validation context
  26861. * @elem: an element node
  26862. *
  26863. * Validate a branch of a tree, starting with the given @elem.
  26864. *
  26865. * Returns 0 if the element and its subtree is valid, a positive error
  26866. * code number otherwise and -1 in case of an internal or API error.
  26867. */
  26868. int
  26869. xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
  26870. {
  26871. if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
  26872. return (-1);
  26873. if (ctxt->schema == NULL)
  26874. return (-1);
  26875. ctxt->doc = elem->doc;
  26876. ctxt->node = elem;
  26877. ctxt->validationRoot = elem;
  26878. return(xmlSchemaVStart(ctxt));
  26879. }
  26880. /**
  26881. * xmlSchemaValidateDoc:
  26882. * @ctxt: a schema validation context
  26883. * @doc: a parsed document tree
  26884. *
  26885. * Validate a document tree in memory.
  26886. *
  26887. * Returns 0 if the document is schemas valid, a positive error code
  26888. * number otherwise and -1 in case of internal or API error.
  26889. */
  26890. int
  26891. xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
  26892. {
  26893. if ((ctxt == NULL) || (doc == NULL))
  26894. return (-1);
  26895. ctxt->doc = doc;
  26896. ctxt->node = xmlDocGetRootElement(doc);
  26897. if (ctxt->node == NULL) {
  26898. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  26899. XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
  26900. (xmlNodePtr) doc, NULL,
  26901. "The document has no document element", NULL, NULL);
  26902. return (ctxt->err);
  26903. }
  26904. ctxt->validationRoot = ctxt->node;
  26905. return (xmlSchemaVStart(ctxt));
  26906. }
  26907. /************************************************************************
  26908. * *
  26909. * Function and data for SAX streaming API *
  26910. * *
  26911. ************************************************************************/
  26912. typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
  26913. typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
  26914. struct _xmlSchemaSplitSAXData {
  26915. xmlSAXHandlerPtr user_sax;
  26916. void *user_data;
  26917. xmlSchemaValidCtxtPtr ctxt;
  26918. xmlSAXHandlerPtr schemas_sax;
  26919. };
  26920. #define XML_SAX_PLUG_MAGIC 0xdc43ba21
  26921. struct _xmlSchemaSAXPlug {
  26922. unsigned int magic;
  26923. /* the original callbacks information */
  26924. xmlSAXHandlerPtr *user_sax_ptr;
  26925. xmlSAXHandlerPtr user_sax;
  26926. void **user_data_ptr;
  26927. void *user_data;
  26928. /* the block plugged back and validation information */
  26929. xmlSAXHandler schemas_sax;
  26930. xmlSchemaValidCtxtPtr ctxt;
  26931. };
  26932. /* All those functions just bounces to the user provided SAX handlers */
  26933. static void
  26934. internalSubsetSplit(void *ctx, const xmlChar *name,
  26935. const xmlChar *ExternalID, const xmlChar *SystemID)
  26936. {
  26937. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26938. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26939. (ctxt->user_sax->internalSubset != NULL))
  26940. ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
  26941. SystemID);
  26942. }
  26943. static int
  26944. isStandaloneSplit(void *ctx)
  26945. {
  26946. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26947. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26948. (ctxt->user_sax->isStandalone != NULL))
  26949. return(ctxt->user_sax->isStandalone(ctxt->user_data));
  26950. return(0);
  26951. }
  26952. static int
  26953. hasInternalSubsetSplit(void *ctx)
  26954. {
  26955. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26956. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26957. (ctxt->user_sax->hasInternalSubset != NULL))
  26958. return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
  26959. return(0);
  26960. }
  26961. static int
  26962. hasExternalSubsetSplit(void *ctx)
  26963. {
  26964. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26965. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26966. (ctxt->user_sax->hasExternalSubset != NULL))
  26967. return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
  26968. return(0);
  26969. }
  26970. static void
  26971. externalSubsetSplit(void *ctx, const xmlChar *name,
  26972. const xmlChar *ExternalID, const xmlChar *SystemID)
  26973. {
  26974. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26975. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26976. (ctxt->user_sax->externalSubset != NULL))
  26977. ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
  26978. SystemID);
  26979. }
  26980. static xmlParserInputPtr
  26981. resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
  26982. {
  26983. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26984. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26985. (ctxt->user_sax->resolveEntity != NULL))
  26986. return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
  26987. systemId));
  26988. return(NULL);
  26989. }
  26990. static xmlEntityPtr
  26991. getEntitySplit(void *ctx, const xmlChar *name)
  26992. {
  26993. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26994. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26995. (ctxt->user_sax->getEntity != NULL))
  26996. return(ctxt->user_sax->getEntity(ctxt->user_data, name));
  26997. return(NULL);
  26998. }
  26999. static xmlEntityPtr
  27000. getParameterEntitySplit(void *ctx, const xmlChar *name)
  27001. {
  27002. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27003. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27004. (ctxt->user_sax->getParameterEntity != NULL))
  27005. return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
  27006. return(NULL);
  27007. }
  27008. static void
  27009. entityDeclSplit(void *ctx, const xmlChar *name, int type,
  27010. const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
  27011. {
  27012. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27013. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27014. (ctxt->user_sax->entityDecl != NULL))
  27015. ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
  27016. systemId, content);
  27017. }
  27018. static void
  27019. attributeDeclSplit(void *ctx, const xmlChar * elem,
  27020. const xmlChar * name, int type, int def,
  27021. const xmlChar * defaultValue, xmlEnumerationPtr tree)
  27022. {
  27023. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27024. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27025. (ctxt->user_sax->attributeDecl != NULL)) {
  27026. ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
  27027. def, defaultValue, tree);
  27028. } else {
  27029. xmlFreeEnumeration(tree);
  27030. }
  27031. }
  27032. static void
  27033. elementDeclSplit(void *ctx, const xmlChar *name, int type,
  27034. xmlElementContentPtr content)
  27035. {
  27036. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27037. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27038. (ctxt->user_sax->elementDecl != NULL))
  27039. ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
  27040. }
  27041. static void
  27042. notationDeclSplit(void *ctx, const xmlChar *name,
  27043. const xmlChar *publicId, const xmlChar *systemId)
  27044. {
  27045. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27046. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27047. (ctxt->user_sax->notationDecl != NULL))
  27048. ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
  27049. systemId);
  27050. }
  27051. static void
  27052. unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
  27053. const xmlChar *publicId, const xmlChar *systemId,
  27054. const xmlChar *notationName)
  27055. {
  27056. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27057. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27058. (ctxt->user_sax->unparsedEntityDecl != NULL))
  27059. ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
  27060. systemId, notationName);
  27061. }
  27062. static void
  27063. setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
  27064. {
  27065. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27066. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27067. (ctxt->user_sax->setDocumentLocator != NULL))
  27068. ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
  27069. }
  27070. static void
  27071. startDocumentSplit(void *ctx)
  27072. {
  27073. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27074. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27075. (ctxt->user_sax->startDocument != NULL))
  27076. ctxt->user_sax->startDocument(ctxt->user_data);
  27077. }
  27078. static void
  27079. endDocumentSplit(void *ctx)
  27080. {
  27081. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27082. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27083. (ctxt->user_sax->endDocument != NULL))
  27084. ctxt->user_sax->endDocument(ctxt->user_data);
  27085. }
  27086. static void
  27087. processingInstructionSplit(void *ctx, const xmlChar *target,
  27088. const xmlChar *data)
  27089. {
  27090. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27091. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27092. (ctxt->user_sax->processingInstruction != NULL))
  27093. ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
  27094. }
  27095. static void
  27096. commentSplit(void *ctx, const xmlChar *value)
  27097. {
  27098. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27099. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27100. (ctxt->user_sax->comment != NULL))
  27101. ctxt->user_sax->comment(ctxt->user_data, value);
  27102. }
  27103. /*
  27104. * Varargs error callbacks to the user application, harder ...
  27105. */
  27106. static void XMLCDECL
  27107. warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  27108. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27109. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27110. (ctxt->user_sax->warning != NULL)) {
  27111. TODO
  27112. }
  27113. }
  27114. static void XMLCDECL
  27115. errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  27116. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27117. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27118. (ctxt->user_sax->error != NULL)) {
  27119. TODO
  27120. }
  27121. }
  27122. static void XMLCDECL
  27123. fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  27124. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27125. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27126. (ctxt->user_sax->fatalError != NULL)) {
  27127. TODO
  27128. }
  27129. }
  27130. /*
  27131. * Those are function where both the user handler and the schemas handler
  27132. * need to be called.
  27133. */
  27134. static void
  27135. charactersSplit(void *ctx, const xmlChar *ch, int len)
  27136. {
  27137. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27138. if (ctxt == NULL)
  27139. return;
  27140. if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
  27141. ctxt->user_sax->characters(ctxt->user_data, ch, len);
  27142. if (ctxt->ctxt != NULL)
  27143. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  27144. }
  27145. static void
  27146. ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
  27147. {
  27148. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27149. if (ctxt == NULL)
  27150. return;
  27151. if ((ctxt->user_sax != NULL) &&
  27152. (ctxt->user_sax->ignorableWhitespace != NULL))
  27153. ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
  27154. if (ctxt->ctxt != NULL)
  27155. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  27156. }
  27157. static void
  27158. cdataBlockSplit(void *ctx, const xmlChar *value, int len)
  27159. {
  27160. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27161. if (ctxt == NULL)
  27162. return;
  27163. if ((ctxt->user_sax != NULL) &&
  27164. (ctxt->user_sax->cdataBlock != NULL))
  27165. ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
  27166. if (ctxt->ctxt != NULL)
  27167. xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
  27168. }
  27169. static void
  27170. referenceSplit(void *ctx, const xmlChar *name)
  27171. {
  27172. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27173. if (ctxt == NULL)
  27174. return;
  27175. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27176. (ctxt->user_sax->reference != NULL))
  27177. ctxt->user_sax->reference(ctxt->user_data, name);
  27178. if (ctxt->ctxt != NULL)
  27179. xmlSchemaSAXHandleReference(ctxt->user_data, name);
  27180. }
  27181. static void
  27182. startElementNsSplit(void *ctx, const xmlChar * localname,
  27183. const xmlChar * prefix, const xmlChar * URI,
  27184. int nb_namespaces, const xmlChar ** namespaces,
  27185. int nb_attributes, int nb_defaulted,
  27186. const xmlChar ** attributes) {
  27187. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27188. if (ctxt == NULL)
  27189. return;
  27190. if ((ctxt->user_sax != NULL) &&
  27191. (ctxt->user_sax->startElementNs != NULL))
  27192. ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
  27193. URI, nb_namespaces, namespaces,
  27194. nb_attributes, nb_defaulted,
  27195. attributes);
  27196. if (ctxt->ctxt != NULL)
  27197. xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
  27198. URI, nb_namespaces, namespaces,
  27199. nb_attributes, nb_defaulted,
  27200. attributes);
  27201. }
  27202. static void
  27203. endElementNsSplit(void *ctx, const xmlChar * localname,
  27204. const xmlChar * prefix, const xmlChar * URI) {
  27205. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27206. if (ctxt == NULL)
  27207. return;
  27208. if ((ctxt->user_sax != NULL) &&
  27209. (ctxt->user_sax->endElementNs != NULL))
  27210. ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
  27211. if (ctxt->ctxt != NULL)
  27212. xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
  27213. }
  27214. /**
  27215. * xmlSchemaSAXPlug:
  27216. * @ctxt: a schema validation context
  27217. * @sax: a pointer to the original xmlSAXHandlerPtr
  27218. * @user_data: a pointer to the original SAX user data pointer
  27219. *
  27220. * Plug a SAX based validation layer in a SAX parsing event flow.
  27221. * The original @saxptr and @dataptr data are replaced by new pointers
  27222. * but the calls to the original will be maintained.
  27223. *
  27224. * Returns a pointer to a data structure needed to unplug the validation layer
  27225. * or NULL in case of errors.
  27226. */
  27227. xmlSchemaSAXPlugPtr
  27228. xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
  27229. xmlSAXHandlerPtr *sax, void **user_data)
  27230. {
  27231. xmlSchemaSAXPlugPtr ret;
  27232. xmlSAXHandlerPtr old_sax;
  27233. if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
  27234. return(NULL);
  27235. /*
  27236. * We only allow to plug into SAX2 event streams
  27237. */
  27238. old_sax = *sax;
  27239. if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
  27240. return(NULL);
  27241. if ((old_sax != NULL) &&
  27242. (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
  27243. ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
  27244. return(NULL);
  27245. /*
  27246. * everything seems right allocate the local data needed for that layer
  27247. */
  27248. ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
  27249. if (ret == NULL) {
  27250. return(NULL);
  27251. }
  27252. memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
  27253. ret->magic = XML_SAX_PLUG_MAGIC;
  27254. ret->schemas_sax.initialized = XML_SAX2_MAGIC;
  27255. ret->ctxt = ctxt;
  27256. ret->user_sax_ptr = sax;
  27257. ret->user_sax = old_sax;
  27258. if (old_sax == NULL) {
  27259. /*
  27260. * go direct, no need for the split block and functions.
  27261. */
  27262. ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
  27263. ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
  27264. /*
  27265. * Note that we use the same text-function for both, to prevent
  27266. * the parser from testing for ignorable whitespace.
  27267. */
  27268. ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
  27269. ret->schemas_sax.characters = xmlSchemaSAXHandleText;
  27270. ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
  27271. ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
  27272. ret->user_data = ctxt;
  27273. *user_data = ctxt;
  27274. } else {
  27275. /*
  27276. * for each callback unused by Schemas initialize it to the Split
  27277. * routine only if non NULL in the user block, this can speed up
  27278. * things at the SAX level.
  27279. */
  27280. if (old_sax->internalSubset != NULL)
  27281. ret->schemas_sax.internalSubset = internalSubsetSplit;
  27282. if (old_sax->isStandalone != NULL)
  27283. ret->schemas_sax.isStandalone = isStandaloneSplit;
  27284. if (old_sax->hasInternalSubset != NULL)
  27285. ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
  27286. if (old_sax->hasExternalSubset != NULL)
  27287. ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
  27288. if (old_sax->resolveEntity != NULL)
  27289. ret->schemas_sax.resolveEntity = resolveEntitySplit;
  27290. if (old_sax->getEntity != NULL)
  27291. ret->schemas_sax.getEntity = getEntitySplit;
  27292. if (old_sax->entityDecl != NULL)
  27293. ret->schemas_sax.entityDecl = entityDeclSplit;
  27294. if (old_sax->notationDecl != NULL)
  27295. ret->schemas_sax.notationDecl = notationDeclSplit;
  27296. if (old_sax->attributeDecl != NULL)
  27297. ret->schemas_sax.attributeDecl = attributeDeclSplit;
  27298. if (old_sax->elementDecl != NULL)
  27299. ret->schemas_sax.elementDecl = elementDeclSplit;
  27300. if (old_sax->unparsedEntityDecl != NULL)
  27301. ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
  27302. if (old_sax->setDocumentLocator != NULL)
  27303. ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
  27304. if (old_sax->startDocument != NULL)
  27305. ret->schemas_sax.startDocument = startDocumentSplit;
  27306. if (old_sax->endDocument != NULL)
  27307. ret->schemas_sax.endDocument = endDocumentSplit;
  27308. if (old_sax->processingInstruction != NULL)
  27309. ret->schemas_sax.processingInstruction = processingInstructionSplit;
  27310. if (old_sax->comment != NULL)
  27311. ret->schemas_sax.comment = commentSplit;
  27312. if (old_sax->warning != NULL)
  27313. ret->schemas_sax.warning = warningSplit;
  27314. if (old_sax->error != NULL)
  27315. ret->schemas_sax.error = errorSplit;
  27316. if (old_sax->fatalError != NULL)
  27317. ret->schemas_sax.fatalError = fatalErrorSplit;
  27318. if (old_sax->getParameterEntity != NULL)
  27319. ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
  27320. if (old_sax->externalSubset != NULL)
  27321. ret->schemas_sax.externalSubset = externalSubsetSplit;
  27322. /*
  27323. * the 6 schemas callback have to go to the splitter functions
  27324. * Note that we use the same text-function for ignorableWhitespace
  27325. * if possible, to prevent the parser from testing for ignorable
  27326. * whitespace.
  27327. */
  27328. ret->schemas_sax.characters = charactersSplit;
  27329. if ((old_sax->ignorableWhitespace != NULL) &&
  27330. (old_sax->ignorableWhitespace != old_sax->characters))
  27331. ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
  27332. else
  27333. ret->schemas_sax.ignorableWhitespace = charactersSplit;
  27334. ret->schemas_sax.cdataBlock = cdataBlockSplit;
  27335. ret->schemas_sax.reference = referenceSplit;
  27336. ret->schemas_sax.startElementNs = startElementNsSplit;
  27337. ret->schemas_sax.endElementNs = endElementNsSplit;
  27338. ret->user_data_ptr = user_data;
  27339. ret->user_data = *user_data;
  27340. *user_data = ret;
  27341. }
  27342. /*
  27343. * plug the pointers back.
  27344. */
  27345. *sax = &(ret->schemas_sax);
  27346. ctxt->sax = *sax;
  27347. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27348. xmlSchemaPreRun(ctxt);
  27349. return(ret);
  27350. }
  27351. /**
  27352. * xmlSchemaSAXUnplug:
  27353. * @plug: a data structure returned by xmlSchemaSAXPlug
  27354. *
  27355. * Unplug a SAX based validation layer in a SAX parsing event flow.
  27356. * The original pointers used in the call are restored.
  27357. *
  27358. * Returns 0 in case of success and -1 in case of failure.
  27359. */
  27360. int
  27361. xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
  27362. {
  27363. xmlSAXHandlerPtr *sax;
  27364. void **user_data;
  27365. if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
  27366. return(-1);
  27367. plug->magic = 0;
  27368. xmlSchemaPostRun(plug->ctxt);
  27369. /* restore the data */
  27370. sax = plug->user_sax_ptr;
  27371. *sax = plug->user_sax;
  27372. if (plug->user_sax != NULL) {
  27373. user_data = plug->user_data_ptr;
  27374. *user_data = plug->user_data;
  27375. }
  27376. /* free and return */
  27377. xmlFree(plug);
  27378. return(0);
  27379. }
  27380. /**
  27381. * xmlSchemaValidateSetLocator:
  27382. * @vctxt: a schema validation context
  27383. * @f: the locator function pointer
  27384. * @ctxt: the locator context
  27385. *
  27386. * Allows to set a locator function to the validation context,
  27387. * which will be used to provide file and line information since
  27388. * those are not provided as part of the SAX validation flow
  27389. * Setting @f to NULL disable the locator.
  27390. */
  27391. void
  27392. xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
  27393. xmlSchemaValidityLocatorFunc f,
  27394. void *ctxt)
  27395. {
  27396. if (vctxt == NULL) return;
  27397. vctxt->locFunc = f;
  27398. vctxt->locCtxt = ctxt;
  27399. }
  27400. /**
  27401. * xmlSchemaValidateStreamLocator:
  27402. * @ctx: the xmlTextReaderPtr used
  27403. * @file: returned file information
  27404. * @line: returned line information
  27405. *
  27406. * Internal locator function for the readers
  27407. *
  27408. * Returns 0 in case the Schema validation could be (de)activated and
  27409. * -1 in case of error.
  27410. */
  27411. static int
  27412. xmlSchemaValidateStreamLocator(void *ctx, const char **file,
  27413. unsigned long *line) {
  27414. xmlParserCtxtPtr ctxt;
  27415. if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
  27416. return(-1);
  27417. if (file != NULL)
  27418. *file = NULL;
  27419. if (line != NULL)
  27420. *line = 0;
  27421. ctxt = (xmlParserCtxtPtr) ctx;
  27422. if (ctxt->input != NULL) {
  27423. if (file != NULL)
  27424. *file = ctxt->input->filename;
  27425. if (line != NULL)
  27426. *line = ctxt->input->line;
  27427. return(0);
  27428. }
  27429. return(-1);
  27430. }
  27431. /**
  27432. * xmlSchemaValidateStream:
  27433. * @ctxt: a schema validation context
  27434. * @input: the input to use for reading the data
  27435. * @enc: an optional encoding information
  27436. * @sax: a SAX handler for the resulting events
  27437. * @user_data: the context to provide to the SAX handler.
  27438. *
  27439. * Validate an input based on a flow of SAX event from the parser
  27440. * and forward the events to the @sax handler with the provided @user_data
  27441. * the user provided @sax handler must be a SAX2 one.
  27442. *
  27443. * Returns 0 if the document is schemas valid, a positive error code
  27444. * number otherwise and -1 in case of internal or API error.
  27445. */
  27446. int
  27447. xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
  27448. xmlParserInputBufferPtr input, xmlCharEncoding enc,
  27449. xmlSAXHandlerPtr sax, void *user_data)
  27450. {
  27451. xmlSchemaSAXPlugPtr plug = NULL;
  27452. xmlSAXHandlerPtr old_sax = NULL;
  27453. xmlParserCtxtPtr pctxt = NULL;
  27454. xmlParserInputPtr inputStream = NULL;
  27455. int ret;
  27456. if ((ctxt == NULL) || (input == NULL))
  27457. return (-1);
  27458. /*
  27459. * prepare the parser
  27460. */
  27461. pctxt = xmlNewParserCtxt();
  27462. if (pctxt == NULL)
  27463. return (-1);
  27464. old_sax = pctxt->sax;
  27465. pctxt->sax = sax;
  27466. pctxt->userData = user_data;
  27467. #if 0
  27468. if (options)
  27469. xmlCtxtUseOptions(pctxt, options);
  27470. #endif
  27471. pctxt->linenumbers = 1;
  27472. xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
  27473. inputStream = xmlNewIOInputStream(pctxt, input, enc);;
  27474. if (inputStream == NULL) {
  27475. ret = -1;
  27476. goto done;
  27477. }
  27478. inputPush(pctxt, inputStream);
  27479. ctxt->parserCtxt = pctxt;
  27480. ctxt->input = input;
  27481. /*
  27482. * Plug the validation and launch the parsing
  27483. */
  27484. plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
  27485. if (plug == NULL) {
  27486. ret = -1;
  27487. goto done;
  27488. }
  27489. ctxt->input = input;
  27490. ctxt->enc = enc;
  27491. ctxt->sax = pctxt->sax;
  27492. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27493. ret = xmlSchemaVStart(ctxt);
  27494. if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
  27495. ret = ctxt->parserCtxt->errNo;
  27496. if (ret == 0)
  27497. ret = 1;
  27498. }
  27499. done:
  27500. ctxt->parserCtxt = NULL;
  27501. ctxt->sax = NULL;
  27502. ctxt->input = NULL;
  27503. if (plug != NULL) {
  27504. xmlSchemaSAXUnplug(plug);
  27505. }
  27506. /* cleanup */
  27507. if (pctxt != NULL) {
  27508. pctxt->sax = old_sax;
  27509. xmlFreeParserCtxt(pctxt);
  27510. }
  27511. return (ret);
  27512. }
  27513. /**
  27514. * xmlSchemaValidateFile:
  27515. * @ctxt: a schema validation context
  27516. * @filename: the URI of the instance
  27517. * @options: a future set of options, currently unused
  27518. *
  27519. * Do a schemas validation of the given resource, it will use the
  27520. * SAX streamable validation internally.
  27521. *
  27522. * Returns 0 if the document is valid, a positive error code
  27523. * number otherwise and -1 in case of an internal or API error.
  27524. */
  27525. int
  27526. xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
  27527. const char * filename,
  27528. int options ATTRIBUTE_UNUSED)
  27529. {
  27530. int ret;
  27531. xmlParserInputBufferPtr input;
  27532. if ((ctxt == NULL) || (filename == NULL))
  27533. return (-1);
  27534. input = xmlParserInputBufferCreateFilename(filename,
  27535. XML_CHAR_ENCODING_NONE);
  27536. if (input == NULL)
  27537. return (-1);
  27538. ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
  27539. NULL, NULL);
  27540. return (ret);
  27541. }
  27542. /**
  27543. * xmlSchemaValidCtxtGetParserCtxt:
  27544. * @ctxt: a schema validation context
  27545. *
  27546. * allow access to the parser context of the schema validation context
  27547. *
  27548. * Returns the parser context of the schema validation context or NULL
  27549. * in case of error.
  27550. */
  27551. xmlParserCtxtPtr
  27552. xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
  27553. {
  27554. if (ctxt == NULL)
  27555. return(NULL);
  27556. return (ctxt->parserCtxt);
  27557. }
  27558. #define bottom_xmlschemas
  27559. #include "elfgcchack.h"
  27560. #endif /* LIBXML_SCHEMAS_ENABLED */